|
|
1.1 root 1: #ifndef __COMMON__CCOMPAT_H__
2: #define __COMMON__CCOMPAT_H__
3:
4: /*
5: * Define some handy things that allow us to work with K&R, ANSI and C++
6: * compilers in a way that is at least less painful than not working. This
7: * file does mandate an ANSI C pre-processing environment.
8: *
9: * While ANSI allows us to not define function prototypes, C++ mandates that
10: * they exist, and it's a *really* good idea to use them whereever possible.
11: *
12: * This file also deals with some compiler-specific features that are either
13: * in the C or C++ language standards but not always available, and some
14: * language extensions that are very widely available, if only because they
15: * are part of the C++ standard and have been incorporated into C compilers.
16: *
17: * This file specifically excludes specifics about target machines and
18: * compiler interactions. Such definitions belong in another file.
19: */
20:
21: #include <common/feature.h>
22:
23:
24: /*
25: * There is some complexity on the way __STDC__ is used in practice: the ANSI
26: * committee merely says that if __STDC__ is defined and value 1, then the
27: * implementation is ISO-conforming.
28: *
29: * Unfortunately, much existing code uses #ifdef as the only test, which
30: * means that some non-conforming compilers which defined __STDC__ as zero
31: * caused problems (the Coherent 3.x compiler is one such; the 4.x compiler
32: * uses the alternate convention). The #if test is preferable in programs,
33: * since in preprocessor tests undefined symbols assume value 0, but still
34: * many programs use the alternate form.
35: *
36: * For compilers with an intermediate status, eg. with an ISO preprocessor,
37: * or support for "const" but not prototypes, or prototypes but not "const"
38: * we perform individual featurectomies below.
39: *
40: * A general rule for future extensions: use double-underscores before and
41: * after for non-parameterized macros, double-underscores before for macros
42: * that take parameters. If this file's definitions are to be used by user-
43: * level code, create a header that exports the definitions into the user
44: * namespace.
45: *
46: * Jun '93 - split profile in two sections in anticipation of future growth.
47: * We can't assume more than 16-bit arithmetic because of some extremely
48: * losing preprocessors out there.
49: */
50:
51: /* __STD_PROFILE__ bits */
52: #define __STRINGIZE_M__ 0x0001 /* supports ISO C "stringize" */
53: #define __PASTE_M__ 0x0002 /* support ISO C token-pasting */
54: #define __PROTODECL_M__ 0x0004 /* supports prototype declarations */
55: #define __PROTODEFN_M__ 0x0008 /* supports prototype definitions */
56: #define __CONST_M__ 0x0010 /* supports "const" construct */
57: #define __VOLATILE_M__ 0x0020 /* supports "volatile" construct */
58: #define __VOIDSTAR_M__ 0x0040 /* supports "void *" type */
59:
60: #define __STD_PROFILE_MASK__ 0x007F
61:
62: /* __MISC_PROFILE__ bits */
63: #define __NOTUSED_M__ 0x0001 /* allows "not used" warning suppression */
64: #define __REGISTER_M__ 0x0002 /* requires "register" declaration */
65: #define __LINKID_M__ 0x0004 /* requires linkage specifier (eg C++) */
66: #define __INLINE_M__ 0x0008 /* allows inline functions */
67: #define __INLINEL_M__ 0x0010 /* allows inline functions with loops */
68: #define __DOTDOTDOT_M__ 0x0020 /* requires (...) rather than () */
69: #define __NOMERGESTR_M__ 0x0040 /* cannot merge identical strings */
70:
71: #define __MISC_PROFILE_MASK__ 0x007F
72:
73:
74: /*
75: * The Standard C language features in one definition for simplicity. This may
76: * not be all the bits in __STD_PROFILE_MASK__ once C++ standards start
77: * hitting the streets. Normative addenda to ISO C will complicate this, too.
78: */
79:
80: #define __STDC_M__ (__STD_PROFILE_MASK__)
81:
82:
83: /*
84: * Below, we attempt to determine a configuration suitable for the translator
85: * that is working on the current program. Each group of macros attempts to
86: * set a preprocessor macro __PROFILE__ with a bit-mask of the features
87: * supported by the current translator.
88: *
89: * This approach has been taken since it considerably simplifies both the
90: * task of adding new features to test for and adding new translators. Many
91: * other programs intermingle the tasks of determining the translator and
92: * defining the responses to that determination; in general, such programs
93: * fail to be maintainable when the matrix of features and translators grows
94: * larger than about 3x3.
95: *
96: * Jun '93 - With the split into two parts, we still let people use the single
97: * __PROFILE__ definition if their translator's preprocessor can deal with
98: * 32-bit arithmetic.
99: */
100:
101: #if defined (__PROFILE__) /* user-overridden */
102:
103: # if (1 << 31) == 0
104: # error Your preprocessor cannot handle 32-bit arithmetic!
105: # endif
106: # if __PROFILE__ & ~ (__STD_PROFILE_MASK__ | (__MISC_PROFILE_MASK << 16))
107: # error __PROFILE__ contains unknown flag bits.
108: # endif
109:
110: # define __STD_PROFILE__ (__PROFILE__ & __STD_PROFILE_MASK__)
111: # define __MISC_PROFILE__ ((__PROFILE__ >> 16) & __MISC_PROFILE_MASK__)
112:
113: #elif defined (__STD_PROFILE__) || defined (__MISC_PROFILE__)
114:
115: # ifndef __STD_PROFILE__
116: # error If you defined __MISC_PROFILE__, you must also define __STD_PROFILE__
117: # elif __STD_PROFILE__ & ~ __STD_PROFILE_MASK__
118: # error Unknown bits set in __STD_PROFILE__
119: # endif
120:
121: # ifndef __MISC_PROFILE__
122: # error If you defined __STD_PROFILE__, you must also define __MISC_PROFILE__
123: # elif __MISC_PROFILE__ & ~ __MISC_PROFILE_MASK__
124: # error Unknown bits set in __MISC_PROFILE__
125: # endif
126:
127: #elif defined (__cplusplus) /* C++ */
128:
129: # ifdef __GNUC__
130: # define __STD_PROFILE__ __STDC_M__
131: # define __MISC_PROFILE__ (__NOTUSED_M__ | __LINKID_M__ | \
132: __INLINE_M__ | __INLINEL_M__ | \
133: __DOTDOTDOT_2M__)
134: # else
135: # define __STD_PROFILE__ __STDC_M__
136: # define __MISC_PROFILE__ (__NOTUSED_M__ | __LINKID_M__ | \
137: __INLINE_M__ | __DOTDOTDOT_M__)
138: # endif
139:
140: #elif __BORLANDC__ /* Borland C */
141:
142: # if __BORLANDC__ >= 0x410
143: # define __STD_PROFILE__ __STDC_M__
144: # define __MISC_PROFILE__ 0 /* features restricted to C++ */
145: # else
146: # define __STD_PROFILE__ __STDC_M__
147: # define __MISC_PROFILE__ (__NOTUSED_M__ | __INLINE_M__)
148: # endif
149:
150: #elif defined (__GNUC__) /* GCC w/o C++ */
151:
152: # define __STD_PROFILE__ __STDC_M__
153: # define __MISC_PROFILE__ (__INLINE_M__ | __INLINEL_M__)
154:
155: #elif __STDC__ + 0 /* minimal ANSI C */
156:
157: # define __STD_PROFILE__ __STDC_M__
158: # define __MISC_PROFILE__ 0
159:
160: #elif __COHERENT__ /* MWC Coherent */
161:
162: # define __STD_PROFILE__ (__STRINGIZE_M__ | __PASTE_M__)
163: # define __MISC_PROFILE__ (__REGISTER_M__ | __NOMERGESTR_M__)
164:
165: #else /* VANILLA */
166:
167: # define __STD_PROFILE__ 0
168: # define __MISC_PROFILE__ __REGISTER_M__
169:
170: #endif
171:
172:
173: /*
174: * In the following sections we determine the responses to take on the basis
175: * of whether or not each feature/misfeature is supported by the current
176: * translator.
177: *
178: * In cases where the feature requires considerable change to source code,
179: * such as prototyping and inline functions, we define both an existence
180: * feature-test and a value macro.
181: *
182: * For the case of inline functions, this is because the function should not
183: * appear at all in the souce code unless unlining is supported (and because
184: * often a macro may suffice in place, although with less safety).
185: *
186: * In addition, the tests below always check to see whether a particular
187: * symbol is defined already, allowing almost any feature to be turned on or
188: * off at will from the command-line. This is useful when testing the
189: * characteristics of a new translator, and may often be useful to suppress
190: * certain features to aid in debugging.
191: */
192:
193: /*
194: * Some old Reiser preprocessors looked for macro-expansions unside quoted
195: * strings; this was useful, but dangerous, so ISO C defined a new operator
196: * for doing just this job. A tip of the hat to P.J. Plauger for the form of
197: * these macros.
198: */
199:
200: #ifndef __STRING
201: # if __STD_PROFILE__ & __STRINGIZE_M__
202:
203: # define __STRING(x) __VALUE(x)
204: # define __VALUE(x) #x
205:
206: # else
207:
208: # define __STRING(x) "x"
209:
210: # endif
211: #endif
212:
213:
214: /*
215: * As above, this is a feature supported in old systems by ill-advised hacks,
216: * so ISO C has a special operator just for the job. We define __CONCAT3 ()
217: * and __CONCAT4 () as primitives just for fun; it's handy, and nested calls
218: * to __CONCAT () are just too messy to be practical.
219: */
220:
221: #ifndef __CONCAT
222: # if __STD_PROFILE__ & __PASTE_M__
223:
224: # define __CONCAT(x,y) x##y
225: # define __CONCAT3(x,y,z) x##y##z
226: # define __CONCAT4(a,b,c,d) a##b##c##d
227:
228: # else
229:
230: # define __CONCAT(x,y) x/**/y
231: # define __CONCAT3(x,y,z) x/**/y/**/z
232: # define __CONCAT4(a,b,c,d) a/**/b/**/c/**/d
233:
234: # endif
235: #endif
236:
237:
238: /*
239: * __USE_PROTO__ is a general test which can be performed in .c files to see
240: * whether to use a prototype form or a K&R form, since the two are so
241: * different. This has the advantage that some tools which are hard-wired for
242: * K&R source code can get confused by macros in the function header, so
243: * keeping a real K&R header around can help.
244: *
245: * __PROTO () is a macro that can be used in header files, since all that
246: * differs between K&R and ANSI external definitions is whether the types
247: * are present.
248: *
249: * The difference between the two is important, especially when "lint"-like
250: * tools are used. In order to check for consistency between the prototype
251: * and K&R-style definitions, it may be necessary to enable prototypes in
252: * the header files while suppressing them in the C files.
253: */
254:
255: #ifndef __PROTO
256: # if __STD_PROFILE__ & __PROTODECL_M__
257:
258: # define __PROTO(p) p
259:
260: # else /* prototypes are not supported */
261:
262: # define __PROTO(p) ()
263:
264: # endif
265: # if __STD_PROFILE__ & __PROTODEFN_M__
266:
267: # define __USE_PROTO__ 1
268:
269: # endif
270: #endif /* ! defined (__PROTO) */
271:
272:
273: /*
274: * There are several existing compilers still in use which either do not
275: * support the notion of a "const" language element or implement the feature
276: * incorrectly with respect to the C standard.
277: *
278: * For these compilers, we allow the "const" specifier in prototypes, local
279: * variables and structure declarations to be suppressed. Note that "const"
280: * will never appear in a K&R function header.
281: */
282:
283: #ifndef __CONST__
284: # if __STD_PROFILE__ & __CONST_M__
285:
286: # define __CONST__ const
287:
288: # else /* const is not supported */
289:
290: # define __CONST__
291:
292: # endif
293: #endif /* ! defined (__CONST__) */
294:
295:
296: /*
297: * For symmetry with the "const" definition, we provide a wrapper for the
298: * "volatile" feature. Note that for some reason "volatile" is available in
299: * some compilers that do not implement "const", probably because the feature
300: * was defined in simpler terms.
301: *
302: * For these compilers, we allow the "volatile" specifier in prototypes,
303: * local variables, and structure declarations to be suppressed.
304: */
305:
306: #ifndef __VOLATILE__
307: # if __STD_PROFILE__ & __VOLATILE_M__
308:
309: # define __VOLATILE__ volatile
310:
311: # else /* const is not supported */
312:
313: # define __VOLATILE__
314:
315: # endif
316: #endif /* ! defined (__VOLATILE__) */
317:
318:
319: /*
320: * Some compilers support the "void" type, but not the semantics of "void *".
321: *
322: * The following definition is similar to a usage in System V documentation
323: * which probably exists for the same reason, except that we use two
324: * underscores in ours before and after, where theirs is called _VOID.
325: *
326: * A word of explanation; what we are doing here is declaring an incomplete
327: * type; pointers to this incomplete type should function more-or-less as
328: * a pointer to "void" would except for lacking the implicit conversions that
329: * are special to "void *", because "void" is an "incomplete type that cannot
330: * be completed". Read the standard if you don't know about incomplete types.
331: */
332:
333: #ifndef __VOID__
334: # if __STD_PROFILE__ & __VOIDSTAR_M__
335:
336: # define __VOID__ void
337:
338: # else /* void with a pointer is not supported */
339:
340: # if __COHERENT__ && ! __GNUC__ /* stroke a bug in Coherent 'cc' */
341:
342: # define __VOID__ char
343:
344: #else
345:
346: typedef struct __deep_magic__ __void__;
347: # define __VOID__ __void__
348:
349: # endif
350:
351: # endif
352: #endif /* ! defined (__VOID__) */
353:
354:
355: /*
356: * In order for some of the useful compiler extensions below to be kept
357: * available during a "strict" compile (assuming that the feature-tests above
358: * enable their use) then the convention is to prepend compiler-specific
359: * keywords with double-underscores.
360: *
361: * This also serves to document which usages are not ISO C. Note that this
362: * may have to change a little for a potential standardized C++.
363: */
364:
365: #if __STDC__ + 0
366:
367: # define __NON_ISO(k) __CONCAT (__, k)
368:
369: #else
370:
371: # define __NON_ISO(k) k
372:
373: #endif
374:
375:
376: /*
377: * A feature defined as part of the C++ language that also exists in many
378: * C implementations is the ability to suppress "argument not used" warnings
379: * in some cases by omitting the name of the variable in the function
380: * prototype and merely giving the type.
381: *
382: * This feature is common in type-checking compilers since the checking of
383: * function pointer arguments and other extra checks mean that functions
384: * must be declared with unused arguments to match the shape of some function
385: * pointer.
386: *
387: * Of course, it is desirable to leave the original name of the variable in
388: * the same place for documentation purposes, often commented out, but this
389: * usage chokes some compilers. It seems preferable use the following
390: * definition to explicitly state the intention, even in cases where the
391: * compiler generates spurious warnings.
392: */
393:
394: #ifndef __NOTUSED
395: # if __MISC_PROFILE__ & __NOTUSED_M__
396:
397: # define __NOTUSED(name) /* name */
398:
399: # else /* does not understand name suppression */
400:
401: # define __NOTUSED(name) __CONCAT (unused_, name)
402:
403: # endif
404: #endif /* ! defined (__NOTUSED) */
405:
406:
407: /*
408: * Most modern compilers perform their own register allocation and ignore
409: * the "register" directive from K&R C. Such compilers usually have debugging
410: * tools that know how to deal with variables that spend at least part of
411: * their lifetime in a machine register (or at worst, the option to suppress
412: * the auto-register allocation).
413: *
414: * For compilers that require a register declaration for a variable to be
415: * placed in a machine register, often it is desirable to suppress the use
416: * of registers when debugging.
417: */
418:
419: #ifndef __REGISTER__
420: # if __MISC_PROFILE__ & __REGISTER_M__
421:
422: # define __REGISTER__ register
423:
424: # else
425:
426: # define __REGISTER__
427:
428: # endif
429: #endif /* ! defined (__REGISTER__) */
430:
431:
432: /*
433: * Some compilers for C-like languages such as C++, Objective-C or even
434: * conceivably Pascal/Modula-2/Fortran support cross-language linkage.
435: *
436: * The standard way of doing this within the C family is to use a special
437: * form of "extern" which names the language a function is implemented in.
438: * Functions which are implemented in C in a library should be declared as
439: * such in the exported header.
440: *
441: * Currently, this is most important for C++.
442: */
443:
444: #ifndef __EXTERN_C__
445: # if __MISC_PROFILE__ & __LINKID_M__
446:
447: # define __EXTERN_C__ extern "C"
448: # define __EXTERN_C_BEGIN__ __EXTERN_C__ {
449: # define __EXTERN_C_END__ }
450:
451: # else /* this is being compiled by a C compiler */
452:
453: # define __EXTERN_C__
454: # define __EXTERN_C_BEGIN__
455: # define __EXTERN_C_END__
456:
457: # endif
458: #endif /* ! defined (__EXTERN_C__) */
459:
460:
461: /*
462: * All C++ compilers and many C compilers support the notion of "inline
463: * functions" as an alternative to macros that (i) can be used to wrap up
464: * casts so they are only used in safe contexts, (ii) can be used as an
465: * alternative to macros that allow arguments with side-effects.
466: *
467: * This comes in two strengths: can inline anything, and can inline anything
468: * that does not contain a loop. GNU C has extra strength, can inline tail-
469: * recursive inline function, but that facility is not sufficiently widespread
470: * to be useful as yet.
471: *
472: * The question is, what should the default setting of the client tests be?
473: * #if ! __NO_INLINE__ is a double-negative, so don't use that. The
474: * possibility of defining __INLINE__ as "static" so that inline functions
475: * appear in the module separately breakpointable from other modules is a
476: * desirable facility (assuming the debug namespace is separate from the
477: * linkage namespace, likely in a system sophisticated enough to support
478: * inlining). Furthermore, be aware of any interactions with the __LOCAL__
479: * macro defined in <common/xdebug.h>
480: */
481:
482: #ifndef __INLINE__
483: # if __MISC_PROFILE__ & __INLINE_M__
484:
485: # define __INLINE__ __NON_ISO (inline)
486: # define __USE_INLINE__ 1
487:
488: # else
489:
490: # define __INLINE__
491:
492: # endif
493: #endif
494:
495: #ifndef __INLINEL__
496: # if __MISC_PROFILE__ & __INLINEL_M__
497:
498: # define __INLINEL__ __NON_ISO (inline)
499: # define __USE_INLINEL__ 1
500:
501: # else
502:
503: # define __INLINEL__
504:
505: # endif
506: #endif
507:
508:
509: /*
510: * One particular incompatibility between ANSI C and C++ code exists in the
511: * way in which prototypes which do not specify any types at all are handled.
512: * Under C++, the () form is used to imply (void), since such declarations
513: * are extremely common and because early versions of the C++ translators did
514: * not allow any declarations in the argument lists of constructors or
515: * destructors, not even void, so this form was used to syntactically imply
516: * (void).
517: *
518: * The ANSI C committe declared that a prototype of the form
519: * extern char * malloc ();
520: * said nothing whatsoever about the types of it's arguments, since such
521: * declarations were extremely common in K&R C code, and doing anything else
522: * would gratuitously require considerable rewriting.
523: *
524: * Unfortunately, the ANSI C committee decided that the special form "..." to
525: * introduce variable arguments was not valid unless preceeded by a regular
526: * argument type declaration, so that there is no way of being unambiguous
527: * that will compile under both transators.
528: *
529: * ANSI C++
530: *
531: * () (...) (void) ambiguous
532: *
533: * (void) (void) (void) unambiguous
534: *
535: * (...) error (...) thanks, X3J11
536: *
537: * Use the preprocessor symbol __ANY_ARGS__ in this context to expand to
538: * whatever the current translator needs to see for it to make no assumptions
539: * about the number and type of any function arguments.
540: */
541:
542: #ifndef __ANY_ARGS__
543: # if __MISC_PROFILE__ & __DOTDOTDOT__
544:
545: # define __ANY_ARGS__ ...
546:
547: # else
548:
549: # define __ANY_ARGS__
550:
551: # endif
552: #endif /* ! defined (__ANY_ARGS__) */
553:
554:
555: /*
556: * String constants have been mightily botched in C, largely because K&R C
557: * always treated strings as unique, writeable data. The introduction of the
558: * 'const' qualifier should have made things simpler by allowing compilers to
559: * figure out whether a string is being used in a 'const' or non-'const'
560: * way. However, the precedent of just making all strings which are not being
561: * used as character array initializers into shareable constants has already
562: * been established.
563: *
564: * This has an effect on complex macros, because a string in a macro may (in
565: * a K&R environment or an ISO environment with certain switch settings)
566: * cause a host of anonymous, identical string constants to be created, which
567: * have to be suppressed by using a static declaration. On the other hand,
568: * this does worse than a compiler which does share strings, because if the
569: * macro is not actually used then the data space is still taken up.
570: *
571: * Here we give a hint to those macros that care.
572: */
573:
574: #ifndef _SHARED_STRINGS
575: # if (__MISC_PROFILE__ & __NOMERGESTR_M__) == 0
576:
577: # define _SHARED_STRINGS 1
578:
579: # endif
580: #endif /* ! defined (_SHARED_STRINGS) */
581:
582:
583: /*
584: * It is frequently convenient to be able to map a pointer to a member of a
585: * structure back to a pointer to the parent structure. Unfortunately, while
586: * ISO C mandates that conversions between pointer types and will not cause
587: * loss of information, there are few things that can portably be done with
588: * such a converted pointer. In particular, the easy way of mapping back from
589: * a structure member pointer to the containing structure performs address
590: * arithmetic on character pointers using offsetof (). It appears that this
591: * puts us in the realm of implementation-defined behaviour, except when the
592: * offsetof () the member is 0.
593: */
594:
595: #ifndef __DOWNCAST
596:
597: # define __DOWNCAST(str,mem,ptomem) \
598: ((str *) ((char *) (ptomem) - \
599: offsetof (str, mem)))
600:
601: #endif
602:
603:
604: /*
605: * This is a minor K&R compatibility issue: certain K&R compilers reject the
606: * ISO C idiom of enclosing a macro name in parentheses to suppress macro
607: * expansion when this idiom is used in function declarations. To get around
608: * this, we can use the ISO preprocessor in a clumsy fashion by providing an
609: * identity macro to provide the same overall effect of making the name we
610: * wish to suppress expansion for not be immediately followed by a left
611: * parenthesis (it will be followed by a parenthesis eventually, but since the
612: * proprocessor won't revisit the text it has seen before the expansion of
613: * the identity macro we get the behaviour we want).
614: */
615:
616: #define __ARGS(x) x
617:
618:
619: /*
620: * The POSIX.1 standard discusses a special namespace issue; how can standard
621: * structures be portably extended, given that the structure tags are in the
622: * user namespace. For structures which have members with regular names and
623: * which are likely to be extended, the POSIX.1 standard deals with this by
624: * implicitly reserving all names of that form (something which further
625: * underscores the restrictions on standard headers not including each other).
626: *
627: * However, for situations where we wish to extend a structure not covered by
628: * the namespace reservation rules, or we wish to name a member according to
629: * some other usage, we must take care to not define the member such that it
630: * might conflict with some macro name which the user is permitted to define.
631: * See POSIX.1 B.2.7.2 for discussion of this point.
632: *
633: * The following definition can be used to wrap the definition of structure
634: * member names such that those names will not conflict with user macros if
635: * _POSIX_SOURCE is defined. This form can be used in references to the member
636: * name which may be encapsulated in macros so that there is no loss of
637: * functionality or alteration of behaviour when _POSIX_SOURCE is used.
638: */
639:
640: #if _POSIX_SOURCE
641: # define __NON_POSIX(name) __CONCAT (_, name)
642: #else
643: # define __NON_POSIX(name) name
644: #endif
645:
646:
647: /*
648: * GCC has a special feature for declaring functions as not ever returning.
649: */
650:
651: #if __GNUC__
652: # define __NO_RETURN__ volatile
653: #else
654: # define __NO_RETURN__
655: #endif
656:
657:
658: /*
659: * Undefine all our internal symbols... why pollute the namespace?
660: */
661:
662: #undef __STRINGIZE_M__
663: #undef __PASTE_M__
664: #undef __PROTODECL_M__
665: #undef __PROTODEFN_M__
666: #undef __CONST_M__
667: #undef __VOLATILE_M__
668: #undef __VOIDSTAR_M__
669: #undef __STD_PROFILE_MASK__
670:
671: #undef __NOTUSED_M__
672: #undef __REGISTER_M__
673: #undef __LINKID_M__
674: #undef __INLINE_M__
675: #undef __INLINEL_M__
676: #undef __DOTDOTDOT_M__
677: #undef __NOMERGESTR_M__
678: #undef __MISC_PROFILE_MASK__
679:
680: #undef __STDC_M__
681: #undef __PROFILE__
682: #undef __STD_PROFILE__
683: #undef __MISC_PROFILE__
684:
685: #endif /* ! defined (__COMMON__CCOMPAT_H__) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.