Bug 26639 - CDT should enforce newline at end of header files
Summary: CDT should enforce newline at end of header files
Status: RESOLVED FIXED
Alias: None
Product: CDT
Classification: Tools
Component: cdt-core (show other bugs)
Version: 2.0   Edit
Hardware: PC Linux-GTK
: P3 enhancement (vote)
Target Milestone: 4.0 M5   Edit
Assignee: Anton Leherbauer CLA
QA Contact:
URL:
Whiteboard:
Keywords: contributed
Depends on:
Blocks:
 
Reported: 2002-11-19 02:07 EST by Johan Walles CLA
Modified: 2008-06-20 10:36 EDT (History)
4 users (show)

See Also:


Attachments
A patch file which contains the code to fix bug #26639 (1.18 KB, patch)
2006-07-14 05:15 EDT, Abeer Bagul CLA
no flags Details | Diff
Patch modified according to comments by Anton Leherbauer and Doug Schaefer (6.77 KB, patch)
2006-07-18 01:18 EDT, Abeer Bagul CLA
no flags Details | Diff
Some more modifications :) (6.43 KB, patch)
2006-07-20 09:26 EDT, Abeer Bagul CLA
no flags Details | Diff
The patch made ready for commit (6.79 KB, patch)
2006-07-21 10:26 EDT, Anton Leherbauer CLA
bjorn.freeman-benson: iplog+
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Johan Walles CLA 2002-11-19 02:07:25 EST
When saving a header file, CDT should add a newline as the last character if
there isn't one already.  The reason is that if we have two header files foo.h
and bar.h containing...

#define FOO 1

#define BAR 2

... respectively (without newlines at the end), and then #include them after
each other, the result could become:

#define FOO 1#define BAR 2

... which is not what we want.

Another (more pragmatic) reason is that gcc has a warning for this that can't be
shut off :-).
Comment 1 Henning Riedel CLA 2003-09-08 08:35:26 EDT
I'm not sure if this is really right what you tell as example, since you 
don't include like: 
 
#include "foo.h" "bar.h" 
 
but as: 
 
#include "foo.h"     /* <--- there is a new line here! */ 
#include "bar.h" 
 
 
Comment 2 Johan Walles CLA 2003-09-08 08:51:58 EDT
The ending newline (that you marked) gets replaced with the contents of the
#include:d file, together with the rest of the #include line.
Comment 3 Doug Schaefer CLA 2004-05-27 15:10:06 EDT
This is more of an enhancement request than a bug.
Comment 4 Kleo Hapitas CLA 2004-07-07 16:46:37 EDT
PR was targeted at 2.0 but was not resolved at release time. Changing target 
to 2.1
Comment 5 Abeer Bagul CLA 2006-07-14 05:15:21 EDT
Created attachment 46288 [details]
A patch file which contains the code to fix bug #26639
Comment 6 Abeer Bagul CLA 2006-07-14 05:17:55 EDT
I would like to submit a patch for this bug. It involves modifying the method
createSaveOperation() in class
org.eclipse.cdt.internal.ui.editor.CDocumentProvider. The extra code to be
added at the start of the method checks if the document in question has a '\n'
character as the last character. If not, it will append a "\r\n" for Windows
and a '\n' for *nix. The patch is like so:

Index: CDocumentProvider.java
===================================================================
RCS file:
/cvsroot/tools/org.eclipse.cdt-core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CDocumentProvider.java,v
retrieving revision 1.33
diff -u -r1.33 CDocumentProvider.java
--- CDocumentProvider.java      6 Jul 2006 14:52:55 -0000       1.33
+++ CDocumentProvider.java      14 Jul 2006 09:15:45 -0000
@@ -922,6 +922,18 @@
         * @see
org.eclipse.ui.editors.text.TextFileDocumentProvider#createSaveOperation(java.lang.Object,
org.eclipse.jface.text.IDocument, boolean)
         */
        protected DocumentProviderOperation createSaveOperation(final Object
element, final IDocument document, final boolean overwrite) throws
CoreException {
+
+               //add a newline to the end of the document (if it is not
already present)
+               int offset = document.getLength() - 1;
+               try {
+                       char lastChar = document.getChar(offset);
+                       if (lastChar != '\n')
+                       {
+                               document.replace(offset, 1, lastChar +
System.getProperty("line.separator"));
+                       }
+               } catch (BadLocationException e) {
+               }
+
                final FileInfo info= getFileInfo(element);
                if (info instanceof TranslationUnitInfo) {
                        return new DocumentProviderOperation() {


------------------------------------------------
Legal Message: I, Abeer Bagul, declare that I developed attached code from
scratch, without referencing any 3rd party materials except material licensed
under the EPL. {I am authorized by my employer, Tensilica Inc. to make this
contribution under the EPL.} 
Comment 7 Anton Leherbauer CLA 2006-07-17 05:26:38 EDT
I am not quite happy with the patch.
- it does not handle Mac style line delimiter \r
  (hint: avoid explicit line separator characters by checking the length
  of the last line)
- use IDocumentExtension4.getDefaultLineDelimiter() instead of 
  System.getProperty("file.separator")
- it should consider an empty document 
- why is the last character replaced by itself?
- maybe there should be a preference option
Comment 8 Doug Schaefer CLA 2006-07-17 09:14:06 EDT
I'm not massively in favour of this feature request at all to begin with. I don't like my editors magically changing my files on me. What if I didn't want a newline at the end of my file for whatever bizarre reason.

gcc gives a warning about missing nl's at the end of files which leaves markers at those lines. I use that to help make keep my files clean.
Comment 9 Abeer Bagul CLA 2006-07-18 01:18:39 EDT
Created attachment 46416 [details]
Patch modified according to comments by Anton Leherbauer and Doug Schaefer

I have modified my earlier patch according to suggestions given in comments #7 and #8. 
- Checking the presence of a newline by looking at the length of the last line. (This will handle Mac style newlines)
- I am using IDocumentExtension4.getDefaultLineDelimiter() and also System.getProperty("file.separator") incase the concrete document class does not implement the interface IDocumentExtension4.
- I have added a preference option to C/C++ -> Editor -> Appearances. This option is disabled by default. So users who dont prefer auto-modification of their source code will not be affected by it. 
- Our customers had requested this feature, so we can enable this feature preference in the startup code of our product plugin.
Comment 10 Pete MacLiesh CLA 2006-07-18 03:05:59 EDT
(In reply to comment #8)
> I'm not massively in favour of this feature request at all to begin with. I
> don't like my editors magically changing my files on me. What if I didn't want
> a newline at the end of my file for whatever bizarre reason.
> gcc gives a warning about missing nl's at the end of files which leaves markers
> at those lines. I use that to help make keep my files clean.

The fix in the broader "source files" sense, not just headers, comes from default emacs and vi behaviour. I was surprised when i first encountered it, but both of those editors are smart enough to ensure that there is a newline at the end of source files - but not other (unrecognized extension) files. That seems a reasonable behaviour to emulate.
Comment 11 Anton Leherbauer CLA 2006-07-19 07:46:28 EDT
That's much better, still there are some suggestions:
- the preference option label should read something like:
  "Add missing line delimiter at the end of the file when saving"
  I think this describes the feature more accurately, as not only headers 
  or .c files are fixed, but all files that are opened with the CEditor and it 
  happens only when a file is saved. (Native english speakers, please improve 
  the wording!)
- Use org.eclipse.jface.TextUtilities.getDefaultLineDelimiter(IDocument)
  This utility method handles all cases.
- Use IDocument.replace(document.getLength(), 0, newLine) to append the 
  newline.
Comment 12 Abeer Bagul CLA 2006-07-20 09:26:38 EDT
Created attachment 46576 [details]
Some more modifications :)

I have changed the preference option label. Also using TextUtilities.getDefaultLineDelimiter and appending the newline rather than replacing the last char with itself.
Comment 13 Anton Leherbauer CLA 2006-07-21 10:16:54 EDT
Is there a special reason why you omitted the checkbox in the preference page? No problem, though, I can add it myself, I just wanted to make sure, this was by accident.
BTW, I have changed my mind regarding the option label. Now, my favorite is:
"Ensure &newline at end of file when saving".
Comment 14 Anton Leherbauer CLA 2006-07-21 10:26:55 EDT
Created attachment 46636 [details]
The patch made ready for commit

I did only minor changes:
- added missing checkbox to preference page
- changed label text as indicated
- moved preference constant from CEditor to PreferenceConstants
Comment 15 Abeer Bagul CLA 2006-07-23 02:52:29 EDT
Sorry, I forgot to add the checkbox to the preference page. 
Comment 16 Anton Leherbauer CLA 2006-07-25 03:25:12 EDT
Applied to 4.0 > 20060725