Working DOS version
authorRobert Pengelly <robertapengelly@hotmail.com>
Sun, 1 Mar 2026 15:04:20 +0000 (15:04 +0000)
committerRobert Pengelly <robertapengelly@hotmail.com>
Sun, 1 Mar 2026 15:04:20 +0000 (15:04 +0000)
Makefile.wat [new file with mode: 0644]
bitstream.c
huffman.c
inflate.c
lib.c
lib.h
report.c
unzip.c

diff --git a/Makefile.wat b/Makefile.wat
new file mode 100644 (file)
index 0000000..9f789b7
--- /dev/null
@@ -0,0 +1,19 @@
+#******************************************************************************
+# @file             Makefile.wat
+#******************************************************************************
+SRCDIR              ?=  $(CURDIR)
+VPATH               :=  $(SRCDIR)
+
+CSRC                :=  unzip.c bitstream.c huffman.c inflate.c lib.c lz77.c report.c tables.c vector.c
+INCDIR              :=  $(subst /,\,$(SRCDIR))
+
+all: unzip.exe
+
+unzip.exe: $(CSRC)
+
+       wcl -I$(INCDIR)\\include -fe=$@ $^
+
+clean:
+
+       for /r %%f in (*.obj) do ( if exist %%f ( del /q %%f ) )
+       if exist unzip.exe ( del /q unzip.exe )
index 18f811369fa6321d2edf299b3a6ea911c3c42d05..740afce296d1a464996af72f2f3e495a5b5d5b06 100644 (file)
@@ -14,8 +14,8 @@ int istream_init (istream_t *is, unsigned char *s, uint64_t n) {
 
     is->end = (is->src = s) + n;
     
-    is->bitpos = 0;
     is->bitpos_end = n * 8;
+    is->bitpos = 0;
     
     return 0;
 
index 319e9f31f5a8845b134a6da4c7028b3c4dea7e23..b7ac1701099452c6cdd658787de9184f05590800 100644 (file)
--- a/huffman.c
+++ b/huffman.c
@@ -3,6 +3,8 @@
  *****************************************************************************/
 #include    <assert.h>
 #include    <limits.h>
+#include    <stdio.h>
+#include    <stdlib.h>
 
 #include    "huffman.h"
 #include    "lib.h"
@@ -52,8 +54,9 @@ static void table_insert (huffman_decoder_t *d, uint64_t sym, uint64_t len, uint
 int huffman_decoder_init (huffman_decoder_t *d, unsigned char *lengths, uint64_t n) {
 
     uint16_t count[MAX_HUFFMAN_BITS + 1] = { 0 };
-    uint16_t code[MAX_HUFFMAN_BITS + 1];
-    uint16_t sym_idx[MAX_HUFFMAN_BITS + 1];
+    uint16_t code[MAX_HUFFMAN_BITS + 1] = { 0 };
+    
+    uint16_t sym_idx[MAX_HUFFMAN_BITS + 1] = { 0 };
     
     uint64_t i, l;
     uint32_t s;
@@ -92,7 +95,7 @@ int huffman_decoder_init (huffman_decoder_t *d, unsigned char *lengths, uint64_t
         
         }
         
-        s = (uint32_t) ((code[l] + count[l]) << (MAX_HUFFMAN_BITS - l));
+        s = (uint32_t) (((uint32_t) code[l] + (uint32_t) count[l]) << (MAX_HUFFMAN_BITS - l));
         
         d->sentinel_bits[l] = s;
         assert (d->sentinel_bits[l] >= code[l] && "no overflow!");
index e1d163435d6b94ef33785c3f2f92e520c5e1b441..69d3368da211d42876f795b582732f6f81ec7af7 100644 (file)
--- a/inflate.c
+++ b/inflate.c
@@ -253,8 +253,8 @@ static inf_stat_t init_dyn_decoders (istream_t *is, huffman_decoder_t *litlen_de
     uint64_t num_litlen_lens, num_dist_lens, num_codelen_lens;
     uint64_t i, n, used;
     
-    unsigned char code_lengths[MAX_LITLEN_LENS + MAX_DIST_LENS];
-    unsigned char codelen_lengths[MAX_CODELEN_LENS];
+    static unsigned char code_lengths[MAX_LITLEN_LENS + MAX_DIST_LENS] = { 0 };
+    static unsigned char codelen_lengths[MAX_CODELEN_LENS] = { 0 };
     
     huffman_decoder_t codelen_dec;
     int sym;
@@ -262,19 +262,19 @@ static inf_stat_t init_dyn_decoders (istream_t *is, huffman_decoder_t *litlen_de
     uint64_t bits = istream_bits (is);
     
     /* Number of litlen codeword lengths (5 bits + 257). */
-    num_litlen_lens = (uint64_t) (lsb (bits, 5) + MIN_LITLEN_LENS);
+    num_litlen_lens = (uint64_t) lsb (bits, 5) + MIN_LITLEN_LENS;
     bits >>= 5;
     
     assert (num_litlen_lens <= MAX_LITLEN_LENS);
     
     /* Number of codeword lengths (5 bits + 1). */
-    num_dist_lens = (uint64_t) (lsb (bits, 5) + MIN_DIST_LENS);
+    num_dist_lens = (uint64_t) lsb (bits, 5) + MIN_DIST_LENS;
     bits >>= 5;
     
     assert (num_dist_lens <= MAX_DIST_LENS);
     
     /* Number of code length lengths (4 bits + 4). */
-    num_codelen_lens = (uint64_t) (lsb (bits, 4) + MIN_CODELEN_LENS);
+    num_codelen_lens = (uint64_t) lsb (bits, 4) + MIN_CODELEN_LENS;
     bits >>= 4;
     
     assert (num_codelen_lens <= MAX_CODELEN_LENS);
@@ -355,7 +355,7 @@ static inf_stat_t init_dyn_decoders (istream_t *is, huffman_decoder_t *litlen_de
         } else if (sym == CODELEN_ZEROS) {
         
             /* 3--10 zeros; 3 bits + 3 */
-            n = (uint64_t) (lsb (bits, 3) + CODELEN_ZEROS_MIN);
+            n = (uint64_t) lsb (bits, 3) + CODELEN_ZEROS_MIN;
             
             if (!istream_advance (is, 3)) {
                 return HWINF_ERR;
@@ -372,7 +372,7 @@ static inf_stat_t init_dyn_decoders (istream_t *is, huffman_decoder_t *litlen_de
         } else if (sym == CODELEN_ZEROS2) {
         
             /* 11--138 zeros; 7 bits + 11 */
-            n = (uint64_t) (lsb (bits, 7) + CODELEN_ZEROS2_MIN);
+            n = (uint64_t) lsb (bits, 7) + CODELEN_ZEROS2_MIN;
             
             if (!istream_advance (is, 7)) {
                 return HWINF_ERR;
@@ -409,7 +409,7 @@ static inf_stat_t init_dyn_decoders (istream_t *is, huffman_decoder_t *litlen_de
 
 static inf_stat_t inf_dyn_block (istream_t *is, FILE *outfile, uint64_t dst_cap, uint64_t *dst_pos) {
 
-    huffman_decoder_t litlen_dec, dist_dec;
+    static huffman_decoder_t litlen_dec = { 0 }, dist_dec = { 0 };
     inf_stat_t stat;
     
     if ((stat = init_dyn_decoders (is, &litlen_dec, &dist_dec)) != HWINF_OK) {
@@ -422,7 +422,7 @@ static inf_stat_t inf_dyn_block (istream_t *is, FILE *outfile, uint64_t dst_cap,
 
 static inf_stat_t inf_fixed_block (istream_t *is, FILE *outfile, uint64_t dst_cap, uint64_t *dst_pos) {
 
-    huffman_decoder_t litlen_dec, dist_dec;
+    static huffman_decoder_t litlen_dec = { 0 }, dist_dec = { 0 };
     
     huffman_decoder_init (&litlen_dec, fixed_litlen_lengths, sizeof (fixed_litlen_lengths) / sizeof (fixed_litlen_lengths[0]));
     huffman_decoder_init (&dist_dec, fixed_dist_lengths, sizeof (fixed_dist_lengths) / sizeof (fixed_dist_lengths[0]));
diff --git a/lib.c b/lib.c
index 4f167689373e14a0ede25069cefa364ef891b723..8a1a9984edfd758b15ec6c0d2d4f00690e8d9d9a 100755 (executable)
--- a/lib.c
+++ b/lib.c
@@ -143,7 +143,7 @@ uint64_t array_to_integer (unsigned char *arr, int size, int bigendian) {
 
 }
 
-uint64_t lsb (uint64_t x, uint64_t n) {
+int lsb (uint64_t x, uint64_t n) {
 
 #ifdef      NO_LONG_LONG
 
diff --git a/lib.h b/lib.h
index 6746a5e37ab0f44ed8e5915fab02940d0c1c63ec..be5d5d5d236bceb68ca2efadbb5d9f6c74774818 100755 (executable)
--- a/lib.h
+++ b/lib.h
@@ -4,7 +4,6 @@
 #ifndef     _LIB_H
 #define     _LIB_H
 
-
 char *xstrdup (const char *str);
 int wild_compare (const char *wild, const char *s);
 
@@ -14,8 +13,9 @@ void *xrealloc (void *ptr, unsigned long size);
 void parse_args (int argc, char **argv, int optind);
 
 #include    "stdint.h"
+int lsb (uint64_t x, uint64_t n);
+
 uint64_t array_to_integer (unsigned char *arr, int size, int bigendian);
-uint64_t lsb (uint64_t x, uint64_t n);
 uint64_t round_up (uint64_t x, uint64_t m);
 
 #endif      /* _LIB_H */
index 8e128ef31f46400f43a7afab03f4526adf5fcc2c..b30b515c4703e607e0182757afe9ccaf441c510e 100644 (file)
--- a/report.c
+++ b/report.c
@@ -17,7 +17,11 @@ static int OriginalConsoleColor = -1;
 
 static void reset_console_color (void) {
 
-#if     defined (_WIN32)
+#if     defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__)
+
+    fprintf (stderr, "\033[0m");
+
+#elif   defined (_WIN32)
 
     HANDLE hStdError = GetStdHandle (STD_ERROR_HANDLE);
     
@@ -26,17 +30,17 @@ static void reset_console_color (void) {
     SetConsoleTextAttribute (hStdError, OriginalConsoleColor);
     OriginalConsoleColor = -1;
 
-#else
-
-    fprintf (stderr, "\033[0m");
-
 #endif
 
 }
 
 static void set_console_color (int color) {
 
-#if     defined (_WIN32)
+#if     defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__)
+
+    fprintf (stderr, "\033[%dm", color);
+
+#elif   defined (_WIN32)
 
     HANDLE hStdError = GetStdHandle (STD_ERROR_HANDLE);
     WORD wColor;
@@ -56,10 +60,6 @@ static void set_console_color (int color) {
     wColor = (OriginalConsoleColor & 0xF0) + (color & 0xF);
     SetConsoleTextAttribute (hStdError, wColor);
 
-#else
-
-    fprintf (stderr, "\033[%dm", color);
-
 #endif
 
 }
diff --git a/unzip.c b/unzip.c
index 40bb6c272c65cc179f56b8fcb25a0e3ba236d7a7..8007b8c3cafcbbb6db148e2a23282b5a81dc0019 100755 (executable)
--- a/unzip.c
+++ b/unzip.c
@@ -88,6 +88,111 @@ static int make_directory (const char *path) {
     
     return 0;
 
+}
+#elif   defined (__WATCOMC__)
+# include       <i86.h>
+
+static char cwd[68] = { 0 }, *old_path = 0;
+
+int make_directory (const char *path) {
+
+    struct SREGS sr = { 0 };
+    union REGS r = { 0 };
+    
+    char *p = (char *) path;
+    
+    while (p && *p != '\0') {
+    
+        while (*p && *p == '\\') {
+            p++;
+        }
+        
+        if (*p == '\0') { break; }
+        
+        if ((p = strchr (p, '\\'))) {
+            *p = '\0';
+        }
+        
+        r.w.ax = 0x3900;
+        r.w.dx = FP_OFF (path);
+        
+        sr.ds = FP_SEG (path);
+        int86x (0x21, &r, &r, &sr);
+        
+        if (r.w.cflag & 1) {
+        
+            r.w.ax = 0x4300;
+            r.w.dx = FP_OFF (path);
+            
+            sr.ds = FP_SEG (path);
+            int86x (0x21, &r, &r, &sr);
+            
+            if (r.w.cflag & 1) {
+                return 1;
+            }
+        
+        }
+        
+        if (p) { *p = '\\'; }
+    
+    }
+    
+    return 0;
+
+}
+
+int entry_exists (const char *path) {
+
+    struct SREGS sr = { 0 };
+    union REGS r = { 0 };
+    
+    char *temp = xstrdup (path);
+    unsigned len = strlen (temp);
+    
+    if (len > 3) {
+    
+        while (temp[len - 1] == '\\') {
+            temp[--len] = '\0';
+        }
+    
+    }
+    
+    r.w.ax = 0x4300;
+    r.w.dx = FP_OFF (temp);
+    
+    sr.ds = FP_SEG (temp);
+    int86x (0x21, &r, &r, &sr);
+    
+    free (temp);
+    return (!(r.w.cflag & 1));
+
+}
+
+int is_directory (const char *path) {
+
+    struct SREGS sr = { 0 };
+    union REGS r = { 0 };
+    
+    char *temp = xstrdup (path);
+    unsigned len = strlen (temp);
+    
+    if (len > 3) {
+    
+        while (temp[len - 1] == '\\') {
+            temp[--len] = '\0';
+        }
+    
+    }
+    
+    r.w.ax = 0x4300;
+    r.w.dx = FP_OFF (temp);
+    
+    sr.ds = FP_SEG (temp);
+    int86x (0x21, &r, &r, &sr);
+    
+    free (temp);
+    return (!(r.w.cflag & 1) && (r.w.cx & 0x10));
+
 }
 #endif
 
@@ -617,14 +722,18 @@ static void extract_zip (const char *path) {
     
 #if     defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__)
 
-    char ch = '/';
     struct stat sb;
+    char ch = '/';
 
 #elif   defined (_WIN32)
 
     char ch = '\\';
     DWORD dwAttrib;
 
+#elif   defined (__WATCOMC__)
+
+    char ch = '\\';
+
 #endif
     
     unsigned char *data;
@@ -718,7 +827,7 @@ static void extract_zip (const char *path) {
         
         p = cfh.name;
         
-#if     defined (_WIN32)
+#if     defined (_WIN32) || defined (__WATCOMC__)
 
         while ((p = strchr (p, '/'))) {
             *p++ = '\\';
@@ -820,11 +929,28 @@ static void extract_zip (const char *path) {
                 printf ("   creating: %s%c\n", temp, ch);
             }
 
+#elif   defined (__WATCOMC__)
+
+            if (entry_exists (temp)) {
+            
+                if (!is_directory (temp)) {
+                
+                    report_at (program_name, 0, REPORT_ERROR, "%s exists but is not a directory", temp);
+                    
+                    free (temp);
+                    break;
+                
+                }
+            
+            } else {
+                printf ("   creating: %s%c\n", temp, ch);
+            }
+
 #endif
 
             if (make_directory (temp)) {
             
-                report_at (program_name, 0, REPORT_ERROR, "failed to create %s", state->exdir);
+                report_at (program_name, 0, REPORT_ERROR, "failed to create %s", temp);
                 
                 free (temp);
                 break;