public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Doug Evans <xdje42@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: gdb-patches@sourceware.org
Subject: Re: [PATCH] TUI: Expand TABs into spaces
Date: Tue, 27 Jan 2015 11:17:00 -0000	[thread overview]
Message-ID: <m3mw548x6z.fsf@sspiff.org> (raw)
In-Reply-To: <834mreq9t3.fsf@gnu.org> (Eli Zaretskii's message of "Mon, 26 Jan	2015 09:29:28 +0200")

Eli Zaretskii <eliz@gnu.org> writes:
>> From: Doug Evans <xdje42@gmail.com>
>> Cc: gdb-patches@sourceware.org
>> Date: Sat, 24 Jan 2015 13:26:47 -0800
>> 
>> For tui_register_format it used to be such a straightforward function,
>> it's a shame to grow it by 2x for bitfiddly tab handling.
>> 
>> Let's add a helper routine that takes one string and returns
>> another with tabs expanded, and put this helper routine in, say tui-io.c
>> (this routine isn't tui-regs specific), and then call that routine from
>> tui_register_format.
>
> I did that below, but since tui_register_format is its only user,
> keeping that function in tui-regs.c would have allowed us to make it
> static.  Wouldn't that be slightly better?

That's not an invalid viewpoint, and if you want to go
that route, fine by me.  One argument for going that route
is that if another user comes along one can always make
it public later.  Alas that doesn't always happen, and one
ends up writing something that already exists.
[If a year from now I need something like that the last
place I'm going to look is tui-regs.c, whereas I will at least look
through all the headers and generic-looking files for something.
I wish I had a previous example at hand, I've paged out the details
from memory and all that's left is wanting to avoid that.
IIRC we've even had cases where something generic was used by
multiple callers, then only one, and then someone moved it and
made it static.  If there were multiple callers once there may
be again (depending on the situation of course) so if I'm given the
choice I wouldn't have made that move.]
[Also, one could argue that this function isn't even tui-specific
and thus should go in something like gdb/utils.c or even libiberty.
Keeping it in tui just violates what I said above about being in
the last place someone would look.
I opted for not getting too carried away with things: I don't
yet see a need for expanding tabs to spaces outside of tui,
but I could be wrong of course.  Plus I wouldn't impose spending
any time going back and forth picking the absolute best location,
there are far more important things, and one could argue I've made
you read too much already.]
[OTOOH :-), if I hadn't said at least some of this the probability
is too high that someone else would.  Bleah.
[Not saying it would be you though!]]

So to make a long story short, feel free to leave it where it is or
make it static.

A few comments below.

> Thanks for the review; updated patch attached.
>
> 2015-01-26  Eli Zaretskii  <eliz@gnu.org>
>
> 	* tui/tui-io.c (tui_expand_tabs): New function.
> 	(tui_puts, tui_redisplay_readline): Expand TABs into the
> 	appropriate number of spaces.
> 	* tui/tui-regs.c: Include tui-io.h.
> 	(tui_register_format): Call tui_expand_tabs to expand TABs into
> 	the appropriate number of spaces.
> 	* tui/tui-io.h: Add prototype for tui_expand_tabs.
>
> --- tui/tui-io.c~0	Wed Oct 29 21:45:50 2014
> +++ tui/tui-io.c	Mon Jan 26 09:10:34 2015
> @@ -179,7 +179,20 @@ tui_puts (const char *string)
>        else if (tui_skip_line != 1)
>          {
>            tui_skip_line = -1;
> -          waddch (w, c);
> +	  /* Expand TABs, since ncurses on MS-Windows doesn't.  */
> +	  if (c == '\t')
> +	    {
> +	      int line, col;
> +
> +	      getyx (w, line, col);
> +	      do
> +		{
> +		  waddch (w, ' ');
> +		  col++;
> +		} while ((col % 8) != 0);
> +	    }
> +	  else
> +	    waddch (w, c);
>          }
>        else if (c == '\n')
>          tui_skip_line = -1;
> @@ -254,6 +269,16 @@ tui_redisplay_readline (void)
>            waddch (w, '^');
>            waddch (w, CTRL_CHAR (c) ? UNCTRL (c) : '?');
>  	}
> +      else if (c == '\t')
> +	{
> +	  /* Expand TABs, since ncurses on MS-Windows doesn't.  */
> +	  getyx (w, line, col);
> +	  do
> +	    {
> +	      waddch (w, ' ');
> +	      col++;
> +	    } while ((col % 8) != 0);
> +	}
>        else
>  	{
>            waddch (w, c);
> @@ -700,6 +725,58 @@ tui_getc (FILE *fp)
>    return ch;
>  }
>  
> +/* Utility function to expand TABs in a STRING into spaces.  STRING
> +   will be displayed starting at column COL.  The returned expanded
> +   string is malloc'ed.  */

blank line between function comment and definition
[I realize tui_get_register doesn't do that, but best do that with
new code.]

Also, I'm guessing that newlines in STRING isn't supported here, right?
If so, mention that in the function comment.
One could even add an assert like:

  gdb_assert (strchr (string, '\n') == NULL);

or some such.

> +char *
> +tui_expand_tabs (const char *string, int col)
> +{
> +  int n_adjust;
> +  const char *s;
> +  char *ret, *q;
> +
> +  /* 1. How many additional characters do we need?  */
> +  for (n_adjust = 0, s = string; s; )
> +    {
> +      s = strpbrk (s, "\t");
> +      if (s)
> +	{
> +	  col += (s - string) + n_adjust;
> +	  /* Adjustment for the next tab stop, minus one for the TAB
> +	     we replace with spaces.  */
> +	  n_adjust += 8 - (col % 8) - 1;
> +	  s++;
> +	}
> +    }
> +
> +  /* Allocate the copy.  */
> +  ret = q = xmalloc (strlen (string) + n_adjust + 1);
> +
> +  /* 2. Copy the original string while replacing TABs with spaces.  */
> +  for (s = string; s; )
> +    {
> +      char *s1 = strpbrk (s, "\t");
> +      if (s1)
> +	{
> +	  if (s1 > s)
> +	    {
> +	      strncpy (q, s, s1 - s);
> +	      q += s1 - s;
> +	      col += s1 - s;
> +	    }
> +	  do {
> +	    *q++ = ' ';
> +	    col++;
> +	  } while ((col % 8) != 0);
> +	  s1++;
> +	}
> +      else
> +	strcpy (q, s);
> +      s = s1;
> +    }
> +
> +  return ret;
> +}
>  
>  /* Cleanup when a resize has occured.
>     Returns the character that must be processed.  */
>
>
> --- tui/tui-regs.c~0	Wed Oct 29 21:45:50 2014
> +++ tui/tui-regs.c	Mon Jan 26 09:24:23 2015
> @@ -37,6 +37,7 @@
>  #include "tui/tui-wingeneral.h"
>  #include "tui/tui-file.h"
>  #include "tui/tui-regs.h"
> +#include "tui/tui-io.h"
>  #include "reggroups.h"
>  #include "valprint.h"
>  
> @@ -694,7 +695,9 @@ tui_register_format (struct frame_info *
>    if (s && s[1] == 0)
>      *s = 0;
>  
> -  ret = xstrdup (p);
> +  /* Expand tabs into spaces, since ncurses on MS-Windows doesn't.  */
> +  ret = tui_expand_tabs (p, 0);
> +
>    do_cleanups (cleanups);
>  
>    return ret;
>
>
> --- tui/tui-io.h~0	Wed Jun 11 19:34:41 2014
> +++ tui/tui-io.h	Mon Jan 26 09:11:42 2015
> @@ -41,6 +41,9 @@
>     changed the edited text.  */
>  extern void tui_redisplay_readline (void);
>  
> +/* Expand TABs into spaces.  */

For reference sake, there are multiple schools of thought, and no
fixed convention in gdb, for whether to put a comment here, and
what it should look like.  No need to change anything, and I can
go into details if you want.  Just wanted to mention the issue,
and the acceptable choice of not having any comment here.

> +extern char *tui_expand_tabs (const char *, int);
> +
>  extern struct ui_out *tui_out;
>  extern struct ui_out *tui_old_uiout;
>  

  reply	other threads:[~2015-01-27  8:07 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-01-03 11:30 Eli Zaretskii
2015-01-16 11:17 ` Eli Zaretskii
2015-01-16 16:32   ` Doug Evans
2015-01-16 16:43     ` Eli Zaretskii
2015-01-16 17:30       ` Doug Evans
2015-01-16 17:53         ` Eli Zaretskii
2015-01-16 18:25           ` Doug Evans
2015-01-16 20:11             ` Eli Zaretskii
2015-01-17  1:02               ` Doug Evans
2015-01-17  7:56                 ` Eli Zaretskii
2015-01-24 14:15     ` Eli Zaretskii
2015-01-25 11:31       ` Doug Evans
2015-01-26 11:42         ` Eli Zaretskii
2015-01-27 11:17           ` Doug Evans [this message]
2015-01-31 21:08             ` Eli Zaretskii

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

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

  git send-email \
    --in-reply-to=m3mw548x6z.fsf@sspiff.org \
    --to=xdje42@gmail.com \
    --cc=eliz@gnu.org \
    --cc=gdb-patches@sourceware.org \
    /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.
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).