@z --- os.web ---

FWEB version 1.40 (October 30, 1993)

Based on version 0.5 of S. Levy's CWEB [copyright (C) 1987 Princeton University]

@x-----------------------------------------------------------------------------

\Title{OS.WEB}

@c

@ This header file takes care of operating system/machine-dependent
details, since not all (virtually none?) compilers are fully ANSI. Here,
and elsewhere, macro commands that customize for a particular machine have
a comment line that include the phrase ``\.{Machine-dependent}:''; search
for that with an editor.

@A
@<Beginning of \.{os.h}@>@;
@<Operating system-specific macros@>@;
@<End of \.{os.h}@>@;

@ The next two sections ensure that \.{os.h} is loaded only once.
@<Beginning of \.{os.h}@>=

#ifndef OS_H_
#define OS_H_

@
@<End of \.{os.h}@>=

#endif // |OS_H_|

@i sfile.hweb

@ Here we read the customization file \.{custom.h} and an extra macro file
\.{strmac.h}. 

@<Operating system-specific macros@>=

#include SFILE(custom.h) /* Macros defined by the user. */

@I proto.hweb
@i includes.hweb

@ Some things might not be defined by the user, but they need values.
@<Operating sys...@>=

#ifndef THE_SYSTEM
	#define THE_SYSTEM "UNKNOWN"
#endif

#ifndef LOCAL_BANNER
	#define LOCAL_BANNER ""
#endif

#ifndef NULL_FILE_NAME
	#define NULL_FILE_NAME "null"
#endif

#ifndef C_EXT
	#define C_EXT "c"
#endif

#ifndef M_EXT
	#define M_EXT "mk"
#endif

#ifndef X_EXT
	#define X_EXT "sty"
#endif

#ifndef Cpp_EXT 
	#define Cpp_EXT "c++"
#endif

#ifndef R_EXT
	#define R_EXT "r"
#endif

#ifndef R90_EXT
	#define R90_EXT "r90"
#endif

#ifndef N_EXT
	#define N_EXT "f"
#endif

#ifndef N90_EXT
	#define N90_EXT "f90"
#endif

#ifndef VARIABLE_ARGUMENTS
	#define VARIABLE_ARGUMENTS 0
#endif

#if VARIABLE_ARGUMENTS
	#ifndef NUM_VA_ARGS
		#define NUM_VA_ARGS 2
	#endif
#endif

#ifndef PREFIX_END_CHAR
	#define PREFIX_END_CHAR '/'
#endif


@
@<Operating sys...@>=

#ifndef _strmac_
   #include SFILE(strmac.h) /* Macros for casting calls to string routines. */
#endif /* |_strmac_| */

@  To get rid of warning messages about unused variables, it is convenient
to include a macro that generates a dummy usage. One wants to retain some
of these variables for future use in debugging; the dummy usage should
presumable be optimized away so it doesn't affect execution speed.

@<Operating sys...@>=

#define UNUSED(var) var

@ For personal computers, we must worry about small vs.\ large memory
models. The \FWEB\ processors must be compiled with the |HUGE| memory
model. Among other things, that means that pointer arithmetic is done on
the full \.{segment}:\.{offset} combination. However, in some cases, such
as the Borland compiler, to ensure that the pointers are uniquely
normalized we have to declare them explicitly to be |HUGE|.

@f HUGE huge
@f HUGE_FCN_PTR huge

@<Operating sys...@>=

#define HUGE_FCN_PTR

#ifndef _POSIX_SOURCE
	#define _POSIX_SOURCE // Otherwise, the Sun gets hopelessly confused.
#endif

#include <math.h> // ANSI: Declarations of mathematics functions such as |pow|.
#ifdef HUGE
	#undef HUGE // The Sun's annoying.
#endif

#if HUGE_POINTERS // \.{Machine-dependent}: Force full pointer arithmetic.
	#define HUGE huge /* \It{Normalized} far pointer. */
#else
	#define HUGE // Null def'n for everything except personal computers.
#endif // |HUGE_POINTERS|

@ Here we deal with various foibles of the individual compilers. For
example, in ANSI |sprintf| returns the number of characters written, and
that fact is used in a variety of places in the code; however, this value
is not made available on the Sun. Also, the ellipsis is only available with
function prototyping under \.{gcc}. Note that, as much as possible, we use
C~macros, as this generally makes the output file more readable. (The
ellipsis is an exception.)  We use \.{FWEB} macros only when they provide a
feature not available from the C~preprocessor.

We also use the \.{FWEB} |$ASSERT| feature and the ANSI \.{\#error} feature
to help ensure that the machine flags are consistent. The |$ASSERT| won't
be expanded until \.{FTANGLE} starts writing the output file, but better late
than never. Similarly, the \.{\#error} tests won't be recognized until one
actually compiles.


@ Not all the compilers recognize the ANSI unary plus sign. We don't really
need it; we just use it occasionally for emphasis. Therefore, we just
define it to be null.

@f PLUS $UNOP_

@<Operating sys...@>=

#define PLUS

@ Here we handle some deficiencies of the Aztec compiler on the Mac.

@<Operating sys...@>=

#define CAST(type,var) var
#define _Xx(fmt) fmt

@#if 0 /* \.{Machine-dependent}: Idiosyncracies. */
	@m CAST(type,var) ((type)var)
	@m _Xx(fmt) $STRING($TRANSLIT(fmt,"X","x")) /* |printf| doesn't
understand |"%X"|. */ 
@#endif /* Idiosyncracies. */

@ Here we try to ensure that the machine-specific flags have been set up
consistently, to save you some grief in working with a new machine.

@m INCOMPATIBLE(machine) `_P`##error "! INCOMPATIBLE compiler flags.\
Is " machine " defined from the compiler's command line?"

@#if 0

$ASSERT(ANSI || APOLLO || DSU || IBMPC || MAC || MISC || SGI || SUN || VAX)@; 
	/* \.{Machine-dependent}: Consistency check. */

/* \.{Machine-dependent}: It's assumed that the compiler, or the compiler's
command line, defines a lower-case macro identifying the system/machine. */
#if HAVE_ERROR
	@#if VAX
		#if !defined vax || defined sun || defined mac\
				 || defined ibmpc || defined sgi
			INCOMPATIBLE(vax)
		#endif
	@#elif SUN_GCC
		#if !defined sun || defined vax || defined mac\
				 || defined ibmpc || defined sgi
			INCOMPATIBLE(sun)
		#endif
	@#elif IBMPC
		#if !defined ibmpc || defined vax || defined sun\
				 || defined mac || defined sgi
			INCOMPATIBLE(ibmpc)
		#elif !defined tcc && !defined mcc
#error "You must define either `mcc' or `tcc' from the compiler's cmd line."
		#elif defined tcc && defined mcc
#error "You may define only one of `mcc' or `tcc', not both."
		#endif
	@#endif /* Individual machine checks. */

#endif // |HAVE_ERROR|

@#endif

@ Here are more checks for specific machine-dependent compiler flags that
\It{must} be defined. 

@<Operating sys...@>=

@#if 0 // Sun-cc doesn't like \.{\#error}.
#ifdef ibmpc
	#if defined tcc && !defined(__HUGE__) /* Borland! */
		#error "! You must compile all modules with the HUGE model!"
	#endif /* |tcc| */
#endif /* |IBMPC| */
@#endif

