Subject: Re: bug#25623: CC Mode 5.32.99 (C/l); `c-defun-name' returns wrong result for filescope enums, structs and unions

From: Alan Mackenzie <[email-masked]>
Date: Sun, 23 Apr 2017 12:18:05 +0000

Hello, Mohammed.

On Sun, Feb 05, 2017 at 08:17:50 +0530, Mohammed Sadiq wrote:

> When the point is in struct, enum or union of file scope, `c-defun-name'
> returns wrong result.

> Eg: In the following example (where `|' is where the points are (ie, 3
> cursors are 3 different cases),
> case 1, in struct: the result is "t" ("struct test" may be a better
> result, the same for union)
> case 2, in enum: the result is "ONE" ("enum" may be better)
> case 3, in main: the result is "main" (which is of course, right)

> Also, simply return "struct", "union", etc if no tag name is present
> (like in "typedef struct {...")

> struct test
> {
>   int a;|
> };

> enum {
>   ONE,
>   TWO|
> };

> int
> main (void)
> {
>   |
> }

Thanks for the bug report.  This bug is simply a matter of buggy code in
CC Mode.  There follows a patch.

Would you please apply this patch, compile cc-cmds.el, try it out, then
either confirm to me that the bug is fixed, or tell me what still needs
looking at.  Thanks in advance!

diff -r f78dfc813575 cc-cmds.el
--- a/cc-cmds.el	Sat Apr 22 14:18:55 2017 +0000
+++ b/cc-cmds.el	Sun Apr 23 12:09:06 2017 +0000
@@ -1769,19 +1769,25 @@
 	  (unless (eq where 'at-header)
 	    (c-backward-to-nth-BOF-{ 1 where)
 	    (c-beginning-of-decl-1))
+	  (when (looking-at c-typedef-key)
+	    (goto-char (match-end 0))
+	    (c-forward-syntactic-ws))
 
 	  ;; Pick out the defun name, according to the type of defun.
 	  (cond
 	   ;; struct, union, enum, or similar:
-	   ((and (looking-at c-type-prefix-key)
-		 (progn (c-forward-token-2 2) ; over "struct foo "
-			(or (eq (char-after) ?\{)
-			    (looking-at c-symbol-key)))) ; "struct foo bar ..."
-	    (save-match-data (c-forward-token-2))
-	    (when (eq (char-after) ?\{)
-	      (c-backward-token-2)
-	      (looking-at c-symbol-key))
-	    (match-string-no-properties 0))
+	   ((looking-at c-type-prefix-key)
+	    (let ((key-pos (point)))
+	      (c-forward-token-2 1)	; over "struct ".
+	      (cond
+	       ((looking-at c-symbol-key)	; "struct foo { ..."
+		(buffer-substring-no-properties key-pos (match-end 0)))
+	       ((eq (char-after) ?{)	; "struct { ... } foo"
+		(when (c-go-list-forward)
+		  (c-forward-syntactic-ws)
+		  (when (looking-at c-symbol-key) ; a bit bogus - there might
+						  ; be several identifiers.
+		    (match-string-no-properties 0)))))))
 
 	   ((looking-at "DEFUN\\s-*(") ;"DEFUN\\_>") think of XEmacs!
 	    ;; DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory, ...) ==> Ffile_name_directory

> Thanks

[ .... ]

-- 
Alan Mackenzie (Nuremberg, Germany).