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
Author: Pieter Hintjens
Date: Sun, 25 Feb 1996 19:45
Date: Sun, 25 Feb 1996 19:45
332 lines
11714 bytes
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
Author: Phil Edwards
Date: Tue, 27 Feb 1996 04:20
Date: Tue, 27 Feb 1996 04:20
41 lines
2089 bytes
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
Author: Pieter Hintjens
Date: Fri, 01 Mar 1996 23:32
Date: Fri, 01 Mar 1996 23:32
40 lines
2391 bytes
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
Author: Greg Bacon
Date: Mon, 04 Mar 1996 04:09
Date: Mon, 04 Mar 1996 04:09
40 lines
2310 bytes
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
Author: Hans-Bernhard Broeker
Date: Tue, 12 Mar 1996 01:26
Date: Tue, 12 Mar 1996 01:26
33 lines
1608 bytes
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
Author: Michael Smith
Date: Sat, 16 Mar 1996 16:53
Date: Sat, 16 Mar 1996 16:53
50 lines
1786 bytes
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
Author: Chris Torek
Date: Wed, 20 Mar 1996 04:29
Date: Wed, 20 Mar 1996 04:29
82 lines
4013 bytes
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
Author: Michael Smith
Date: Sat, 23 Mar 1996 06:44
Date: Sat, 23 Mar 1996 06:44
37 lines
2091 bytes
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
Author: Chris Torek
Date: Mon, 25 Mar 1996 12:24
Date: Mon, 25 Mar 1996 12:24
34 lines
2014 bytes
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