🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.lang.c.moderated
9 messages
9 total messages Started by Pieter Hintjens Sun, 25 Feb 1996 19:45
Search for the Universal Header File
#2073
Author: Pieter Hintjens
Date: Sun, 25 Feb 1996 19:45
332 lines
11714 bytes
I am building the ultimate Universal Header File.  :-)
This is a tool to make cross-platform programming in C
easier.  Basically, all 'common' header files are put
in the uUHF, instead of in each program.  By 'common',
I mean: all ANSI C header files, plus file i/o, socket
i/o, and anything else that is useful.

Up to a point, this is working, but I need help.  If
you want to participate, send me information about your
platform:

   - What C compiler, version 
   - What operating system, version
   - Standard define's made by the compiler - e.g. __UNIX__
   - Compiler switches for ANSI C compilation
   - Any particular order for include files
   - Location of common include files
   - Supports sockets?  If so, what include files

I attach the current version of the uUHF - prelude.h.

Cheers,
Pieter A. Hintjens


/*===========================================================================*
 *                                                                           *
 *  prelude.h   Universal header file for C programming                      *
 *                                                                           *
 *  Written:    93/03/29  Pieter Hintjens  <ph@mymail.com>                   *
 *  Revised:    96/02/25  Version 1.01                                       *
 *                                                                           *
 *  This header encapsulates all generally-useful include files and defines  *
 *  various useful things.  To use, specify as first include file in code.   *
 *                                                                           *
 *  Contributors & critics:                                                  *
 *      Gordon Burditt    <gordon@sneaky.lerctr.org>      25 Feb 1996        *
 *      Steve Leibel      <stevel@coastside.net>          25 Feb 1996        *
 *                                                                           *
 *  Copyright (c) 1991-96 Pieter A. Hintjens.  May be freely distributed.    *
 *===========================================================================*/

#ifndef _PRELUDE_INCLUDED               /*  Allow multiple inclusions        */
#define _PRELUDE_INCLUDED


/*- Generally-useful include files ------------------------------------------*/

#include <ctype.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>


/*- Establish the compiler and computer system ------------------------------*/
/*
 *  Defines one or more of these symbols, for use in any non-portable
 *  code:
 *
 *  __WINDOWS__         Microsoft C/C++ with Windows calls
 *  __MSDOS__           File system is MS-DOS
 *  __VMS__             System is VAX/VMS or Alpha/OpenVMS
 *  __UNIX__            System is UNIX
 *  __MAC__             System is Mac/OS
 *
 *  __32BIT__           OS/compiler is 32 bits
 *  __64BIT__           OS/compiler is 64 bits
 *
 *  When __UNIX__ is defined, we also define exactly one of these:
 *
 *  __UTYPE_AUX         Apple AUX
 *  __UTYPE_DECALPHA    Digital UNIX (Alpha)
 *  __UTYPE_HPUX        HP/UX
 *  __UTYPE_IBMAIX      IBM RS/6000 AIX
 *  __UTYPE_LINUX       Linux
 *  __UTYPE_MIPS        MIPS (BSD 4.3/System V mixture)
 *  __UTYPE_NETBSD      NetBSD
 *  __UTYPE_NEXT        NeXT
 *  __UTYPE_SCO         SCO Unix
 *  __UTYPE_SUNOS       SunOS
 *  __UTYPE_SUNSOLARIS  Sun Solaris
 *  __UTYPE_GENERIC     Any other UNIX
 */

#define __32BIT__                       /*  Assume 32-bit OS/compiler        */

#if (defined (WIN32) || defined (WINDOWS))
#   undef __WINDOWS__
#   define __WINDOWS__
#   undef __MSDOS__
#   define __MSDOS__
#endif

/*  MSDOS      is Microsoft C                                                */
/*  _MSC_VER   is Microsoft C                                                */
/*  __TURBOC__ is Borland Turbo C                                            */
#if (defined (MSDOS) || defined (_MSC_VER) || defined (__TURBOC__))
#   undef __MSDOS__
#   define __MSDOS__
#endif

/*  VMS        is VAX C (VAX/VMS)                                            */
/*  __VMS      is Dec C (Alpha/OpenVMS)                                      */
/*  __vax__    is gcc                                                        */
#if (defined (VMS) || defined (__VMS) || defined (__vax__))
#   undef __VMS__
#   define __VMS__
#endif

/*  unix          is SunOS                                                   */
/*  __unix__      is gcc                                                     */
/*  _POSIX_SOURCE is various UNIX systems, maybe also VAX/VMS                */
#if (defined (unix) || defined (__unix__) || defined (_POSIX_SOURCE))
#   if (!defined (__VMS__))
#       undef __UNIX__
#       define __UNIX__
#       if (defined (__alpha))          /*  Digital UNIX is 64-bit           */
#           undef  __32BIT__
#           define __64BIT__
#       endif
#   endif
#endif

/*  Try to define a __UTYPE_xxx symbol...                                    */
#if (defined __UNIX__)
#   if (defined (_AUX))
#       define __UTYPE_AUX
#   elif (defined (__alpha))
#       define __UTYPE_DECALPHA
#   elif (defined (__hpux))
#       define __UTYPE_HPUX
#   elif (defined (_AIX) || defined (AIX))
#       define __UTYPE_IBMAIX
#   elif (defined (linux))
#       define __UTYPE_LINUX
#   elif (defined (Mips))
#       define __UTYPE_MIPS
#   elif (defined (NetBSD))
#       define __UTYPE_NETBSD
#   elif (defined (NeXT))
#       define __UTYPE_NEXT
#   elif (defined (sco))
#       define __UTYPE_SCO
#   elif (defined (SUNOS))
#       define __UTYPE_SUNOS
#   elif (defined (SOLARIS))
#       define __UTYPE_SUNSOLARIS
#   else
#       define __UTYPE_GENERIC
#   endif
#endif

/*  Untested                                                                 */
#if (defined (_MAC))
#   undef __MAC__
#   define __MAC__
#endif


/*- System-specific include files -------------------------------------------*/

#if (defined (__TURBOC__))              /*  Borland Turbo-C uses this        */
#   include <alloc.h>                   /*    name for its include file      */
#else
#   include <malloc.h>
#endif

#if (defined (__WINDOWS__))             /*  When __WINDOWS__ is defined,     */
#   include <windows.h>                 /*    so is __MSDOS__                */
#endif

#if (defined (__MSDOS__))
#   include <dos.h>
#   include <io.h>
#   include <fcntl.h>
#   include <sys\types.h>
#   include <sys\stat.h>
#endif

#if (defined (__UNIX__))
#   include <netdb.h>
#   include <unistd.h>
#   include <netinet/in.h>
#   include <sys/types.h>
#   include <sys/param.h>
#   include <sys/socket.h>
#   include <sys/time.h>
#   include <sys/stat.h>
    /*  Specific includes for UNIX varieties                                 */
#   if defined (__UTYPE_IBMAIX)
#       include <sys/select.h>
#   endif
#endif

#if (defined (__VMS__))
#   include <types.h>
#   include <netdb.h>
#   include <unixio.h>
#   include <in.h>
#   include <param.h>
#   include <socket.h>
#   include <time.h>
#   include <stat.h>
#endif


/*- Data types --------------------------------------------------------------*/

typedef int            Bool;            /*  Boolean TRUE / FALSE value       */
typedef unsigned char  byte;            /*  Single unsigned byte = 8 bits    */
typedef unsigned short dbyte;           /*  Double byte = 16 bits            */
#if (defined (__32BIT__))
typedef unsigned long  qbyte;           /*  Quad byte = 32 bits              */
#else
typedef unsigned int   qbyte;           /*  Quad byte = 32 bits              */
#endif
typedef void (*function) (void);        /*  Address of simple function       */
#define local static void               /*  Shorthand for local functions    */


/*- Check compiler data type sizes ------------------------------------------*/

#if (UCHAR_MAX != 0xFF)
#   error "Cannot compile: must change definition of 'byte'."
#endif
#if (USHRT_MAX != 0xFFFFU)
#   error "Cannot compile: must change definition of 'dbyte'."
#endif
#if (defined (__32BIT__))
#   if (ULONG_MAX != 0xFFFFFFFFUL)
#       error "Cannot compile: must change definition of 'qbyte'."
#   endif
#else
#   if (UINT_MAX != 0xFFFFFFFFU)
#       error "Cannot compile: must change definition of 'qbyte'."
#   endif
#endif


/*- Pseudo-functions --------------------------------------------------------*/

#define until(expr)     while (!(expr))     /*  do { ... } until (expr)      */
#define streq(s1, s2)   (!strcmp ((s1), (s2)))
#define strneq(s1, s2)  (strcmp ((s1), (s2)))
#define strused(s)      (*(s) != 0)
#define strnull(s)      (*(s) == 0)
#define strclr(s)       (*(s) = 0)

#define bit_msk(bit)    (1 << (bit))
#define bit_set(x, bit) ((x) |=  bit_msk (bit))
#define bit_clr(x, bit) ((x) &= ~bit_msk (bit))
#define bit_tst(x, bit) ((x) &   bit_msk (bit))

#define tblsize(x)      (sizeof (x) / sizeof ((x) [0]))
#define tbllast(x)      (x [tblsize (x) - 1]);

#if (defined (random))
#   undef random
#   undef randomize
#endif
#if (defined (min))
#   undef min
#   undef max
#endif

#if (defined (__32BIT__))
#define random(num)     (int) ((long) rand () % (num))
#else
#define random(num)     (int) ((int)  rand () % (num))
#endif
#define randomize()     srand ((unsigned) time (NULL))
#define min(a,b)        (((a) < (b))? (a): (b))
#define max(a,b)        (((a) > (b))? (a): (b))


/*- ASSERT and debugging ----------------------------------------------------*/

#if (defined (DEBUG))
    /*  Define _Assert function here locally                                 */
    local _Assert (char *File, unsigned Line)
    {
        fflush  (stdout);
        fprintf (stderr, "\nAssertion failed: %s, line %u\n", File, Line);
        fflush  (stderr);
        abort   ();
    }
#   define ASSERT(f)            \
        if (f)                  \
            ;                   \
        else                    \
            _Assert (__FILE__, __LINE__)
#else
#   define ASSERT(f)
#endif


/*- Boolean operators and constants -----------------------------------------*/

#if (defined (TRUE))
#   undef TRUE
#   undef FALSE
#endif
#define TRUE           (1==1)
#define FALSE          (1==0)


/*- Symbolic constants ------------------------------------------------------*/

#define FORK_ERROR      -1              /*  Return codes from fork()         */
#define FORK_CHILD      0
#if (!defined (LINE_MAX))
#   define LINE_MAX     255
#endif


/*- System-specific definitions ---------------------------------------------*/

#if (defined (__VMS__))
#   define RET_OKAY             1       /*  Return codes for main()          */
#   define RET_ERROR            0       /*  VMS does it its own way.         */
#else
#   define RET_OKAY             0       /*  On non-VMS systems 0 is okay,    */
#   define RET_ERROR            1       /*    and 1 is an error.             */
#endif

#endif                                  /*  Include PRELUDE.H                */
Re: Search for the Universal Header File
#2095
Author: Phil Edwards
Date: Tue, 27 Feb 1996 04:20
41 lines
2089 bytes
[cc'd to poster]


With <4gqe8u$pn7@solutions.solon.com>,
it seems Pieter Hintjens (pahint@eunet.be) sez:

+ I am building the ultimate Universal Header File.  :-)
+ This is a tool to make cross-platform programming in C
+ easier.  Basically, all 'common' header files are put
+ in the uUHF, instead of in each program.  By 'common',
+ I mean: all ANSI C header files, plus file i/o, socket
+ i/o, and anything else that is useful.

[snip 350-line header]

I did something similar on a smaller scale.  Compilation of even
the small programs took forever.  I went back and commented out
the #include statements which I knew weren't being used.  The
speedup was *significant*, and I say that running Digital Unix on
a DEC Alpha 4000.

What I had been seeing -- but not reading -- for years finally
sank in after that experience:  more often than not, the most
expensive (timewise) step in compilation is processing of header
files.  What you have in mind may be great for those platforms
which support preprocessed header files, with the result of the
preprocessing being stored in some intermediate state in a local
directory with the rest of the source, but for typical platforms
which process the same file again and again -- sorry, but I'd
hate to use anything that massive.

Just my two timeslices.


Luck++;
Phil

-- 
#include<std/disclaimer.h>               The gods do not protect fools. Fools
finger pedwards@gamma.cs.wright.edu      are protected by more capable fools.
email pedwards@valhalla.cs.wright.edu                            -Larry Niven
Re: Search for the Universal Header File
#2146
Author: Pieter Hintjens
Date: Fri, 01 Mar 1996 23:32
40 lines
2391 bytes
Phil Edwards (pedwards@valhalla.cs.wright.edu) wrote:
: it seems Pieter Hintjens (pahint@eunet.be) sez:
: + I am building the ultimate Universal Header File.  :-)

: I did something similar on a smaller scale.  Compilation of even
: the small programs took forever.  I went back and commented out
: the #include statements which I knew weren't being used.  The
: speedup was *significant*, and I say that running Digital Unix on
: a DEC Alpha 4000.

: What I had been seeing -- but not reading -- for years finally
: sank in after that experience:  more often than not, the most
: expensive (timewise) step in compilation is processing of header
: files.  What you have in mind may be great for those platforms
: which support preprocessed header files, with the result of the
: preprocessing being stored in some intermediate state in a local
: directory with the rest of the source, but for typical platforms
: which process the same file again and again -- sorry, but I'd
: hate to use anything that massive.

When I started with this 'universal header file' the motivation was
to let me edit and compile my code on a PC, with Borland's fast tools
and their pop-up help.  Once I had a 'clean' source I could recompile
and test on the UNIX.

This still stands.  On my cheap pentium, Turbo-C is *fast*.  Even
with all the include's.  The total time I spend compiling is much
less than if I worked only on a UNIX, with a many fewer include's.

Sure, I can't really test my code, but I tyep baldy^H^H^H^H^H^Htype
badly, and I save a lot of time by editing and proof-compiling on
the platform of choice.

Okay, point taken about including masses of files: I am making the
UIF smarter, so that you can tune it with a few #define's at the
start of your program.

Anyone interested in following this project, drop me a line. 
--
Pieter A. Hintjens
Re: Search for the Universal Header File
#2160
Author: Greg Bacon
Date: Mon, 04 Mar 1996 04:09
40 lines
2310 bytes
Pieter Hintjens (pahint@eunet.be) wrote:
[snip]
: When I started with this 'universal header file' the motivation was
: to let me edit and compile my code on a PC, with Borland's fast tools
: and their pop-up help.  Once I had a 'clean' source I could recompile
: and test on the UNIX.

: This still stands.  On my cheap pentium, Turbo-C is *fast*.  Even
: with all the include's.  The total time I spend compiling is much
: less than if I worked only on a UNIX, with a many fewer include's.

: Sure, I can't really test my code, but I tyep baldy^H^H^H^H^H^Htype
: badly, and I save a lot of time by editing and proof-compiling on
: the platform of choice.

: Okay, point taken about including masses of files: I am making the
: UIF smarter, so that you can tune it with a few #define's at the
: start of your program.

: Anyone interested in following this project, drop me a line. 
: --
: Pieter A. Hintjens

With almost any well thought-out project, there's usually an associated
rationale (take the C Standard for instance).  However, I really don't
see any point in creating a "universal header file".  It's like the
physics profs drill into our heads "you can't get something for nothing".
Kind of a conservation of CPU cycles principle :)

Anyway... if you want to do something useful, write a piece of code that
scans C source modules and determines what headers should be included and
add those to the source.  Otherwise, you'll end up with a bunch of useless
clutter with .h as its file extension.  (However, such a product might
get you hired by Microsoft :)

Greg
--
Greg Bacon <gbacon@cs.uah.edu>
University of Alabama in Huntsville
CS Department Systems Support Team
Re: Search for the Universal Header File
#2242
Author: Hans-Bernhard Broeker
Date: Tue, 12 Mar 1996 01:26
33 lines
1608 bytes
pahint@eunet.be (Pieter Hintjens) writes:

>Phil Edwards (pedwards@valhalla.cs.wright.edu) wrote:
>: it seems Pieter Hintjens (pahint@eunet.be) sez:
>: + I am building the ultimate Universal Header File.  :-)

[...]
>Okay, point taken about including masses of files: I am making the
>UIF smarter, so that you can tune it with a few #define's at the
>start of your program.

But that's absolutely counter-useful! Where's the real gain if you have
to write 

#define WANT_STDIO
#define WANT_LOCAL_SOMETHING
#include <uUHF.h>

instead of

#include <stdio.h>
#include <local_something.h>

(And you would actually *have* to use such a method of defining *all*
the necessary WANT's, or equivalently some DONT_WANT's, to keep at least
a bit of your available namespace free for use by the program you're
writing)

Anyway, IMHO such an uUHF would be such a big waste of name space as
to render it a real nuisance, and lose all it's possible benefits
at once.

Hans-Bernhard Broeker (Aachen, Germany)
Re: Search for the Universal Header File
#2306
Author: Michael Smith
Date: Sat, 16 Mar 1996 16:53
50 lines
1786 bytes
Hans-Bernhard Broeker wrote:
> But that's absolutely counter-useful! Where's the real gain if you have
> to write
> 
> #define WANT_STDIO
> #define WANT_LOCAL_SOMETHING
> #include <uUHF.h>
> 
> instead of
> 
> #include <stdio.h>
> #include <local_something.h>
> 

I missed the start of this, so I may have the wrong end of the stick, but 
I think that the intention would be to replace code like:

#if defined(SOME_SYSTEM)
#include <malloc.h>
#elif defined(SOME_OTHER_SYSTEM)
#include <alloc.h>
#elif defined(YET_ANOTHER_SYSTEM)
#include <memory.h>
#else
#include <stdlib.h>
#endif

#if defined(MSDOS)
#include <sys\\stat.h>
#elif defined(VMS)
#include <whatever file spec needed for VMS>
#else
#include <sys/stat.h>
#endif

with code like this:

#define INCLUDE_MALLOC
#define INCLUDE_STAT
#include <uUHF.h>

There are lots of cases where different systems need different include 
files.


-- 
#####################################################################
Michael Smith                                       msmith@mpx.com.au
Emmenjay Consulting                 http://www.hutch.com.au/~emmenjay
#####################################################################
Re: Search for the Universal Header File
#2341
Author: Chris Torek
Date: Wed, 20 Mar 1996 04:29
82 lines
4013 bytes
(My apologies for the large quote, but the example was pretty hard to
trim....)

In article <4iermd$apc@solutions.solon.com> Michael Smith <msmith@mpx.com.au>
writes:
>I missed the start of this, so I may have the wrong end of the stick, but 
>I think that the intention would be to replace code like:
>
>#if defined(SOME_SYSTEM)
>#include <malloc.h>
>#elif defined(SOME_OTHER_SYSTEM)
>#include <alloc.h>
>#elif defined(YET_ANOTHER_SYSTEM)
>#include <memory.h>
>#else
>#include <stdlib.h>
>#endif
>
>#if defined(MSDOS)
>#include <sys\\stat.h>
>#elif defined(VMS)
>#include <whatever file spec needed for VMS>
>#else
>#include <sys/stat.h>
>#endif
>
>with code like this:
>
>#define INCLUDE_MALLOC
>#define INCLUDE_STAT
>#include <uUHF.h>

I think this is the wrong approach.  These two examples are actually
rather good, because they are also rather different.

Let us consider malloc() first.  If we have a conformant compiler,
<stdlib.h> will be the correct include file, but there are still some
compilers Out There that require the use of `alloc.h' or `memory.h'
or some such.  In this case, it is actually fairly reasonable to want
a simple and direct way to include the correct header.  I would
probably solve this in one of two or three ways:

	- Simply #include <stdlib.h>, and require that it be
	  correct (by fixing or replacing the implementation if
	  necessary).

	- Write my own module that implements memory allocation;
	  put any gross #ifdef'ing into it, and use `myalloc()'
	  everywhere.  This is particularly sensible if you want to
	  use a `void *' allocator (some of the systems return
	  `char *') and/or have a standard out-of-memory error.

	- Use a macro to define the name of the correct header, and
	  `#include MALLOC_H'.

The second case is harder, if less subtle (e.g., for malloc we had to
think about pre-ANSI implementations).  In this case, there is no
guarantee that there *is* a `stat.h' of *any* kind.  Here, I would
relegate the inclusion of a stat.h (or equivalent) to a port-specific
module, and hide access to the `struct stat' (or equivalent) behind
soem sort of interface.  Then, when the application is ported to an
ancient IBM O/S, we simply (hah!) need to write a module that gleans
the desired information from the various FCBs.  The application may
even become usable on a system that lacks files entirely (and therefore
has no equivalent of any stat structure), though obviously this would
depend on the application itself.

Writing portable code is difficult, but I think that attempting a
universal header file is the wrong approach in most, if not all,
cases.  The right approach is to pick a set of standards you will
require (such as ANSI or POSIX), define your own abstractions for
what you need from the system, and write everything *not* provided
in those standards using those abstractions.  Perhaps (e.g., for
efficiency) some or most of those will simply be macros, and only
time and porting can prove which abstractions were sufficiently
abstract -- but there is no way that (for instance) you are going
to make a TCP application work on a machine that has no networking
code of any kind, so there is no point in `universalizing' the
header file for TCP on machines that do not support it.
-- 
In-Real-Life: Chris Torek, Berkeley Software Design Inc
El Cerrito, CA	Domain:	torek@bsdi.com	+1 510 234 3167
Re: Search for the Universal Header File
#2357
Author: Michael Smith
Date: Sat, 23 Mar 1996 06:44
37 lines
2091 bytes
Chris Torek wrote:
> 
>         - Simply #include <stdlib.h>, and require that it be
>           correct (by fixing or replacing the implementation if
>           necessary).

Can't agree with that.  Changing system headers is a recipe for 
maintenance disasters.

> 
>         - Write my own module that implements memory allocation;
>           put any gross #ifdef'ing into it, and use `myalloc()'
>           everywhere.  This is particularly sensible if you want to
>           use a `void *' allocator (some of the systems return
>           `char *') and/or have a standard out-of-memory error.
> 
>         - Use a macro to define the name of the correct header, and
>           `#include MALLOC_H'.

No real objection to either of these.


Let me clear up one thing.  I was not saying that I agreed with the 
universal header concept, simply explaining what it was.  An earlier 
poster appeared to have misunderstood.

My preferred method is to encapsulate particular subsystems where 
portability is an issue.  I have been known to use a "sysdefs.h" or 
similar where system specific macros were defined, such as the
#define MALLOC_H <stdlib.h> from your example.


-- 
#####################################################################
Michael Smith                                       msmith@mpx.com.au
Emmenjay Consulting                 http://www.hutch.com.au/~emmenjay
#####################################################################
Re: Search for the Universal Header File
#2389
Author: Chris Torek
Date: Mon, 25 Mar 1996 12:24
34 lines
2014 bytes
I suggested (as one approach for dealing with broken <stdlib.h> headers):
>>         - Simply #include <stdlib.h>, and require that it be
>>           correct (by fixing or replacing the implementation if
>>           necessary).

In article <4j06k0$7s9@solutions.solon.com> Michael Smith <msmith@mpx.com.au>
writes:
>Can't agree with that.  Changing system headers is a recipe for 
>maintenance disasters.

That depends -- sometimes I am the implementor. :-)

Seriously, though, by `replacing the implementation' I meant
`returning the broken compiler, and buying a correct one from
another vendor'.  This is often possible, and is a good idea since
it exerts the most effective kind of pressure available to the
consumer.

Sometimes the real world interferes with this approach (e.g., when
the vendor has a monopoly on the supply of compilers for the CPU
in question).  In such cases, however, it usually turns out that
broken header files are the least of your worries.  Also, most of
these situations involve writing code that will never be portable
anyway (since, e.g., the 98951J is used entirely differently in
the electric mixer than in the toaster, all to save 3/10ths of a
cent per unit).

>My preferred method is to encapsulate particular subsystems where 
>portability is an issue.

Agreed.
-- 
In-Real-Life: Chris Torek, Berkeley Software Design Inc
El Cerrito, CA	Domain:	torek@bsdi.com	+1 510 234 3167
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads