unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Andreas Schwab <schwab@suse.de>
Cc: Kenichi Handa <handa@m17n.org>
Subject: Re: dired doesn't work properly with a multibyte locale
Date: Mon, 27 Jan 2003 11:56:48 +0100	[thread overview]
Message-ID: <jey956n9n3.fsf@sykes.suse.de> (raw)
In-Reply-To: <buoptqjb51e.fsf@mcspd15.ucom.lsi.nec.co.jp> (Miles Bader's message of "27 Jan 2003 13:17:01 +0900")

Miles Bader <miles@lsi.nec.co.jp> writes:

|> Kenichi Handa <handa@m17n.org> writes:
|> > > If there's a file containing a newline, then if LANG=C, dired can
|> > > correctly deal with it (e.g., I can put the cursor on it and hit RET,
|> > > and it visits that file), but if LANG=ja_JP.eucjp, then it correctly
|> > > displays all _other_ files, but you can't use RET to visit the
|> > > newline-in-the-file-name file (it says `File no longer exists; type `g'
|> > > to update Dired buffer').
|> > 
|> > So, I have no idea what's wrong with the current code.
|> > Could you debug it?
|> 
|> Hmm, it actually seems to be a bug with `ls'!
|> 
|> I created two files, one called `abc\ndef' (where \n is a newline), and
|> one called `1234567'.  Here's what ls prints if stdout is a tty (I've
|> indented the output by 3 spaces):
|> 
|>    (tmp) LANG=ja_JP.eucJP ls -l --dired abc* 123*
|>      -rw-rw----    1 miles           6 2003-01-27 13:03 1234567
|>      -rw-rw----    1 miles           6 2003-01-27 12:58 abc?def
|>    //DIRED// 53 60 114 121
|>    //DIRED-OPTIONS// --quoting-style=literal
|> 
|> [note that the start/end offsets of each filename differ by 7]
|> 
|> But here's what the _same_ command prints if stdout is a pipe (which I
|> presume is the case for dired):
|> 
|>    (tmp) LANG=ja_JP.eucJP ls -l --dired abc* 123* | cat
|>      -rw-rw----    1 miles           6 2003-01-27 13:03 1234567
|>      -rw-rw----    1 miles           6 2003-01-27 12:58 abc
|>    def
|>    //DIRED// 53 60 114 120
|>    //DIRED-OPTIONS// --quoting-style=literal
|> 
|> Now the start/end offsets of `abc\ndef' now only differ by 6 (which is
|> obviously wrong, since the filename is 7 characters long)!  Morever
|> this problem only seems to occur if LANG=ja_JP.eucJP, _not_ if LANG=C.

Here is a patch.  The dired offset are documented as being byte counts,
not character counts.  The bug happens in any multibyte locale.

Andreas.

2003-01-27  Andreas Schwab  <schwab@suse.de>

	* src/ls.c (quote_name): Add fourth parameter width into which to
	store the screen columns and return number of bytes instead.
	(print_dir): Pass NULL as fourth parameter of quote_name.
	(print_name_with_quoting): Likewise.
	(length_of_file_name_and_frills): Get the width from the fourth
	parameter of quote_name instead of return value.

--- src/ls.c	2002/12/16 18:58:01	1.3
+++ src/ls.c	2003/01/27 10:50:51
@@ -255,7 +255,8 @@ char *getgroup ();
 char *getuser ();
 
 static size_t quote_name PARAMS ((FILE *out, const char *name,
-				  struct quoting_options const *options));
+				  struct quoting_options const *options,
+				  size_t *width));
 static char *make_link_path PARAMS ((const char *path, const char *linkname));
 static int decode_switches PARAMS ((int argc, char **argv));
 static int file_interesting PARAMS ((const struct dirent *next));
@@ -2222,7 +2223,7 @@ print_dir (const char *name, const char 
       DIRED_INDENT ();
       PUSH_CURRENT_DIRED_POS (&subdired_obstack);
       dired_pos += quote_name (stdout, realname ? realname : name,
-			       dirname_quoting_options);
+			       dirname_quoting_options, NULL);
       PUSH_CURRENT_DIRED_POS (&subdired_obstack);
       DIRED_FPUTS_LITERAL (":\n", stdout);
     }
@@ -3064,11 +3065,13 @@ print_long_format (const struct fileinfo
 
 /* Output to OUT a quoted representation of the file name NAME,
    using OPTIONS to control quoting.  Produce no output if OUT is NULL.
-   Return the number of screen columns occupied by NAME's quoted
-   representation.  */
+   Store the number of screen columns occupied by NAME's quoted
+   representation into WIDTH, if non-NULL.  Return the number of bytes
+   produced.  */
 
 static size_t
-quote_name (FILE *out, const char *name, struct quoting_options const *options)
+quote_name (FILE *out, const char *name, struct quoting_options const *options,
+	    size_t *width)
 {
   char smallbuf[BUFSIZ];
   size_t len = quotearg_buffer (smallbuf, sizeof smallbuf, name, -1, options);
@@ -3203,20 +3206,32 @@ quote_name (FILE *out, const char *name,
 	  displayed_width = len;
 	}
     }
-  else
+  else if (width != NULL)
     {
-      /* Assume unprintable characters have a displayed_width of 1.  */
 #if HAVE_MBRTOWC
       if (MB_CUR_MAX > 1)
 	displayed_width = mbsnwidth (buf, len, 0);
       else
 #endif
-	displayed_width = len;
+	{
+	  char *p = buf;
+	  char const *plimit = buf + len;
+
+	  displayed_width = 0;
+	  while (p < plimit)
+	    {
+	      if (ISPRINT ((unsigned char) *p))
+		displayed_width++;
+	      p++;
+	    }
+	}
     }
 
   if (out != NULL)
     fwrite (buf, 1, len, out);
-  return displayed_width;
+  if (width != NULL)
+    *width = displayed_width;
+  return len;
 }
 
 static void
@@ -3229,7 +3244,7 @@ print_name_with_quoting (const char *p, 
   if (stack)
     PUSH_CURRENT_DIRED_POS (stack);
 
-  dired_pos += quote_name (stdout, p, filename_quoting_options);
+  dired_pos += quote_name (stdout, p, filename_quoting_options, NULL);
 
   if (stack)
     PUSH_CURRENT_DIRED_POS (stack);
@@ -3395,6 +3410,7 @@ static int
 length_of_file_name_and_frills (const struct fileinfo *f)
 {
   register int len = 0;
+  size_t name_width;
 
   if (print_inode)
     len += INODE_DIGITS + 1;
@@ -3402,7 +3418,8 @@ length_of_file_name_and_frills (const st
   if (print_block_size)
     len += 1 + block_size_size;
 
-  len += quote_name (NULL, f->name, filename_quoting_options);
+  quote_name (NULL, f->name, filename_quoting_options, &name_width);
+  len += name_width;
 
   if (indicator_style != none)
     {

-- 
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux AG, Deutschherrnstr. 15-19, D-90429 Nürnberg
Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

  parent reply	other threads:[~2003-01-27 10:56 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-01-06  6:04 dired doesn't work properly with a multibyte locale Miles Bader
2003-01-11 20:00 ` Stefan Monnier
2003-01-11 20:16   ` Miles Bader
2003-01-12 11:56 ` Richard Stallman
2003-01-15 10:43 ` Kenichi Handa
2003-01-15 23:30   ` Richard Stallman
2003-01-23  4:31   ` Miles Bader
2003-01-23  6:02     ` Kenichi Handa
2003-01-23  6:12       ` Miles Bader
2003-01-25  0:49         ` Kenichi Handa
2003-01-27  4:17           ` Miles Bader
2003-01-27  5:01             ` Kenichi Handa
2003-01-27 10:58               ` Andreas Schwab
2003-01-27 11:09                 ` Kenichi Handa
2003-01-27 12:15                   ` Andreas Schwab
2003-02-03  0:17                     ` Kenichi Handa
2003-02-03  1:24                       ` Miles Bader
2003-02-03  2:11                         ` Kenichi Handa
2003-02-03  2:22                           ` Miles Bader
2003-02-03  8:40                             ` Kenichi Handa
2003-02-03  9:02                               ` Miles Bader
2003-02-03  9:10                                 ` Kenichi Handa
2003-02-03  9:22                                   ` Miles Bader
2003-02-03  9:37                                     ` Jim Meyering
2003-02-03 11:00                                   ` Andreas Schwab
2003-02-03 11:17                                     ` Kenichi Handa
2003-02-13 13:58                                       ` Dave Love
2003-02-17  6:19                                         ` Kenichi Handa
2003-02-03 17:47                           ` Dave Love
2003-02-03 17:44                         ` Dave Love
2003-02-03 18:45                           ` Michael Livshin
2003-02-03 19:13                             ` Eli Zaretskii
2003-02-03  9:37                       ` Jim Meyering
2003-02-03 17:20                       ` Richard Stallman
2003-02-03 18:53                         ` Andreas Schwab
2003-01-27 10:56             ` Andreas Schwab [this message]
2003-01-27 13:35               ` Jim Meyering
2003-01-24  5:42     ` Richard Stallman

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=jey956n9n3.fsf@sykes.suse.de \
    --to=schwab@suse.de \
    --cc=handa@m17n.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.
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).