unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#13244: cc-mode indentation fails depending on the phase of the moon
@ 2012-12-21  1:06 Dietrich Epp
  2012-12-27 16:20 ` Alan Mackenzie
  0 siblings, 1 reply; 3+ messages in thread
From: Dietrich Epp @ 2012-12-21  1:06 UTC (permalink / raw)
  To: 13244

[-- Attachment #1: Type: text/plain, Size: 3151 bytes --]

This bug is weird.  I couldn't use auto-indentation in a certain file.  I tried restarting Emacs, behavior persists.  I upgraded to the latest version from Bzr, behavior persists.  I created a new account with no .emacs file and tried from there, behavior persists.  In comparison, indentation works correctly in the Emacs that in the current Debian Wheezy repository, which is 24.3.50.1.

Trying to automatically indent code inside the last function in the attached file fails.  It succeeds if I make almost any modification to code above the last function in the file -- it could be something as minor as adding a space on an empty line, but changing text in the comments seems to have no effect.  Indentation works in every function but the last one (or any one you create below it).

The point at which indentation breaks is somewhere very close to the bottom of the file, I deleted code from the bottom of the file until I found the location where it breaks.

In GNU Emacs 24.3.50.1 (x86_64-unknown-linux-gnu, GTK+ Version 3.4.2)
 of 2012-12-20 on moria
Bzr revision: 111280 dmantipov@yandex.ru-20121220160905-qpa3zdo5rx335ydu
Windowing system distributor `The X.Org Foundation', version 11.0.11204000
System Description:	Debian GNU/Linux testing (wheezy)

Configured using:
 `configure '--prefix=/opt/emacs''

Important settings:
  value of $LANG: en_US.UTF-8
  value of $XMODIFIERS: @im=ibus
  locale-coding-system: utf-8-unix
  default enable-multibyte-characters: t

Major mode: C/l

Minor modes in effect:
  tooltip-mode: t
  mouse-wheel-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t
  abbrev-mode: t

Load-path shadows:
None found.

Features:
(shadow sort gnus-util mail-extr emacsbug message cl-macs gv format-spec
rfc822 mml mml-sec mm-decode mm-bodies mm-encode mail-parse rfc2231
mailabbrev gmm-utils mailheader sendmail rfc2047 rfc2045 ietf-drums
mm-util mail-prsvr mail-utils misearch multi-isearch edmacro kmacro
cc-langs cl nadvice cl-lib cc-mode cc-fonts easymenu cc-guess cc-menus
cc-cmds server cc-styles cc-align cc-engine cc-vars cc-defs
deeper-blue-theme time-date tooltip ediff-hook vc-hooks lisp-float-type
mwheel x-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list newcomment lisp-mode register page menu-bar rfn-eshadow
timer select scroll-bar mouse jit-lock font-lock syntax facemenu
font-core frame cham georgian utf-8-lang misc-lang vietnamese tibetan
thai tai-viet lao korean japanese hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese case-table epa-hook
jka-cmpr-hook help simple abbrev minibuffer loaddefs button faces
cus-face macroexp files text-properties overlay sha1 md5 base64 format
env code-pages mule custom widget hashtable-print-readable backquote
make-network-process dbusbind inotify dynamic-setting
system-font-setting font-render-setting move-toolbar gtk x-toolkit x
multi-tty emacs)



[-- Attachment #2: emacsbug.c.gz --]
[-- Type: application/x-gzip, Size: 4141 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* bug#13244: cc-mode indentation fails depending on the phase of the moon
  2012-12-21  1:06 bug#13244: cc-mode indentation fails depending on the phase of the moon Dietrich Epp
@ 2012-12-27 16:20 ` Alan Mackenzie
  2013-03-11 20:57   ` Alan Mackenzie
  0 siblings, 1 reply; 3+ messages in thread
From: Alan Mackenzie @ 2012-12-27 16:20 UTC (permalink / raw)
  To: Dietrich Epp; +Cc: 13244

Hello, Dietrich.

>This bug is weird.  I couldn't use auto-indentation in a certain file.
>I tried restarting Emacs, behavior persists.  I upgraded to the latest
>version from Bzr, behavior persists.  I created a new account with no
>.emacs file and tried from there, behavior persists.  In comparison,
>indentation works correctly in the Emacs that in the current Debian
>Wheezy repository, which is 24.3.50.1.

>Trying to automatically indent code inside the last function in the
>attached file fails.  It succeeds if I make almost any modification to
>code above the last function in the file -- it could be something as
>minor as adding a space on an empty line, but changing text in the
>comments seems to have no effect.  Indentation works in every function
>but the last one (or any one you create below it).

>The point at which indentation breaks is somewhere very close to the
>bottom of the file, I deleted code from the bottom of the file until I
>found the location where it breaks.

What is happening is this: CC Mode maintains a cache of "safe positions"
(i.e. positions not in a string or comment) approximately every 3000
bytes.  By pure chance, one of these supposed positions in your file is
at pos. 21002, which happens to be between the "/" and the "*" of the
comment opener on L836.  This position isn't safe at all, and is found
due to a bug in a low level scanning routine (`parse-partial-sexp') in
Emacs.

Furthermore, that comment contains an "unbalanced" "'".  So when CC Mode
scans forward from that supposed safe position, it finds the "'" and
thinks it's inside a string.  This is why indentation isn't working in
your file after that comment.

As you've noted, the slightest change to the buffer and the error no
longer happens (since the "safe" position is no longer inside the
comment opener).

Thank you very much indeed for taking the trouble to report this arcane
bug.  We actually noticed the possibility of this bug in December 2011
and discussed it a bit, but nobody actually got around to fixing it
then.  Maybe we should now.

-- 
Alan Mackenzie (Nuremberg, Germany).





^ permalink raw reply	[flat|nested] 3+ messages in thread

* bug#13244: cc-mode indentation fails depending on the phase of the moon
  2012-12-27 16:20 ` Alan Mackenzie
@ 2013-03-11 20:57   ` Alan Mackenzie
  0 siblings, 0 replies; 3+ messages in thread
From: Alan Mackenzie @ 2013-03-11 20:57 UTC (permalink / raw)
  To: Dietrich Epp; +Cc: 13244

Hello again, Dietrich.

On Thu, Dec 27, 2012 at 04:20:54PM +0000, Alan Mackenzie wrote:
> >This bug is weird.  I couldn't use auto-indentation in a certain file.
> >I tried restarting Emacs, behavior persists.  I upgraded to the latest
> >version from Bzr, behavior persists.  I created a new account with no
> >.emacs file and tried from there, behavior persists.  In comparison,
> >indentation works correctly in the Emacs that in the current Debian
> >Wheezy repository, which is 24.3.50.1.

> >Trying to automatically indent code inside the last function in the
> >attached file fails.  It succeeds if I make almost any modification to
> >code above the last function in the file -- it could be something as
> >minor as adding a space on an empty line, but changing text in the
> >comments seems to have no effect.  Indentation works in every function
> >but the last one (or any one you create below it).

> >The point at which indentation breaks is somewhere very close to the
> >bottom of the file, I deleted code from the bottom of the file until I
> >found the location where it breaks.

> What is happening is this: CC Mode maintains a cache of "safe positions"
> (i.e. positions not in a string or comment) approximately every 3000
> bytes.  By pure chance, one of these supposed positions in your file is
> at pos. 21002, which happens to be between the "/" and the "*" of the
> comment opener on L836.  This position isn't safe at all, and is found
> due to a bug in a low level scanning routine (`parse-partial-sexp') in
> Emacs.

> Furthermore, that comment contains an "unbalanced" "'".  So when CC Mode
> scans forward from that supposed safe position, it finds the "'" and
> thinks it's inside a string.  This is why indentation isn't working in
> your file after that comment.

> As you've noted, the slightest change to the buffer and the error no
> longer happens (since the "safe" position is no longer inside the
> comment opener).

> Thank you very much indeed for taking the trouble to report this arcane
> bug.  We actually noticed the possibility of this bug in December 2011
> and discussed it a bit, but nobody actually got around to fixing it
> then.  Maybe we should now.


I've got a patch which should fix this problem.  Maybe you could apply
the patch to Emacs and check that it works properly.  Just in case you
don't have the critical file any more, I could send that to you too.  :-)

Again, thanks for the bug report.



diff -r bc6aa6ba14cc cc-engine.el
--- a/cc-engine.el	Wed Mar 06 12:02:31 2013 +0000
+++ b/cc-engine.el	Mon Mar 11 20:51:42 2013 +0000
@@ -2179,32 +2179,45 @@
 ;; reduced by buffer changes, and increased by invocations of
 ;; `c-state-literal-at'.  FIMXE!!!
 
-(defsubst c-state-pp-to-literal (from to)
+(defsubst c-state-pp-to-literal (from to &optional not-in-delimiter)
   ;; Do a parse-partial-sexp from FROM to TO, returning either
   ;;     (STATE TYPE (BEG . END))     if TO is in a literal; or
   ;;     (STATE)                      otherwise,
   ;; where STATE is the parsing state at TO, TYPE is the type of the literal
   ;; (one of 'c, 'c++, 'string) and (BEG . END) is the boundaries of the literal.
   ;;
+  ;; Unless NOT-IN-DELIMITER is non-nil, when TO is inside a two-character
+  ;; comment opener, this is recognized as being in a comment literal.
+  ;;
   ;; Only elements 3 (in a string), 4 (in a comment), 5 (following a quote),
   ;; 7 (comment type) and 8 (start of comment/string) (and possibly 9) of
   ;; STATE are valid.
   (save-excursion
     (let ((s (parse-partial-sexp from to))
-	  ty)
-      (when (or (nth 3 s) (nth 4 s))	; in a string or comment
+	  ty co-st)
+      (cond
+       ((or (nth 3 s) (nth 4 s))	; in a string or comment
 	(setq ty (cond
 		  ((nth 3 s) 'string)
-		  ((eq (nth 7 s) t) 'c++)
+		  ((nth 7 s) 'c++)
 		  (t 'c)))
 	(parse-partial-sexp (point) (point-max)
-			    nil			 ; TARGETDEPTH
-			    nil			 ; STOPBEFORE
-			    s			 ; OLDSTATE
-			    'syntax-table))	 ; stop at end of literal
-      (if ty
-	  `(,s ,ty (,(nth 8 s) . ,(point)))
-	`(,s)))))
+			    nil		   ; TARGETDEPTH
+			    nil		   ; STOPBEFORE
+			    s		   ; OLDSTATE
+			    'syntax-table) ; stop at end of literal
+	`(,s ,ty (,(nth 8 s) . ,(point))))
+
+       ((and (not not-in-delimiter)	; inside a comment starter
+	     (not (bobp))
+	     (progn (backward-char)
+		    (looking-at c-comment-start-regexp)))
+	(setq ty (if (looking-at c-block-comment-start-regexp) 'c 'c++)
+	      co-st (point))
+	(forward-comment 1)
+	`(,s ,ty (,co-st . ,(point))))
+
+       (t `(,s))))))
 
 (defun c-state-safe-place (here)
   ;; Return a buffer position before HERE which is "safe", i.e. outside any
@@ -3146,10 +3159,13 @@
   ;; This function is called from c-after-change.
 
   ;; The caches of non-literals:
-  (if (< here c-state-nonlit-pos-cache-limit)
-      (setq c-state-nonlit-pos-cache-limit here))
-  (if (< here c-state-semi-nonlit-pos-cache-limit)
-      (setq c-state-semi-nonlit-pos-cache-limit here))
+  ;; Note that we use "<=" for the possibility of the second char of a two-char
+  ;; comment opener being typed; this would invalidate any cache position at
+  ;; HERE.
+  (if (<= here c-state-nonlit-pos-cache-limit)
+      (setq c-state-nonlit-pos-cache-limit (1- here)))
+  (if (<= here c-state-semi-nonlit-pos-cache-limit)
+      (setq c-state-semi-nonlit-pos-cache-limit (1- here)))
 
   ;; `c-state-cache':
   ;; Case 1: if `here' is in a literal containing point-min, everything
@@ -4467,19 +4483,12 @@
 	   (lim (or lim (c-state-semi-safe-place pos)))
 	   (pp-to-lit (save-restriction
 			(widen)
-			(c-state-pp-to-literal lim pos)))
+			(c-state-pp-to-literal lim pos not-in-delimiter)))
 	   (state (car pp-to-lit))
 	   (lit-limits (car (cddr pp-to-lit))))
 
       (cond
        (lit-limits)
-       ((and (not not-in-delimiter)
-	     (not (elt state 5))
-	     (eq (char-before) ?/)
-	     (looking-at "[/*]")) ; FIXME!!! use c-line/block-comment-starter.  2008-09-28.
-	;; We're standing in a comment starter.
-	(backward-char 1)
-	(cons (point) (progn (c-forward-single-comment) (point))))
 
        (near
 	(goto-char pos)
diff -r bc6aa6ba14cc cc-fonts.el
--- a/cc-fonts.el	Wed Mar 06 12:02:31 2013 +0000
+++ b/cc-fonts.el	Mon Mar 11 20:51:42 2013 +0000
@@ -2449,7 +2449,7 @@
 	      (setq comment-beg nil))
 	    (setq region-beg comment-beg))
 
-      (if (eq (elt (parse-partial-sexp comment-beg (+ comment-beg 2)) 7) t)
+      (if (elt (parse-partial-sexp comment-beg (+ comment-beg 2)) 7)
 	  ;; Collect a sequence of doc style line comments.
 	  (progn
 	    (goto-char comment-beg)



-- 
Alan Mackenzie (Nuremberg, Germany).





^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-03-11 20:57 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-21  1:06 bug#13244: cc-mode indentation fails depending on the phase of the moon Dietrich Epp
2012-12-27 16:20 ` Alan Mackenzie
2013-03-11 20:57   ` Alan Mackenzie

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).