aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2017-06-07 05:06:13 +0200
committerTristan Gingold <tgingold@free.fr>2017-06-07 05:06:13 +0200
commit14b82144f46a8b33e7b38b105e64dee30d889cf2 (patch)
treed8416f10fe7a547736d65660aa5c2eb2e98ec01e
parent761618ebc4e00fbf3642948f4220a18de002b8b1 (diff)
downloadghdl-14b82144f46a8b33e7b38b105e64dee30d889cf2.tar.gz
ghdl-14b82144f46a8b33e7b38b105e64dee30d889cf2.tar.bz2
ghdl-14b82144f46a8b33e7b38b105e64dee30d889cf2.zip
ghwlib: handle gzip/bzip2 compressed files.
-rw-r--r--src/grt/ghwlib.c48
-rw-r--r--src/grt/ghwlib.h8
2 files changed, 52 insertions, 4 deletions
diff --git a/src/grt/ghwlib.c b/src/grt/ghwlib.c
index 426a01973..99d72d021 100644
--- a/src/grt/ghwlib.c
+++ b/src/grt/ghwlib.c
@@ -25,6 +25,27 @@
#include "ghwlib.h"
+/* Reopen H through decompressor DECOMP. */
+
+static int
+ghw_openz (struct ghw_handler *h, const char *decomp, const char *filename)
+{
+ int plen = strlen (decomp) + 1 + strlen(filename) + 1;
+ char *p = malloc (plen);
+
+ snprintf (p, plen, "%s %s", decomp, filename);
+ fclose (h->stream);
+ h->stream = popen(p, "r");
+ free (p);
+
+ if (h->stream == NULL)
+ return -1;
+
+ h->stream_ispipe = 1;
+
+ return 0;
+}
+
int
ghw_open (struct ghw_handler *h, const char *filename)
{
@@ -36,6 +57,27 @@ ghw_open (struct ghw_handler *h, const char *filename)
if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
return -1;
+
+ /* Check compression layer. */
+ if (!memcmp (hdr, "\x1f\x8b", 2))
+ {
+ if (ghw_openz (h, "gzip -cd", filename) < 0)
+ return -1;
+ if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
+ return -1;
+ }
+ else if (!memcmp (hdr, "BZ", 2))
+ {
+ if (ghw_openz (h, "bzip2 -cd", filename) < 0)
+ return -1;
+ if (fread (hdr, sizeof (hdr), 1, h->stream) != 1)
+ return -1;
+ }
+ else
+ {
+ h->stream_ispipe = 0;
+ }
+
/* Check magic. */
if (memcmp (hdr, "GHDLwave\n", 9) != 0)
return -2;
@@ -1872,7 +1914,11 @@ ghw_close (struct ghw_handler *h)
{
if (h->stream)
{
- fclose (h->stream);
+ if (h->stream_ispipe)
+ pclose (h->stream);
+ else
+ fclose (h->stream);
+
h->stream = NULL;
}
}
diff --git a/src/grt/ghwlib.h b/src/grt/ghwlib.h
index b5347bc46..9fdbd1eb8 100644
--- a/src/grt/ghwlib.h
+++ b/src/grt/ghwlib.h
@@ -321,10 +321,12 @@ struct ghw_hie
struct ghw_handler
{
FILE *stream;
+ /* True if STREAM was popen, else was fopen. */
+ unsigned char stream_ispipe;
/* True if words are big-endian. */
- int word_be;
- int word_len;
- int off_len;
+ unsigned char word_be;
+ unsigned char word_len;
+ unsigned char off_len;
/* Minor version. */
int version;