]> granicus.if.org Git - postgresql/blob - src/include/c.h
From: Phil Thompson <phil@river-bank.demon.co.uk>
[postgresql] / src / include / c.h
1 /*-------------------------------------------------------------------------
2  *
3  * c.h--
4  *        Fundamental C definitions.  This is included by every .c file in
5  *        postgres.
6  *
7  *
8  * Copyright (c) 1994, Regents of the University of California
9  *
10  * $Id: c.h,v 1.29 1998/01/26 01:41:49 scrappy Exp $
11  *
12  *-------------------------------------------------------------------------
13  */
14 /*
15  *       TABLE OF CONTENTS
16  *
17  *              When adding stuff to this file, please try and put stuff
18  *              into the relevant section, or add new sections as appropriate.
19  *
20  *        section       description
21  *        -------       ------------------------------------------------
22  *              1)              bool, true, false, TRUE, FALSE
23  *              2)              __STDC__, non-ansi C definitions:
24  *                              Pointer typedef, NULL
25  *                              cpp magic macros
26  *                              type prefixes: const, signed, volatile, inline
27  *              3)              standard system types
28  *              4)              datum type
29  *              5)              IsValid macros for system types
30  *              6)              offsetof, lengthof, endof
31  *              7)              exception handling definitions, Assert, Trap, etc macros
32  *              8)              Min, Max, Abs, StrNCpy macros
33  *              9)              externs
34  *              10)              Berkeley-specific defs
35  *              11)             system-specific hacks
36  *
37  *       NOTES
38  *
39  *              This file is MACHINE AND COMPILER dependent!!!  (For now.)
40  *
41  * ----------------------------------------------------------------
42  */
43 #ifndef C_H
44 #define C_H
45
46 /* We have to include stdlib.h here because it defines many of these macros
47    on some platforms, and we only want our definitions used if stdlib.h doesn't
48    have its own.
49 */
50 #include <stdlib.h>
51
52 /* ----------------------------------------------------------------
53  *                              Section 1:      bool, true, false, TRUE, FALSE
54  * ----------------------------------------------------------------
55  */
56 /*
57  * bool --
58  *              Boolean value, either true or false.
59  *
60  */
61 #define false   ((char) 0)
62 #define true    ((char) 1)
63 #ifndef __cplusplus
64 typedef char bool;
65
66 #endif                                                  /* not C++ */
67 typedef bool *BoolPtr;
68
69 #ifndef TRUE
70 #define TRUE    1
71 #endif                                                  /* TRUE */
72
73 #ifndef FALSE
74 #define FALSE   0
75 #endif                                                  /* FALSE */
76
77 /* ----------------------------------------------------------------
78  *                              Section 2: __STDC__, non-ansi C definitions:
79  *
80  *                              cpp magic macros
81  *                              Pointer typedef, NULL
82  *                              type prefixes: const, signed, volatile, inline
83  * ----------------------------------------------------------------
84  */
85
86 #ifdef  __STDC__                                /* ANSI C */
87
88 /*
89  * Pointer --
90  *              Variable holding address of any memory resident object.
91  */
92
93 /*
94  *              XXX Pointer arithmetic is done with this, so it can't be void *
95  *              under "true" ANSI compilers.
96  */
97 typedef char *Pointer;
98
99 #ifndef NULL
100 /*
101  * NULL --
102  *              Null pointer.
103  */
104 #define NULL    ((void *) 0)
105 #endif                                                  /* !defined(NULL) */
106
107 #define HAVE_ANSI_CPP                   /* all ANSI C compilers must have this! */
108 #if defined(NEED_STD_HDRS)
109 #undef NEED_STD_HDRS                    /* all ANSI systems must have
110                                                                  * stddef/stdlib */
111 #endif                                                  /* NEED_STD_HDRS */
112
113 #else   /* !defined(__STDC__) *//* NOT ANSI C */
114
115 /*
116  * Pointer --
117  *              Variable containing address of any memory resident object.
118  */
119 typedef char *Pointer;
120
121 #ifndef NULL
122 /*
123  * NULL --
124  *              Null pointer.
125  */
126 #define NULL    0
127 #endif                                                  /* !defined(NULL) */
128
129 /*
130  * const --
131  *              Type modifier.  Identifies read only variables.
132  *
133  * Example:
134  *              extern const Version    RomVersion;
135  */
136 #define const                                   /* const */
137
138 /*
139  * signed --
140  *              Type modifier.  Identifies signed integral types.
141  */
142 #define signed                                  /* signed */
143
144 /*
145  * volatile --
146  *              Type modifier.  Identifies variables which may change in ways not
147  *              noticeable by the compiler, e.g. via asynchronous interrupts.
148  *
149  * Example:
150  *              extern volatile unsigned int    NumberOfInterrupts;
151  */
152 #define volatile                                /* volatile */
153
154 #endif  /* !defined(__STDC__) *//* NOT ANSI C */
155
156 /*
157  * CppAsString --
158  *              Convert the argument to a string, using the C preprocessor.
159  * CppConcat --
160  *              Concatenate two arguments together, using the C preprocessor.
161  */
162 #if defined(HAVE_ANSI_CPP)
163
164 #define CppAsString(identifier) #identifier
165 #define CppConcat(x, y)                 x##y
166
167 #else                                                   /* !HAVE_ANSI_CPP */
168
169 #define CppAsString(identifier) "identifier"
170
171 /*
172  * CppIdentity -- On Reiser based cpp's this is used to concatenate
173  *              two tokens.  That is
174  *                              CppIdentity(A)B ==> AB
175  *              We renamed it to _private_CppIdentity because it should not
176  *              be referenced outside this file.  On other cpp's it
177  *              produces  A  B.
178  */
179 #define _priv_CppIdentity(x)x
180 #define CppConcat(x, y)                 _priv_CppIdentity(x)y
181
182 #endif                                                  /* !HAVE_ANSI_CPP */
183
184 #ifndef __GNUC__                                /* GNU cc */
185 #define inline
186 #endif
187
188 #if defined(NEED_STD_HDRS)
189 /*
190  * You're doomed.  We've removed almost all of our own C library
191  * extern declarations because they conflict on the different
192  * systems.  You'll have to write your own stdlib.h.
193  */
194 #include "stdlib.h"
195 #else                                                   /* NEED_STD_HDRS */
196 #include <stddef.h>
197 #include <stdlib.h>
198 #endif                                                  /* NEED_STD_HDRS */
199
200 /* ----------------------------------------------------------------
201  *                              Section 3:      standard system types
202  * ----------------------------------------------------------------
203  */
204
205 /*
206  * intN --
207  *              Signed integer, EXACTLY N BITS IN SIZE,
208  *              used for numerical computations and the
209  *              frontend/backend protocol.
210  */
211 typedef signed char int8;               /* == 8 bits */
212 typedef signed short int16;             /* == 16 bits */
213 typedef signed int int32;               /* == 32 bits */
214
215 /*
216  * uintN --
217  *              Unsigned integer, EXACTLY N BITS IN SIZE,
218  *              used for numerical computations and the
219  *              frontend/backend protocol.
220  */
221 typedef unsigned char uint8;    /* == 8 bits */
222 typedef unsigned short uint16;  /* == 16 bits */
223 typedef unsigned int uint32;    /* == 32 bits */
224
225 /*
226  * floatN --
227  *              Floating point number, AT LEAST N BITS IN SIZE,
228  *              used for numerical computations.
229  *
230  *              Since sizeof(floatN) may be > sizeof(char *), always pass
231  *              floatN by reference.
232  */
233 typedef float float32data;
234 typedef double float64data;
235 typedef float *float32;
236 typedef double *float64;
237
238 /*
239  * boolN --
240  *              Boolean value, AT LEAST N BITS IN SIZE.
241  */
242 typedef uint8 bool8;                    /* >= 8 bits */
243 typedef uint16 bool16;                  /* >= 16 bits */
244 typedef uint32 bool32;                  /* >= 32 bits */
245
246 /*
247  * bitsN --
248  *              Unit of bitwise operation, AT LEAST N BITS IN SIZE.
249  */
250 typedef uint8 bits8;                    /* >= 8 bits */
251 typedef uint16 bits16;                  /* >= 16 bits */
252 typedef uint32 bits32;                  /* >= 32 bits */
253
254 /*
255  * wordN --
256  *              Unit of storage, AT LEAST N BITS IN SIZE,
257  *              used to fetch/store data.
258  */
259 typedef uint8 word8;                    /* >= 8 bits */
260 typedef uint16 word16;                  /* >= 16 bits */
261 typedef uint32 word32;                  /* >= 32 bits */
262
263 /*
264  * Size --
265  *              Size of any memory resident object, as returned by sizeof.
266  */
267 typedef unsigned int Size;
268
269 /*
270  * Index --
271  *              Index into any memory resident array.
272  *
273  * Note:
274  *              Indices are non negative.
275  */
276 typedef unsigned int Index;
277
278 #define MAXDIM 6
279 typedef struct
280 {
281         int                     indx[MAXDIM];
282 } IntArray;
283
284 /*
285  * Offset --
286  *              Offset into any memory resident array.
287  *
288  * Note:
289  *              This differs from an Index in that an Index is always
290  *              non negative, whereas Offset may be negative.
291  */
292 typedef signed int Offset;
293
294 /* ----------------------------------------------------------------
295  *                              Section 4:      datum type + support macros
296  * ----------------------------------------------------------------
297  */
298 /*
299  * datum.h --
300  *              POSTGRES abstract data type datum representation definitions.
301  *
302  * Note:
303  *
304  * Port Notes:
305  *      Postgres makes the following assumption about machines:
306  *
307  *      sizeof(Datum) == sizeof(long) >= sizeof(void *) >= 4
308  *
309  *      Postgres also assumes that
310  *
311  *      sizeof(char) == 1
312  *
313  *      and that
314  *
315  *      sizeof(short) == 2
316  *
317  *      If your machine meets these requirements, Datums should also be checked
318  *      to see if the positioning is correct.
319  *
320  *              This file is MACHINE AND COMPILER dependent!!!
321  */
322
323 typedef unsigned long Datum;    /* XXX sizeof(long) >= sizeof(void *) */
324 typedef Datum *DatumPtr;
325
326 #define GET_1_BYTE(datum)       (((Datum) (datum)) & 0x000000ff)
327 #define GET_2_BYTES(datum)      (((Datum) (datum)) & 0x0000ffff)
328 #define GET_4_BYTES(datum)      (((Datum) (datum)) & 0xffffffff)
329 #define SET_1_BYTE(value)       (((Datum) (value)) & 0x000000ff)
330 #define SET_2_BYTES(value)      (((Datum) (value)) & 0x0000ffff)
331 #define SET_4_BYTES(value)      (((Datum) (value)) & 0xffffffff)
332
333 /*
334  * DatumGetChar --
335  *              Returns character value of a datum.
336  */
337
338 #define DatumGetChar(X) ((char) GET_1_BYTE(X))
339
340 /*
341  * CharGetDatum --
342  *              Returns datum representation for a character.
343  */
344
345 #define CharGetDatum(X) ((Datum) SET_1_BYTE(X))
346
347 /*
348  * Int8GetDatum --
349  *              Returns datum representation for an 8-bit integer.
350  */
351
352 #define Int8GetDatum(X) ((Datum) SET_1_BYTE(X))
353
354 /*
355  * DatumGetUInt8 --
356  *              Returns 8-bit unsigned integer value of a datum.
357  */
358
359 #define DatumGetUInt8(X) ((uint8) GET_1_BYTE(X))
360
361 /*
362  * UInt8GetDatum --
363  *              Returns datum representation for an 8-bit unsigned integer.
364  */
365
366 #define UInt8GetDatum(X) ((Datum) SET_1_BYTE(X))
367
368 /*
369  * DatumGetInt16 --
370  *              Returns 16-bit integer value of a datum.
371  */
372
373 #define DatumGetInt16(X) ((int16) GET_2_BYTES(X))
374
375 /*
376  * Int16GetDatum --
377  *              Returns datum representation for a 16-bit integer.
378  */
379
380 #define Int16GetDatum(X) ((Datum) SET_2_BYTES(X))
381
382 /*
383  * DatumGetUInt16 --
384  *              Returns 16-bit unsigned integer value of a datum.
385  */
386
387 #define DatumGetUInt16(X) ((uint16) GET_2_BYTES(X))
388
389 /*
390  * UInt16GetDatum --
391  *              Returns datum representation for a 16-bit unsigned integer.
392  */
393
394 #define UInt16GetDatum(X) ((Datum) SET_2_BYTES(X))
395
396 /*
397  * DatumGetInt32 --
398  *              Returns 32-bit integer value of a datum.
399  */
400
401 #define DatumGetInt32(X) ((int32) GET_4_BYTES(X))
402
403 /*
404  * Int32GetDatum --
405  *              Returns datum representation for a 32-bit integer.
406  */
407
408 #define Int32GetDatum(X) ((Datum) SET_4_BYTES(X))
409
410 /*
411  * DatumGetUInt32 --
412  *              Returns 32-bit unsigned integer value of a datum.
413  */
414
415 #define DatumGetUInt32(X) ((uint32) GET_4_BYTES(X))
416
417 /*
418  * UInt32GetDatum --
419  *              Returns datum representation for a 32-bit unsigned integer.
420  */
421
422 #define UInt32GetDatum(X) ((Datum) SET_4_BYTES(X))
423
424 /*
425  * DatumGetObjectId --
426  *              Returns object identifier value of a datum.
427  */
428
429 #define DatumGetObjectId(X) ((Oid) GET_4_BYTES(X))
430
431 /*
432  * ObjectIdGetDatum --
433  *              Returns datum representation for an object identifier.
434  */
435
436 #define ObjectIdGetDatum(X) ((Datum) SET_4_BYTES(X))
437
438 /*
439  * DatumGetPointer --
440  *              Returns pointer value of a datum.
441  */
442
443 #define DatumGetPointer(X) ((Pointer) X)
444
445 /*
446  * PointerGetDatum --
447  *              Returns datum representation for a pointer.
448  */
449
450 #define PointerGetDatum(X) ((Datum) X)
451
452 /*
453  * DatumGetName --
454  *              Returns name value of a datum.
455  */
456
457 #define DatumGetName(X) ((Name) DatumGetPointer((Datum) X))
458
459 /*
460  * NameGetDatum --
461  *              Returns datum representation for a name.
462  */
463
464 #define NameGetDatum(X) PointerGetDatum((Pointer) X)
465
466
467 /*
468  * DatumGetFloat32 --
469  *              Returns 32-bit floating point value of a datum.
470  *              This is really a pointer, of course.
471  */
472
473 #define DatumGetFloat32(X) ((float32) DatumGetPointer((Datum) X))
474
475 /*
476  * Float32GetDatum --
477  *              Returns datum representation for a 32-bit floating point number.
478  *              This is really a pointer, of course.
479  */
480
481 #define Float32GetDatum(X) PointerGetDatum((Pointer) X)
482
483 /*
484  * DatumGetFloat64 --
485  *              Returns 64-bit floating point value of a datum.
486  *              This is really a pointer, of course.
487  */
488
489 #define DatumGetFloat64(X) ((float64) DatumGetPointer(X))
490
491 /*
492  * Float64GetDatum --
493  *              Returns datum representation for a 64-bit floating point number.
494  *              This is really a pointer, of course.
495  */
496
497 #define Float64GetDatum(X) PointerGetDatum((Pointer) X)
498
499 /* ----------------------------------------------------------------
500  *                              Section 5:      IsValid macros for system types
501  * ----------------------------------------------------------------
502  */
503 /*
504  * BoolIsValid --
505  *              True iff bool is valid.
506  */
507 #define BoolIsValid(boolean)    ((boolean) == false || (boolean) == true)
508
509 /*
510  * PointerIsValid --
511  *              True iff pointer is valid.
512  */
513 #define PointerIsValid(pointer) (bool)((void*)(pointer) != NULL)
514
515 /*
516  * PointerIsInBounds --
517  *              True iff pointer is within given bounds.
518  *
519  * Note:
520  *              Assumes the bounded interval to be [min,max),
521  *              i.e. closed on the left and open on the right.
522  */
523 #define PointerIsInBounds(pointer, min, max) \
524                 ((min) <= (pointer) && (pointer) < (max))
525
526 /*
527  * PointerIsAligned --
528  *              True iff pointer is properly aligned to point to the given type.
529  */
530 #define PointerIsAligned(pointer, type) \
531                 (((long)(pointer) % (sizeof (type))) == 0)
532
533 /* ----------------------------------------------------------------
534  *                              Section 6:      offsetof, lengthof, endof
535  * ----------------------------------------------------------------
536  */
537 /*
538  * offsetof --
539  *              Offset of a structure/union field within that structure/union.
540  *
541  *              XXX This is supposed to be part of stddef.h, but isn't on
542  *              some systems (like SunOS 4).
543  */
544 #ifndef offsetof
545 #define offsetof(type, field)   ((long) &((type *)0)->field)
546 #endif                                                  /* offsetof */
547
548 /*
549  * lengthof --
550  *              Number of elements in an array.
551  */
552 #define lengthof(array) (sizeof (array) / sizeof ((array)[0]))
553
554 /*
555  * endof --
556  *              Address of the element one past the last in an array.
557  */
558 #define endof(array)    (&array[lengthof(array)])
559
560 /* ----------------------------------------------------------------
561  *                              Section 7:      exception handling definitions
562  *                                                      Assert, Trap, etc macros
563  * ----------------------------------------------------------------
564  */
565 /*
566  * Exception Handling definitions
567  */
568
569 typedef char *ExcMessage;
570 typedef struct Exception
571 {
572         ExcMessage      message;
573 } Exception;
574
575 /*
576  * NO_ASSERT_CHECKING, if defined, turns off all the assertions.
577  * - plai  9/5/90
578  *
579  * It should _NOT_ be undef'ed in releases or in benchmark copies
580  *
581  * #undef NO_ASSERT_CHECKING
582  */
583
584 /*
585  * Trap --
586  *              Generates an exception if the given condition is true.
587  *
588  */
589 #define Trap(condition, exception) \
590                 { if (condition) \
591                                 ExceptionalCondition(CppAsString(condition), &(exception), \
592                                                 (char*)NULL, __FILE__, __LINE__); }
593
594 /*
595  *      TrapMacro is the same as Trap but it's intended for use in macros:
596  *
597  *              #define foo(x) (AssertM(x != 0) && bar(x))
598  *
599  *      Isn't CPP fun?
600  */
601 #define TrapMacro(condition, exception) \
602         ((bool) ((! condition) || \
603                          (ExceptionalCondition(CppAsString(condition), \
604                                                                   &(exception), \
605                                                                   (char*) NULL, __FILE__, __LINE__))))
606
607 #ifdef NO_ASSERT_CHECKING
608 #define Assert(condition)
609 #define AssertMacro(condition)  true
610 #define AssertArg(condition)
611 #define AssertState(condition)
612 #else
613 #define Assert(condition) \
614                 Trap(!(condition), FailedAssertion)
615
616 #define AssertMacro(condition) \
617                 TrapMacro(!(condition), FailedAssertion)
618
619 #define AssertArg(condition) \
620                 Trap(!(condition), BadArg)
621
622 #define AssertState(condition) \
623                 Trap(!(condition), BadState)
624
625 #endif                                                  /* NO_ASSERT_CHECKING */
626
627 /*
628  * LogTrap --
629  *              Generates an exception with a message if the given condition is true.
630  *
631  */
632 #define LogTrap(condition, exception, printArgs) \
633                 { if (condition) \
634                                 ExceptionalCondition(CppAsString(condition), &(exception), \
635                                                 form printArgs, __FILE__, __LINE__); }
636
637 /*
638  *      LogTrapMacro is the same as LogTrap but it's intended for use in macros:
639  *
640  *              #define foo(x) (LogAssertMacro(x != 0, "yow!") && bar(x))
641  */
642 #define LogTrapMacro(condition, exception, printArgs) \
643         ((bool) ((! condition) || \
644                          (ExceptionalCondition(CppAsString(condition), \
645                                                                    &(exception), \
646                                                                    form printArgs, __FILE__, __LINE__))))
647
648 #ifdef NO_ASSERT_CHECKING
649 #define LogAssert(condition, printArgs)
650 #define LogAssertMacro(condition, printArgs) true
651 #define LogAssertArg(condition, printArgs)
652 #define LogAssertState(condition, printArgs)
653 #else
654 #define LogAssert(condition, printArgs) \
655                 LogTrap(!(condition), FailedAssertion, printArgs)
656
657 #define LogAssertMacro(condition, printArgs) \
658                 LogTrapMacro(!(condition), FailedAssertion, printArgs)
659
660 #define LogAssertArg(condition, printArgs) \
661                 LogTrap(!(condition), BadArg, printArgs)
662
663 #define LogAssertState(condition, printArgs) \
664                 LogTrap(!(condition), BadState, printArgs)
665
666 #endif                                                  /* NO_ASSERT_CHECKING */
667
668 /* ----------------------------------------------------------------
669  *                              Section 8:      Min, Max, Abs macros
670  * ----------------------------------------------------------------
671  */
672 /*
673  * Max --
674  *              Return the maximum of two numbers.
675  */
676 #define Max(x, y)               ((x) > (y) ? (x) : (y))
677
678 /*
679  * Min --
680  *              Return the minimum of two numbers.
681  */
682 #define Min(x, y)               ((x) < (y) ? (x) : (y))
683
684 /*
685  * Abs --
686  *              Return the absolute value of the argument.
687  */
688 #define Abs(x)                  ((x) >= 0 ? (x) : -(x))
689
690 /*
691  * StrNCpy --
692  *              Does string copy, and forces terminating NULL
693  */
694 /* we do this so if the macro is used in an if action, it will work */
695 #define StrNCpy(dst,src,len)    \
696         (strncpy((dst),(src),(len)),(len > 0) ? *((dst)+(len)-1)='\0' : (void)NULL,(void)(dst))
697
698 /* Get a bit mask of the bits set in non-int32 aligned addresses */
699 #define INT_ALIGN_MASK (sizeof(int32) - 1)
700
701 /* This function gets call too often, so we inline it if we can */
702 #define MemSet(start, val, len) do \
703                                                                 {       /* are we aligned for int32? */ \
704                                                                         /* We have to cast the pointer to int \
705                                                                            so we can do the AND */ \
706                                                                         if (((int)(start) & INT_ALIGN_MASK) == 0 && \
707                                                                                 ((len) & INT_ALIGN_MASK) == 0 && \
708                                                                                 (val) == 0 && \
709                                                                         /* \
710                                                                          * We got this number by testing this \
711                                                                          * against the stock memset() on \
712                                                                          * bsd/os 3.0.  Larger values were \
713                                                                          * slower. \
714                                                                          */ \
715                                                                                 (len) <= 64) \
716                                                                         { \
717                                                                                 int32 *_i = (int32 *)(start); \
718                                                                                 int32 *_stop = (int32 *)((char *)(start) + (len)); \
719                                                                                 \
720                                                                                 while (_i < _stop) \
721                                                                                         *_i++ = 0; \
722                                                                         } \
723                                                                         else \
724                                                                                 memset((start), (val), (len)); \
725                                                                 } while (0)
726
727 /* ----------------------------------------------------------------
728  *                              Section 9: externs
729  * ----------------------------------------------------------------
730  */
731
732 extern Exception FailedAssertion;
733 extern Exception BadArg;
734 extern Exception BadState;
735
736 /* in utils/error/assert.c */
737 extern int ExceptionalCondition(char *conditionName,
738                                          Exception *exceptionP, char *details,
739                                          char *fileName, int lineNumber);
740
741
742 /* ----------------
743  *              form is used by assert and the exception handling stuff
744  * ----------------
745  */
746 extern char *form(const char *fmt,...);
747
748
749
750 /* ----------------------------------------------------------------
751  *                              Section 10: berkeley-specific configuration
752  *
753  * this section contains settings which are only relevant to the UC Berkeley
754  * sites.  Other sites can ignore this
755  * ----------------------------------------------------------------
756  */
757
758 /* ----------------
759  *              storage managers
760  *
761  *              These are experimental and are not supported in the code that
762  *              we distribute to other sites.
763  * ----------------
764  */
765 #ifdef SEQUOIA
766 #define MAIN_MEMORY
767 #endif
768
769
770
771 /* ----------------------------------------------------------------
772  *                              Section 11: system-specific hacks
773  *
774  *              This should be limited to things that absolutely have to be
775  *              included in every source file.  The changes should be factored
776  *              into a separate file so that changes to one port don't require
777  *              changes to c.h (and everyone recompiling their whole system).
778  * ----------------------------------------------------------------
779  */
780
781 #ifdef FIXADE
782 #if defined(hpux)
783 #include "port/hpux/fixade.h"   /* for unaligned access fixup */
784 #endif                                                  /* hpux */
785 #endif
786
787 #if defined(sunos4)
788 #define memmove(d, s, l)                bcopy(s, d, l)
789 #include <unistd.h>
790 #endif
791
792 /* These are for things that are one way on Unix and another on NT */
793 #define NULL_DEV                "/dev/null"
794 #define COPY_CMD                "cp"
795 #define SEP_CHAR                '/'
796
797 /* ----------------
798  *              end of c.h
799  * ----------------
800  */
801 #endif                                                  /* C_H */