Fix DOS support
authorRobert Pengelly <robertapengelly@hotmail.com>
Wed, 26 Mar 2025 08:04:42 +0000 (08:04 +0000)
committerRobert Pengelly <robertapengelly@hotmail.com>
Wed, 26 Mar 2025 08:04:42 +0000 (08:04 +0000)
Makefile.wat [new file with mode: 0644]
hashtab.c
include/xmake/hashtab.h
lib.c
read.c
variable.c
xmake.c

diff --git a/Makefile.wat b/Makefile.wat
new file mode 100644 (file)
index 0000000..29f7ade
--- /dev/null
@@ -0,0 +1,18 @@
+#******************************************************************************
+# @file             Makefile.wat
+#******************************************************************************
+SRCDIR              ?=  $(CURDIR)
+VPATH               :=  $(SRCDIR)
+
+SRC                 :=  cstr.c hashtab.c lib.c read.c report.c rule.c variable.c xmake.c
+
+all: xmake.exe
+
+xmake.exe: $(SRC)
+
+       wcl -I.\\include -fe=$@ $^
+
+clean:
+
+       for /r %%f in (*.obj) do ( if exist %%f ( del /q %%f ) )
+       if exist xmake.exe ( del /q xmake.exe )
index c25447dad08d44ee06128556d8b76680fc845571..32f3c401ed850578e1431af57a03d90f0aa36c0b 100644 (file)
--- a/hashtab.c
+++ b/hashtab.c
@@ -6,7 +6,6 @@
 #include    <string.h>
 
 #include    <xmake/hashtab.h>
-
 static struct hashtab_entry *find_entry (struct hashtab_entry *entries, unsigned long capacity, struct hashtab_name *key);
 
 static int adjust_capacity (struct hashtab *table, unsigned long new_capacity) {
@@ -18,7 +17,7 @@ static int adjust_capacity (struct hashtab *table, unsigned long new_capacity) {
         return -2;
     }
     
-    for (i = 0; i < new_capacity; i++) {
+    for (i = 0; i < new_capacity; ++i) {
     
         struct hashtab_entry *entry = &new_entries[i];
         
@@ -32,7 +31,7 @@ static int adjust_capacity (struct hashtab *table, unsigned long new_capacity) {
     
     new_count = 0;
     
-    for (i = 0; i < old_capacity; i++) {
+    for (i = 0; i < old_capacity; ++i) {
     
         struct hashtab_entry *entry = &old_entries[i], *dest;
         
@@ -45,7 +44,7 @@ static int adjust_capacity (struct hashtab *table, unsigned long new_capacity) {
         dest->key = entry->key;
         dest->value = entry->value;
         
-        new_count++;
+        ++new_count;
     
     }
     
@@ -95,13 +94,15 @@ static struct hashtab_entry *find_entry (struct hashtab_entry *entries, unsigned
 
 }
 
-static unsigned long hash_string (const void *p, unsigned long length) {
+static unsigned int hash_string (const void *p, unsigned int length) {
 
-    const unsigned char *str = (const unsigned char *) p;
-    unsigned long i, result = 0;
+    unsigned char *str = (unsigned char *) p;
+    unsigned int i;
+    
+    unsigned int result = 0;
     
     for (i = 0; i < length; i++) {
-        result = (str[i] << 24) + (result >> 19) + (result << 16) + (result >> 13) + (str[i] << 8) - result;
+        result = (((unsigned short) str[i]) << 4) + (result >> 9) + result + (result >> 3) + (((unsigned short) str[i]) << 2) - (result << 12);
     }
     
     return result;
@@ -110,8 +111,8 @@ static unsigned long hash_string (const void *p, unsigned long length) {
 
 struct hashtab_name *hashtab_alloc_name (const char *str) {
 
+    unsigned int bytes = strlen (str), hash = hash_string (str, bytes);
     struct hashtab_name *name;
-    unsigned long bytes = strlen (str), hash = hash_string (str, bytes);
     
     if ((name = malloc (sizeof (*name))) == NULL) {
         return NULL;
@@ -184,10 +185,10 @@ int hashtab_put (struct hashtab *table, struct hashtab_name *key, void *value) {
     
     if (entry->key == NULL) {
     
-        table->count++;
+        ++table->count;
         
         if (entry->value == NULL) {
-            table->used++;
+            ++table->used;
         }
     
     }
index 0c40a69431207c6091e3cf356f5c5017aba38d2f..24e6b0de21d095a64581ecb8129696e953c936a0 100644 (file)
@@ -4,10 +4,17 @@
 #ifndef     _HASHTAB_H
 #define     _HASHTAB_H
 
+#include    <stddef.h>
+
+#define hashtab_get haget
+#define hashtab_put haput
+#define hashtab_remove haremove
+
+
 struct hashtab_name {
 
     const char *chars;
-    unsigned long bytes, hash;
+    unsigned int bytes, hash;
 
 };
 
diff --git a/lib.c b/lib.c
index 3afbd9ab4daf2e715de89c8f074386ec787a4f60..cb7e4a888cef5ebddda1e22f9f12a243da8b51d4 100644 (file)
--- a/lib.c
+++ b/lib.c
@@ -19,25 +19,31 @@ static int print_help (const char *arg) {
 
     (void) arg;
     
-    fprintf (stderr, "Usage: %s [options] [target] ...\n\n", program_name);
-    fprintf (stderr, "Options:\n\n");
+    if (program_name) {
     
-    fprintf (stderr, "    -B                    Ignored.\n");
-    fprintf (stderr, "\n");
-    
-    fprintf (stderr, "    -C DIRECTORY          Change to DIRECTORY before doing anything.\n");
-    fprintf (stderr, "    -I DIRECTORY          Search DIRECTORY for included makefiles.\n");
-    fprintf (stderr, "\n");
-    
-    fprintf (stderr, "    -f FILE               Read FILE as a makefile.\n");
-    fprintf (stderr, "    -s                    Don't echo recipes.\n");
-    fprintf (stderr, "\n");
+        fprintf (stderr, "Usage: %s [options] [target] ...\n\n", program_name);
+        fprintf (stderr, "Options:\n\n");
+        
+        fprintf (stderr, "    -B                    Ignored.\n");
+        fprintf (stderr, "\n");
+        
+        fprintf (stderr, "    -C DIRECTORY          Change to DIRECTORY before doing anything.\n");
+        fprintf (stderr, "    -I DIRECTORY          Search DIRECTORY for included makefiles.\n");
+        fprintf (stderr, "\n");
+        
+        fprintf (stderr, "    -f FILE               Read FILE as a makefile.\n");
+        fprintf (stderr, "    -s                    Don't echo recipes.\n");
+        fprintf (stderr, "\n");
+        
+        fprintf (stderr, "    --no-print-directory  Don't print the current directory.\n");
+        fprintf (stderr, "    --help                Print this help information.\n");
+        
+        fprintf (stderr, "\n");
     
-    fprintf (stderr, "    --no-print-directory  Don't print the current directory.\n");
-    fprintf (stderr, "    --help                Print this help information.\n");
+    }
     
-    fprintf (stderr, "\n");
     exit (EXIT_SUCCESS);
+    return 0;       /* Needed by wcl */
 
 }
 
@@ -539,7 +545,7 @@ int directory_exists (const char *__path) {
     return ((dwAttrib != -1LU) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
 
 }
-#else
+#elif   defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__)
 # include   <dirent.h>
 # include   <unistd.h>
 
@@ -574,5 +580,134 @@ int directory_exists (const char *__path) {
     
     return 0;
 
+}
+#elif   defined (__WATCOMC__)
+# include       <i86.h>
+
+static char cwd[68] = { 0 }, *old_path = 0;
+
+char *get_current_directory (void) {
+
+    char path[65] = { 0 };
+    
+    struct SREGS sr = { 0 };
+    union REGS r = { 0 };
+    
+    int drive_no = 0;
+    
+    r.w.ax = 0x1900;
+    int86x (0x21, &r, &r, &sr);
+    
+    drive_no = r.h.al;
+    memset (cwd, 0, 67);
+    
+    cwd[0] = drive_no + 'A';
+    cwd[1] = ':';
+    cwd[2] = '\\';
+    
+    r.w.ax = 0x4700;
+    r.h.dl = 0;
+    
+    r.w.si = FP_OFF (path);
+    sr.ds = FP_SEG (path);
+    
+    int86x (0x21, &r, &r, &sr);
+    
+    if (*path) {
+        sprintf (cwd + 3, "%s\\", path);
+    }
+    
+    return cwd;
+
+}
+
+int change_directory (const char *path) {
+
+    struct SREGS sr = { 0 };
+    union REGS r = { 0 };
+    
+    char *temp;
+    unsigned long len;
+    
+    if (old_path) {
+    
+        if ((len = strlen (old_path)) > 3) {
+        
+            while (old_path[len - 1] == '\\') {
+                old_path[--len] = '\0';
+            }
+        
+        }
+        
+        r.w.ax = 0x3b00;
+        r.w.dx = FP_OFF (old_path);
+        
+        sr.ds = FP_SEG (old_path);
+        int86x (0x21, &r, &r, &sr);
+        
+        free (old_path);
+    
+    }
+    
+    if (strlen (path) >= 2 && isalpha ((int) path[0]) && path[1] == ':') {
+    
+        r.h.dl = path[0] - 'A';
+        
+        r.w.ax = 0x0e00;
+        int86 (0x21, &r, &r);
+    
+    }
+    
+    old_path = xstrdup (get_current_directory ());
+    
+    if ((len = strlen (temp = xstrdup (path))) > 3) {
+    
+        while (temp[len - 1] == '\\') {
+            temp[--len] = '\0';
+        }
+    
+    }
+    
+    r.w.ax = 0x3b00;
+    r.w.dx = FP_OFF (temp);
+    
+    sr.ds = FP_SEG (temp);
+    int86x (0x21, &r, &r, &sr);
+    
+    free (temp);
+    
+    if (r.w.cflag & 1) {
+        return 0;
+    }
+    
+    return 1;
+
+}
+
+int directory_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) && (r.w.cx & 0x10));
+
 }
 #endif
diff --git a/read.c b/read.c
index c6f8d373f173a234c5e134f73f01ae19ba9c5ea4..c16069e7e1550d9f6087c87c4d880b34a6bf6db0 100644 (file)
--- a/read.c
+++ b/read.c
@@ -255,6 +255,8 @@ static int include_makefile (const char *src_filename, unsigned long line_no, co
     
     fprintf (stderr, "%s: %s:%lu: *** failed to include '%s'. Stop.\n", program_name, src_filename, line_no, filename);
     exit (EXIT_FAILURE);
+    
+    return 1;       /* Needed for wcl */
 
 }
 
index 4ee60ef956041dff50ff45824f622e99c6babf3a..c555bc54da47905afef0ca6db80c6ca68e8c68ad 100644 (file)
@@ -45,12 +45,13 @@ static char *func_error (const char *filename, unsigned long line_no, char *inpu
 
     fprintf (stderr, "%s: %s:%lu: *** %s. Stop.\n", program_name, filename, line_no, input);
     exit (EXIT_FAILURE);
+    
+    return 0;       /* Needed by wcl */
 
 }
 
-#if     !defined (__PDOS__) && !defined (__MSDOS__)
-# if        defined (_WIN32) || defined (__WIN32__)
-#  include      <windows.h>
+#if         defined (_WIN32) || defined (__WIN32__)
+# include       <windows.h>
 static char *internal_commands[] = {
 
     "assoc",
@@ -306,10 +307,10 @@ static char *func_shell (const char *filename, unsigned long line_no, char *inpu
     return lbuf.start;
 
 }
-# else
-#  include      <sys/wait.h>
-#  include      <errno.h>
-#  include      <unistd.h>
+#elif   defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__)
+# include       <sys/wait.h>
+# include       <errno.h>
+# include       <unistd.h>
 static char *func_shell (const char *filename, unsigned long line_no, char *input) {
 
     int pipefd[2], pid, status;
@@ -420,14 +421,13 @@ static char *func_shell (const char *filename, unsigned long line_no, char *inpu
     return lbuf.start;
 
 }
-# endif
 #endif
 
 static struct builtin_function builtin_functions[] ={
 
     {   "error",    &func_error     },
     
-#if     !defined (__PDOS__) && !defined (__MSDOS__)
+#if     defined (_WIN32) || defined (__WIN32__) || defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__)
     {   "shell",    &func_shell     },
 #endif
     
@@ -932,18 +932,18 @@ void parse_var_line (const char *filename, unsigned long line_no, char *line, en
     
     } else if (opt == VAR_SHELL) {
     
-#if     defined (__PDOS__) || defined (__MSDOS__)
-
-        fprintf (stderr, "%s: 'MACRO != value' isn't supported due to OS limitations. Stop.\n", program_name);
-        exit (EXIT_FAILURE);
+#if     defined (_WIN32) || defined (__WIN32__) || defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__)
 
-#else
-        
         char *temp = xstrdup (new_value);
         free (new_value);
         
         new_value = variable_expand_line (filename, line_no, func_shell (filename, line_no, temp));
         free (temp);
+
+#else
+        
+        fprintf (stderr, "%s: 'MACRO != value' isn't supported due to OS limitations. Stop.\n", program_name);
+        exit (EXIT_FAILURE);
         
 #endif
     
diff --git a/xmake.c b/xmake.c
index 300da5a6e159fb63ba8d37a47c2dca3cace6c846..8278eeacf4ac1d8cdf98def8aa0834c2030bebb8 100644 (file)
--- a/xmake.c
+++ b/xmake.c
@@ -23,18 +23,20 @@ struct variable *default_goal_var = 0;
 struct xmake_state *state = 0;
 const char *program_name = 0;
 
-#if     defined (_WIN32) || defined (__WIN32__)
-const char *os_name = "Windows_NT";
-#elif   defined (__PDOS__)
-const char *os_name = "PDOS";
+const char *os_name = "";
+
+#if     defined (__PDOS__)
+os_name = "PDOS";
+#elif   defined (_WIN32) || defined (__WIN32__)
+os_name = "Windows_NT";
 #elif   defined (__MSDOS__)
-const char *os_name = "MSDOS";
+os_name = "MSDOS";
 #elif   defined (__APPLE__)
-const char *os_name = "Apple";
+os_name = "Apple";
 #elif   defined (__linux__)
-const char *os_name = "Linux";
-#else
-const char *os_name = "Unix";
+os_name = "Linux";
+#elif   defined (unix) || defined (__unix) || defined (__unix__)
+os_name = "Unix";
 #endif
 
 struct linebuf {
@@ -48,9 +50,8 @@ struct linebuf {
 
 static int doing_inference_rule_commands = 0;
 
-#if     !defined (__PDOS__) && !defined (__MSDOS__)
-# if        defined (_WIN32) || defined (__WIN32__)
-#  include      <windows.h>
+#if         defined (_WIN32) || defined (__WIN32__)
+# include       <windows.h>
 static void pipe_command (const char *filename, unsigned long line_no, char *input, int is_ignoring_errors, const char *name) {
 
     DWORD dwExitCode;
@@ -200,10 +201,10 @@ static void pipe_command (const char *filename, unsigned long line_no, char *inp
     }
 
 }
-# else
-#  include      <sys/wait.h>
-#  include      <errno.h>
-#  include      <unistd.h>
+#elif   defined (_WIN32) || defined (__WIN32__) || defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__)
+# include       <sys/wait.h>
+# include       <errno.h>
+# include       <unistd.h>
 static void pipe_command (const char *filename, unsigned long line_no, char *input, int is_ignoring_errors, const char *name) {
 
     int pipefd[2], pid, status;
@@ -309,7 +310,6 @@ static void pipe_command (const char *filename, unsigned long line_no, char *inp
     }
 
 }
-# endif
 #endif
 
 static int rule_run_command (const char *filename, unsigned long line_no, const char *name, char *p, char *q) {
@@ -352,8 +352,9 @@ static int rule_run_command (const char *filename, unsigned long line_no, const
     
     if (should_execute) {
     
-#if     defined (__PDOS__) || defined (__MSDOS__)
-
+#if     defined (_WIN32) || defined (__WIN32__) || defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__)
+        pipe_command (filename, line_no, s, is_ignoring_errors, name);
+#else
         int status = system (s);
         
         if (!is_ignoring_errors && status) {
@@ -368,9 +369,6 @@ static int rule_run_command (const char *filename, unsigned long line_no, const
             fprintf (stderr, "%s: *** [%s:%lu: %s] Error %d\n", program_name, filename, line_no, name, status);
         
         }
-
-#else
-        pipe_command (filename, line_no, s, is_ignoring_errors, name);
 #endif
     
     }
@@ -766,7 +764,9 @@ int rule_search_and_build (char *name) {
 
 int main (int argc, char **argv) {
 
+    char *cwd = 0;
     int ret;
+    
     unsigned long i;
     
     if (argc && *argv) {
@@ -800,35 +800,50 @@ int main (int argc, char **argv) {
     if (state->nb_directories > 0) {
     
         char *arg;
-        size_t len = 0;
-        
-        char *cwd = get_current_directory ();
         unsigned long i;
         
+        size_t len = 0;
+        
+        cwd = xstrdup (get_current_directory ());
         state->path = xmalloc (strlen (cwd) + 2);
+
+#if     defined (_WIN32) || defined (__WIN32__) || defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__)
         len = sprintf (state->path, "%s/", cwd);
+#else
+        len = sprintf (state->path, "%s", cwd);
+#endif
         
         for (i = 0; i < state->nb_directories; i++) {
         
             arg = state->directories[i];
             
-#if     defined (_WIN32)
-            if (strlen (arg) < 3 || !(isalpha ((int) arg[0]) && arg[1] == ':' && (arg[2] == '/' || arg[2] == '\\'))) {
-#else
+#if     defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__)
             if (arg[0] != '/') {
-#endif
-            
+#else
+            if (strlen (arg) < 2 || !(isalpha ((int) arg[0]) && arg[1] == ':')) {
+#endif      
                 state->path = xrealloc (state->path, len + strlen (arg) + 2);
                 
+#if     defined (_WIN32) || defined (__WIN32__) || defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__)
                 len += sprintf (state->path + len, "%s/", arg);
+#else
+                len += sprintf (state->path + len, "%s\\", arg);
+#endif
+                
                 state->path[len] = '\0';
             
             } else {
             
+                unsigned long len = strlen (arg);
                 free (state->path);
                 
-                state->path = xmalloc (strlen (arg) + 1);
+                state->path = xmalloc (len + 2);
+                
+#if     defined (_WIN32) || defined (__WIN32__) || defined (unix) || defined (__unix) || defined (__unix__) || defined (__APPLE__)
                 len = sprintf (state->path, "%s/", arg);
+#else
+                len = sprintf (state->path, "%s\\", arg);
+#endif
             
             }
         
@@ -922,7 +937,10 @@ int main (int argc, char **argv) {
 out:
     
     if (state->nb_directories > 0 && !state->no_print) {
+    
         fprintf (stderr, "%s: Leaving directory '%s'\n", program_name, state->path);
+        if (cwd) { change_directory (cwd); }
+    
     }
     
     return ret;