2005-10-27  Juan Manuell Guerrero  <juan.guerrero@gmx.de>

	* src/builtin.c (m4_esyscmd): The variable sysval is set to its
	value in a way that will be correct for big and little endian systems.
	(m4_sysval): Use WEXITSTATUS to get exit status.
	* src/m4.c (main): Added GET_PROGRAM_NAME. On DJGPP systems
	it strips the complete path and extension from argv[0]. For
	all other systems it simply copies argv[0] to the variable.
	* src/m4.h: Added O_RDONLY. If this fcntl.h or sys/fcntl.h has
	already been included this macro will be defined. If not, fcntl.h
	or sys/fcntl.h will be included depending of if HAVE_FCNTL_H or
	HAVE_SYS_FCNTL_H has been defined. Added O_BINARY. This macro is
	used to define a serie of macros to parametrize OS specific issues
	like path separators, directory separators, drive letters, etc.
	Added HAVE_SYS_WAIT_H and WEXITSTATUS for a sane default of
	WEXITSTATUS.
	* src/output.c (make_room_for): Added SET_BINARY. On systems
	that distinguish between text and binary files, tmpfiles are
	opened in binary mode. For all others OS it is no-op macro.
	* src/path.c (include_env_init): Added PATH_SEP. This macro defines
	the form of the path separator to be used according the OS used.
	(path_search): Added IS_ABSOLUTE. Macro defines	form of absolute
	path according to the OS used.



diff -aprNU5 m4-1.4.4.orig/src/builtin.c m4-1.4.4/src/builtin.c
--- m4-1.4.4.orig/src/builtin.c	2005-05-01 11:40:46.000000000 +0000
+++ m4-1.4.4/src/builtin.c	2005-10-27 21:29:30.000000000 +0000
@@ -772,11 +772,11 @@ m4_esyscmd (struct obstack *obs, int arg
   pin = popen (ARG (1), "r");
   if (pin == NULL)
     {
       M4ERROR ((warning_status, errno,
 		"Cannot open pipe to command \"%s\"", ARG (1)));
-      sysval = 0xff << 8;
+      sysval = -1;
     }
   else
     {
       while ((ch = getc (pin)) != EOF)
 	obstack_1grow (obs, (char) ch);
@@ -785,11 +785,11 @@ m4_esyscmd (struct obstack *obs, int arg
 }
 
 static void
 m4_sysval (struct obstack *obs, int argc, token_data **argv)
 {
-  shipout_int (obs, (sysval >> 8) & 0xff);
+  shipout_int (obs, sysval == -1 ? 127 : WEXITSTATUS (sysval));
 }
 
 /*-------------------------------------------------------------------------.
 | This section contains the top level code for the "eval" builtin.  The	   |
 | actual work is done in the function evaluate (), which lives in eval.c.  |
diff -aprNU5 m4-1.4.4.orig/src/m4.c m4-1.4.4/src/m4.c
--- m4-1.4.4.orig/src/m4.c	2005-10-18 11:48:58.000000000 +0000
+++ m4-1.4.4/src/m4.c	2005-10-27 21:29:30.000000000 +0000
@@ -267,11 +267,11 @@ main (int argc, char *const *argv, char 
   int optchar;			/* option character */
 
   macro_definition *defines;
   FILE *fp;
 
-  program_name = argv[0];
+  GET_PROGRAM_NAME(program_name, argv[0]);
 
   include_init ();
   debug_init ();
 #ifdef USE_STACKOVF
   setup_stackovf_trap (argv, envp, stackovf_handler);
diff -aprNU5 m4-1.4.4.orig/src/m4.h m4-1.4.4/src/m4.h
--- m4-1.4.4.orig/src/m4.h	2005-05-01 11:37:08.000000000 +0000
+++ m4-1.4.4/src/m4.h	2005-10-27 21:29:30.000000000 +0000
@@ -169,10 +169,93 @@ void reference_error _((void));
 
 #ifdef USE_STACKOVF
 void setup_stackovf_trap _((char *const *, char *const *,
 			    void (*handler) (void)));
 #endif
+
+
+/* MS-DOS and similar non-Posix systems have some peculiarities:
+    - they distinguish between binary and text files;
+    - they use both `/' and `\\' as directory separator in file names;
+    - they can have a drive letter X: prepended to a file name;
+    - they have a separate root directory on each drive;
+    - their filesystems are case-insensitive;
+    - directories in environment variables (like PATH) are separated
+        by `;' rather than `:';
+    - text files can have their lines ended either with \n or with \r\n pairs.
+   These are all parameterized here.  */
+#ifndef O_RDONLY
+/* Since <fcntl.h> is POSIX, prefer that to <sys/fcntl.h>.
+   This also avoids some useless warnings on (at least) Linux.  */
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#else /* not HAVE_FCNTL_H */
+#ifdef HAVE_SYS_FCNTL_H
+#include <sys/fcntl.h>
+#endif /* not HAVE_SYS_FCNTL_H */
+#endif /* not HAVE_FCNTL_H */
+#endif /* not O_RDONLY */
+
+#ifndef O_BINARY
+# ifdef _O_BINARY
+#  define O_BINARY _O_BINARY
+# else
+#  define O_BINARY 0
+# endif
+#endif /* O_BINARY */
+
+#if O_BINARY
+# include <io.h>
+# include <stdio.h>
+# include <unistd.h>
+# ifdef __MSDOS__
+#  ifdef __DJGPP__
+#   ifndef HAVE_LC_MESSAGES
+#    define LC_MESSAGES (-1)
+#   endif
+#   define GET_PROGRAM_NAME(progname, name)  \
+    do {                                     \
+      char *p, *my_program_name;             \
+                                             \
+      p = strrchr((name), '/');              \
+      if (p == NULL)                         \
+        p = (name);                          \
+      else                                   \
+        p++;                                 \
+                                             \
+      my_program_name = strdup(p);           \
+      p = strrchr(my_program_name, '.');     \
+      if (p != NULL)                         \
+        *p = '\0';                           \
+                                             \
+      progname = my_program_name;            \
+    } while (0)
+#  endif /* O_BINARY && __DJGPP__ */
+# else   /* O_BINARY && !__MSDOS__ */
+#  define setmode(f,m)                      _setmode(f,m)
+# endif  /* O_BINARY && !__MSDOS__ */
+# ifdef __CYGWIN__
+#  define PATH_SEP                          ':'
+# else  /* O_BINARY && !__CYGWIN__ */
+#  define PATH_SEP                          ';'
+# endif /* O_BINARY && !__CYGWIN__ */
+  /* Back to any O_BINARY system.  */
+# define HAVE_DRIVE(n)                      ((n)[0] && (n)[1] == ':')
+# define IS_SLASH(c)                        ((c) == '/' || (c) == '\\')
+# define IS_ABSOLUTE(n)                     (IS_SLASH((n)[0]) || ((n)[0] && (n)[1] == ':'))
+# define SET_BINARY(f)                      do {int fd = fileno((f)); if (!isatty(fd)) setmode(fd,O_BINARY);} while (0)
+# ifndef GET_PROGRAM_NAME
+#  define GET_PROGRAM_NAME(progname, name)  do {(progname) = (name);} while (0)
+# endif
+#else  /* not O_BINARY, i.e., Unix */
+# define SET_BINARY(f)                      (void)0
+# define IS_SLASH(c)                        ((c) == '/')
+# define HAVE_DRIVE(n)                      (0)
+# define IS_ABSOLUTE(n)                     ((n)[0] == '/')
+# define PATH_SEP                           ':'
+# define GET_PROGRAM_NAME(progname, name)   do {(progname) = (name);} while (0)
+#endif /* not O_BINARY */
 
 /* File: debug.c  --- debugging and tracing function.  */
 
 extern FILE *debug;
 
@@ -415,10 +498,18 @@ void hack_all_symbols _((hack_symbol *, 
 void expand_input _((void));
 void call_macro _((symbol *, int, token_data **, struct obstack *));
 
 /* File: builtin.c  --- builtins.  */
 
+#include <sys/types.h>
+#if HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#ifndef WEXITSTATUS
+# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+
 struct builtin
 {
   const char *name;
   boolean gnu_extension;
   boolean groks_macro_args;
diff -aprNU5 m4-1.4.4.orig/src/output.c m4-1.4.4/src/output.c
--- m4-1.4.4.orig/src/output.c	2005-05-01 11:36:26.000000000 +0000
+++ m4-1.4.4/src/output.c	2005-10-27 21:29:30.000000000 +0000
@@ -194,10 +194,11 @@ make_room_for (int length)
 
       /* Create a temporary file, write the in-memory buffer of the
 	 diversion to this file, then release the buffer.  */
 
       selected_diversion->file = tmpfile ();
+      SET_BINARY(selected_diversion->file);
       if (selected_diversion->file == NULL)
 	M4ERROR ((EXIT_FAILURE, errno,
 		  "ERROR: Cannot create temporary file for diversion"));
 
       if (selected_diversion->used > 0)
diff -aprNU5 m4-1.4.4.orig/src/path.c m4-1.4.4/src/path.c
--- m4-1.4.4.orig/src/path.c	2005-05-01 11:36:10.000000000 +0000
+++ m4-1.4.4/src/path.c	2005-10-27 21:29:30.000000000 +0000
@@ -59,11 +59,11 @@ include_env_init (void)
   if (path == NULL)
     return;
 
   do
     {
-      path_end = strchr (path, ':');
+      path_end = strchr (path, PATH_SEP);
       if (path_end)
 	*path_end = '\0';
       add_include_directory (path);
       path = path_end + 1;
     }
@@ -112,11 +112,11 @@ path_search (const char *dir)
   fp = fopen (dir, "r");
   if (fp != NULL)
     return fp;
 
   /* If file not found, and filename absolute, fail.  */
-  if (*dir == '/' || no_gnu_extensions)
+  if (IS_ABSOLUTE(dir) || no_gnu_extensions)
     return NULL;
   e = errno;
 
   name = (char *) xmalloc (dir_max_length + 1 + strlen (dir) + 1);
 
