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 *
next prev parent 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.