]> git.donarmstrong.com Git - lilypond.git/blob - guile18/libguile/gen-scmconfig.c
Import guile-1.8 as multiple upstream tarball component
[lilypond.git] / guile18 / libguile / gen-scmconfig.c
1
2 /**********************************************************************
3
4   Description of Guile's public config header mechanics:
5   ----------------------------------------------------- 
6
7   Guile has four core headers:
8
9     config.h: Guile's private automatically generated configuration
10       header -- generated by configure.in and autoheader.  *NOT*
11       installed during "make install" and so may not be referred to by
12       any public headers.
13
14     libguile/_scm.h: Guile's private core header.  _scm.h is not
15       installed.  It's only visible to the libguile sources
16       themselves, and it includes config.h, the private config header.
17       Among other things this file provides a place to make decisions
18       based on the information gathered in config.h.
19
20     libguile/scmconfig.h: Guile's public automatically generated
21       configuration header -- generated at build time by concatenating
22       the contents of libguile/scmconfig.h.top with the output from
23       libguile/gen-scmconfig.  gen-scmconfig bases its output on the
24       information in the private config.h header, the contents of
25       gen-scmconfig.h (which is created by configure.in from
26       gen-scmconfig.h.in), and the information provided in this file,
27       gen-scmconfig.c.
28
29     libguile/__scm.h: Guile's public core header.  This file is
30       installed and publically visible.  It includes
31       libguile/scmconfig.h, the public config header and provides a
32       place to make decisions based on the information gathered in
33       scmconfig.h to define things that other headers can depend on.
34
35    Notes and guidelines:
36
37    - use 1 and 0 for public #defines instead of "def and undef",
38      i.e. use #define SCM_HAVE_FOO rather than just not defining
39      SCM_HAVE_FOO whenever possible.  See GNU Coding Guidelines for
40      rationale.  The only notable non-deprecated exceptions to this
41      rule are GUILE_DEBUG and GUILE_DEBUG_FREELIST which do not follow
42      this convention in order to retain backward compatibility.
43
44    - in the code below, be *VERY* careful not to use or rely on any
45      runtime-dynamic information below.  For example, you cannot use
46      sizeof (FOO), but must use static information like SIZEOF_BAR
47      (from config.h) or SCM_SIZEOF_BAZ (from scmconfig.h).  This is
48      because the gcc that is compiling gen-scmconfig.c and/or the
49      machine that is running gen-scmconfig may not be the same
50      compiler and/or hardware that will eventually be running Guile.
51      (i.e. keep the cross-compilation case in mind).
52
53    - try to avoid adding names to the public namespace when possible.
54      Note in the code below, that in a number of cases, we detect a
55      feature and based on that, we decide whether or not to print
56      anything at all.  This decreases the extraneous #defines and
57      #ifdefery that we require in scmconfig.h
58
59    - try to avoid adding any duplicate definitions to config.h and
60      scmconfig.h.  i.e. have just SCM_ENABLE_ELISP in scmconfig.h
61      rather than ENABLE_ELISP in config.h and SCM_ENABLE_ELISP in
62      scmconfig.h.
63
64    - in cases where you need to communicate information from
65      configure.in to gen-scmconfig.c, don't add an AC_DEFINE unless
66      you need it for other purposes.  Just add a suitable SCM_I_GSC_*
67      variable to configure.in, set the value, AC_SUBST the value, and
68      add an appropriate line to gen-scmconfig.h.in.  All gen-scmconfig
69      related AC_SUBST vars should be prefixed with SCM_I_GSC_.
70
71    - make sure that anything that we explicitly typedef publically is
72      prefixed with scm_t_.  i.e. we used to typedef long to ptrdiff_t
73      if we didn't detect ptrdiff_t, but this has been changed so that
74      we typedef scm_t_ptrdiff instead so that we won't conflict with
75      any non-guile header definitions of the same type.  For types
76      like intptr_t and uintptr_t which we just try to detect and don't
77      actually define, it's fine not to have a corresponding scm_t_
78      type.
79
80    - we now use SCM_SIZEOF_FOO != 0 rather than SCM_HAVE_FOO for any
81      cases where the size might actually vary.  For types where the
82      size is fixed, we use SCM_HAVE_FOO, i.e. you can see us define or
83      not define SCM_HAVE_T_INT64 below when appropriate.
84
85    Rationales (not finished):
86
87      Why do we use a C program here rather than AC_OUTPUT_COMMANDS?
88      --------------------------------------------------------------
89
90      The main reason is that there are some values we would need
91      access to at AC_OUTPUT_COMMANDs that are determined by configure
92      but are not available at AC_OUTPUT time.  The values are *only*
93      available via config.h.  We use gen-scmconfig so we can see those
94      values and make decisions based on their settings.
95
96      Why have gen-scmconfig.h.in?
97      ----------------------------
98
99      Without that header, we could end up needing multiple aliases for
100      public settings like SCM_ENABLE_ELISP.  We can't define
101      SCM_ENABLE_ELISP in config.h since that header is private and any
102      definition in scmconfig.h would conflict (#ifndef might be
103      possible but runs the risk of conflicting directives), so a
104      likely solution would be to AC_DEFINE([SCM_I_ENABLE_ELISP]), and
105      then use SCM_I_ENABLE_ELISP in gen-scmconfig via config.h to
106      determine whether or not to #define SCM_ENABLE_ELISP, but this
107      leaves us with two #defined symbols for each public setting --
108      better to just have one value (public or private) that all code
109      uses.
110
111      Having this header means we can AC_SUBST a value like
112      SCM_I_GSC_ENABLE_ELISP and then set it in here via AC_OUTPUT
113      substitutions, and gen-scmconfig can use that definition to
114      determine whether or not to #define SCM_ENABLE_ELISP when
115      generating scmconfig.h, and we end up with nothing extraneous
116      added to config.h.
117
118  **********************************************************************/
119
120 #ifdef HAVE_CONFIG_H
121 #  include <config.h>
122 #endif
123
124 #include <libguile/gen-scmconfig.h>
125
126 #include <stdio.h>
127 #include <string.h>
128
129 #define pf printf
130
131 int
132 main (int argc, char *argv[])
133 {
134   pf ("/* This file is automatically generated --"
135       " see configure.in for details */\n"
136       "\n"
137       "#ifndef SCM_SCMCONFIG_H\n"
138       "#define SCM_SCMCONFIG_H\n");
139   
140   /*** various important headers ***/
141   pf ("\n");
142   pf ("/* Important headers */\n");
143   if (SCM_I_GSC_NEEDS_STDINT_H)
144     pf ("#include <stdint.h>\n");
145   if (SCM_I_GSC_NEEDS_INTTYPES_H)
146     pf ("#include <inttypes.h>\n");
147
148 #ifdef HAVE_LIMITS_H
149   pf ("#include <limits.h>\n");
150 #else
151   pf ("/* limits.h not available */\n");
152 #endif
153
154 # ifdef TIME_WITH_SYS_TIME
155   pf ("#include <sys/time.h>\n");
156   pf ("#include <time.h>\n");
157 # else
158 #  ifdef HAVE_SYS_TIME_H
159   pf ("#include <sys/time.h>\n");
160 #  else
161 #   ifdef HAVE_TIME_H
162   pf ("#include <time.h>\n");
163 #   endif
164 #  endif
165 # endif
166
167   pf("\n");
168 #ifdef STDC_HEADERS
169   pf ("#define SCM_HAVE_STDC_HEADERS 1 /* 0 or 1 */\n");
170   pf ("#include <stdlib.h>\n");
171 # if HAVE_SYS_TYPES_H
172   pf ("#include <sys/types.h>\n");
173 # endif
174 # if HAVE_SYS_STDTYPES_H
175   pf ("#include <sys/stdtypes.h>\n");
176 # endif
177   pf ("#include <stddef.h>\n");
178 #else /* STDC_HEADERS */
179   pf ("#define SCM_HAVE_STDC_HEADERS 0 /* 0 or 1 */");
180 #endif /* def STDC_HEADERS */
181
182   pf("\n");
183 #ifdef HAVE_SYS_SELECT_H
184   pf ("#define SCM_HAVE_SYS_SELECT_H 1 /* 0 or 1 */\n");
185 #else
186   pf ("#define SCM_HAVE_SYS_SELECT_H 0 /* 0 or 1 */\n");
187 #endif
188
189 #ifdef HAVE_FLOATINGPOINT_H
190   pf ("#define SCM_HAVE_FLOATINGPOINT_H 1 /* 0 or 1 */\n");
191 #else
192   pf ("#define SCM_HAVE_FLOATINGPOINT_H 0 /* 0 or 1 */\n");
193 #endif
194
195 #ifdef HAVE_IEEEFP_H
196   pf ("#define SCM_HAVE_IEEEFP_H 1 /* 0 or 1 */\n");
197 #else
198   pf ("#define SCM_HAVE_IEEEFP_H 0 /* 0 or 1 */\n");
199 #endif
200
201 #ifdef HAVE_NAN_H
202   pf ("#define SCM_HAVE_NAN_H 1 /* 0 or 1 */\n");
203 #else
204   pf ("#define SCM_HAVE_NAN_H 0 /* 0 or 1 */\n");
205 #endif
206
207 #ifdef HAVE_WINSOCK2_H
208   pf ("#define SCM_HAVE_WINSOCK2_H 1 /* 0 or 1 */\n");
209 #else
210   pf ("#define SCM_HAVE_WINSOCK2_H 0 /* 0 or 1 */\n");
211 #endif
212
213
214   /*** GUILE_DEBUG (defined or undefined) ***/
215   pf ("\n");
216   pf ("/* Define to include various undocumented debugging functions. */\n");
217   if (SCM_I_GSC_GUILE_DEBUG)
218     pf ("#define GUILE_DEBUG 1 /* defined or undefined */\n");
219   else
220     pf ("/* #undef GUILE_DEBUG */\n");
221   
222   /*** GUILE_DEBUG_FREELIST (deined or undefined) ***/
223   pf ("\n");
224   pf ("/* Define this to debug the free list (helps w/ GC bugs). */\n");
225   if (SCM_I_GSC_GUILE_DEBUG_FREELIST)
226     pf ("#define GUILE_DEBUG_FREELIST 1 /* defined or undefined */\n");
227   else
228     pf ("/* #undef GUILE_DEBUG_FREELIST */\n");
229
230   /*** SCM_ENABLE_DISCOURAGED (0 or 1) ***/
231   pf ("\n");
232   pf ("/* Set to 1 if you want to enable discouraged features. */\n");
233   pf ("/* (value will be 0 or 1). */\n");
234   pf ("#define SCM_ENABLE_DISCOURAGED %d\n", SCM_I_GSC_ENABLE_DISCOURAGED);
235   
236   /*** SCM_ENABLE_DEPRECATED (0 or 1) ***/
237   pf ("\n");
238   pf ("/* Set to 1 if you want to enable deprecated features. */\n");
239   pf ("/* (value will be 0 or 1). */\n");
240   pf ("#define SCM_ENABLE_DEPRECATED %d\n", SCM_I_GSC_ENABLE_DEPRECATED);
241
242   /*** SCM_ENABLE_ELISP (0 or 1) ***/
243   pf ("\n");
244   pf ("/* Set to 1 to add Elisp support (in addition to Scheme). */\n");
245   pf ("#define SCM_ENABLE_ELISP %d /* 0 or 1 */\n", SCM_I_GSC_ENABLE_ELISP);
246
247   /*** SCM_STACK_GROWS_UP (0 or 1) ***/
248   pf ("\n");
249   pf ("/* Set to 1 if the stack grows up, 0 otherwise. */\n");
250   pf ("#define SCM_STACK_GROWS_UP %d /* 0 or 1 */\n",
251       SCM_I_GSC_STACK_GROWS_UP);
252
253   /*** SCM_C_INLINE (defined to appropriate string or undefined) ***/
254   pf ("\n");
255   pf ("/* C compiler's syntax for inline functions if any,\n"
256       "   otherwise undefined. */\n");
257   if (SCM_I_GSC_C_INLINE)
258     pf ("#define SCM_C_INLINE %s\n", SCM_I_GSC_C_INLINE);
259   else
260     pf ("/* #undef SCM_C_INLINE */\n");
261
262   pf ("\n");
263   pf ("/* Standard types. */\n");
264
265   pf ("/* These are always defined */\n");  
266   pf ("#define SCM_SIZEOF_CHAR %d\n", SIZEOF_CHAR);
267   pf ("#define SCM_SIZEOF_UNSIGNED_CHAR %d\n", SIZEOF_UNSIGNED_CHAR);
268   pf ("#define SCM_SIZEOF_SHORT %d\n", SIZEOF_SHORT);
269   pf ("#define SCM_SIZEOF_UNSIGNED_SHORT %d\n", SIZEOF_UNSIGNED_SHORT);
270   pf ("#define SCM_SIZEOF_LONG %d\n", SIZEOF_LONG);
271   pf ("#define SCM_SIZEOF_UNSIGNED_LONG %d\n", SIZEOF_UNSIGNED_LONG);
272   pf ("#define SCM_SIZEOF_INT %d\n", SIZEOF_INT);
273   pf ("#define SCM_SIZEOF_UNSIGNED_INT %d\n", SIZEOF_UNSIGNED_INT);
274   pf ("#define SCM_SIZEOF_SIZE_T %d\n", SIZEOF_SIZE_T);
275
276   pf ("\n");
277   pf ("/* Size of (unsigned) long long or 0 if not available (scm_t_*64 may\n"
278       "   be more likely to be what you want */\n");
279   pf ("#define SCM_SIZEOF_LONG_LONG %d\n", SIZEOF_LONG_LONG);
280   pf ("#define SCM_SIZEOF_UNSIGNED_LONG_LONG %d\n", SIZEOF_UNSIGNED_LONG_LONG);
281
282   pf("\n");
283   pf("/* handling for the deprecated long_long and ulong_long types */\n");  
284   pf("/* If anything suitable is available, it'll be defined here.  */\n");  
285   pf("#if (SCM_ENABLE_DEPRECATED == 1)\n");
286   if (SIZEOF_LONG_LONG != 0)
287     pf ("typedef long long long_long;\n");
288   else if (SIZEOF___INT64 != 0)
289     pf ("typedef __int64 long_long;\n");
290   
291   if (SIZEOF_UNSIGNED_LONG_LONG != 0)
292     pf ("typedef unsigned long long ulong_long;\n");
293   else if (SIZEOF_UNSIGNED___INT64 != 0)
294     pf ("typedef unsigned __int64 ulong_long;\n");
295   pf("#endif /* SCM_ENABLE_DEPRECATED == 1 */\n");
296
297   pf ("\n");
298   pf ("/* These are always defined. */\n");
299   pf ("typedef %s scm_t_int8;\n", SCM_I_GSC_T_INT8);
300   pf ("typedef %s scm_t_uint8;\n", SCM_I_GSC_T_UINT8);
301   pf ("typedef %s scm_t_int16;\n", SCM_I_GSC_T_INT16);
302   pf ("typedef %s scm_t_uint16;\n", SCM_I_GSC_T_UINT16);
303   pf ("typedef %s scm_t_int32;\n", SCM_I_GSC_T_INT32);
304   pf ("typedef %s scm_t_uint32;\n", SCM_I_GSC_T_UINT32);
305   pf ("typedef %s scm_t_intmax;\n", SCM_I_GSC_T_INTMAX);
306   pf ("typedef %s scm_t_uintmax;\n", SCM_I_GSC_T_UINTMAX);
307
308   if (0 == strcmp ("intmax_t", SCM_I_GSC_T_INTMAX))
309     pf ("#define SCM_SIZEOF_INTMAX %d\n", SIZEOF_INTMAX_T);
310   else if (0 == strcmp ("long long", SCM_I_GSC_T_INTMAX))
311     pf ("#define SCM_SIZEOF_INTMAX %d\n", SIZEOF_LONG_LONG);
312   else if (0 == strcmp ("__int64", SCM_I_GSC_T_INTMAX))
313     pf ("#define SCM_SIZEOF_INTMAX %d\n", SIZEOF___INT64);
314   else
315     return 1;
316
317   pf ("\n");
318   pf ("#define SCM_HAVE_T_INT64 1 /* 0 or 1 */\n");
319   pf ("typedef %s scm_t_int64;\n", SCM_I_GSC_T_INT64);
320   pf ("#define SCM_HAVE_T_UINT64 1 /* 0 or 1 */\n");
321   pf ("typedef %s scm_t_uint64;\n", SCM_I_GSC_T_UINT64);
322
323   pf ("\n");
324   pf ("/* scm_t_ptrdiff_t and size, always defined -- defined to long if\n"
325       "   platform doesn't have ptrdiff_t. */\n");
326   pf ("typedef %s scm_t_ptrdiff;\n", SCM_I_GSC_T_PTRDIFF);
327   if (0 == strcmp ("long", SCM_I_GSC_T_PTRDIFF))
328     pf ("#define SCM_SIZEOF_SCM_T_PTRDIFF %d\n", SIZEOF_LONG);
329   else
330     pf ("#define SCM_SIZEOF_SCM_T_PTRDIFF %d\n", SIZEOF_PTRDIFF_T);
331
332   pf ("\n");
333   pf ("/* Size of intptr_t or 0 if not available */\n");
334   pf ("#define SCM_SIZEOF_INTPTR_T %d\n", SIZEOF_INTPTR_T);
335   pf ("/* Size of uintptr_t or 0 if not available */\n");
336   pf ("#define SCM_SIZEOF_UINTPTR_T %d\n", SIZEOF_UINTPTR_T);
337
338   pf ("\n");
339   pf ("/* same as POSIX \"struct timespec\" -- always defined */\n");
340 #ifdef HAVE_STRUCT_TIMESPEC
341   pf ("typedef struct timespec scm_t_timespec;\n");
342 #else
343   pf ("/* POSIX.4 structure for a time value.  This is like a `struct timeval'"
344       "   but has nanoseconds instead of microseconds.  */\n");
345   pf ("typedef struct\n"
346       "{\n"
347       "  long int tv_sec;               /* Seconds.  */\n"
348       "  long int tv_nsec;              /* Nanoseconds.  */\n"
349       "} scm_t_timespec;\n");
350 #endif
351
352   pf ("\n");
353   pf ("/*** Threading model (scmconfig.h support not finished) ***/\n");
354
355   pf ("/* Define to 1 if using pthread multithreading. */\n");
356   pf ("#define SCM_USE_PTHREAD_THREADS %d /* 0 or 1 */\n",
357       SCM_I_GSC_USE_PTHREAD_THREADS);
358
359   pf ("/* Define to 1 if using one-thread 'multi'threading. */\n");
360   pf ("#define SCM_USE_NULL_THREADS %d /* 0 or 1 */\n",
361       SCM_I_GSC_USE_NULL_THREADS);
362
363   pf ("/* Define to 1 if need braces around PTHREAD_ONCE_INIT (for Solaris). */\n");
364   pf ("#define SCM_NEED_BRACES_ON_PTHREAD_ONCE_INIT %d /* 0 or 1 */\n",
365       SCM_I_GSC_NEED_BRACES_ON_PTHREAD_ONCE_INIT);
366
367   pf ("/* Define to 1 if need braces around PTHREAD_MUTEX_INITIALIZER\n"
368       "   (for IRIX with GCC)  */\n");
369   pf ("#define SCM_NEED_BRACES_ON_PTHREAD_MUTEX_INITIALIZER %d /* 0 or 1 */\n",
370       SCM_I_GSC_NEED_BRACES_ON_PTHREAD_MUTEX_INITIALIZER);
371
372   pf ("\n\n/*** File system access ***/\n");
373
374   pf ("/* Define to 1 if `struct dirent64' is available.  */\n");
375   pf ("#define SCM_HAVE_STRUCT_DIRENT64 %d /* 0 or 1 */\n",
376       SCM_I_GSC_HAVE_STRUCT_DIRENT64);
377
378   pf ("/* Define to 1 if `readdir64_r ()' is available.  */\n");
379 #ifdef HAVE_READDIR64_R
380   pf ("#define SCM_HAVE_READDIR64_R 1 /* 0 or 1 */\n");
381 #else
382   pf ("#define SCM_HAVE_READDIR64_R 0 /* 0 or 1 */\n");
383 #endif
384
385 #if USE_DLL_IMPORT
386   pf ("\n");
387   pf ("/* Define some additional CPP macros on Win32 platforms. */\n");
388   pf ("# define __REGEX_IMPORT__ 1\n");
389   pf ("# define __CRYPT_IMPORT__ 1\n");
390   pf ("# define __READLINE_IMPORT__ 1\n");
391   pf ("# define QT_IMPORT 1\n");
392 #endif
393
394   pf ("\n");
395   pf ("#if SCM_ENABLE_DEPRECATED == 1\n"
396       "# define USE_THREADS 1 /* always true now */\n"
397       "# define GUILE_ISELECT 1 /* always true now */\n"
398       "# define READER_EXTENSIONS 1 /* always true now */\n"
399       "# define DEBUG_EXTENSIONS 1 /* always true now */\n"
400       "# define DYNAMIC_LINKING 1 /* always true now */\n"
401       "#endif\n");
402   printf ("\n");
403
404   pf ("#define SCM_HAVE_ARRAYS 1 /* always true now */\n");
405
406   printf ("#endif\n");
407
408   return 0;
409 }