1151497Sru/* Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005
2151497Sru   Free Software Foundation, Inc.
375584Sru     Written by Eli Zaretskii (eliz@is.elta.co.il)
475584Sru
575584SruThis file is part of groff.
675584Sru
775584Srugroff is free software; you can redistribute it and/or modify it under
875584Sruthe terms of the GNU General Public License as published by the Free
975584SruSoftware Foundation; either version 2, or (at your option) any later
1075584Sruversion.
1175584Sru
1275584Srugroff is distributed in the hope that it will be useful, but WITHOUT ANY
1375584SruWARRANTY; without even the implied warranty of MERCHANTABILITY or
1475584SruFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1575584Srufor more details.
1675584Sru
1775584SruYou should have received a copy of the GNU General Public License along
1875584Sruwith groff; see the file COPYING.  If not, write to the Free Software
19151497SruFoundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
2075584Sru
2175584Sru/* This header file compartmentalize all idiosyncrasies of non-Posix
22151497Sru   systems, such as MS-DOS, MS-Windows, etc.  It should be loaded after
23151497Sru   the system headers like stdio.h to protect against warnings and error
24151497Sru   messages w.r.t. redefining macros. */
2575584Sru
2675584Sru#if defined _MSC_VER
2775584Sru# ifndef _WIN32
2875584Sru#  define _WIN32
2975584Sru# endif
3075584Sru#endif
3175584Sru
32114402Sru#if defined(__MSDOS__) || defined(__EMX__) \
33104862Sru    || (defined(_WIN32) && !defined(_UWIN) && !defined(__CYGWIN__))
3475584Sru
35151497Sru/* Binary I/O nuisances. */
3675584Sru# include <fcntl.h>
3775584Sru# include <io.h>
3875584Sru# ifdef HAVE_UNISTD_H
3975584Sru#  include <unistd.h>
4075584Sru# endif
41151497Sru# ifndef STDIN_FILENO
42151497Sru#  define STDIN_FILENO	0
43151497Sru#  define STDOUT_FILENO	1
44151497Sru#  define STDERR_FILENO	2
4575584Sru# endif
46151497Sru# ifdef HAVE_DIRECT_H
47151497Sru#  include <direct.h>
48151497Sru# endif
49151497Sru# ifdef HAVE_PROCESS_H
50151497Sru#  include <process.h>
51151497Sru# endif
52151497Sru# if defined(_MSC_VER) || defined(__MINGW32__)
53151497Sru#  define POPEN_RT	"rt"
54151497Sru#  define POPEN_WT	"wt"
55151497Sru#  define popen(c,m)	_popen(c,m)
56151497Sru#  define pclose(p)	_pclose(p)
57151497Sru#  define pipe(pfd)	_pipe((pfd),0,_O_BINARY|_O_NOINHERIT)
58151497Sru#  define mkdir(p,m)	_mkdir(p)
59151497Sru#  define setmode(f,m)	_setmode(f,m)
60151497Sru#  define WAIT(s,p,m)	_cwait(s,p,m)
61151497Sru#  define creat(p,m)	_creat(p,m)
62151497Sru#  define read(f,b,s)	_read(f,b,s)
63151497Sru#  define write(f,b,s)	_write(f,b,s)
64151497Sru#  define dup(f)	_dup(f)
65151497Sru#  define dup2(f1,f2)	_dup2(f1,f2)
66151497Sru#  define close(f)	_close(f)
67151497Sru#  define isatty(f)	_isatty(f)
68151497Sru#  define access(p,m)	_access(p,m)
69151497Sru# endif
70151497Sru# define SET_BINARY(f)	do {if (!isatty(f)) setmode(f,O_BINARY);} while(0)
71151497Sru# define FOPEN_RB	"rb"
72151497Sru# define FOPEN_WB	"wb"
73151497Sru# define FOPEN_RWB	"wb+"
7475584Sru# ifndef O_BINARY
7575584Sru#  ifdef _O_BINARY
76151497Sru#   define O_BINARY	(_O_BINARY)
7775584Sru#  endif
7875584Sru# endif
7975584Sru
8075584Sru/* The system shell.  Groff assumes a Unixy shell, but non-Posix
8175584Sru   systems don't have standard places where it lives, and might not
8275584Sru   have it installed to begin with.  We want to give them some leeway.  */
83114402Sru# ifdef __EMX__
84151497Sru#  define getcwd(b,s)	_getcwd2(b,s)
85114402Sru# else
86151497Sru#  define BSHELL	(system_shell_name())
87151497Sru#  define BSHELL_DASH_C	(system_shell_dash_c())
88151497Sru#  define IS_BSHELL(s)	(is_system_shell(s))
89114402Sru# endif
9075584Sru
9175584Sru/* The separator for directories in PATH and other environment
9275584Sru   variables.  */
93151497Sru# define PATH_SEP	";"
94151497Sru# define PATH_SEP_CHAR	';'
9575584Sru
9675584Sru/* Characters that separate directories in a path name.  */
97151497Sru# define DIR_SEPS	"/\\:"
9875584Sru
9975584Sru/* How to tell if the argument is an absolute file name.  */
10075584Sru# define IS_ABSOLUTE(f) \
10175584Sru ((f)[0] == '/' || (f)[0] == '\\' || (f)[0] && (f)[1] == ':')
10275584Sru
10375584Sru/* The executable extension.  */
104151497Sru# define EXE_EXT	".exe"
10575584Sru
106151497Sru/* Possible executable extensions.  */
107151497Sru# define PATH_EXT	".com;.exe;.bat;.cmd"
108151497Sru
10975584Sru/* The system null device.  */
110151497Sru# define NULL_DEV	"NUL"
11175584Sru
112151497Sru/* The default place to create temporary files.  */
113151497Sru# ifndef P_tmpdir
114151497Sru#  ifdef _P_tmpdir
115151497Sru#   define P_tmpdir	_P_tmpdir
116151497Sru#  else
117151497Sru#   define P_tmpdir	"c:/temp"
118151497Sru#  endif
119151497Sru# endif
120151497Sru
12175584Sru/* Prototypes.  */
12275584Sru# ifdef __cplusplus
12375584Sru  extern "C" {
12475584Sru# endif
125151497Sru    char       * system_shell_name(void);
12675584Sru    const char * system_shell_dash_c(void);
127151497Sru    int		 is_system_shell(const char *);
12875584Sru# ifdef __cplusplus
12975584Sru  }
13075584Sru# endif
13175584Sru
13275584Sru#endif
13375584Sru
134151497Sru#if defined(_WIN32) && !defined(_UWIN) && !defined(__CYGWIN__)
135151497Sru/* Win32 implementations which use the Microsoft runtime library
136151497Sru * are prone to hanging when a pipe reader quits with unread data in the pipe.
137151497Sru * `gtroff' avoids this, by invoking `FLUSH_INPUT_PIPE()', defined as ... */
138151497Sru# define FLUSH_INPUT_PIPE(fd)		      \
139151497Sru do if (!isatty(fd))			      \
140151497Sru {					      \
141151497Sru   char drain[BUFSIZ];			      \
142151497Sru   while (read(fd, drain, sizeof(drain)) > 0) \
143151497Sru     ;					      \
144151497Sru } while (0)
145151497Sru
146151497Sru/* The Microsoft runtime library also has a broken argument passing mechanism,
147151497Sru * which may result in improper grouping of arguments passed to a child process
148151497Sru * by the `spawn()' family of functions.  In `groff', only the `spawnvp()'
149151497Sru * function is affected; we work around this defect, by substituting a
150151497Sru * wrapper function in place of `spawnvp()' calls. */
151151497Sru
152151497Sru# ifdef __cplusplus
153151497Sru  extern "C" {
154151497Sru# endif
155151497Sru  int spawnvp_wrapper(int, char *, char **);
156151497Sru# ifdef __cplusplus
157151497Sru  }
158151497Sru# endif
159151497Sru# ifndef SPAWN_FUNCTION_WRAPPERS
160151497Sru#  undef  spawnvp
161151497Sru#  define spawnvp      spawnvp_wrapper
162151497Sru#  undef  _spawnvp
163151497Sru#  define _spawnvp     spawnvp
164151497Sru# endif /* SPAWN_FUNCTION_WRAPPERS */
165151497Sru
166151497Sru#else
167151497Sru/* Other implementations do not suffer from Microsoft runtime bugs,
168151497Sru * but `gtroff' requires a dummy definition for FLUSH_INPUT_PIPE() */
169151497Sru# define FLUSH_INPUT_PIPE(fd)	do {} while(0)
170151497Sru#endif
171151497Sru
17275584Sru/* Defaults, for Posix systems.  */
17375584Sru
174114402Sru#ifndef SET_BINARY
175151497Sru# define SET_BINARY(f)	do {} while(0)
176114402Sru#endif
17775584Sru#ifndef FOPEN_RB
178151497Sru# define FOPEN_RB	"r"
17975584Sru#endif
18075584Sru#ifndef FOPEN_WB
181151497Sru# define FOPEN_WB	"w"
18275584Sru#endif
18375584Sru#ifndef FOPEN_RWB
184151497Sru# define FOPEN_RWB	"w+"
18575584Sru#endif
18675584Sru#ifndef POPEN_RT
187151497Sru# define POPEN_RT	"r"
18875584Sru#endif
18975584Sru#ifndef POPEN_WT
190151497Sru# define POPEN_WT	"w"
19175584Sru#endif
19275584Sru#ifndef O_BINARY
193151497Sru# define O_BINARY	0
19475584Sru#endif
19575584Sru#ifndef BSHELL
196151497Sru# define BSHELL		"/bin/sh"
19775584Sru#endif
19875584Sru#ifndef BSHELL_DASH_C
199151497Sru# define BSHELL_DASH_C	"-c"
20075584Sru#endif
20175584Sru#ifndef IS_BSHELL
202151497Sru# define IS_BSHELL(s)	((s) && strcmp(s,BSHELL) == 0)
20375584Sru#endif
20475584Sru#ifndef PATH_SEP
205151497Sru# define PATH_SEP	":"
206151497Sru# define PATH_SEP_CHAR	':'
20775584Sru#endif
20875584Sru#ifndef DIR_SEPS
209151497Sru# define DIR_SEPS	"/"
21075584Sru#endif
21175584Sru#ifndef IS_ABSOLUTE
212151497Sru# define IS_ABSOLUTE(f)	((f)[0] == '/')
21375584Sru#endif
21475584Sru#ifndef EXE_EXT
215151497Sru# define EXE_EXT	""
21675584Sru#endif
217151497Sru#ifndef PATH_EXT
218151497Sru# define PATH_EXT	""
219151497Sru#endif
22075584Sru#ifndef NULL_DEV
221151497Sru# define NULL_DEV	"/dev/null"
22275584Sru#endif
223104862Sru#ifndef GS_NAME
224151497Sru# define GS_NAME	"gs"
225104862Sru#endif
226104862Sru#ifndef WAIT
227151497Sru# define WAIT(s,p,m)	wait(s)
228104862Sru#endif
229104862Sru#ifndef _WAIT_CHILD
230151497Sru# define _WAIT_CHILD	0
231104862Sru#endif
232