all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Eli Zaretskii <eliz@gnu.org>
To: "Francesco Potortì" <pot@gnu.org>
Cc: eggert@cs.ucla.edu, emacs-devel@gnu.org
Subject: Re: etags test is broken on MS-Windows
Date: Thu, 21 May 2015 19:49:22 +0300	[thread overview]
Message-ID: <83mw0x6fl9.fsf@gnu.org> (raw)
In-Reply-To: <E1YvQSq-0005SX-0e@tucano.isti.cnr.it>

> Date: Thu, 21 May 2015 15:24:44 +0200
> From: Francesco Potortì <pot@gnu.org>
> Cc: emacs-devel@gnu.org, Paul Eggert <eggert@cs.ucla.edu>
> 
> >f-src/entry.for,172
> >      LOGICAL FUNCTION PRTPKG ^?3,75
> >       ENTRY  SETPRT ^?194,3866
> >       ENTRY  MSGSEL ^?395,8478
> >     & intensity1(^?577,12231
> >       character*(*) function foo(^?579,12307
> >^L
> >f-src/entry.strange_suffix,172
> >      LOGICAL FUNCTION PRTPKG ^?3,75
> >       ENTRY  SETPRT ^?194,3866
> >       ENTRY  MSGSEL ^?395,8478
> >     & intensity1(^?577,12231
> >       character*(*) function foo(^?579,12307
> >^L
> >f-src/entry.strange,171
> >      LOGICAL FUNCTION PRTPKG ^?2,2
> >       ENTRY  SETPRT ^?193,3793
> >       ENTRY  MSGSEL ^?394,8405
> >     & intensity1(^?576,12158
> >       character*(*) function foo(^?578,12234
> >
> >Now, these 3 files have exactly identical contents, and the _only_
> >difference between the first 2 and the 3rd is that the latter is
> >gzip-compressed.  So that should be the only reason why all its line
> >counts are off by 1, and its byte counts are all off by 73, which just
> >happens to be the length of the first line of the (uncompressed) file.
> 
> This is a bug.
> 
> >So could it be that rewinding a 'popen'-created stream doesn't work
> >correctly on GNU/Linux as well?  If so, we will have to make changes
> >in etags to not do that, I think, and instead reuse the already-read
> >stuff as needed.
> 
> It could well be.  It may have happened that, when I checked that the
> TAGS files were the same, I just looked at them without running diff and
> I missed this discrepancy.

After thinking a bit about the alternative solution, I concluded that
the simplest will be to decompress to a temporary file and read from
there.  Does the patch below look OK?  Or can someone think about a
more elegant way of solving this?


diff --git a/lib-src/etags.c b/lib-src/etags.c
index 0a308c1..28729da 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -116,6 +116,7 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 # undef HAVE_NTGUI
 # undef  DOS_NT
 # define DOS_NT
+# define O_CLOEXEC O_NOINHERIT
 #endif /* WINDOWSNT */
 
 #include <unistd.h>
@@ -125,6 +126,7 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 #include <sysstdio.h>
 #include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <binary-io.h>
@@ -336,6 +338,7 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 static char *absolute_dirname (char *, char *);
 static bool filename_is_absolute (char *f);
 static void canonicalize_filename (char *);
+static char *etags_mktmp (void);
 static void linebuffer_init (linebuffer *);
 static void linebuffer_setlen (linebuffer *, int);
 static void *xmalloc (size_t);
@@ -1437,7 +1440,7 @@ C code are parsed as C code (use --help --lang=c --lang=yacc\n\
   fdesc *fdp;
   compressor *compr;
   char *compressed_name, *uncompressed_name;
-  char *ext, *real_name;
+  char *ext, *real_name, *tmp_name;
   int retval;
 
   canonicalize_filename (file);
@@ -1522,9 +1525,20 @@ C code are parsed as C code (use --help --lang=c --lang=yacc\n\
     }
   if (real_name == compressed_name)
     {
-      char *cmd = concat (compr->command, " ", real_name);
-      inf = popen (cmd, "r" FOPEN_BINARY);
-      free (cmd);
+      tmp_name = etags_mktmp ();
+      if (!tmp_name)
+	inf = NULL;
+      else
+	{
+	  char *cmd1 = concat (compr->command, " ", real_name);
+	  char *cmd = concat (cmd1, " > ", tmp_name);
+	  free (cmd1);
+	  if (system (cmd) == -1)
+	    inf = NULL;
+	  else
+	    inf = fopen (tmp_name, "r" FOPEN_BINARY);
+	  free (cmd);
+	}
     }
   else
     inf = fopen (real_name, "r" FOPEN_BINARY);
@@ -1536,10 +1550,12 @@ C code are parsed as C code (use --help --lang=c --lang=yacc\n\
 
   process_file (inf, uncompressed_name, lang);
 
+  retval = fclose (inf);
   if (real_name == compressed_name)
-    retval = pclose (inf);
-  else
-    retval = fclose (inf);
+    {
+      remove (tmp_name);
+      free (tmp_name);
+    }
   if (retval < 0)
     pfatal (file);
 
@@ -1707,9 +1723,6 @@ C code are parsed as C code (use --help --lang=c --lang=yacc\n\
 	}
     }
 
-  /* We rewind here, even if inf may be a pipe.  We fail if the
-     length of the first line is longer than the pipe block size,
-     which is unlikely. */
   rewind (inf);
 
   /* Else try to guess the language given the case insensitive file name. */
@@ -1734,8 +1747,6 @@ C code are parsed as C code (use --help --lang=c --lang=yacc\n\
       if (old_last_node == last_node)
 	/* No Fortran entries found.  Try C. */
 	{
-	  /* We do not tag if rewind fails.
-	     Only the file name will be recorded in the tags file. */
 	  rewind (inf);
 	  curfdp->lang = get_language_from_langname (cplusplus ? "c++" : "c");
 	  find_entries (inf);
@@ -5015,8 +5026,6 @@ enum,		0,			st_C_enum
       TEX_opgrp = '<';
       TEX_clgrp = '>';
     }
-  /* If the input file is compressed, inf is a pipe, and rewind may fail.
-     No attempt is made to correct the situation. */
   rewind (inf);
 }
 
@@ -6344,6 +6353,51 @@ enum,		0,			st_C_enum
   return path;
 }
 
+/* Return a newly allocated string containing a name of a temporary file.  */
+static char *
+etags_mktmp (void)
+{
+  const char *tmpdir = getenv ("TMPDIR");
+  const char *slash = "/";
+
+#if MSDOS || defined (DOS_NT)
+  if (!tmpdir)
+    tmpdir = getenv ("TEMP");
+  if (!tmpdir)
+    tmpdir = getenv ("TMP");
+  if (!tmpdir)
+    tmpdir = ".";
+  if (tmpdir[strlen (tmpdir) - 1] == '/'
+      || tmpdir[strlen (tmpdir) - 1] == '\\')
+    slash = "";
+#else
+  if (!tmpdir)
+    tmpdir = "/tmp";
+  if (tmpdir[strlen (tmpdir) - 1] == '/')
+    slash = "";
+#endif
+
+  char *templt = concat (tmpdir, slash, "etXXXXXX");
+  int fd = mkostemp (templt, O_CLOEXEC);
+  if (fd < 0)
+    {
+      free (templt);
+      templt = NULL;
+    }
+  else
+    close (fd);
+
+#if defined (DOS_NT)
+  /* The file name will be used in shell redirection, so it needs to have
+     DOS-style backslashes, or else the Windows shell will barf.  */
+  char *p;
+  for (p = templt; *p; p++)
+    if (*p == '/')
+      *p = '\\';
+#endif
+  return templt;
+}
+
 /* Return a newly allocated string containing the file name of FILE
    relative to the absolute directory DIR (which should end with a slash). */
 static char *




  reply	other threads:[~2015-05-21 16:49 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <83y4kmdjmj.fsf@gnu.org>
     [not found] ` <555A8E62.7060700@cs.ucla.edu>
2015-05-19 15:27   ` etags test is broken on MS-Windows Eli Zaretskii
2015-05-19 17:57     ` Paul Eggert
2015-05-19 18:26       ` Eli Zaretskii
2015-05-20 15:38     ` Eli Zaretskii
2015-05-21  5:05       ` Paul Eggert
2015-05-21 13:24       ` Francesco Potortì
2015-05-21 16:49         ` Eli Zaretskii [this message]
2015-05-23  8:46           ` Eli Zaretskii
2015-05-21 13:16     ` Francesco Potortì
2015-05-21 16:31       ` Eli Zaretskii
2015-05-21 16:37         ` Paul Eggert
2015-05-21 16:55           ` Eli Zaretskii
2015-05-21 19:03             ` Paul Eggert
2015-05-21 19:54               ` Eli Zaretskii
2015-05-21 23:28                 ` Paul Eggert
2015-05-22  8:32                   ` Eli Zaretskii
2015-05-22 13:08                     ` Francesco Potortì
2015-05-22 13:19                       ` Eli Zaretskii
2015-05-22 18:23                         ` Paul Eggert
2015-05-22 19:08                           ` Eli Zaretskii
2015-05-22 19:25                             ` Andreas Schwab
2015-05-22 19:38                               ` Eli Zaretskii
2015-05-22 19:41                                 ` Andreas Schwab
2015-05-22 19:42                                 ` Eli Zaretskii
2015-05-22 19:50                                   ` Andreas Schwab
2015-05-22 20:05                                     ` Eli Zaretskii
2015-05-22 20:30                                       ` Andreas Schwab
2015-05-22 21:26                                         ` Paul Eggert
2015-05-23  6:40                                           ` Eli Zaretskii
2015-05-23  6:39                                         ` Eli Zaretskii
2015-05-23  8:02                                           ` Andreas Schwab
2015-05-23  8:27                                             ` Eli Zaretskii
2015-05-23  9:41                                               ` Andreas Schwab
2015-05-23  9:49                                                 ` Eli Zaretskii
2015-05-23  9:59                                                   ` Andreas Schwab
2015-05-23 10:20                                                     ` Eli Zaretskii
2015-05-23 10:54                                                       ` Andreas Schwab
2015-05-23 11:31                                                         ` Eli Zaretskii
2015-05-23 12:10                                                           ` Andreas Schwab
2015-05-23 13:46                                                             ` Eli Zaretskii
2015-05-23 17:27                                                               ` Andreas Schwab
2015-05-23 17:37                                                                 ` Eli Zaretskii
2015-05-23 18:46                                                                   ` Andreas Schwab
2015-05-23 19:04                                                                     ` Eli Zaretskii
2015-05-25 12:33                                                                       ` Francesco Potortì
2015-05-23 19:01                                                               ` Paul Eggert
2015-05-23 19:27                                                                 ` Eli Zaretskii
2015-05-25 16:44                                                                   ` Paul Eggert
2015-05-25 19:33                                                                     ` Eli Zaretskii
2015-05-25 20:29                                                                       ` Paul Eggert
2015-05-22 12:40               ` Francesco Potortì

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=83mw0x6fl9.fsf@gnu.org \
    --to=eliz@gnu.org \
    --cc=eggert@cs.ucla.edu \
    --cc=emacs-devel@gnu.org \
    --cc=pot@gnu.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 external index

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

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.