unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Yuan Fu <casouri@gmail.com>
To: Po Lu <luangruo@yahoo.com>
Cc: 59468@debbugs.gnu.org
Subject: bug#59468: 29.0.50; c-ts-mode cannot fontify after macros are  encountered
Date: Tue, 22 Nov 2022 12:11:17 -0800	[thread overview]
Message-ID: <BE9875BB-5434-4BEE-8774-97F3D5995D2A@gmail.com> (raw)
In-Reply-To: <87k03n4v0r.fsf@yahoo.com>


Po Lu <luangruo@yahoo.com> writes:

> Insert the following code in a buffer, and enable c-ts-mode.
>
> #define CheckExtension(name)				\
>   if (!name)						\
>     {							\
>       if (display)					\
> 	eglTerminate (display);				\
>       fprintf (stderr, "Missing: egl%s\n", #name + 1);	\
>       return False;					\
>     }
>
> #define CheckExtensionGl(name)				\
>   if (!name)						\
>     {							\
>       /* If the context remains current, then nothing	\
> 	 will get released upon eglTerminate.  */	\
>       eglMakeCurrent (display, EGL_NO_SURFACE,		\
> 		      EGL_NO_SURFACE, EGL_NO_CONTEXT);	\
>       eglTerminate (display);				\
>       fprintf (stderr, "Missing: gl%s\n", #name + 1);	\
>       return False;					\
>     }
>
> #define LoadProc(name, ext, extname)			\
>   if (HaveEglExtension (extname))			\
>     I##name						\
>       = (void *) eglGetProcAddress ("egl" #name ext)
>
> #define LoadProcGl(name, ext, extname)			\
>   if (HaveGlExtension (extname))			\
>     I##name						\
>       = (void *) eglGetProcAddress ("gl" #name ext)
>
> #define CheckGlExtension(name)			\
>   if (!HaveGlExtension (name))			\
>     {						\
>       fprintf (stderr, "Missing %s\n", name);	\
> 						\
>       eglMakeCurrent (display, EGL_NO_SURFACE,	\
> 		      EGL_NO_SURFACE,		\
> 		      EGL_NO_CONTEXT);		\
>       eglTerminate (display);			\
>       return False;				\
>     }
>
> There will be no fontification of types or string constants inside the
> macro bodies.  CC Mode works fine.
>
> Now, insert the following code below the macro definition:
>
> static Visual *
> FindVisual (VisualID visual, int *depth)
> {
>   XVisualInfo vinfo, *visuals;
>   Visual *value;
>   int nvisuals;
>   const char *override;
> }
>
> visual, depth, visuals, value and override are not fontified as
> identifiers.  Line feed characters below the macros are also fontfied as
> "errors".
>
> Within the following code:
>
> static BufferActivityRecord *
> FindBufferActivityRecord (PictureBuffer *buffer, PictureTarget *target)
> {
>   BufferActivityRecord *record;
>
>   /* Look through the global activity list for a record matching
>      the given values.  */
>   record = all_activity.global_next;
>   while (record != &all_activity)
>     {
>       if (record->buffer == buffer
> 	  && record->target == target)
> 	return record;
>
>       record = record->global_next;
>     }
>
>   return NULL;
> }
>
> "record" is fontified as an identifier, but not within the condition in
> the while loop.
>
> Within the following code:
>
> static void
> compare_single_row_8bpc4 (unsigned char *data, unsigned char *xdata,
> 			  size_t size,
> 			  struct image_difference_statistics *statistics)
> {
>   unsigned char channel_a, channel_b;
>   int diff;
>   size_t i;
>
>   for (i = 0; i < size; ++i)
>     {
>       channel_a = data[i];
>       channel_b = xdata[i];
>
>       diff = (int) channel_b - (int) channel_a;
>       statistics->min_diff = MIN (statistics->min_diff,
> 				  diff);
>       statistics->max_diff = MAX (statistics->max_diff,
> 				  diff);
>     }
> }
>
> the "i" in "size_t i" is fontified as an identifier the first time, but
> not in future appearances in the function.
>
> Within src/xterm.c, every appearance of ATOM_REFS_INIT is fontified in
> the error face.  Also, inside `xm_setup_dnd_targets',
>
>   xm_targets_table_header header;
>   xm_targets_table_rec **recs UNINIT;
>   xm_byte_order byteorder;
>
> "recs" is fontified in the error face.
>
> 	      recs = xmalloc (sizeof *recs);
> 	      recs[0] = xmalloc (FLEXSIZEOF (struct xm_targets_table_rec,
> 					     targets, ntargets * 4));
>
> 	      recs[0]->n_targets = ntargets;
>
> "struct" is fontified in the error face.  Within
> x_sync_note_frame_times:
>
> #ifdef FRAME_DEBUG
>   uint_fast64_t last_frame_ms = output->last_frame_time / 1000;
>   fprintf (stderr,
> 	   "Drawing the last frame took: %"PRIuFAST64" ms (%"PRIuFAST64")\n",
> 	   last_frame_ms, time);
> #endif
>
> "PRIuFAST64" is fontified in the error face.  Within
> x_dnd_begin_drag_and_drop:
>
> 	  if (x_dnd_movement_frame
> 	      /* FIXME: how come this can end up with movement frames
> 		 from other displays on GTK builds?  */
> 	      && (FRAME_X_DISPLAY (x_dnd_movement_frame)
> 		  == FRAME_X_DISPLAY (f))
> 	      /* If both those variables are false, then F is no
> 		 longer protected from deletion by Lisp code.  This
> 		 can only happen during the final iteration of the DND
> 		 event loop.  */
> 	      && (x_dnd_in_progress || x_dnd_waiting_for_finish))
> 	    {
> 	      XSETFRAME (frame_object, x_dnd_movement_frame);
>
> is fontified incorrectly: the "if" is not fontified at all, and the last
> three lines show up in the error faces.
>
> In addition:
>
> Lisp_Object
> x_dnd_begin_drag_and_drop (struct frame *f, Time time, Atom xaction,
> 			   Lisp_Object return_frame, Atom *ask_action_list,
> 			   const char **ask_action_names, size_t n_ask_actions,
> 			   bool allow_current_frame, Atom *target_atoms,
> 			   int ntargets, Lisp_Object selection_target_list,
> 			   bool follow_tooltip)
>
> "Lisp_Object" and "x_dnd_begin_drag_and_drop" are not fontified at all.
>
> Here:
>
> /* Select for input extension events used by scroll bars.  This will
>    result in the corresponding core events not being generated for
>    SCROLL_BAR.  */
>
> MAYBE_UNUSED static void
> xi_select_scroll_bar_events (struct x_display_info *dpyinfo,
> 			     Window scroll_bar)
>
> "void" is fontified in the error face.
>
> Here, in handle_one_xevent:
>
> #ifdef HAVE_XINPUT2
>       if (event->type != GenericEvent)
> #endif
> 	any = x_any_window_to_frame (dpyinfo, event->xany.window);
> #ifdef HAVE_XINPUT2
>       else
> 	any = NULL;
> #endif
>
> the "else" is fontified as a type.
>
> static int
> handle_one_xevent (struct x_display_info *dpyinfo,
> #ifndef HAVE_XINPUT2
> 		   const XEvent *event,
> #else
> 		   XEvent *event,
> #endif
> 		   int *finish, struct input_event *hold_quit)
>
> the "const XEvent *" is fontified in the error face.
>
> Here:
>
>     case GraphicsExpose:	/* This occurs when an XCopyArea's
>                                    source area was obscured or not
>                                    available.  */
>       f = x_window_to_frame (dpyinfo, event->xgraphicsexpose.drawable);
>       if (f)
>         {
>           expose_frame (f, event->xgraphicsexpose.x,
>                         event->xgraphicsexpose.y,
>                         event->xgraphicsexpose.width,
>                         event->xgraphicsexpose.height);
> #ifndef USE_TOOLKIT_SCROLL_BARS
> 	  x_scroll_bar_handle_exposure (f, (XEvent *) event);
> #endif
> #ifdef USE_GTK
> 	  x_clear_under_internal_border (f);
> #endif
> #ifdef HAVE_XDBE
> 	  show_back_buffer (f);
> #endif
>         }
> #ifdef USE_X_TOOLKIT
>       else
>         goto OTHER;
> #endif /* USE_X_TOOLKIT */
>       break;
>
> "goto OTHER" is fontified in the error face, and "else" as a type.
>
> Here:
>
> #ifdef HAVE_XINPUT2
> 	      if (event->xkey.time == pending_keystroke_time)
> 		{
> 		  source = xi_device_from_id (dpyinfo,
> 					      dpyinfo->pending_keystroke_source);
>
> 		  if (source)
> 		    inev.ie.device = source->name;
> 		}
> #endif
>
> "inev" is fontified in the error face.
>
> Here:
>
> #ifdef USE_GTK
>       /* See comment in EnterNotify above */
>       else if (dpyinfo->last_mouse_glyph_frame)
>         x_note_mouse_movement (dpyinfo->last_mouse_glyph_frame,
> 			       &event->xmotion, Qnil);
> #endif
>
> "else" and "dpyinfo" are fontified as types.
>
> #ifdef USE_MOTIF
> 	    Widget widget;
>
> 	    widget = XtWindowToWidget (dpyinfo->display,
> 				       event->xbutton.window);
>
> 	    if (widget && XmIsCascadeButton (widget)
> 		&& XtIsSensitive (widget))
> 	      {
> #endif
> 		if (!f->output_data.x->saved_menu_event)
> 		  f->output_data.x->saved_menu_event = xmalloc (sizeof *event);
> 		*f->output_data.x->saved_menu_event = *event;
> 		inev.ie.kind = MENU_BAR_ACTIVATE_EVENT;
> 		XSETFRAME (inev.ie.frame_or_window, f);
> 		*finish = X_EVENT_DROP;
> #ifdef USE_MOTIF
> 	      }
> #endif
>
> here, the last closing brace is fontified in the error face.
>
> Here:
>
> static void NO_INLINE
> x_error_quitter (Display *display, XErrorEvent *event)
> {
>   char buf[256], buf1[400 + INT_STRLEN_BOUND (int)
> 		      + INT_STRLEN_BOUND (unsigned long)];
>
> "NO_INLINE" and "unsigned long" are fontified in the error face.
>
> CC mode fontifies all of the examples above fine, and they are not even
> pre-standard C.  Would someone please fix c-ts-mode to fontify them
> correctly as well?
>

Thanks for these reports! Buuuuut as we’ve seen, tree-sitter really
doesn’t handle macros that well. I’ll see what I can do when I find the
time, but there really isn’t any good solutions to this (right now, that
I can think of). I’m not even sure the author of tree-sitter-c would
accept changes that try to parse macros: he has made it clear that the
purpose of tree-sitter-c is to support post-processed C and leave macros
and preprocessor to error-recovery.

Yuan





  reply	other threads:[~2022-11-22 20:11 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <87k03n4v0r.fsf.ref@yahoo.com>
2022-11-22  1:50 ` bug#59468: 29.0.50; c-ts-mode cannot fontify after macros are encountered Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-22 20:11   ` Yuan Fu [this message]
2022-11-23  0:41     ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-23  3:30     ` Eli Zaretskii
2022-11-23  4:13       ` Yuan Fu
2022-11-23  7:36         ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-23 12:53           ` Eli Zaretskii
2022-11-23 12:43         ` Eli Zaretskii
2022-11-23  1:27   ` Yuan Fu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-24  0:03   ` Yuan Fu
2022-11-24  0:36     ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-24  9:19       ` Eli Zaretskii
2022-11-24 10:36         ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-24 10:55           ` Eli Zaretskii
2022-11-24 12:12             ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-11-26  2:39     ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=BE9875BB-5434-4BEE-8774-97F3D5995D2A@gmail.com \
    --to=casouri@gmail.com \
    --cc=59468@debbugs.gnu.org \
    --cc=luangruo@yahoo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).