1 /********************************************************************/
2 /*                                                                  */
3 /*  chkccomp.c    Check properties of C compiler and runtime.       */
4 /*  Copyright (C) 2010 - 2021  Thomas Mertes                        */
5 /*                                                                  */
6 /*  This program is free software; you can redistribute it and/or   */
7 /*  modify it under the terms of the GNU General Public License as  */
8 /*  published by the Free Software Foundation; either version 2 of  */
9 /*  the License, or (at your option) any later version.             */
10 /*                                                                  */
11 /*  This program is distributed in the hope that it will be useful, */
12 /*  but WITHOUT ANY WARRANTY; without even the implied warranty of  */
13 /*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   */
14 /*  GNU General Public License for more details.                    */
15 /*                                                                  */
16 /*  You should have received a copy of the GNU General Public       */
17 /*  License along with this program; if not, write to the           */
18 /*  Free Software Foundation, Inc., 51 Franklin Street,             */
19 /*  Fifth Floor, Boston, MA  02110-1301, USA.                       */
20 /*                                                                  */
21 /*  Module: Chkccomp                                                */
22 /*  File: seed7/src/chkccomp.c                                      */
23 /*  Changes: 2010 - 2021  Thomas Mertes                             */
24 /*  Content: Program to Check properties of C compiler and runtime. */
25 /*                                                                  */
26 /********************************************************************/
27 
28 #include "base.h"
29 
30 /**
31  *  From base.h the following defines are used (for details see: read_me.txt):
32  *
33  *  PATH_DELIMITER: (mandatory)
34  *      Path delimiter character used by the command shell of the operating system.
35  *  OBJECT_FILE_EXTENSION: (mandatory)
36  *      The extension used by the C compiler for object files.
37  *  C_COMPILER: (mandatory)
38  *      Contains the command to call the stand-alone C compiler and linker.
39  *      C_COMPILER_SCRIPT and TEST_C_COMPILER can be used instead of C_COMPILER.
40  *      If the C compiler is called via a script C_COMPILER_SCRIPT is defined
41  *      and C_COMPILER is not defined. In that case TEST_C_COMPILER is defined
42  *      (in chkccomp.h) and it is used instead of C_COMPILER as command of
43  *      the stand-alone C compiler and linker.
44  *  LINKER_OPT_OUTPUT_FILE: (mandatory)
45  *      Contains the linker option to provide the output filename (e.g.: "-o ").
46  *      Usually C compiler and linker are called with C_COMPILER. Without
47  *      LINKER_OPT_OUTPUT_FILE the output file name depends on the linker
48  *      used. Some use a fixed name like a.out while others use the source
49  *      name with a different extension.
50  *  OS_STRI_WCHAR: (optional)
51  *      Defined if the system calls (os_...) use wide characters (type wchar_t)
52  *      for string and path parameters.
53  *  QUOTE_WHOLE_SHELL_COMMAND: (optional)
54  *      Defined if shell commands, starting with " need to be quoted again.
55  *  EXECUTABLE_FILE_EXTENSION: (optional)
56  *      The extension which is used by the operating system for executables.
57  *  LINKED_PROGRAM_EXTENSION: (optional)
58  *      The extension of the file produced by compiling and linking a program.
59  *      Normally this is identical to the EXECUTABLE_FILE_EXTENSION, but in case
60  *      of Emscripten this is independent from the EXECUTABLE_FILE_EXTENSION.
61  *  INTERPRETER_FOR_LINKED_PROGRAM: (optional)
62  *      Defines an interpreter that is used if compiler and linker create
63  *      a file that must be interpreted.
64  *  CC_OPT_TRAP_OVERFLOW: (optional)
65  *      Contains a C compiler option that triggers the generation of code to
66  *      raise OVERFLOW_SIGNAL in case there is an integer overflow.
67  *  CC_OPT_VERSION_INFO: (optional)
68  *      C compiler option to write the C compiler version information.
69  *  CC_FLAGS: (optional)
70  *      Contains C compiler flags, which should be used when C programs are
71  *      compiled.
72  *  CC_NO_OPT_OUTPUT_FILE: (optional)
73  *      Defined, if compiling and linking with one command cannot use -o.
74  *  CC_ERROR_FILEDES: (optional)
75  *      File descriptor to which the C compiler writes errors.
76  *  CC_VERSION_INFO_FILEDES: (optional)
77  *      File descriptor to which the C compiler writes its version info.
78  *  LINKER: (optional)
79  *      Defined if C_COMPILER does just invoke the stand-alone C compiler.
80  *      In that case LINKER contains the command to call the stand-alone linker.
81  *  SYSTEM_LIBS: (optional)
82  *      Contains system libraries for the stand-alone linker.
83  *  SYSTEM_MATH_LIBS: (optional)
84  *      Contains system mathematic libraries for the stand-alone linker.
85  *  INT64TYPE_NO_SUFFIX_BUT_CAST: (optional)
86  *      Defined if 64-bit integer literals do not use a suffix.
87  *  TURN_OFF_FP_EXCEPTIONS (optional)
88  *      Use the function _control87() to turn off floating point exceptions.
89  *  INT_DIV_BY_ZERO_POPUP: (optional)
90  *      Defined if an integer division by zero may trigger a popup window.
91  *      Consequently chkccomp.c defines CHECK_INT_DIV_BY_ZERO, to avoid the
92  *      popup.
93  *  DO_SIGFPE_WITH_DIV_BY_ZERO: (optional)
94  *      TRUE, if SIGFPE should be raised with an integer division by zero.
95  *      If it is FALSE raise(SIGFPE) can be called instead. Under Windows
96  *      it is necessary to trigger SIGFPE this way, to assure that the debugger
97  *      can catch it.
98  *  USE_ALTERNATE_LOCALTIME_R: (optional)
99  *      Defined if the function alternate_localtime_r() should be used
100  *      instead of localtime().
101  *  FORMAT_LL_TRIGGERS_WARNINGS: (optional)
102  *      Defined if the printf format ll triggers a warning (and there is an
103  *      alternate format).
104  *  FILENO_WORKS_FOR_NULL: (optional)
105  *      TRUE, if the fileno() function works for NULL and returns -1.
106  *  STAT_MISSING: (optional)
107  *      Defined if the function stat() is missing.
108  *  REDIRECT_FILEDES_1: (optional)
109  *      Symbol to redirect stdout in shell commands (executed with system()).
110  *  REDIRECT_FILEDES_2: (optional)
111  *      Symbol to redirect stderr in shell commands (executed with system()).
112  */
113 
114 #include "stdlib.h"
115 #include "string.h"
116 #include "stdio.h"
117 #include "stddef.h"
118 #include "time.h"
119 #include "ctype.h"
120 #include "sys/types.h"
121 #include "sys/stat.h"
122 #include "errno.h"
123 
124 #include "chkccomp.h"
125 
126 /**
127  *  The file chkccomp.h is NOT part of the Seed7 release.
128  *  Instead chkccomp.h is generated by the makefile and
129  *  removed after chkccomp was compiled and executed.
130  *  In chkccomp.h the following macros might be defined:
131  *
132  *  TEST_C_COMPILER:
133  *      If TEST_C_COMPILER is defined it is used instead of C_COMPILER
134  *      as command of the stand-alone C compiler and linker.
135  *  LIST_DIRECTORY_CONTENTS;
136  *      Either "ls" or "dir".
137  *      E.g.: #define LIST_DIRECTORY_CONTENTS "ls"
138  *            #define LIST_DIRECTORY_CONTENTS "dir"
139  *  CC_OPT_LINK_TIME_OPTIMIZATION (optional)
140  *      Contains the compiler option for link time optimization (e.g.: "-flto").
141  *  LINKER_OPT_STATIC_LINKING: (optional)
142  *      Contains the linker option to force static linking (e.g.: "-static").
143  *  LINKER_OPT_DYN_LINK_LIBS: (optional)
144  *      Contains the linker option to add the dynamic linking library.
145  *      It might be added to the SYSTEM_DRAW_LIBS, SYSTEM_CONSOLE_LIBS___ or
146  *      SYSTEM_DATABASE_LIBS settings.
147  *  SUPPORTS_PARTIAL_LINKING: (optional)
148  *      Defined if partial/incremental linking is prossible.
149  *      In this case source code can be compiled with the options -r -c.
150  *      The option -r produces a relocatable object as output. This is
151  *      also known as partial linking. The tool objcopy is used also.
152  *      Objcopy is used with the option -L symbolname which converts
153  *      a global or weak symbol called symbolname into a local symbol.
154  *      This way the symbol is not visible externally.
155  *  ALLOW_REPLACEMENT_OF_SYSTEM_HEADERS: (optional)
156  *      Defined if X11 or ncurses header files can be replaced by header
157  *      files provided by Seed7.
158  *  PRINTF_MAXIMUM_FLOAT_PRECISION: (optional)
159  *      Precision up to which writing a float with printf (using format %e or
160  *      %f) will always work ok.
161  *  The macros described can be defined in a makefile and they are only used
162  *  in chkccomp.c. This macros are not used in the Seed7 Interpreter (s7) or
163  *  in the Seed7 Runtime Library.
164  */
165 
166 
167 #ifndef LINKED_PROGRAM_EXTENSION
168 #ifdef EXECUTABLE_FILE_EXTENSION
169 #define LINKED_PROGRAM_EXTENSION EXECUTABLE_FILE_EXTENSION
170 #else
171 #define LINKED_PROGRAM_EXTENSION ""
172 #endif
173 #endif
174 
175 #ifndef ARCHIVER
176 #define ARCHIVER "ar"
177 #endif
178 
179 #ifndef ARCHIVER_OPT_REPLACE
180 #define ARCHIVER_OPT_REPLACE "r "
181 #endif
182 
183 #ifndef LIBRARY_FILE_EXTENSION
184 #define LIBRARY_FILE_EXTENSION ".a"
185 #endif
186 
187 #define UNIX_LIBRARIES 1
188 #define MACOS_LIBRARIES 2
189 #define WINDOWS_LIBRARIES 3
190 
191 #ifdef _WIN32
192 #define LIBRARY_TYPE WINDOWS_LIBRARIES
193 #elif __APPLE__
194 #define LIBRARY_TYPE MACOS_LIBRARIES
195 #else
196 #define LIBRARY_TYPE UNIX_LIBRARIES
197 #endif
198 
199 #ifndef CC_OPT_TRAP_OVERFLOW
200 #define CC_OPT_TRAP_OVERFLOW ""
201 #endif
202 
203 #ifndef CC_OPT_VERSION_INFO
204 #define CC_OPT_VERSION_INFO ""
205 #endif
206 
207 #ifndef CC_FLAGS
208 #define CC_FLAGS ""
209 #endif
210 
211 #ifndef LINKER_OPT_DYN_LINK_LIBS
212 #define LINKER_OPT_DYN_LINK_LIBS ""
213 #endif
214 
215 #ifndef S_ISREG
216 #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
217 #endif
218 
219 #ifndef S_ISDIR
220 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
221 #endif
222 
223 #ifndef REDIRECT_FILEDES_1
224 #define REDIRECT_FILEDES_1 ">"
225 #endif
226 
227 #ifndef REDIRECT_FILEDES_2
228 #define REDIRECT_FILEDES_2 "2>"
229 #endif
230 
231 #ifndef FORMAT_LL_TRIGGERS_WARNINGS
232 #define FORMAT_LL_TRIGGERS_WARNINGS 0
233 #endif
234 
235 #ifndef SYSTEM_LIBS
236 #define SYSTEM_LIBS ""
237 #endif
238 
239 #ifndef SYSTEM_MATH_LIBS
240 #define SYSTEM_MATH_LIBS ""
241 #endif
242 
243 #ifndef MYSQL_LIBRARY_PATH
244 #define MYSQL_LIBRARY_PATH ""
245 #endif
246 
247 #ifndef SQLITE_LIBRARY_PATH
248 #define SQLITE_LIBRARY_PATH ""
249 #endif
250 
251 #ifndef POSTGRESQL_LIBRARY_PATH
252 #define POSTGRESQL_LIBRARY_PATH ""
253 #endif
254 
255 #ifndef ODBC_LIBRARY_PATH
256 #define ODBC_LIBRARY_PATH ""
257 #endif
258 
259 #ifndef OCI_LIBRARY_PATH
260 #define OCI_LIBRARY_PATH ""
261 #endif
262 
263 #ifndef FIRE_LIBRARY_PATH
264 #define FIRE_LIBRARY_PATH ""
265 #endif
266 
267 #ifndef DB2_LIBRARY_PATH
268 #define DB2_LIBRARY_PATH ""
269 #endif
270 
271 #ifndef SQL_SERVER_LIBRARY_PATH
272 #define SQL_SERVER_LIBRARY_PATH ""
273 #endif
274 
275 #ifndef TDS_LIBRARY_PATH
276 #define TDS_LIBRARY_PATH ""
277 #endif
278 
279 #define NAME_SIZE    1024
280 #define COMMAND_SIZE 1024
281 #define BUFFER_SIZE  4096
282 
283 static int testNumber = 0;
284 static char c_compiler[COMMAND_SIZE];
285 static const char *nullDevice = NULL;
286 static FILE *logFile = NULL;
287 static unsigned long removeReattempts = 0;
288 
289 static const char *int16TypeStri = NULL;
290 static const char *uint16TypeStri = NULL;
291 static const char *int32TypeStri = NULL;
292 static const char *uint32TypeStri = NULL;
293 static const char *int32TypeSuffix = "";
294 static const char *int32TypeFormat = NULL;
295 static const char *int64TypeStri = NULL;
296 static const char *uint64TypeStri = NULL;
297 static const char *int64TypeSuffix = "";
298 static const char *int64TypeFormat = NULL;
299 static const char *int128TypeStri = NULL;
300 static const char *uint128TypeStri = NULL;
301 
302 static const char *makeDirDefinition = NULL;
303 static const char *removeDirDefinition = NULL;
304 
305 
306 
prepareCompileCommand(void)307 static void prepareCompileCommand (void)
308 
309   {
310     int mapAbsolutePathToDriveLetters = 0;
311     int pos;
312     int quote_command = 0;
313     int len;
314 
315   /* prepareCompileCommand */
316 #ifdef TEST_C_COMPILER
317     strcpy(c_compiler, TEST_C_COMPILER);
318 #else
319     strcpy(c_compiler, C_COMPILER);
320 #endif
321     {
322       char *searchPath;
323 
324       searchPath = getenv("PATH");
325       if (searchPath != NULL &&
326           isalpha(searchPath[0]) && searchPath[1] == ':') {
327         mapAbsolutePathToDriveLetters = 1;
328       } /* if */
329     }
330     if (mapAbsolutePathToDriveLetters) {
331       if (c_compiler[0] == '/' && isalpha(c_compiler[1]) &&
332           c_compiler[2] == '/') {
333         c_compiler[0] = c_compiler[1];
334         c_compiler[1] = ':';
335       } /* if */
336     } /* if */
337     for (pos = 0; c_compiler[pos] != '\0'; pos++) {
338       if (c_compiler[pos] == '/') {
339         c_compiler[pos] = PATH_DELIMITER;
340       } else if (c_compiler[pos] == ' ') {
341         quote_command = 1;
342       } /* if */
343     } /* for */
344     if (quote_command) {
345       len = strlen(c_compiler);
346       memmove(&c_compiler[1], c_compiler, len);
347       c_compiler[0] = '\"';
348       c_compiler[len + 1] = '\"';
349       c_compiler[len + 2] = '\0';
350     } /* if */
351   } /* prepareCompileCommand */
352 
353 
354 
355 #ifdef STAT_MISSING
fileExists(const char * fileName)356 static int fileExists (const char *fileName)
357 
358   {
359     FILE *aFile;
360     int exists;
361 
362   /* fileExists */
363     aFile = fopen(fileName, "r");
364     exists = aFile != NULL;
365     if (exists) {
366       fclose(aFile);
367     } /* if */
368     return exists;
369   } /* fileExists */
370 
371 
372 #define fileIsRegular fileExists
373 #define fileIsDir fileExists
374 
375 #else
376 
377 
378 
fileIsRegular(const char * fileName)379 static int fileIsRegular (const char *fileName)
380 
381   {
382     struct stat stat_buf;
383 
384   /* fileIsRegular */
385     return stat(fileName, &stat_buf) == 0 && S_ISREG(stat_buf.st_mode);
386   } /* fileIsRegular */
387 
388 
389 
fileIsDir(const char * fileName)390 static int fileIsDir (const char *fileName)
391 
392   {
393     struct stat stat_buf;
394 
395   /* fileIsDir */
396     return stat(fileName, &stat_buf) == 0 && S_ISDIR(stat_buf.st_mode);
397   } /* fileIsDir */
398 #endif
399 
400 
401 
doRemove(const char * fileName)402 static void doRemove (const char *fileName)
403 
404   {
405 
406   /* doRemove */
407     fprintf(logFile, "#");
408     fflush(logFile);
409     if (fileIsRegular(fileName)) {
410       if (remove(fileName) != 0) {
411 #if defined OS_STRI_WCHAR && defined _WIN32
412         /* This workaround is necessary for windows. */
413         time_t start_time;
414         char command[COMMAND_SIZE];
415 
416         sprintf(command, "DEL %s > nul 2>&1", fileName);
417         start_time = time(NULL);
418         while (time(NULL) < start_time + 20 &&
419                fileIsRegular(fileName)) {
420           removeReattempts++;
421           if (remove(fileName) != 0) {
422             removeReattempts++;
423             system(command);
424           } /* if */
425         } /* while */
426         if (fileIsRegular(fileName)) {
427           fprintf(logFile, "\n *** Cannot remove %s\n", fileName);
428         } /* if */
429 #else
430         fprintf(logFile, "\n *** Cannot remove %s\n", fileName);
431 #endif
432       } /* if */
433     } /* if */
434     fprintf(logFile, "\b");
435     fflush(logFile);
436   } /* doRemove */
437 
438 
439 
copyFile(const char * sourceName,const char * destName)440 static void copyFile (const char *sourceName, const char *destName)
441 
442   {
443     FILE *source;
444     FILE *dest;
445     char buffer[BUFFER_SIZE];
446     size_t len;
447 
448   /* copyFile */
449     if (sourceName != NULL && destName != NULL) {
450       if ((source = fopen(sourceName, "r")) != NULL) {
451         if ((dest = fopen(destName, "w")) != NULL) {
452           while ((len = fread(buffer, 1, 1024, source)) != 0) {
453             fwrite(buffer, 1, len, dest);
454           } /* while */
455           fclose(dest);
456         } /* if */
457         fclose(source);
458       } /* if */
459     } /* if */
460   } /* copyFile */
461 
462 
463 
appendFile(const char * sourceName,const char * destName)464 static void appendFile (const char *sourceName, const char *destName)
465 
466   {
467     FILE *source;
468     FILE *dest;
469     char buffer[BUFFER_SIZE];
470     size_t len;
471 
472   /* appendFile */
473     if (sourceName != NULL && destName != NULL) {
474       if ((source = fopen(sourceName, "r")) != NULL) {
475         if ((dest = fopen(destName, "a")) != NULL) {
476           while ((len = fread(buffer, 1, 1024, source)) != 0) {
477             fwrite(buffer, 1, len, dest);
478           } /* while */
479           fclose(dest);
480         } /* if */
481         fclose(source);
482       } /* if */
483     } /* if */
484   } /* appendFile */
485 
486 
487 
replaceNLBySpace(char * text)488 static void replaceNLBySpace (char *text)
489 
490   { /* replaceNLBySpace */
491     while (*text != '\0') {
492       if (*text == '\n') {
493         *text = ' ';
494       } /* if */
495       text++;
496     } /* while */
497   } /* replaceNLBySpace */
498 
499 
500 
determineCompilerVersion(FILE * versionFile)501 static void determineCompilerVersion (FILE *versionFile)
502 
503   {
504     char command[BUFFER_SIZE];
505     int cc_version_info_filedes = 0;
506     FILE *aFile;
507     int ch;
508 
509   /* determineCompilerVersion */
510 #ifdef CC_VERSION_INFO_FILEDES
511     cc_version_info_filedes = CC_VERSION_INFO_FILEDES;
512 #else
513     /* Use heuristic to determine CC_VERSION_INFO_FILEDES. */
514     sprintf(command, "%s %s %s cc_vers1.txt %s cc_vers2.txt",
515             c_compiler, CC_OPT_VERSION_INFO,
516             REDIRECT_FILEDES_1, REDIRECT_FILEDES_2);
517     aFile = fopen("cc_vers1.txt", "r");
518     if (aFile != NULL) {
519       ch = getc(aFile);
520       fclose(aFile);
521       if (ch != EOF) {
522         cc_version_info_filedes = 1;
523       } /* if */
524     } /* if */
525     if (cc_version_info_filedes == 0) {
526       aFile = fopen("cc_vers2.txt", "r");
527       if (aFile != NULL) {
528         ch = getc(aFile);
529         fclose(aFile);
530         if (ch != EOF) {
531           cc_version_info_filedes = 2;
532         } /* if */
533       } /* if */
534     } /* if */
535     doRemove("cc_vers1.txt");
536     doRemove("cc_vers2.txt");
537     fprintf(versionFile, "#define CC_VERSION_INFO_FILEDES %d\n", cc_version_info_filedes);
538 #endif
539     if (cc_version_info_filedes == 1) {
540       if (nullDevice != NULL) {
541         sprintf(command, "%s %s %s cc_vers.txt %s %s",
542                 c_compiler, CC_OPT_VERSION_INFO, REDIRECT_FILEDES_1,
543                 REDIRECT_FILEDES_2, nullDevice);
544       } else {
545         sprintf(command, "%s %s %s cc_vers.txt",
546                 c_compiler, CC_OPT_VERSION_INFO, REDIRECT_FILEDES_1);
547       } /* if */
548     } else if (cc_version_info_filedes == 2) {
549       if (nullDevice != NULL) {
550         sprintf(command, "%s %s %s cc_vers.txt %s %s",
551                 c_compiler, CC_OPT_VERSION_INFO, REDIRECT_FILEDES_2,
552                 REDIRECT_FILEDES_1, nullDevice);
553       } else {
554         sprintf(command, "%s %s %s cc_vers.txt",
555                 c_compiler, CC_OPT_VERSION_INFO, REDIRECT_FILEDES_2);
556       } /* if */
557     } /* if */
558     system(command);
559     aFile = fopen("cc_vers.txt", "r");
560     if (aFile != NULL) {
561       fprintf(versionFile, "#define C_COMPILER_VERSION \"");
562       do {
563         ch = getc(aFile);
564       } while (ch == 10 || ch == 13);
565       for (; ch != EOF && ch != 10 && ch != 13; ch = getc(aFile)) {
566         if (ch >= ' ' && ch <= '~') {
567           if (ch == '\"' || ch == '\'' || ch == '\\') {
568             putc('\\', versionFile);
569           } /* if */
570           putc(ch, versionFile);
571         } else {
572           fprintf(versionFile, "\\%3o", ch);
573         } /* if */
574       } /* for */
575       fputs("\"\n", versionFile);
576       fclose(aFile);
577       doRemove("cc_vers.txt");
578     } /* if */
579   } /* determineCompilerVersion */
580 
581 
582 
cleanUpCompilation(int testNumber)583 static void cleanUpCompilation (int testNumber)
584 
585   {
586     char fileName[NAME_SIZE];
587 
588   /* cleanUpCompilation */
589     sprintf(fileName, "ctest%d.c", testNumber);
590     doRemove(fileName);
591     sprintf(fileName, "ctest%d.cerrs", testNumber);
592     doRemove(fileName);
593     sprintf(fileName, "ctest%d.lerrs", testNumber);
594     doRemove(fileName);
595     sprintf(fileName, "ctest%d%s", testNumber, OBJECT_FILE_EXTENSION);
596     doRemove(fileName);
597     sprintf(fileName, "ctest%d%s", testNumber, LINKED_PROGRAM_EXTENSION);
598     doRemove(fileName);
599     sprintf(fileName, "ctest%d.out", testNumber);
600     doRemove(fileName);
601   } /* cleanUpCompilation */
602 
603 
604 
doCompile(const char * compilerOptions,int testNumber)605 static int doCompile (const char *compilerOptions, int testNumber)
606 
607   {
608     char command[COMMAND_SIZE];
609     int len;
610     char fileName[NAME_SIZE];
611     int returncode;
612     int okay = 0;
613 
614   /* doCompile */
615     fprintf(logFile, "*");
616     fflush(logFile);
617     sprintf(command, "%s %s %s -c ctest%d.c",
618             c_compiler, compilerOptions, CC_FLAGS, testNumber);
619     replaceNLBySpace(command);
620 #ifdef CC_ERROR_FILEDES
621     /* A missing CC_ERROR_FILEDES or an CC_ERROR_FILEDES of zero means: Do not redirect. */
622     if (CC_ERROR_FILEDES == 1) {
623       sprintf(&command[strlen(command)], " %sctest%d.cerrs %s%s",
624               REDIRECT_FILEDES_1, testNumber, REDIRECT_FILEDES_2, nullDevice);
625     } else if (CC_ERROR_FILEDES == 2) {
626       sprintf(&command[strlen(command)], " %sctest%d.cerrs %s%s",
627               REDIRECT_FILEDES_2, testNumber, REDIRECT_FILEDES_1, nullDevice);
628     } /* if */
629 #endif
630 #ifdef QUOTE_WHOLE_SHELL_COMMAND
631     if (command[0] == '\"') {
632       len = strlen(command);
633       memmove(&command[1], command, len);
634       command[0] = '\"';
635       command[len + 1] = '\"';
636       command[len + 2] = '\0';
637     } /* if */
638 #endif
639     /* fprintf(logFile, "command: %s\n", command); */
640     returncode = system(command);
641     sprintf(fileName, "ctest%d%s", testNumber, OBJECT_FILE_EXTENSION);
642     if (fileIsRegular(fileName)) {
643       if (returncode == 0) {
644         okay = 1;
645       } else {
646         /* fprintf(logFile, "\n *** The compiler %s fails, but creates an executable.\n", c_compiler); */
647       } /* if */
648     } else {
649       /* fprintf(logFile, "\n *** The compiler %s produces no executable: %s\n", c_compiler, fileName); */
650     } /* if */
651 #ifdef DEBUG_CHKCCOMP
652     fprintf(logFile, "doCompile command: %s\n", command);
653     fprintf(logFile, "returncode: %d\n", returncode);
654     if (returncode == -1) {
655       fprintf(logFile, "errno: %d\nerror: %s\n", errno, strerror(errno));
656     } /* if */
657     fprintf(logFile, "okay: %d\n", okay);
658 #endif
659     fprintf(logFile, "\b.");
660     fflush(logFile);
661     return okay;
662   } /* doCompile */
663 
664 
665 
compileWithOptionsOk(const char * content,const char * compilerOptions)666 static int compileWithOptionsOk (const char *content, const char *compilerOptions)
667 
668   {
669     char fileName[NAME_SIZE];
670     FILE *testFile;
671     int okay = 0;
672 
673   /* compileWithOptionsOk */
674     /* fprintf(logFile, "compileWithOptionsOk(%s)\n", content); */
675     cleanUpCompilation(testNumber);
676     testNumber++;
677     cleanUpCompilation(testNumber);
678     sprintf(fileName, "ctest%d.c", testNumber);
679     testFile = fopen(fileName, "w");
680     if (testFile != NULL) {
681       fprintf(testFile, "%s", content);
682       fclose(testFile);
683       okay = doCompile(compilerOptions, testNumber);
684     } /* if */
685 #ifdef DEBUG_CHKCCOMP
686     fprintf(logFile, "content: %s\n", content);
687 #endif
688     /* fprintf(logFile, "compileWithOptionsOk --> %d\n", okay); */
689     return okay;
690   } /* compileWithOptionsOk */
691 
692 
693 
doLink(const char * objectOrLibraryName,const char * linkerOptions)694 static int doLink (const char *objectOrLibraryName, const char *linkerOptions)
695 
696   {
697     char command[COMMAND_SIZE];
698     int len;
699     char fileName[NAME_SIZE];
700     int returncode;
701     int okay = 0;
702 
703   /* doLink */
704     fprintf(logFile, "*");
705     fflush(logFile);
706 #ifdef LINKER
707     sprintf(command, "%s %s %s %sctest%d%s",
708             LINKER, objectOrLibraryName, linkerOptions,
709             LINKER_OPT_OUTPUT_FILE, testNumber, LINKED_PROGRAM_EXTENSION);
710 #else
711     sprintf(command, "%s %s %s",
712             c_compiler, objectOrLibraryName, linkerOptions);
713     replaceNLBySpace(command);
714 #if defined LINKER_OPT_OUTPUT_FILE && !defined CC_NO_OPT_OUTPUT_FILE
715     sprintf(&command[strlen(command)], " %sctest%d%s",
716             LINKER_OPT_OUTPUT_FILE, testNumber, LINKED_PROGRAM_EXTENSION);
717 #endif
718 #endif
719 #ifdef CC_ERROR_FILEDES
720     /* A missing CC_ERROR_FILEDES or an CC_ERROR_FILEDES of zero means: Do not redirect. */
721     if (CC_ERROR_FILEDES == 1) {
722       sprintf(&command[strlen(command)], " %sctest%d.lerrs %s%s",
723               REDIRECT_FILEDES_1, testNumber, REDIRECT_FILEDES_2, nullDevice);
724     } else if (CC_ERROR_FILEDES == 2) {
725       sprintf(&command[strlen(command)], " %sctest%d.lerrs %s%s",
726               REDIRECT_FILEDES_2, testNumber, REDIRECT_FILEDES_1, nullDevice);
727     } /* if */
728 #endif
729 #ifdef QUOTE_WHOLE_SHELL_COMMAND
730     if (command[0] == '\"') {
731       len = strlen(command);
732       memmove(&command[1], command, len);
733       command[0] = '\"';
734       command[len + 1] = '\"';
735       command[len + 2] = '\0';
736     } /* if */
737 #endif
738     /* fprintf(logFile, "command: %s\n", command); */
739     returncode = system(command);
740     /* fprintf(logFile, "returncode: %d\n", returncode); */
741     sprintf(fileName, "ctest%d%s", testNumber, LINKED_PROGRAM_EXTENSION);
742     /* fprintf(logFile, "fileName: \"%s\"\n", fileName); */
743     if (fileIsRegular(fileName)) {
744       if (returncode == 0) {
745         okay = 1;
746       } else {
747         /* fprintf(logFile, "\n *** The compiler %s fails, but creates an executable.\n", c_compiler); */
748       } /* if */
749     } else {
750       /* fprintf(logFile, "\n *** The compiler %s produces no executable: %s\n", c_compiler, fileName); */
751     } /* if */
752 #ifdef DEBUG_CHKCCOMP
753     fprintf(logFile, "doLink command: %s\n", command);
754     fprintf(logFile, "returncode: %d\n", returncode);
755     if (returncode == -1) {
756       fprintf(logFile, "errno: %d\nerror: %s\n", errno, strerror(errno));
757     } /* if */
758     fprintf(logFile, "okay: %d\n", okay);
759 #endif
760     fprintf(logFile, "\b.");
761     fflush(logFile);
762     return okay;
763   } /* doLink */
764 
765 
766 
doCompileAndLink(const char * compilerOptions,const char * linkerOptions,int testNumber)767 static int doCompileAndLink (const char *compilerOptions, const char *linkerOptions, int testNumber)
768 
769   {
770     char command[COMMAND_SIZE];
771     int len;
772     char fileName[NAME_SIZE];
773     int returncode;
774     int okay = 0;
775 
776   /* doCompileAndLink */
777     fprintf(logFile, "*");
778     fflush(logFile);
779 #ifdef LINKER
780     sprintf(command, "%s %s %s -c ctest%d.c",
781             c_compiler, compilerOptions, CC_FLAGS, testNumber);
782 #else
783     sprintf(command, "%s %s %s ctest%d.c %s",
784             c_compiler, compilerOptions, CC_FLAGS, testNumber, linkerOptions);
785 #endif
786     replaceNLBySpace(command);
787 #if !defined LINKER && defined LINKER_OPT_OUTPUT_FILE && !defined CC_NO_OPT_OUTPUT_FILE
788     sprintf(&command[strlen(command)], " %sctest%d%s",
789             LINKER_OPT_OUTPUT_FILE, testNumber, LINKED_PROGRAM_EXTENSION);
790 #endif
791 #ifdef CC_ERROR_FILEDES
792     /* A missing CC_ERROR_FILEDES or an CC_ERROR_FILEDES of zero means: Do not redirect. */
793     if (CC_ERROR_FILEDES == 1) {
794       sprintf(&command[strlen(command)], " %sctest%d.cerrs %s%s",
795               REDIRECT_FILEDES_1, testNumber, REDIRECT_FILEDES_2, nullDevice);
796     } else if (CC_ERROR_FILEDES == 2) {
797       sprintf(&command[strlen(command)], " %sctest%d.cerrs %s%s",
798               REDIRECT_FILEDES_2, testNumber, REDIRECT_FILEDES_1, nullDevice);
799     } /* if */
800 #endif
801 #ifdef QUOTE_WHOLE_SHELL_COMMAND
802     if (command[0] == '\"') {
803       len = strlen(command);
804       memmove(&command[1], command, len);
805       command[0] = '\"';
806       command[len + 1] = '\"';
807       command[len + 2] = '\0';
808     } /* if */
809 #endif
810     /* fprintf(logFile, "command: %s\n", command); */
811     returncode = system(command);
812 #ifdef LINKER
813     if (returncode == 0) {
814       /* fprintf(logFile, "returncode: %d\n", returncode); */
815       sprintf(command, "%s ctest%d%s %s %sctest%d%s",
816               LINKER, testNumber, OBJECT_FILE_EXTENSION, linkerOptions,
817               LINKER_OPT_OUTPUT_FILE, testNumber, LINKED_PROGRAM_EXTENSION);
818       /* fprintf(logFile, "command: %s\n", command); */
819       returncode = system(command);
820     } /* if */
821 #endif
822     sprintf(fileName, "ctest%d%s", testNumber, LINKED_PROGRAM_EXTENSION);
823     if (fileIsRegular(fileName)) {
824       if (returncode == 0) {
825         okay = 1;
826       } else {
827         /* fprintf(logFile, "\n *** The compiler %s fails, but creates an executable.\n", c_compiler); */
828       } /* if */
829     } else {
830       /* fprintf(logFile, "\n *** The compiler %s produces no executable: %s\n", c_compiler, fileName); */
831     } /* if */
832 #ifdef DEBUG_CHKCCOMP
833     fprintf(logFile, "doCompileAndLink command: %s\n", command);
834     fprintf(logFile, "returncode: %d\n", returncode);
835     if (returncode == -1) {
836       fprintf(logFile, "errno: %d\nerror: %s\n", errno, strerror(errno));
837     } /* if */
838     fprintf(logFile, "okay: %d\n", okay);
839 #endif
840     fprintf(logFile, "\b.");
841     fflush(logFile);
842     return okay;
843   } /* doCompileAndLink */
844 
845 
846 
compileAndLinkWithOptionsOk(const char * content,const char * compilerOptions,const char * linkerOptions)847 static int compileAndLinkWithOptionsOk (const char *content, const char *compilerOptions,
848     const char *linkerOptions)
849 
850   {
851     char fileName[NAME_SIZE];
852     FILE *testFile;
853     int okay = 0;
854 
855   /* compileAndLinkWithOptionsOk */
856     /* fprintf(logFile, "compileAndLinkWithOptionsOk(%s)\n", content); */
857     cleanUpCompilation(testNumber);
858     testNumber++;
859     cleanUpCompilation(testNumber);
860     sprintf(fileName, "ctest%d.c", testNumber);
861     testFile = fopen(fileName, "w");
862     if (testFile != NULL) {
863       fprintf(testFile, "%s", content);
864       fclose(testFile);
865       okay = doCompileAndLink(compilerOptions, linkerOptions, testNumber);
866     } /* if */
867 #ifdef DEBUG_CHKCCOMP
868     fprintf(logFile, "content: %s\n", content);
869 #endif
870     /* fprintf(logFile, "compileAndLinkWithOptionsOk --> %d\n", okay); */
871     return okay;
872   } /* compileAndLinkWithOptionsOk */
873 
874 
875 
showErrors(void)876 static void showErrors (void)
877 
878   {
879     char fileName[NAME_SIZE];
880     FILE *errorFile;
881     int ch;
882 
883   /* showErrors */
884     sprintf(fileName, "ctest%d.cerrs", testNumber);
885     errorFile = fopen(fileName, "r");
886     if (errorFile != NULL) {
887       fprintf(logFile, "\nCompiler errors:\n");
888       while ((ch = getc(errorFile)) != EOF) {
889         fputc(ch, logFile);
890       } /* while */
891       fclose(errorFile);
892       fprintf(logFile, "\n");
893     } /* if */
894     sprintf(fileName, "ctest%d.lerrs", testNumber);
895     errorFile = fopen(fileName, "r");
896     if (errorFile != NULL) {
897       fprintf(logFile, "\nLinker errors:\n");
898       while ((ch = getc(errorFile)) != EOF) {
899         fputc(ch, logFile);
900       } /* while */
901       fclose(errorFile);
902       fprintf(logFile, "\n");
903     } /* if */
904   } /* showErrors */
905 
906 
907 
assertCompAndLnkWithOptions(const char * content,const char * compilerOptions,const char * linkerOptions)908 static int assertCompAndLnkWithOptions (const char *content, const char *compilerOptions,
909     const char *linkerOptions)
910 
911   {
912     int okay;
913 
914   /* assertCompAndLnkWithOptions */
915     okay = compileAndLinkWithOptionsOk(content, compilerOptions, linkerOptions);
916     if (!okay) {
917       fprintf(logFile, "\n **** Compile and link failed for:\n%s\n", content);
918       showErrors();
919     } /* if */
920     return okay;
921   } /* assertCompAndLnkWithOptions */
922 
923 
924 
compileAndLinkOk(const char * content)925 static int compileAndLinkOk (const char *content)
926 
927   { /* compileAndLinkOk */
928     return compileAndLinkWithOptionsOk(content, "", "");
929   } /* compileAndLinkOk */
930 
931 
932 
assertCompAndLnk(const char * content)933 static int assertCompAndLnk (const char *content)
934 
935   {
936     int okay;
937 
938   /* assertCompAndLnk */
939     okay = compileAndLinkOk(content);
940     if (!okay) {
941       fprintf(logFile, "\n **** Compile and link failed for:\n%s\n", content);
942       showErrors();
943     } /* if */
944     return okay;
945   } /* assertCompAndLnk */
946 
947 
948 
doTest(void)949 static int doTest (void)
950 
951   {
952     char command[COMMAND_SIZE];
953     char fileName[NAME_SIZE];
954     int returncode;
955     FILE *outFile;
956     int result = -1;
957 
958   /* doTest */
959     fprintf(logFile, "+");
960     fflush(logFile);
961 #ifdef INTERPRETER_FOR_LINKED_PROGRAM
962     sprintf(command, "%s .%cctest%d%s>ctest%d.out",
963             INTERPRETER_FOR_LINKED_PROGRAM, PATH_DELIMITER, testNumber,
964             LINKED_PROGRAM_EXTENSION, testNumber);
965 #else
966     sprintf(command, ".%cctest%d%s>ctest%d.out", PATH_DELIMITER,
967             testNumber, LINKED_PROGRAM_EXTENSION, testNumber);
968 #endif
969     returncode = system(command);
970     if (returncode != -1) {
971       sprintf(fileName, "ctest%d.out", testNumber);
972       outFile = fopen(fileName, "r");
973       if (outFile != NULL) {
974         fscanf(outFile, "%d", &result);
975         fclose(outFile);
976       } /* if */
977     } else {
978       printf("\n *** system(\"%s\") failed with errno: %d.\n ", command, errno);
979     } /* if */
980     fprintf(logFile, "\b");
981     fflush(logFile);
982     return result;
983   } /* doTest */
984 
985 
986 
expectTestResult(const char * content,int expected)987 static int expectTestResult (const char *content, int expected)
988 
989   {
990     int testResult = -1;
991     int okay = 0;
992 
993   /* expectTestResult */
994     if (compileAndLinkOk(content)) {
995       testResult = doTest();
996       okay = testResult == expected;
997     } else {
998       fprintf(logFile, "\n *** Unable to compile test program:\n%s\n", content);
999     } /* if */
1000     return okay;
1001   } /* expectTestResult */
1002 
1003 
1004 
testOutputToVersionFile(FILE * versionFile)1005 static void testOutputToVersionFile (FILE *versionFile)
1006 
1007   {
1008     char command[COMMAND_SIZE];
1009     char fileName[NAME_SIZE];
1010     int returncode;
1011     FILE *outFile;
1012     int ch;
1013 
1014   /* testOutputToVersionFile */
1015     fprintf(logFile, ">");
1016     fflush(logFile);
1017 #ifdef INTERPRETER_FOR_LINKED_PROGRAM
1018     sprintf(command, "%s .%cctest%d%s>ctest%d.out",
1019             INTERPRETER_FOR_LINKED_PROGRAM, PATH_DELIMITER, testNumber,
1020             LINKED_PROGRAM_EXTENSION, testNumber);
1021 #else
1022     sprintf(command, ".%cctest%d%s>ctest%d.out", PATH_DELIMITER,
1023             testNumber, LINKED_PROGRAM_EXTENSION, testNumber);
1024 #endif
1025     returncode = system(command);
1026     if (returncode != -1) {
1027       sprintf(fileName, "ctest%d.out", testNumber);
1028       outFile = fopen(fileName, "r");
1029       if (outFile != NULL) {
1030         while ((ch = getc(outFile)) != EOF) {
1031           putc(ch, versionFile);
1032         } /* while */
1033         fclose(outFile);
1034       } /* if */
1035     } /* if */
1036     fprintf(logFile, "\b");
1037     fflush(logFile);
1038   } /* testOutputToVersionFile */
1039 
1040 
1041 
isNullDevice(const char * fileName,int eofChar)1042 static int isNullDevice (const char *fileName, int eofChar)
1043 
1044   {
1045     FILE *aFile;
1046     int fileIsEmpty;
1047     int fileIsNullDevice = 0;
1048 
1049   /* isNullDevice */
1050     aFile = fopen(fileName, "r");
1051     if (aFile != NULL) {
1052       /* The file exists. Now check if the file is empty. */
1053       fileIsEmpty = getc(aFile) == eofChar;
1054       fclose(aFile);
1055       if (fileIsEmpty) {
1056         /* Reading from a null device returns always EOF. */
1057         aFile = fopen(fileName, "r+");
1058         if (aFile != NULL) {
1059           /* Writing of 'X' to a null device should be ignored. */
1060           putc('X', aFile);
1061           fclose(aFile);
1062           aFile = fopen(fileName, "r");
1063           if (aFile != NULL) {
1064             /* Check if the file is still empty. */
1065             fileIsEmpty = getc(aFile) == eofChar;
1066             fclose(aFile);
1067             if (fileIsEmpty) {
1068               /* Everything written to the null device is ignored. */
1069               fileIsNullDevice = 1;
1070             } else {
1071               /* The file is not empty, so it is not a null device. */
1072               aFile = fopen(fileName, "w");
1073               if (aFile != NULL) {
1074                 /* Make sure that the file is empty, as it was before. */
1075                 fclose(aFile);
1076               } /* if */
1077             } /* if */
1078           } /* if */
1079         } /* if */
1080       } /* if */
1081     } /* if */
1082     return fileIsNullDevice;
1083   } /* isNullDevice */
1084 
1085 
1086 
initializeNullDevice(void)1087 static void initializeNullDevice (void)
1088 
1089   { /* initializeNullDevice */
1090     if (isNullDevice("/dev/null", EOF)) {
1091       nullDevice = "/dev/null";
1092     } else if (isNullDevice("NUL:", EOF)) {
1093       nullDevice = "NUL:";
1094     } else if (isNullDevice("NUL", EOF)) {
1095       nullDevice = "NUL";
1096     } else if (isNullDevice("NUL:", 0)) {
1097       nullDevice = "NUL:";
1098     } else if (isNullDevice("NUL", 0)) {
1099       nullDevice = "NUL";
1100     } /* if */
1101     if (nullDevice == NULL) {
1102       fputs("\n **** Unable to determine a null device for chkccomp.\n", logFile);
1103       nullDevice = "null_device";
1104     } /* if */
1105   } /* initializeNullDevice */
1106 
1107 
1108 
checkIfNullDevice(const char * fileName,int eofChar)1109 static int checkIfNullDevice (const char *fileName, int eofChar)
1110 
1111   {
1112     char buffer[BUFFER_SIZE];
1113     int fileIsNullDevice = 0;
1114 
1115   /* checkIfNullDevice */
1116     sprintf(buffer,
1117             "#include <stdio.h>\n"
1118             "int main(int argc, char *argv[]) {\n"
1119             "FILE *aFile;\n"
1120             "int fileIsEmpty;\n"
1121             "char *fileName = \"%s\";\n"
1122             "int eofChar = %d;\n"
1123             "int fileIsNullDevice = 0;\n"
1124             "aFile = fopen(fileName, \"r\");\n"
1125             "if (aFile != NULL) {\n"
1126             "  fileIsEmpty = getc(aFile) == eofChar;\n"
1127             "  fclose(aFile);\n"
1128             "  if (fileIsEmpty) {\n"
1129             "    aFile = fopen(fileName, \"r+\");\n"
1130             "    if (aFile != NULL) {\n"
1131             "      putc('X', aFile);\n"
1132             "      fclose(aFile);\n"
1133             "      aFile = fopen(fileName, \"r\");\n"
1134             "      if (aFile != NULL) {\n"
1135             "        fileIsEmpty = getc(aFile) == eofChar;\n"
1136             "        fclose(aFile);\n"
1137             "        if (fileIsEmpty) {\n"
1138             "          fileIsNullDevice = 1;\n"
1139             "        } else {\n"
1140             "          aFile = fopen(fileName, \"w\");\n"
1141             "          if (aFile != NULL) {\n"
1142             "            fclose(aFile);\n"
1143             "          }\n"
1144             "        }\n"
1145             "      }\n"
1146             "    }\n"
1147             "  }\n"
1148             "}\n"
1149             "printf(\"%%d\\n\", fileIsNullDevice);\n"
1150             "return 0;}",
1151             fileName, eofChar);
1152     if (assertCompAndLnk(buffer)) {
1153       fileIsNullDevice = doTest() == 1;
1154     } /* if */
1155     return fileIsNullDevice;
1156   } /* checkIfNullDevice */
1157 
1158 
1159 
determineNullDevice(FILE * versionFile)1160 static void determineNullDevice (FILE *versionFile)
1161 
1162   {
1163     const char *nullDevice = NULL;
1164 
1165   /* determineNullDevice */
1166     if (checkIfNullDevice("/dev/null", EOF)) {
1167       nullDevice = "/dev/null";
1168     } else if (checkIfNullDevice("NUL:", EOF)) {
1169       nullDevice = "NUL:";
1170     } else if (checkIfNullDevice("NUL", EOF)) {
1171       nullDevice = "NUL";
1172     } else if (checkIfNullDevice("NUL:", 0)) {
1173       nullDevice = "NUL:";
1174     } else if (checkIfNullDevice("NUL", 0)) {
1175       nullDevice = "NUL";
1176     } /* if */
1177     if (nullDevice == NULL) {
1178       fputs("\n **** Unable to determine a null device.\n", logFile);
1179       nullDevice = "null_device";
1180     } /* if */
1181     fprintf(versionFile, "#define NULL_DEVICE \"%s\"\n", nullDevice);
1182   } /* determineNullDevice */
1183 
1184 
1185 
determineCallingConventions(FILE * versionFile)1186 static void determineCallingConventions (FILE *versionFile)
1187 
1188   {
1189     int has_cdecl;
1190     int has_stdcall;
1191 
1192   /* determineCallingConventions */
1193     has_cdecl = compileAndLinkOk("#include <stdio.h>\n"
1194                                  "int __cdecl aFunction (void) { return 1; }\n"
1195                                  "int main (int argc, char *argv[]) {\n"
1196                                  "printf(\"%d\\n\", aFunction());\n"
1197                                  "return 0; }\n") &&
1198                 doTest() == 1;
1199     has_stdcall = compileAndLinkOk("#include <stdio.h>\n"
1200                                    "int __stdcall aFunction (void) { return 1; }\n"
1201                                    "int main (int argc, char *argv[]) {\n"
1202                                    "printf(\"%d\\n\", aFunction());\n"
1203                                    "return 0; }\n") &&
1204                   doTest() == 1;
1205     fprintf(versionFile, "#define HAS_CDECL %d\n", has_cdecl);
1206     fprintf(versionFile, "#define HAS_STDCALL %d\n", has_stdcall);
1207   } /* determineCallingConventions */
1208 
1209 
1210 
checkSignal(FILE * versionFile)1211 static void checkSignal (FILE *versionFile)
1212 
1213   {
1214     int has_signal = 0;
1215     int has_sigaction = 0;
1216     int signal_resets_handler = 0;
1217 
1218   /* checkSignal */
1219     if (compileAndLinkOk("#include <stdio.h>\n#include <signal.h>\n"
1220                          "volatile int res=4;\n"
1221                          "void handleSig1(int sig){res = 1;}\n"
1222                          "void handleSig2(int sig){res = 2;}\n"
1223                          "int main (int argc, char *argv[]){\n"
1224                          "if (signal(SIGINT, handleSig2) == SIG_ERR ||\n"
1225                          "signal(SIGINT, handleSig1) != handleSig2){\n"
1226                          "puts(\"3\");"
1227                          "}else if (raise(SIGINT) != 0){puts(\"5\");\n"
1228                          "}else{printf(\"%d\\n\",res);}\n"
1229                          "return 0;}\n") && doTest() == 1) {
1230       has_signal = 1;
1231     } /* if */
1232     fprintf(versionFile, "#define HAS_SIGNAL %d\n", has_signal);
1233     if (compileAndLinkOk("#include <stdio.h>\n#include <signal.h>\n"
1234                          "int main(int argc, char *argv[]){\n"
1235                          "printf(\"%d\\n\",(int)sizeof(struct sigaction));\n"
1236                          "return 0;}\n") &&
1237         compileAndLinkOk("#include <stdio.h>\n#include <signal.h>\n"
1238                          "volatile int res=4;\n"
1239                          "void handleSig(int sig){res=1;}\n"
1240                          "int main(int argc, char *argv[]){\n"
1241                          "struct sigaction sigAct;\n"
1242                          "sigAct.sa_handler = handleSig;\n"
1243                          "sigemptyset(&sigAct.sa_mask);\n"
1244                          "sigAct.sa_flags = SA_RESTART;\n"
1245                          "if (sigaction(SIGINT, &sigAct, NULL) == -1){\n"
1246                          "puts(\"3\");"
1247                          "}else if (raise(SIGINT) != 0){puts(\"5\");\n"
1248                          "}else{printf(\"%d\\n\",res);}\n"
1249                          "return 0;}\n") && doTest() == 1) {
1250       has_sigaction = 1;
1251     } /* if */
1252     fprintf(versionFile, "#define HAS_SIGACTION %d\n", has_sigaction);
1253     if (!has_sigaction) {
1254       if (compileAndLinkOk("#include <stdio.h>\n#include <signal.h>\n"
1255                            "volatile int res=4;\n"
1256                            "void handleSig1(int sig)\n"
1257                            "{if (signal(SIGINT, handleSig1) == SIG_DFL) res = 1; else res = 6;}\n"
1258                            "int main (int argc, char *argv[]){\n"
1259                            "if (signal(SIGINT, handleSig1) == SIG_ERR){\n"
1260                            "puts(\"3\");"
1261                            "}else if (raise(SIGINT) != 0){puts(\"5\");\n"
1262                            "}else{printf(\"%d\\n\",res);}\n"
1263                            "return 0;}\n") && doTest() == 1) {
1264         signal_resets_handler = 1;
1265       } /* if */
1266     } /* if */
1267     fprintf(versionFile, "#define SIGNAL_RESETS_HANDLER %d\n", signal_resets_handler);
1268   } /* checkSignal */
1269 
1270 
1271 
writeMacroDefs(FILE * versionFile)1272 static void writeMacroDefs (FILE *versionFile)
1273 
1274   {
1275     char macroDefs[BUFFER_SIZE];
1276 
1277   /* writeMacroDefs */
1278     if (compileAndLinkOk("static inline int test(int a){return 2*a;}\n"
1279                          "int main(int argc,char *argv[]){return test(argc);}\n")) {
1280       /* The C compiler accepts the definition of inline functions. */
1281     } else if (compileAndLinkOk("static __inline int test(int a){return 2*a;}\n"
1282                                 "int main(int argc,char *argv[]){return test(argc);}\n")) {
1283       fputs("#define inline __inline\n", versionFile);
1284     } else if (compileAndLinkOk("static __inline__ int test(int a){return 2*a;}\n"
1285                                 "int main(int argc,char *argv[]){return test(argc);}\n")) {
1286       fputs("#define inline __inline__\n", versionFile);
1287     } else {
1288       fputs("#define inline\n", versionFile);
1289     } /* if */
1290     if (!compileAndLinkOk("int test (int *restrict ptrA, int *restrict ptrB, int *restrict ptrC)\n"
1291                           "{*ptrA += *ptrC; *ptrB += *ptrC; return *ptrA + *ptrB;}\n"
1292                           "int main(int argc,char *argv[])\n"
1293                           "{int a=1, b=2, c=3; return test(&a, &b, &c);}\n")) {
1294       fputs("#define restrict\n", versionFile);
1295     } /* if */
1296     macroDefs[0] = '\0';
1297     if (compileAndLinkOk("#include <stdio.h>\nint main(int argc,char *argv[])\n"
1298                          "{if(__builtin_expect(1,1))puts(\"1\");else puts(\"0\");\n"
1299                          "return 0;}\n") && doTest() == 1) {
1300       fputs("#define likely(x)   __builtin_expect((x),1)\n", versionFile);
1301       fputs("#define unlikely(x) __builtin_expect((x),0)\n", versionFile);
1302       strcat(macroDefs, "#define likely(x)   __builtin_expect((x),1)\\n");
1303       strcat(macroDefs, "#define unlikely(x) __builtin_expect((x),0)\\n");
1304     } else {
1305       fputs("#define likely(x) (x)\n", versionFile);
1306       fputs("#define unlikely(x) (x)\n", versionFile);
1307       strcat(macroDefs, "#define likely(x) (x)\\n");
1308       strcat(macroDefs, "#define unlikely(x) (x)\\n");
1309     } /* if */
1310     if (compileAndLinkOk("#include <stdlib.h>\n"
1311                          "void fatal (void) __attribute__ ((noreturn));\n"
1312                          "void fatal (void) {exit(1);}\n"
1313                          "int main(int argc,char *argv[])\n"
1314                          "{return 0;}\n")) {
1315       fputs("#define NORETURN __attribute__ ((noreturn))\n", versionFile);
1316       strcat(macroDefs, "#define NORETURN __attribute__ ((noreturn))\\n");
1317     } else {
1318       fputs("#define NORETURN\n", versionFile);
1319       strcat(macroDefs, "#define NORETURN\\n");
1320     } /* if */
1321     fprintf(versionFile, "#define MACRO_DEFS \"%s\"\n", macroDefs);
1322   } /* writeMacroDefs */
1323 
1324 
1325 
checkPopen(FILE * versionFile)1326 static void checkPopen (FILE *versionFile)
1327 
1328   {
1329     const char *popen = NULL;
1330     int binary_mode_supported;
1331     const char *binary_mode = "";
1332     char buffer[BUFFER_SIZE];
1333     char fileName[NAME_SIZE];
1334 
1335   /* checkPopen */
1336     if (compileAndLinkOk("#include <stdio.h>\n"
1337                          "int main(int argc, char *argv[])\n"
1338                          "{FILE *aFile; aFile=popen(\""
1339                          LIST_DIRECTORY_CONTENTS
1340                          "\", \"r\");\n"
1341                          "printf(\"%d\\n\", aFile != NULL); return 0;}\n") && doTest() == 1) {
1342       popen = "popen";
1343     } else if (compileAndLinkOk("#include <stdio.h>\n"
1344                                 "int main(int argc, char *argv[])\n"
1345                                 "{FILE *aFile; aFile=_popen(\""
1346                                 LIST_DIRECTORY_CONTENTS
1347                                 "\", \"r\");\n"
1348                                 "printf(\"%d\\n\", aFile != NULL); return 0;}\n") && doTest() == 1) {
1349       popen = "_popen";
1350     } /* if */
1351     if (popen != NULL) {
1352       sprintf(buffer, "#include <stdio.h>\n"
1353                       "int main(int argc, char *argv[])\n"
1354                       "{FILE *aFile; aFile=%s(\""
1355                       LIST_DIRECTORY_CONTENTS
1356                       "\", \"r\");\n"
1357                       "printf(\"%%d\\n\", aFile != NULL &&\n"
1358                       "       fileno(aFile) != -1); return 0;}\n", popen);
1359       if (compileAndLinkOk(buffer) && doTest() != 1) {
1360         fprintf(logFile, "\n *** fileno() does not work on a file opened with %s().\n",
1361                 popen);
1362         popen = NULL;
1363       } /* if */
1364     } /* if */
1365     fprintf(versionFile, "#define HAS_POPEN %d\n", popen != NULL);
1366     if (popen != NULL) {
1367       sprintf(buffer, "#include <stdio.h>\n"
1368                       "int main(int argc, char *argv[])\n"
1369                       "{FILE *aFile; aFile=%s(\""
1370                       LIST_DIRECTORY_CONTENTS
1371                       "\", \"rb\");\n"
1372                       "printf(\"%%d\\n\", aFile != NULL); return 0;}\n", popen);
1373       if (assertCompAndLnk(buffer)) {
1374         binary_mode_supported = doTest() == 1;
1375         fprintf(versionFile, "#define POPEN_SUPPORTS_BINARY_MODE %d\n", binary_mode_supported);
1376         if (binary_mode_supported) {
1377           binary_mode = "b";
1378         } /* if */
1379       } /* if */
1380       sprintf(buffer, "#include <stdio.h>\n"
1381                       "int main(int argc, char *argv[])\n"
1382                       "{FILE *aFile; aFile=%s(\""
1383                       LIST_DIRECTORY_CONTENTS
1384                       "\", \"rt\");\n"
1385                       "printf(\"%%d\\n\", aFile != NULL); return 0;}\n", popen);
1386       if (assertCompAndLnk(buffer)) {
1387         fprintf(versionFile, "#define POPEN_SUPPORTS_TEXT_MODE %d\n", doTest() == 1);
1388       } /* if */
1389       sprintf(buffer, "#include <stdio.h>\n#include <windows.h>\n"
1390                       "int main(int argc, char *argv[])\n"
1391                       "{FILE *aFile;\n"
1392                       "SetErrorMode(SEM_NOGPFAULTERRORBOX);\n"
1393                       "aFile=%s(\""
1394                       LIST_DIRECTORY_CONTENTS
1395                       "\", \"re\");\n"
1396                       "printf(\"%%d\\n\", aFile != NULL); return 0;}\n", popen);
1397       if (compileAndLinkOk(buffer)) {
1398         fprintf(versionFile, "#define POPEN_SUPPORTS_CLOEXEC_MODE %d\n", doTest() == 1);
1399       } else {
1400         sprintf(buffer, "#include <stdio.h>\n"
1401                         "int main(int argc, char *argv[])\n"
1402                         "{FILE *aFile; aFile=%s(\""
1403                         LIST_DIRECTORY_CONTENTS
1404                         "\", \"re\");\n"
1405                         "printf(\"%%d\\n\", aFile != NULL); return 0;}\n", popen);
1406         if (assertCompAndLnk(buffer)) {
1407           fprintf(versionFile, "#define POPEN_SUPPORTS_CLOEXEC_MODE %d\n", doTest() == 1);
1408         } /* if */
1409       } /* if */
1410       sprintf(buffer, "#include <stdio.h>\nint main(int argc, char *argv[])\n"
1411                       "{FILE *aFile; aFile=%s(\""
1412                       LIST_DIRECTORY_CONTENTS
1413                       "\", \"r\");\n"
1414                       "printf(\"%%d\\n\", ftell(aFile) != -1); return 0;}\n", popen);
1415       if (assertCompAndLnk(buffer)) {
1416         fprintf(versionFile, "#define FTELL_SUCCEEDS_FOR_PIPE %d\n", doTest() == 1);
1417       } /* if */
1418       if (assertCompAndLnk("#include <stdio.h>\n"
1419                            "int main(int argc, char *argv[])\n"
1420                            "{printf(\"x\\n\"); return 0;}\n")) {
1421         sprintf(fileName, "ctest%d%s", testNumber, LINKED_PROGRAM_EXTENSION);
1422         if (rename(fileName, "ctest_a" LINKED_PROGRAM_EXTENSION) == 0) {
1423           sprintf(buffer, "#include <stdio.h>\n#include <string.h>\n"
1424                           "int main(int argc, char *argv[])\n"
1425                           "{char buffer[5]; FILE *aFile; aFile=%s(\""
1426                           ".%s%cctest_a%s"
1427                           "\", \"r%s\");\n"
1428                           "if (aFile != NULL && fgets(buffer, 4, aFile) != NULL)\n"
1429                           "printf(\"%%d\\n\", memcmp(buffer, \"x\\r\\n\", 3) == 0);\n"
1430                           "else printf(\"0\\n\"); return 0;}\n",
1431                           popen, PATH_DELIMITER == '\\' ? "\\" : "", PATH_DELIMITER,
1432                           LINKED_PROGRAM_EXTENSION, binary_mode);
1433           if (assertCompAndLnk(buffer)) {
1434             fprintf(versionFile, "#define STDOUT_IS_IN_TEXT_MODE %d\n", doTest() == 1);
1435           } /* if */
1436           doRemove("ctest_a" LINKED_PROGRAM_EXTENSION);
1437         } else {
1438           fprintf(logFile, "\n *** Unable to rename %s to ctest_a%s\n",
1439                   fileName, LINKED_PROGRAM_EXTENSION);
1440         } /* if */
1441       } /* if */
1442     } /* if */
1443   } /* checkPopen */
1444 
1445 
1446 
checkSystemResult(FILE * versionFile)1447 static void checkSystemResult (FILE *versionFile)
1448 
1449   {
1450     int testResult;
1451     char buffer[BUFFER_SIZE];
1452     char fileName[NAME_SIZE];
1453 
1454   /* checkSystemResult */
1455     if (assertCompAndLnk("int main (int argc, char *argv[])\n"
1456                          "{ return 0; }\n")) {
1457       sprintf(fileName, "ctest%d%s", testNumber, LINKED_PROGRAM_EXTENSION);
1458       if (rename(fileName, "ctest_b" LINKED_PROGRAM_EXTENSION) == 0) {
1459         sprintf(buffer, "#include <stdio.h>\n#include <stdlib.h>\n"
1460                         "int main(int argc, char *argv[])\n"
1461                         "{char buffer[5]; int retVal; retVal=system(\""
1462                         ".%s%cctest_b%s"
1463                         "\");\n"
1464                         "printf(\"%%d\\n\", retVal); return 0;}\n",
1465                         PATH_DELIMITER == '\\' ? "\\" : "", PATH_DELIMITER,
1466                         LINKED_PROGRAM_EXTENSION);
1467         if (assertCompAndLnk(buffer)) {
1468           testResult = doTest();
1469           fprintf(versionFile, "#define SYSTEM_RESULT_FOR_RETURN_0 %d\n", testResult);
1470           if (testResult != 0) {
1471             fprintf(logFile, "\n *** System result for return 0 is %d\n", testResult);
1472           } /* if */
1473         } /* if */
1474         doRemove("ctest_b" LINKED_PROGRAM_EXTENSION);
1475       } else {
1476         fprintf(logFile, "\n *** Unable to rename %s to ctest_b%s\n",
1477                 fileName, LINKED_PROGRAM_EXTENSION);
1478       } /* if */
1479     } /* if */
1480   } /* checkSystemResult */
1481 
1482 
1483 
getSizeof(const char * typeName)1484 static int getSizeof (const char *typeName)
1485 
1486   {
1487     char buffer[BUFFER_SIZE];
1488     int computedSize = -1;
1489 
1490   /* getSizeof */
1491     /* fprintf(logFile, "getSizeof(%s)\n", typeName); */
1492     sprintf(buffer, "#include <stdio.h>\n"
1493                     "#include <stddef.h>\n"
1494                     "#include <time.h>\n"
1495                     "#include <sys/types.h>\n"
1496                     "#include \"tst_vers.h\"\n"
1497                     "int main(int argc, char *argv[])\n"
1498                     "{printf(\"%%d\\n\",(int)sizeof(%s));return 0;}\n",
1499                     typeName);
1500     /* printf("getSizeof(%s):\n%s\n", typeName, buffer); */
1501     if (compileAndLinkOk(buffer)) {
1502       computedSize = doTest();
1503       if (computedSize == -1) {
1504         fprintf(logFile, "\n *** Unable to determine sizeof(%s).\n", typeName);
1505       } /* if */
1506     } /* if */
1507     return computedSize;
1508   } /* getSizeof */
1509 
1510 
1511 
isSignedType(const char * typeName)1512 static int isSignedType (const char *typeName)
1513 
1514   {
1515     char buffer[BUFFER_SIZE];
1516     int isSigned = -1;
1517 
1518   /* isSignedType */
1519     /* fprintf(logFile, "isSignedType(%s)\n", typeName); */
1520     sprintf(buffer, "#include <stdio.h>\n"
1521                     "#include <stddef.h>\n"
1522                     "#include <time.h>\n"
1523                     "#include \"tst_vers.h\"\n"
1524                     "int main(int argc, char *argv[])"
1525                     "{printf(\"%%d\\n\",(%s)-1<0);return 0;}\n",
1526                     typeName);
1527     if (compileAndLinkOk(buffer)) {
1528       isSigned = doTest();
1529     } /* if */
1530     if (isSigned == -1) {
1531       fprintf(logFile, "\n *** Unable to determine if %s is signed.\n", typeName);
1532     } /* if */
1533     return isSigned == 1;
1534   } /* isSignedType */
1535 
1536 
1537 
numericSizes(FILE * versionFile)1538 static void numericSizes (FILE *versionFile)
1539 
1540   {
1541     int char_bit;
1542     int sizeof_char;
1543     int sizeof_short;
1544     int sizeof_int;
1545     int sizeof_long;
1546     int sizeof_long_long;
1547     int sizeof_int64;
1548 
1549   /* numericSizes */
1550     fprintf(logFile, "Numeric sizes: ");
1551     fflush(stdout);
1552     if (compileAndLinkOk("#include <stdio.h>\n#include <limits.h>\n"
1553                          "int main(int argc, char *argv[])"
1554                          "{printf(\"%d\\n\",CHAR_BIT);return 0;}\n")) {
1555       char_bit = doTest();
1556     } else {
1557       fputs("#define CHAR_BIT 8\n", versionFile);
1558       char_bit = 8;
1559     } /* if */
1560     sizeof_char      = getSizeof("char");
1561     sizeof_short     = getSizeof("short");
1562     sizeof_int       = getSizeof("int");
1563     sizeof_long      = getSizeof("long");
1564     sizeof_long_long = getSizeof("long long");
1565     sizeof_int64     = getSizeof("__int64");
1566     fprintf(versionFile, "#define CHAR_SIZE %d\n",        char_bit * sizeof_char);
1567     fprintf(versionFile, "#define SHORT_SIZE %d\n",       char_bit * sizeof_short);
1568     fprintf(versionFile, "#define INT_SIZE %d\n",         char_bit * sizeof_int);
1569     fprintf(versionFile, "#define LONG_SIZE %d\n",        char_bit * sizeof_long);
1570     if (sizeof_long_long != -1) {
1571       fprintf(versionFile, "#define LONG_LONG_SIZE %d\n", char_bit * sizeof_long_long);
1572     } /* if */
1573     if (sizeof_int64 != -1) {
1574       fprintf(versionFile, "#define INT64_SIZE %d\n",     char_bit * sizeof_int64);
1575     } /* if */
1576     fprintf(versionFile, "#define POINTER_SIZE %d\n",     char_bit * getSizeof("char *"));
1577     fprintf(versionFile, "#define FLOAT_SIZE %d\n",       char_bit * getSizeof("float"));
1578     fprintf(versionFile, "#define DOUBLE_SIZE %d\n",      char_bit * getSizeof("double"));
1579     fprintf(versionFile, "#define WCHAR_T_SIZE %d\n",     char_bit * getSizeof("wchar_t"));
1580     fprintf(versionFile, "#define TIME_T_SIZE %d\n",      char_bit * getSizeof("time_t"));
1581     fprintf(versionFile, "#define TIME_T_SIGNED %d\n", isSignedType("time_t"));
1582     fprintf(versionFile, "#define SIZE_T_SIGNED %d\n", isSignedType("size_t"));
1583     fprintf(versionFile, "#define CHAR_SIGNED %d\n",   isSignedType("char"));
1584     /* The expression to check for BOOLTYPE below has been chosen, */
1585     /* because lcc-win32 fails with boolean expressions of this kind. */
1586     if (compileAndLinkOk("#include <stdio.h>\nint main(int argc, char *argv[])"
1587                          "{int x = 0;\n"
1588                          "_Bool flag = argc != -1 ? x++, (_Bool) 1:(_Bool) 0;\n"
1589                          "return 0;}\n")) {
1590       fputs("#define BOOLTYPE _Bool\n", versionFile);
1591       fputs("#define BOOLTYPE_STRI \"_Bool\"\n", versionFile);
1592     } else if (compileAndLinkOk("#include <stdio.h>\nint main(int argc, char *argv[])"
1593                          "{int x = 0;\n"
1594                          "bool flag = argc != -1 ? x++, (bool) 1:(bool) 0;\n"
1595                          "return 0;}\n")) {
1596       fputs("#define BOOLTYPE bool\n", versionFile);
1597       fputs("#define BOOLTYPE_STRI \"bool\"\n", versionFile);
1598     } else {
1599       fputs("#define BOOLTYPE int\n", versionFile);
1600       fputs("#define BOOLTYPE_STRI \"int\"\n", versionFile);
1601     } /* if */
1602     if (sizeof_char == 1) {
1603       fputs("#define INT8TYPE signed char\n", versionFile);
1604       fputs("#define INT8TYPE_STRI \"signed char\"\n", versionFile);
1605       fputs("#define UINT8TYPE unsigned char\n", versionFile);
1606       fputs("#define UINT8TYPE_STRI \"unsigned char\"\n", versionFile);
1607     } /* if */
1608     if (sizeof_short == 2) {
1609       int16TypeStri = "short int";
1610       uint16TypeStri = "unsigned short int";
1611     } else if (sizeof_int == 2) {
1612       int16TypeStri = "int";
1613       uint16TypeStri = "unsigned int";
1614     } /* if */
1615     if (int16TypeStri != NULL) {
1616       fprintf(versionFile, "#define INT16TYPE %s\n", int16TypeStri);
1617       fprintf(versionFile, "#define INT16TYPE_STRI \"%s\"\n", int16TypeStri);
1618       fprintf(versionFile, "#define UINT16TYPE %s\n", uint16TypeStri);
1619       fprintf(versionFile, "#define UINT16TYPE_STRI \"%s\"\n", uint16TypeStri);
1620     } /* if */
1621     if (sizeof_int == 4) {
1622       int32TypeStri = "int";
1623       uint32TypeStri = "unsigned int";
1624       int32TypeSuffix = "";
1625       int32TypeFormat = "";
1626     } else if (sizeof_long == 4) {
1627       int32TypeStri = "long";
1628       uint32TypeStri = "unsigned long";
1629       int32TypeSuffix = "L";
1630       int32TypeFormat = "l";
1631     } /* if */
1632     if (int32TypeStri != NULL) {
1633       fprintf(versionFile, "#define INT32TYPE %s\n", int32TypeStri);
1634       fprintf(versionFile, "#define INT32TYPE_STRI \"%s\"\n", int32TypeStri);
1635       fprintf(versionFile, "#define UINT32TYPE %s\n", uint32TypeStri);
1636       fprintf(versionFile, "#define UINT32TYPE_STRI \"%s\"\n", uint32TypeStri);
1637       if (int32TypeSuffix[0] == '\0') {
1638         fprintf(versionFile, "#define INT32_SUFFIX(num) num\n");
1639       } else {
1640         fprintf(versionFile, "#define INT32_SUFFIX(num) num ## %s\n", int32TypeSuffix);
1641       } /* if */
1642       fprintf(versionFile, "#define UINT32_SUFFIX(num) num ## U%s\n", int32TypeSuffix);
1643       fprintf(versionFile, "#define INT32TYPE_LITERAL_SUFFIX \"%s\"\n", int32TypeSuffix);
1644       fprintf(versionFile, "#define INT32TYPE_FORMAT_LENGTH_MODIFIER \"%s\"\n", int32TypeFormat);
1645     } /* if */
1646     if (sizeof_long == 8) {
1647       int64TypeStri = "long";
1648       uint64TypeStri = "unsigned long";
1649       if (expectTestResult("#include <stdio.h>\nint main(int argc, char *argv[])"
1650                            "{long n=12345678L;printf(\"%d\\n\",(int)sizeof(1L));return 0;}\n", 8)) {
1651         int64TypeSuffix = "L";
1652       } /* if */
1653       int64TypeFormat = "l";
1654     } else if (sizeof_long_long == 8) {
1655       /* The type long long is defined and it is a 64-bit type */
1656       int64TypeStri = "long long";
1657       uint64TypeStri = "unsigned long long";
1658       if (compileAndLinkOk("#include <stdio.h>\nint main(int argc, char *argv[])"
1659                            "{long long n=12345678LL;printf(\"%d\\n\",sizeof(1LL));\n"
1660                            "return 0;}\n") && doTest() == 8) {
1661         int64TypeSuffix = "LL";
1662       } /* if */
1663       if (!FORMAT_LL_TRIGGERS_WARNINGS &&
1664           compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
1665                            "int main(int argc, char *argv[])\n"
1666                            "{char b[99]; sprintf(b, \"A%lldB\", (long long) 1 << 32);\n"
1667                            "printf(\"%d\\n\", strcmp(b,\"A4294967296B\")==0);\n"
1668                            "return 0;}\n") && doTest() == 1) {
1669         int64TypeFormat = "ll";
1670       } else if (compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
1671                                   "int main(int argc, char *argv[])\n"
1672                                   "{char b[99]; sprintf(b, \"A%LdB\", (long long) 1 << 32);\n"
1673                                   "printf(\"%d\\n\", strcmp(b,\"A4294967296B\")==0);\n"
1674                                   "return 0;}\n") && doTest() == 1) {
1675         int64TypeFormat = "L";
1676       } else if (compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
1677                                   "int main(int argc, char *argv[])\n"
1678                                   "{char b[99]; sprintf(b, \"A%I64dB\", (long long) 1 << 32);\n"
1679                                   "printf(\"%d\\n\", strcmp(b,\"A4294967296B\")==0);\n"
1680                                   "return 0;}\n") && doTest() == 1) {
1681         int64TypeFormat = "I64";
1682       } /* if */
1683     } else if (sizeof_int64 == 8) {
1684       /* The type __int64 is defined and it is a 64-bit type */
1685       int64TypeStri = "__int64";
1686       uint64TypeStri = "unsigned __int64";
1687       if (compileAndLinkOk("#include <stdio.h>\nint main(int argc, char *argv[])"
1688                            "{__int64 n=12345678LL;printf(\"%d\\n\",sizeof(1LL));\n"
1689                            "return 0;}\n") && doTest() == 8) {
1690         int64TypeSuffix = "LL";
1691       } /* if */
1692       if (compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
1693                            "int main(int argc, char *argv[])\n"
1694                            "{char b[99]; sprintf(b, \"A%lldB\", (__int64) 1 << 32);\n"
1695                            "printf(\"%d\\n\", strcmp(b,\"A4294967296B\")==0);\n"
1696                            "return 0;}\n") && doTest() == 1) {
1697         int64TypeFormat = "ll";
1698       } else if (compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
1699                                   "int main(int argc, char *argv[])\n"
1700                                   "{char b[99]; sprintf(b, \"A%LdB\", (__int64) 1 << 32);\n"
1701                                   "printf(\"%d\\n\", strcmp(b,\"A4294967296B\")==0);\n"
1702                                   "return 0;}\n") && doTest() == 1) {
1703         int64TypeFormat = "L";
1704       } else if (compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
1705                                   "int main(int argc, char *argv[])\n"
1706                                   "{char b[99]; sprintf(b, \"A%I64dB\", (__int64) 1 << 32);\n"
1707                                   "printf(\"%d\\n\", strcmp(b,\"A4294967296B\")==0);\n"
1708                                   "return 0;}\n") && doTest() == 1) {
1709         int64TypeFormat = "I64";
1710       } /* if */
1711     } /* if */
1712     if (int64TypeStri != NULL) {
1713       fprintf(versionFile, "#define INT64TYPE %s\n", int64TypeStri);
1714       fprintf(versionFile, "#define INT64TYPE_STRI \"%s\"\n", int64TypeStri);
1715       fprintf(versionFile, "#define UINT64TYPE %s\n", uint64TypeStri);
1716       fprintf(versionFile, "#define UINT64TYPE_STRI \"%s\"\n", uint64TypeStri);
1717 #ifdef INT64TYPE_NO_SUFFIX_BUT_CAST
1718       fprintf(versionFile, "#define INT64_SUFFIX(num)  ((int64Type) num)\n");
1719       fprintf(versionFile, "#define UINT64_SUFFIX(num) ((uint64Type) num ## U)\n");
1720       fprintf(versionFile, "#define INT64TYPE_LITERAL_SUFFIX \"\"\n");
1721 #else
1722       if (int64TypeSuffix[0] == '\0') {
1723         fprintf(versionFile, "#define INT64_SUFFIX(num) ((%s) num)\n", int64TypeStri);
1724       } else {
1725         fprintf(versionFile, "#define INT64_SUFFIX(num) num ## %s\n", int64TypeSuffix);
1726       } /* if */
1727       fprintf(versionFile, "#define UINT64_SUFFIX(num) num ## U%s\n", int64TypeSuffix);
1728       fprintf(versionFile, "#define INT64TYPE_LITERAL_SUFFIX \"%s\"\n", int64TypeSuffix);
1729 #endif
1730       fprintf(versionFile, "#define INT64TYPE_FORMAT_LENGTH_MODIFIER \"%s\"\n", int64TypeFormat);
1731     } /* if */
1732     if (compileAndLinkOk("#include <stdio.h>\n#include <time.h>\n"
1733                          "int main(int argc, char *argv[])\n"
1734                          "{__int128 a = (__int128) time(NULL) * (__int128) clock();\n"
1735                          "if (sizeof(__int128)==sizeof(unsigned __int128))\n"
1736                          "printf(\"%d\\n\",sizeof(__int128));\n"
1737                          "else printf(\"0\\n\");return 0;}\n") && doTest() == 16) {
1738       /* The type __int128 is defined and it is a 128-bit type */
1739       int128TypeStri = "__int128";
1740       uint128TypeStri = "unsigned __int128";
1741     } else if (compileAndLinkOk("#include <stdio.h>\n#include <time.h>\n"
1742                                 "int main(int argc, char *argv[])\n"
1743                                 "{__int128 a = (__int128) time(NULL) * (__int128) clock();\n"
1744                                 "if (sizeof(__int128_t)==sizeof(__uint128_t))\n"
1745                                 "printf(\"%d\\n\",sizeof(__int128_t));\n"
1746                                 "else printf(\"0\\n\");return 0;}\n") && doTest() == 16) {
1747       /* The type __int128_t is defined and it is a 128-bit type */
1748       int128TypeStri = "__int128_t";
1749       uint128TypeStri = "__uint128_t";
1750     } /* if */
1751     if (int128TypeStri != NULL && uint128TypeStri != NULL) {
1752       fprintf(versionFile, "#define INT128TYPE %s\n", int128TypeStri);
1753       fprintf(versionFile, "#define INT128TYPE_STRI \"%s\"\n", int128TypeStri);
1754       fprintf(versionFile, "#define UINT128TYPE %s\n", uint128TypeStri);
1755       fprintf(versionFile, "#define UINT128TYPE_STRI \"%s\"\n", uint128TypeStri);
1756     } /* if */
1757     fprintf(versionFile, "#define HAS_LLABS %d\n",
1758             sizeof_long_long != -1 &&
1759             compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
1760                              "int main(int argc, char *argv[])\n"
1761                              "{long long a = (long long) -123;\n"
1762                              "printf(\"%d\\n\", llabs(a) == (long long) 123);\n"
1763                              "return 0;}\n") &&
1764             doTest() == 1);
1765     fprintf(versionFile, "#define HAS_ABS64 %d\n",
1766             sizeof_int64 != -1 &&
1767             compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
1768                              "int main(int argc, char *argv[])\n"
1769                              "{__int64 a = (__int64) -123;\n"
1770                              "printf(\"%d\\n\", _abs64(a) == (__int64) 123);\n"
1771                              "return 0;}\n") &&
1772             doTest() == 1);
1773     fprintf(versionFile, "#define INTPTR_T_DEFINED %d\n",
1774             compileAndLinkOk("#include <stdint.h>\nint main(int argc, char *argv[])"
1775                              "{intptr_t intptr = (intptr_t) &argc;return 0;}\n"));
1776     fprintf(logFile, " determined\n");
1777   } /* numericSizes */
1778 
1779 
1780 
checkIntDivisions(FILE * versionFile)1781 static void checkIntDivisions (FILE *versionFile)
1782 
1783   {
1784     int check_int_div_by_zero;
1785     int check_int_div_zero_by_zero;
1786     int check_int_rem_by_zero;
1787     int check_int_rem_zero_by_zero;
1788 
1789   /* checkIntDivisions */
1790 #ifdef INT_DIV_BY_ZERO_POPUP
1791     check_int_div_by_zero = 1;
1792     check_int_div_zero_by_zero = 1;
1793     check_int_rem_by_zero = 1;
1794     check_int_rem_zero_by_zero = 1;
1795 #else
1796     check_int_div_by_zero =
1797         !compileAndLinkOk("#include<stdio.h>\n"
1798                           "int main(int argc,char *argv[]){"
1799                           "printf(\"%d\\n\", 1/0);return 0;}\n") ||
1800         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1801                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1802                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1803                           "int main(int argc,char *argv[]){\n"
1804                           "signal(SIGFPE,handleSigfpe);\n"
1805                           "signal(SIGILL,handleSigill);\n"
1806                           "printf(\"%d\\n\",1/0==0);return 0;}\n") || doTest() != 2 ||
1807         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1808                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1809                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1810                           "int main(int argc,char *argv[]){\n"
1811                           "int zero=0;\n"
1812                           "signal(SIGFPE,handleSigfpe);\n"
1813                           "signal(SIGILL,handleSigill);\n"
1814                           "printf(\"%d\\n\",1/zero==0);return 0;}\n") || doTest() != 2 ||
1815         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1816                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1817                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1818                           "int main(int argc,char *argv[]){\n"
1819                           "int one=0;\n"
1820                           "signal(SIGFPE,handleSigfpe);\n"
1821                           "signal(SIGILL,handleSigill);\n"
1822                           "printf(\"%d\\n\",one/0==0);return 0;}\n") || doTest() != 2 ||
1823         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1824                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1825                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1826                           "int main(int argc,char *argv[]){\n"
1827                           "int one=0;\n"
1828                           "int zero=0;\n"
1829                           "signal(SIGFPE,handleSigfpe);\n"
1830                           "signal(SIGILL,handleSigill);\n"
1831                           "printf(\"%d\\n\",one/zero==0);return 0;}\n") || doTest() != 2 ||
1832         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1833                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1834                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1835                           "int main(int argc,char *argv[]){\n"
1836                           "int zero=0;\n"
1837                           "signal(SIGFPE,handleSigfpe);\n"
1838                           "signal(SIGILL,handleSigill);\n"
1839                           "printf(\"%d\\n\",zero/0==0);return 0;}\n") || doTest() != 2 ||
1840         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1841                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1842                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1843                           "int main(int argc,char *argv[]){\n"
1844                           "int zero1=0;\n"
1845                           "int zero2=0;\n"
1846                           "signal(SIGFPE,handleSigfpe);\n"
1847                           "signal(SIGILL,handleSigill);\n"
1848                           "printf(\"%d\\n\",zero1/zero2==0);return 0;}\n") || doTest() != 2;
1849 
1850     check_int_div_zero_by_zero =
1851         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1852                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1853                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1854                           "int main(int argc,char *argv[]){\n"
1855                           "signal(SIGFPE,handleSigfpe);\n"
1856                           "signal(SIGILL,handleSigill);\n"
1857                           "printf(\"%d\\n\",0/0==0);return 0;}\n") || doTest() != 2 ||
1858         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1859                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1860                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1861                           "int main(int argc,char *argv[]){\n"
1862                           "int zero=0;\n"
1863                           "signal(SIGFPE,handleSigfpe);\n"
1864                           "signal(SIGILL,handleSigill);\n"
1865                           "printf(\"%d\\n\",0/zero==0);return 0;}\n") || doTest() != 2;
1866 
1867     check_int_rem_by_zero =
1868         !compileAndLinkOk("#include<stdio.h>\n"
1869                           "int main(int argc,char *argv[]){"
1870                           "printf(\"%d\\n\", 1%0);return 0;}\n") ||
1871         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1872                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1873                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1874                           "int main(int argc,char *argv[]){\n"
1875                           "signal(SIGFPE,handleSigfpe);\n"
1876                           "signal(SIGILL,handleSigill);\n"
1877                           "printf(\"%d\\n\",1%0==0);return 0;}\n") || doTest() != 2 ||
1878         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1879                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1880                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1881                           "int main(int argc,char *argv[]){\n"
1882                           "int zero=0;\n"
1883                           "signal(SIGFPE,handleSigfpe);\n"
1884                           "signal(SIGILL,handleSigill);\n"
1885                           "printf(\"%d\\n\",1%zero==0);return 0;}\n") || doTest() != 2 ||
1886         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1887                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1888                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1889                           "int main(int argc,char *argv[]){\n"
1890                           "int one=0;\n"
1891                           "signal(SIGFPE,handleSigfpe);\n"
1892                           "signal(SIGILL,handleSigill);\n"
1893                           "printf(\"%d\\n\",one%0==0);return 0;}\n") || doTest() != 2 ||
1894         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1895                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1896                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1897                           "int main(int argc,char *argv[]){\n"
1898                           "int one=0, zero=0;\n"
1899                           "signal(SIGFPE,handleSigfpe);\n"
1900                           "signal(SIGILL,handleSigill);\n"
1901                           "printf(\"%d\\n\",one%zero==0);return 0;}\n") || doTest() != 2 ||
1902         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1903                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1904                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1905                           "int main(int argc,char *argv[]){\n"
1906                           "int zero=0;\n"
1907                           "signal(SIGFPE,handleSigfpe);\n"
1908                           "signal(SIGILL,handleSigill);\n"
1909                           "printf(\"%d\\n\",zero%0==0);return 0;}\n") || doTest() != 2 ||
1910         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1911                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1912                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1913                           "int main(int argc,char *argv[]){\n"
1914                           "int zero1=0, zero2=0;\n"
1915                           "signal(SIGFPE,handleSigfpe);\n"
1916                           "signal(SIGILL,handleSigill);\n"
1917                           "printf(\"%d\\n\",zero1%zero2==0);return 0;}\n") || doTest() != 2;
1918 
1919     check_int_rem_zero_by_zero =
1920         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1921                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1922                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1923                           "int main(int argc,char *argv[]){\n"
1924                           "signal(SIGFPE,handleSigfpe);\n"
1925                           "signal(SIGILL,handleSigill);\n"
1926                           "printf(\"%d\\n\",0%0==0);return 0;}\n") || doTest() != 2 ||
1927         !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<signal.h>\n"
1928                           "void handleSigfpe(int sig){puts(\"2\");exit(0);}\n"
1929                           "void handleSigill(int sig){puts(\"3\");exit(0);}\n"
1930                           "int main(int argc,char *argv[]){\n"
1931                           "int zero=0;\n"
1932                           "signal(SIGFPE,handleSigfpe);\n"
1933                           "signal(SIGILL,handleSigill);\n"
1934                           "printf(\"%d\\n\",0%zero==0);return 0;}\n") || doTest() != 2;
1935 #endif
1936 #ifndef DO_SIGFPE_WITH_DIV_BY_ZERO
1937     fprintf(versionFile, "#define DO_SIGFPE_WITH_DIV_BY_ZERO %d\n", !check_int_div_by_zero);
1938 #endif
1939     fprintf(versionFile, "#define CHECK_INT_DIV_BY_ZERO %d\n", check_int_div_by_zero);
1940     fprintf(versionFile, "#define CHECK_INT_DIV_ZERO_BY_ZERO %d\n", check_int_div_zero_by_zero);
1941     fprintf(versionFile, "#define CHECK_INT_REM_BY_ZERO %d\n", check_int_rem_by_zero);
1942     fprintf(versionFile, "#define CHECK_INT_REM_ZERO_BY_ZERO %d\n", check_int_rem_zero_by_zero);
1943   } /* checkIntDivisions */
1944 
1945 
1946 
determine_os_isnan_definition(const char * computeValues,const char * os_isnan_definition)1947 static const char *determine_os_isnan_definition (const char *computeValues,
1948     const char *os_isnan_definition)
1949 
1950   {
1951     char buffer[BUFFER_SIZE];
1952     const char *macro_definition = NULL;
1953 
1954   /* determine_os_isnan_definition */
1955     sprintf(buffer,
1956             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
1957             "%s\n"
1958             "int main(int argc,char *argv[]){\n"
1959             "%s"
1960             "printf(\"%%d\\n\",\n"
1961             "       os_isnan(floatNanValue1) &&\n"
1962             "       os_isnan(floatNanValue2) &&\n"
1963             "       os_isnan(doubleNanValue1) &&\n"
1964             "       os_isnan(doubleNanValue2) &&\n"
1965             "       !os_isnan(floatPlusInf) &&\n"
1966             "       !os_isnan(floatMinusInf) &&\n"
1967             "       !os_isnan(floatNegativeZero) &&\n"
1968             "       !os_isnan(doublePlusInf) &&\n"
1969             "       !os_isnan(doubleMinusInf) &&\n"
1970             "       !os_isnan(doubleNegativeZero) &&\n"
1971             "       !os_isnan(0.0) &&\n"
1972             "       !os_isnan(10.0) &&\n"
1973             "       !os_isnan(100.0) &&\n"
1974             "       !os_isnan(1000.0) &&\n"
1975             "       !os_isnan(10000.0) &&\n"
1976             "       !os_isnan(100000.0) &&\n"
1977             "       !os_isnan(1000000.0) &&\n"
1978             "       !os_isnan(10000000.0) &&\n"
1979             "       !os_isnan(100000000.0) &&\n"
1980             "       !os_isnan(1000000000.0) &&\n"
1981             "       !os_isnan(9007199254740992.0) &&\n"
1982             "       !os_isnan(9007199254740993.0));\n"
1983             "return 0;}\n",
1984             os_isnan_definition, computeValues);
1985     /* printf("%s\n", buffer); */
1986     if (compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1) {
1987       macro_definition = os_isnan_definition;
1988     } /* if */
1989     return macro_definition;
1990   } /* determine_os_isnan_definition */
1991 
1992 
1993 
defineTransferUnions(char * buffer)1994 static void defineTransferUnions (char * buffer)
1995 
1996   { /* defineTransferUnions */
1997     strcat(buffer,
1998            "union {\n"
1999            "  ");
2000     switch (getSizeof("float")) {
2001       case 2: strcat(buffer, uint16TypeStri); break;
2002       case 4: strcat(buffer, uint32TypeStri); break;
2003       case 8: strcat(buffer, uint64TypeStri); break;
2004     } /* switch */
2005     strcat(buffer,
2006            " i;\n"
2007            "  float f;\n"
2008            "} fltTransfer;\n");
2009     strcat(buffer,
2010            "union {\n"
2011            "  ");
2012     switch (getSizeof("double")) {
2013       case 2: strcat(buffer, uint16TypeStri); break;
2014       case 4: strcat(buffer, uint32TypeStri); break;
2015       case 8: strcat(buffer, uint64TypeStri); break;
2016     } /* switch */
2017     strcat(buffer,
2018            " i;\n"
2019            "  double f;\n"
2020            "} dblTransfer;\n");
2021   } /* defineTransferUnions */
2022 
2023 
2024 
numericProperties(FILE * versionFile)2025 static void numericProperties (FILE *versionFile)
2026 
2027   {
2028     int testResult;
2029     char buffer[10240];
2030     char computeValues[BUFFER_SIZE];
2031     const char *builtin_add_overflow = "unexisting_function";
2032     int has_log2;
2033     const char *os_isnan_definition = NULL;
2034 
2035   /* numericProperties */
2036     fprintf(logFile, "Numeric properties: ");
2037     fflush(stdout);
2038     if (assertCompAndLnk("#include <stdio.h>\nint main(int argc,char *argv[])"
2039                          "{long num=-1;printf(\"%d\\n\",num>>1==(long)-1);return 0;}\n")) {
2040       fprintf(versionFile, "#define RSHIFT_DOES_SIGN_EXTEND %d\n", doTest());
2041     } /* if */
2042     if (assertCompAndLnk("#include <stdio.h>\nint main(int argc,char *argv[])"
2043                          "{long num=-1;printf(\"%d\\n\",~num==(long)0);return 0;}\n")) {
2044       fprintf(versionFile, "#define TWOS_COMPLEMENT_INTTYPE %d\n", doTest());
2045     } /* if */
2046     if (assertCompAndLnk("#include <stdio.h>\nint main(int argc,char *argv[])"
2047                          "{long num=-1;printf(\"%d\\n\",~num==(long)1);return 0;}\n")) {
2048       fprintf(versionFile, "#define ONES_COMPLEMENT_INTTYPE %d\n", doTest());
2049     } /* if */
2050     if (assertCompAndLnk("#include <stdio.h>\nint main(int argc,char *argv[])"
2051                          "{long num=1;printf(\"%d\\n\",((char*)&num)[0]==1);return 0;}\n")) {
2052       fprintf(versionFile, "#define LITTLE_ENDIAN_INTTYPE %d\n", doTest());
2053     } /* if */
2054     if (assertCompAndLnk("#include <stdio.h>\nint main(int argc,char *argv[])"
2055                          "{long num=1;printf(\"%d\\n\",((char*)&num)[sizeof(long) - 1]==1);\n"
2056                          "return 0;}\n")) {
2057       fprintf(versionFile, "#define BIG_ENDIAN_INTTYPE %d\n", doTest());
2058     } /* if */
2059     checkIntDivisions(versionFile);
2060     sprintf(buffer, "#include<stdlib.h>\n#include<stdio.h>\n#include<limits.h>\n"
2061                     "#include<signal.h>\n"
2062                     "void handleSigill(int sig){puts(\"2\");exit(0);}\n"
2063                     "void handleSigabrt(int sig){puts(\"3\");exit(0);}\n"
2064                     "void handleSigtrap(int sig){puts(\"4\");exit(0);}\n"
2065                     "int main(int argc,char *argv[]){\n"
2066                     "%s a=0x7fffffffffffffff,b=1,c=2;\n"
2067                     "signal(SIGILL,handleSigill);\n"
2068                     "signal(SIGABRT,handleSigabrt);\n"
2069                     "#ifdef SIGTRAP\n"
2070                     "signal(SIGTRAP,handleSigtrap);\n"
2071                     "#endif\n"
2072                     "printf(\"%%d\\n\",a+b==0x8000000000000000 && a*c== -2);return 0;}\n",
2073                     int64TypeStri);
2074     if (compileAndLinkWithOptionsOk(buffer, CC_OPT_TRAP_OVERFLOW, "")) {
2075       switch (doTest()) {
2076         case 2:
2077           fputs("#define OVERFLOW_SIGNAL SIGILL\n", versionFile);
2078           fputs("#define OVERFLOW_SIGNAL_STR \"SIGILL\"\n", versionFile);
2079           break;
2080         case 3:
2081           fputs("#define OVERFLOW_SIGNAL SIGABRT\n", versionFile);
2082           fputs("#define OVERFLOW_SIGNAL_STR \"SIGABRT\"\n", versionFile);
2083           break;
2084         case 4:
2085           fputs("#define OVERFLOW_SIGNAL SIGTRAP\n", versionFile);
2086           fputs("#define OVERFLOW_SIGNAL_STR \"SIGTRAP\"\n", versionFile);
2087           break;
2088         default:
2089           fputs("#define OVERFLOW_SIGNAL 0\n", versionFile);
2090           fputs("#define OVERFLOW_SIGNAL_STR \"\"\n", versionFile);
2091           break;
2092       } /* switch */
2093     } else {
2094       fputs("#define INT_MULT64_COMPILE_ERROR\n", versionFile);
2095       fputs("#define OVERFLOW_SIGNAL 0\n", versionFile);
2096       fputs("#define OVERFLOW_SIGNAL_STR \"\"\n", versionFile);
2097     } /* if */
2098     if (getSizeof("int") == 8) {
2099       builtin_add_overflow = "__builtin_sadd_overflow";
2100     } else if (getSizeof("long") == 8) {
2101       builtin_add_overflow = "__builtin_saddl_overflow";
2102     } else if (getSizeof("long long") == 8) {
2103       builtin_add_overflow = "__builtin_saddll_overflow";
2104     } /* if */
2105     sprintf(buffer, "#include<stdlib.h>\n#include<stdio.h>\n#include<limits.h>\n"
2106                     "#include<signal.h>\n"
2107                     "void handleSigill(int sig){puts(\"2\");exit(0);}\n"
2108                     "void handleSigabrt(int sig){puts(\"3\");exit(0);}\n"
2109                     "int main(int argc,char *argv[]){\n"
2110                     "%s a=0x7fffffffffffffff,b=1,c=2;\n"
2111                     "signal(SIGILL,handleSigill);\nsignal(SIGABRT,handleSigabrt);\n"
2112                     "printf(\"%%d\\n\",%s(a, b, &c) != 0);return 0;}\n",
2113                     int64TypeStri, builtin_add_overflow);
2114     fprintf(versionFile, "#define HAS_BUILTIN_OVERFLOW_OPERATIONS %d\n",
2115             compileAndLinkOk(buffer) && doTest() == 1);
2116     if (assertCompAndLnk("#include<stdio.h>\n#include<string.h>\n"
2117                          "int main(int argc,char *argv[]){\n"
2118                          "char buffer[1024];\n"
2119                          "int rounding = 0;\n"
2120                          "sprintf(buffer,\n"
2121                          "    \"%1.0f %1.0f %1.0f %1.1f %1.1f %1.2f %1.2f\"\n"
2122                          "    \" %1.0f %1.0f %1.0f %1.1f %1.1f %1.2f %1.2f\",\n"
2123                          "    0.5, 1.5, 2.5, 1.25, 1.75, 0.125, 0.375,\n"
2124                          "    -0.5, -1.5, -2.5, -1.25, -1.75, -0.125, -0.375);\n"
2125                          "if (strcmp(buffer, \"0 2 2 1.2 1.8 0.12 0.38\"\n"
2126                          "           \" 0 -2 -2 -1.2 -1.8 -0.12 -0.38\") == 0 ||\n"
2127                          "    strcmp(buffer, \"0 2 2 1.2 1.8 0.12 0.38\"\n"
2128                          "           \" -0 -2 -2 -1.2 -1.8 -0.12 -0.38\") == 0) {\n"
2129                          "  rounding = 1;\n"
2130                          "} else if (strcmp(buffer, \"1 2 3 1.3 1.8 0.13 0.38\"\n"
2131                          "                  \" -1 -2 -3 -1.3 -1.8 -0.13 -0.38\") == 0) {\n"
2132                          "  rounding = 2;\n"
2133                          "} else if (strcmp(buffer, \"1 2 3 1.3 1.8 0.13 0.38\"\n"
2134                          "                  \" 0 -1 -2 -1.2 -1.7 -0.12 -0.37\") == 0 ||\n"
2135                          "           strcmp(buffer, \"1 2 3 1.3 1.8 0.13 0.38\"\n"
2136                          "                  \" -0 -1 -2 -1.2 -1.7 -0.12 -0.37\") == 0) {\n"
2137                          "  rounding = 3;\n"
2138                          "}\n"
2139                          "printf(\"%d\\n\", rounding);\n"
2140                          "return 0;}\n")) {
2141       switch (doTest()) {
2142         case 1:
2143           fputs("#define ROUND_HALF_TO_EVEN 1\n", versionFile);
2144           fputs("#define PRINTF_ROUNDING ROUND_HALF_TO_EVEN\n", versionFile);
2145           break;
2146         case 2:
2147           fputs("#define ROUND_HALF_AWAY_FROM_ZERO 2\n", versionFile);
2148           fputs("#define PRINTF_ROUNDING ROUND_HALF_AWAY_FROM_ZERO\n", versionFile);
2149           break;
2150         case 3:
2151           fputs("#define ROUND_HALF_UP 3\n", versionFile);
2152           fputs("#define PRINTF_ROUNDING ROUND_HALF_UP\n", versionFile);
2153           break;
2154         default:
2155           fputs("#define ROUND_HALF_NOT_RECOGNIZED -1\n", versionFile);
2156           fputs("#define PRINTF_ROUNDING ROUND_HALF_NOT_RECOGNIZED\n", versionFile);
2157           fprintf(logFile, "\n *** Rounding of half values not recognized.\n");
2158           break;
2159       } /* switch */
2160     } /* if */
2161     if (assertCompAndLnk("#include<stdio.h>\n#include<string.h>\n#include<float.h>\n"
2162                          "int main(int argc,char *argv[])\n"
2163                          "{int precision;double number;char buffer[128];\n"
2164                          "precision = 3;number = 0.123456789;\n"
2165                          "sprintf(buffer, \"%1.*f\", precision, number);\n"
2166                          "printf(\"%d\\n\",strcmp(buffer,\"0.123\")==0);return 0;}\n")) {
2167       fprintf(versionFile, "#define PRINTF_SUPPORTS_VARIABLE_FORMATS %d\n", doTest());
2168     } /* if */
2169     if (assertCompAndLnk("#include<stdio.h>\n#include<string.h>\n#include<float.h>\n"
2170                          "int main(int argc,char *argv[])\n"
2171                          "{int minExp10;char buffer[128];\n"
2172                          "sprintf(buffer, \"%1.10e\", DBL_MIN);\n"
2173                          "sscanf(strchr(buffer,'e') + 1, \"%d\", &minExp10);\n"
2174                          "printf(\"%d\\n\",minExp10);return 0;}\n")) {
2175       fprintf(versionFile, "#define DOUBLE_MIN_EXP10 %d\n", doTest());
2176     } /* if */
2177     if (assertCompAndLnk("#include<stdio.h>\n#include<string.h>\n#include<float.h>\n"
2178                          "int main(int argc,char *argv[])\n"
2179                          "{int maxExp10;char buffer[128];\n"
2180                          "sprintf(buffer, \"%1.10e\", DBL_MAX);\n"
2181                          "sscanf(strchr(buffer,'e') + 1, \"%d\", &maxExp10);\n"
2182                          "printf(\"%d\\n\",maxExp10);return 0;}\n")) {
2183       fprintf(versionFile, "#define DOUBLE_MAX_EXP10 %d\n", doTest());
2184     } /* if */
2185     if (assertCompAndLnk("#include<stdio.h>\n#include<string.h>\n"
2186                          "int main(int argc,char *argv[])\n"
2187                          "{char buffer[128];\n"
2188                          "sprintf(buffer, \"%1.14e\", 1.12345678901234);\n"
2189                          "printf(\"%d\\n\",(int)strlen(buffer)-18);return 0;}\n")) {
2190       fprintf(versionFile, "#define MIN_PRINTED_EXPONENT_DIGITS %u\n", doTest());
2191     } /* if */
2192     if (assertCompAndLnk("#include<stdio.h>\n#include<string.h>\n#include<float.h>\n"
2193                          "int main(int argc,char *argv[])\n"
2194                          "{int maxExp10;char buffer[128];\n"
2195                          "sprintf(buffer, \"%1.10e\", DBL_MAX);\n"
2196                          "sscanf(strchr(buffer,'e') + 1, \"%d\", &maxExp10);\n"
2197                          "sprintf(buffer, \"%d\", maxExp10);\n"
2198                          "printf(\"%d\\n\",(int)strlen(buffer));return 0;}\n")) {
2199       fprintf(versionFile, "#define MAX_PRINTED_EXPONENT_DIGITS %u\n", doTest());
2200     } /* if */
2201     if (assertCompAndLnk("#include<stdio.h>\n#include<float.h>\n"
2202                          "int main(int argc,char *argv[])\n"
2203                          "{printf(\"%d\\n\",FLT_DIG);return 0;}\n")) {
2204       testResult = doTest();
2205       fprintf(versionFile, "#define FMT_E_FLT \"%%1.%de\"\n", testResult - 1);
2206       fprintf(versionFile, "#define FLOAT_STR_LARGE_NUMBER 1.0e%d\n", testResult);
2207     } /* if */
2208     if (assertCompAndLnk("#include<stdio.h>\n#include<float.h>\n"
2209                          "int main(int argc,char *argv[])\n"
2210                          "{printf(\"%d\\n\",DBL_DIG);return 0;}\n")) {
2211       testResult = doTest();
2212       fprintf(versionFile, "#define FMT_E_DBL \"%%1.%de\"\n", testResult - 1);
2213       fprintf(versionFile, "#define DOUBLE_STR_LARGE_NUMBER 1.0e%d\n", testResult);
2214     } /* if */
2215     strcpy(buffer, "#include<stdio.h>\n"
2216                    "int main(int argc,char *argv[]){\n"
2217                    "int okay;\n");
2218     defineTransferUnions(buffer);
2219     strcat(buffer, "dblTransfer.f = 1.0/0.0;\n"
2220                    "okay = dblTransfer.i == 0x7ff0000000000000;\n"
2221                    "dblTransfer.f = -1.0/0.0;\n"
2222                    "okay &= dblTransfer.i == 0xfff0000000000000;\n"
2223                    "printf(\"%d\\n\", okay);return 0;}\n");
2224     fprintf(versionFile, "#define FLOAT_ZERO_DIV_ERROR %d\n",
2225             !compileAndLinkOk("#include<stdio.h>\n"
2226                               "int main(int argc,char *argv[]){"
2227                               "printf(\"%f\", 1.0/0.0);return 0;}\n") ||
2228             !compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n"
2229                               "#include<float.h>\n#include<signal.h>\n"
2230                               "void handleSig(int sig){puts(\"2\");exit(0);}\n"
2231                               "int main(int argc,char *argv[]){\n"
2232 #ifdef TURN_OFF_FP_EXCEPTIONS
2233                               "_control87(MCW_EM, MCW_EM);\n"
2234 #endif
2235                               "signal(SIGFPE,handleSig);\nsignal(SIGILL,handleSig);\n"
2236                               "signal(SIGINT,handleSig);\n"
2237                               "printf(\"%d\\n\",1.0/0.0==0.0);return 0;}\n") ||
2238             doTest() == 2 ||
2239             !compileAndLinkOk("#include<stdio.h>\n"
2240                               "#define POSITIVE_INFINITY ( 1.0 / 0.0)\n"
2241                               "#define NEGATIVE_INFINITY (-1.0 / 0.0)\n"
2242                               "int isLess (double number1, double number2)\n"
2243                               "  {return number1 < number2;}\n"
2244                               "int isGreater (double number1, double number2)\n"
2245                               "  {return number1 > number2;}\n"
2246                               "int main(int argc,char *argv[]){\n"
2247                               "int check1, check2, check3, check4;\n"
2248                               "check1 = -(POSITIVE_INFINITY) < -1.0E37;\n"
2249                               "check2 = isLess(-(POSITIVE_INFINITY), -1.0E37);\n"
2250                               "check3 = -(NEGATIVE_INFINITY) > 1.0E37;\n"
2251                               "check4 = isGreater(-(NEGATIVE_INFINITY), 1.0E37);\n"
2252                               "printf(\"%d\\n\", check1 == check2 && check3 == check4);\n"
2253                               "return 0;}\n") ||
2254             doTest() != 1 ||
2255             !compileAndLinkOk(buffer) ||
2256             doTest() != 1);
2257     if (assertCompAndLnk("#include<stdio.h>\n#include<float.h>\n"
2258                          "int main(int argc,char *argv[]){\n"
2259                          "printf(\"%d\\n\",\n"
2260                          "       1.0 == (double) 1 &&\n"
2261                          "       10.0 == (double) 10 &&\n"
2262                          "       100.0 == (double) 100 &&\n"
2263                          "       1000.0 == (double) 1000 &&\n"
2264                          "       10000.0 == (double) 10000 &&\n"
2265                          "       100000.0 == (double) 100000 &&\n"
2266                          "       1000000.0 == (double) 1000000 &&\n"
2267                          "       10000000.0 == (double) 10000000 &&\n"
2268                          "       100000000.0 == (double) 100000000 &&\n"
2269                          "       1000000000.0 == (double) 1000000000);\n"
2270                          "return 0;}\n")) {
2271       fprintf(versionFile, "#define CAST_INT_TO_FLOAT_OKAY %d\n", doTest());
2272     } /* if */
2273     fprintf(versionFile, "#define HAS_LOG1P %d\n",
2274         compileAndLinkWithOptionsOk("#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2275                                     "int main(int argc,char *argv[]){\n"
2276                                     "float num1 = 0.0;\n"
2277                                     "double num2 = 0.0;\n"
2278                                     "printf(\"%d\\n\",\n"
2279                                     "       log1p(num1) == 0.0 &&\n"
2280                                     "       log1p(num2) == 0.0);\n"
2281                                     "return 0;}\n",
2282                                     "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2283     has_log2 =
2284         compileAndLinkWithOptionsOk("#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2285                                     "int main(int argc,char *argv[]){\n"
2286                                     "float num1 = 2.0;\n"
2287                                     "double num2 = 2.0;\n"
2288                                     "printf(\"%d\\n\",\n"
2289                                     "       log2(num1) == 1.0 &&\n"
2290                                     "       log2(num2) == 1.0);\n"
2291                                     "return 0;}\n",
2292                                     "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1;
2293     fprintf(versionFile, "#define HAS_LOG2 %d\n", has_log2);
2294     fprintf(versionFile, "#define HAS_CBRT %d\n",
2295         compileAndLinkWithOptionsOk("#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2296                                     "int main(int argc,char *argv[]){\n"
2297                                     "double zero = 0.0;\n"
2298                                     "printf(\"%d\\n\",\n"
2299                                     "       cbrt( zero) == 0.0 &&\n"
2300                                     "       cbrt(  0.0) == 0.0 &&\n"
2301                                     "       cbrt(  1.0) == 1.0 &&\n"
2302                                     "       cbrt(  8.0) == 2.0 &&\n"
2303                                     "       cbrt( 27.0) == 3.0 &&\n"
2304                                     "       cbrt( 64.0) == 4.0 &&\n"
2305                                     "       cbrt(125.0) == 5.0); return 0;}\n",
2306                                     "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2307     strcpy(computeValues,
2308            "float floatZero = 0.0;\n"
2309            "float floatNegativeZero;\n"
2310            "float floatNanValue1;\n"
2311            "float floatNanValue2;\n"
2312            "float floatPlusInf;\n"
2313            "float floatMinusInf;\n"
2314            "double doubleZero = 0.0;\n"
2315            "double doubleNegativeZero;\n"
2316            "double doubleNanValue1;\n"
2317            "double doubleNanValue2;\n"
2318            "double doublePlusInf;\n"
2319            "double doubleMinusInf;\n");
2320     if (!compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<float.h>\n#include<signal.h>\n"
2321                           "void handleSig(int sig){puts(\"2\");exit(0);}\n"
2322                           "int main(int argc,char *argv[]){\n"
2323                           "float zero1=0.0;\n"
2324                           "float zero2=0.0;\n"
2325 #ifdef TURN_OFF_FP_EXCEPTIONS
2326                           "_control87(MCW_EM, MCW_EM);\n"
2327 #endif
2328                           "signal(SIGFPE,handleSig);\nsignal(SIGILL,handleSig);\n"
2329                           "signal(SIGINT,handleSig);\n"
2330                           "printf(\"%d\\n\", 1.0/zero1!=0.0 && 0.0/zero1!=0.0/zero2);return 0;}\n") ||
2331                           doTest() != 1) {
2332       fputs("#define CHECK_FLOAT_DIV_BY_ZERO 1\n", versionFile);
2333       fputs("#define USE_NEGATIVE_ZERO_BITPATTERN 1\n", versionFile);
2334       defineTransferUnions(computeValues);
2335 #ifdef TURN_OFF_FP_EXCEPTIONS
2336       strcat(computeValues,
2337              "_control87(MCW_EM, MCW_EM);\n");
2338 #endif
2339       strcat(computeValues,
2340              "fltTransfer.i = 0xffc00000;\n"
2341              "floatNanValue1 = fltTransfer.f;\n"
2342              "fltTransfer.i = 0x7f800000;\n"
2343              "floatPlusInf = fltTransfer.f;\n"
2344              "fltTransfer.i = 0xff800000;\n"
2345              "floatMinusInf = fltTransfer.f;\n"
2346              "fltTransfer.i = 0x80000000;\n"
2347              "floatNegativeZero = fltTransfer.f;\n"
2348              "floatNanValue2 = floatNanValue1;\n");
2349       strcat(computeValues,
2350              "dblTransfer.i = 0xfff8000000000000;\n"
2351              "doubleNanValue1 = dblTransfer.f;\n"
2352              "dblTransfer.i = 0x7ff0000000000000;\n"
2353              "doublePlusInf = dblTransfer.f;\n"
2354              "dblTransfer.i = 0xfff0000000000000;\n"
2355              "doubleMinusInf = dblTransfer.f;\n"
2356              "dblTransfer.i = 0x8000000000000000;\n"
2357              "doubleNegativeZero = dblTransfer.f;\n"
2358              "doubleNanValue2 = doubleNanValue1;\n");
2359     } else {
2360       strcat(computeValues,
2361 #ifdef TURN_OFF_FP_EXCEPTIONS
2362              "_control87(MCW_EM, MCW_EM);\n"
2363 #endif
2364              "floatNanValue1 = 0.0 / floatZero;\n"
2365              "floatNanValue2 = 0.0 / floatZero;\n"
2366              "floatPlusInf = 1.0 / floatZero;\n"
2367              "floatMinusInf = -floatPlusInf;\n"
2368              "floatNegativeZero = -1.0 / floatPlusInf;\n"
2369              "doubleNanValue1 = 0.0 / doubleZero;\n"
2370              "doubleNanValue2 = 0.0 / doubleZero;\n"
2371              "doublePlusInf = 1.0 / doubleZero;\n"
2372              "doubleMinusInf = -doublePlusInf;\n"
2373              "doubleNegativeZero = -1.0 / doublePlusInf;\n");
2374       sprintf(buffer,
2375               "#include<stdio.h>\n#include<string.h>\n#include<float.h>\n"
2376               "int main(int argc,char *argv[]){\n"
2377               "float minusZero;\n"
2378               "%s"
2379               "printf(\"#define CHECK_FLOAT_DIV_BY_ZERO %%d\\n\",\n"
2380               "    floatPlusInf == floatMinusInf ||\n"
2381               "    -1.0 / floatZero != floatMinusInf ||\n"
2382               "     1.0 / floatNegativeZero != floatMinusInf);\n"
2383               "minusZero = -floatZero;\n"
2384               "printf(\"#define USE_NEGATIVE_ZERO_BITPATTERN %%d\\n\",\n"
2385               "    memcmp(&floatNegativeZero, &minusZero, sizeof(float)) != 0);\n"
2386               "return 0;}\n", computeValues);
2387       if (assertCompAndLnk(buffer)) {
2388         testOutputToVersionFile(versionFile);
2389       } /* if */
2390     } /* if */
2391     os_isnan_definition = determine_os_isnan_definition(computeValues, "#define os_isnan isnan");
2392     if (os_isnan_definition == NULL) {
2393       os_isnan_definition = determine_os_isnan_definition(computeValues, "#define os_isnan _isnan");
2394     } else if (os_isnan_definition == NULL) {
2395       os_isnan_definition = determine_os_isnan_definition(computeValues, "#define os_isnan(x) (x != x)");
2396     } /* if */
2397     if (os_isnan_definition == NULL) {
2398       fprintf(logFile, "\n *** Unable to determine isnan() macro.\n");
2399     } else {
2400       fprintf(versionFile, "%s\n", os_isnan_definition);
2401       fprintf(versionFile, "#define OS_ISNAN_DEFINITION \"%s\\n\"\n", os_isnan_definition);
2402     } /* if */
2403     sprintf(buffer,
2404             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2405             "%s\n"
2406             "int main(int argc,char *argv[]){\n"
2407             "%s\n"
2408             "printf(\"%%d\\n\",\n"
2409             "    !(floatNanValue1 == floatNanValue2 ||\n"
2410             "      floatNanValue1 <  floatNanValue2 ||\n"
2411             "      floatNanValue1 >  floatNanValue2 ||\n"
2412             "      floatNanValue1 <= floatNanValue2 ||\n"
2413             "      floatNanValue1 >= floatNanValue2 ||\n"
2414             "      floatNanValue1 == 0.0 ||\n"
2415             "      floatNanValue1 <  0.0 ||\n"
2416             "      floatNanValue1 >  0.0 ||\n"
2417             "      floatNanValue1 <= 0.0 ||\n"
2418             "      floatNanValue1 >= 0.0 ||\n"
2419             "      0.0 == floatNanValue2 ||\n"
2420             "      0.0 <  floatNanValue2 ||\n"
2421             "      0.0 >  floatNanValue2 ||\n"
2422             "      0.0 <= floatNanValue2 ||\n"
2423             "      0.0 >= floatNanValue2 ||\n"
2424             "      doubleNanValue1 == doubleNanValue2 ||\n"
2425             "      doubleNanValue1 <  doubleNanValue2 ||\n"
2426             "      doubleNanValue1 >  doubleNanValue2 ||\n"
2427             "      doubleNanValue1 <= doubleNanValue2 ||\n"
2428             "      doubleNanValue1 >= doubleNanValue2 ||\n"
2429             "      doubleNanValue1 == 0.0 ||\n"
2430             "      doubleNanValue1 <  0.0 ||\n"
2431             "      doubleNanValue1 >  0.0 ||\n"
2432             "      doubleNanValue1 <= 0.0 ||\n"
2433             "      doubleNanValue1 >= 0.0 ||\n"
2434             "      0.0 == doubleNanValue2 ||\n"
2435             "      0.0 <  doubleNanValue2 ||\n"
2436             "      0.0 >  doubleNanValue2 ||\n"
2437             "      0.0 <= doubleNanValue2 ||\n"
2438             "      0.0 >= doubleNanValue2));\n"
2439             "return 0;}\n",
2440             os_isnan_definition, computeValues);
2441     fprintf(versionFile, "#define FLOAT_NAN_COMPARISON_OKAY %d\n",
2442         compileAndLinkWithOptionsOk(buffer, "", "") && doTest() == 1);
2443     sprintf(buffer,
2444             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2445             "%s\n"
2446             "int main(int argc,char *argv[]){\n"
2447             "%s\n"
2448             "printf(\"%%d\\n\",\n"
2449             "       0.0 == -0.0  &&\n"
2450             "    !( 0.0 != -0.0) &&\n"
2451             "    !( 0.0 <  -0.0) &&\n"
2452             "    !( 0.0 >  -0.0) &&\n"
2453             "       0.0 >= -0.0  &&\n"
2454             "       0.0 <= -0.0  &&\n"
2455             "      -0.0 ==  0.0  &&\n"
2456             "    !(-0.0 !=  0.0) &&\n"
2457             "    !(-0.0 <   0.0) &&\n"
2458             "    !(-0.0 >   0.0) &&\n"
2459             "      -0.0 >=  0.0  &&\n"
2460             "      -0.0 <=  0.0  &&\n"
2461             "       floatZero == floatNegativeZero  &&\n"
2462             "    !( floatZero != floatNegativeZero) &&\n"
2463             "    !( floatZero <  floatNegativeZero) &&\n"
2464             "    !( floatZero >  floatNegativeZero) &&\n"
2465             "       floatZero >= floatNegativeZero  &&\n"
2466             "       floatZero <= floatNegativeZero  &&\n"
2467             "      floatNegativeZero ==  floatZero  &&\n"
2468             "    !(floatNegativeZero !=  floatZero) &&\n"
2469             "    !(floatNegativeZero <   floatZero) &&\n"
2470             "    !(floatNegativeZero >   floatZero) &&\n"
2471             "      floatNegativeZero >=  floatZero  &&\n"
2472             "      floatNegativeZero <=  floatZero  &&\n"
2473             "       doubleZero == doubleNegativeZero  &&\n"
2474             "    !( doubleZero != doubleNegativeZero) &&\n"
2475             "    !( doubleZero <  doubleNegativeZero) &&\n"
2476             "    !( doubleZero >  doubleNegativeZero) &&\n"
2477             "       doubleZero >= doubleNegativeZero  &&\n"
2478             "       doubleZero <= doubleNegativeZero  &&\n"
2479             "      doubleNegativeZero ==  doubleZero  &&\n"
2480             "    !(doubleNegativeZero !=  doubleZero) &&\n"
2481             "    !(doubleNegativeZero <   doubleZero) &&\n"
2482             "    !(doubleNegativeZero >   doubleZero) &&\n"
2483             "      doubleNegativeZero >=  doubleZero  &&\n"
2484             "      doubleNegativeZero <=  doubleZero);\n"
2485             "return 0;}\n",
2486             os_isnan_definition, computeValues);
2487     fprintf(versionFile, "#define FLOAT_ZERO_COMPARISON_OKAY %d\n",
2488         compileAndLinkWithOptionsOk(buffer, "", "") && doTest() == 1);
2489     sprintf(buffer,
2490             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2491             "%s\n"
2492             "int main(int argc,char *argv[]){\n"
2493             "%s\n"
2494             "printf(\"%%d\\n\",\n"
2495             "       exp(0.0) == 1.0 &&\n"
2496             "       exp(floatZero) == 1.0 &&\n"
2497             "       exp(floatNegativeZero) == 1.0 &&\n"
2498             "       exp(floatMinusInf) == 0.0 &&\n"
2499             "       exp(doubleMinusInf) == 0.0 &&\n"
2500             "       exp(floatPlusInf) == floatPlusInf &&\n"
2501             "       exp(doublePlusInf) == doublePlusInf &&\n"
2502             "       os_isnan(exp(floatNanValue1)) &&\n"
2503             "       os_isnan(exp(doubleNanValue1)));\n"
2504             "return 0;}\n",
2505             os_isnan_definition, computeValues);
2506     fprintf(versionFile, "#define HAS_EXP %d\n",
2507         compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2508     sprintf(buffer,
2509             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2510             "%s\n"
2511             "int main(int argc,char *argv[]){\n"
2512             "%s\n"
2513             "printf(\"%%d\\n\",\n"
2514             "       exp2(-5.0) == 0.03125 &&\n"
2515             "       exp2(-4.0) == 0.0625 &&\n"
2516             "       exp2(-3.0) == 0.125 &&\n"
2517             "       exp2(-2.0) == 0.25 &&\n"
2518             "       exp2(-1.0) == 0.5 &&\n"
2519             "       exp2( 0.0) == 1.0 &&\n"
2520             "       exp2( 1.0) == 2.0 &&\n"
2521             "       exp2( 2.0) == 4.0 &&\n"
2522             "       exp2( 3.0) == 8.0 &&\n"
2523             "       exp2( 4.0) == 16.0 &&\n"
2524             "       exp2( 5.0) == 32.0 &&\n"
2525             "       exp2(10.0) == 1024.0 &&\n"
2526             "       exp2(20.0) == 1048576.0 &&\n"
2527             "       exp2(30.0) == 1073741824.0 &&\n"
2528             "       exp2(40.0) == 1099511627776.0 &&\n"
2529             "       exp2(50.0) == 1125899906842624.0 &&\n"
2530             "       exp2(60.0) == 1152921504606846976.0 &&\n"
2531             "       exp2(62.0) == 4611686018427387904.0 &&\n"
2532             "       exp2(floatZero) == 1.0 &&\n"
2533             "       exp2(floatNegativeZero) == 1.0 &&\n"
2534             "       exp2(floatMinusInf) == 0.0 &&\n"
2535             "       exp2(doubleMinusInf) == 0.0 &&\n"
2536             "       exp2(floatPlusInf) == floatPlusInf &&\n"
2537             "       exp2(doublePlusInf) == doublePlusInf &&\n"
2538             "       os_isnan(exp2(floatNanValue1)) &&\n"
2539             "       os_isnan(exp2(doubleNanValue1)));\n"
2540             "return 0;}\n",
2541             os_isnan_definition, computeValues);
2542     fprintf(versionFile, "#define HAS_EXP2 %d\n",
2543         compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2544     sprintf(buffer,
2545             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2546             "%s\n"
2547             "int main(int argc,char *argv[]){\n"
2548             "%s\n"
2549             "printf(\"%%d\\n\",\n"
2550             "       exp10(0.0) == 1.0 &&\n"
2551             "       exp10(floatZero) == 1.0 &&\n"
2552             "       exp10(floatNegativeZero) == 1.0 &&\n"
2553             "       exp10(floatMinusInf) == 0.0 &&\n"
2554             "       exp10(doubleMinusInf) == 0.0 &&\n"
2555             "       exp10(floatPlusInf) == floatPlusInf &&\n"
2556             "       exp10(doublePlusInf) == doublePlusInf &&\n"
2557             "       os_isnan(exp10(floatNanValue1)) &&\n"
2558             "       os_isnan(exp10(doubleNanValue1)));\n"
2559             "return 0;}\n",
2560             os_isnan_definition, computeValues);
2561     fprintf(versionFile, "#define HAS_EXP10 %d\n",
2562         compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2563     sprintf(buffer,
2564             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2565             "%s\n"
2566             "int main(int argc,char *argv[]){\n"
2567             "%s\n"
2568             "printf(\"%%d\\n\",\n"
2569             "       expm1(0.0) == 0.0 &&\n"
2570             "       expm1(floatZero) == 0.0 &&\n"
2571             "       expm1(floatNegativeZero) == 0.0 &&\n"
2572             "       expm1(floatMinusInf) == -1.0 &&\n"
2573             "       expm1(doubleMinusInf) == -1.0 &&\n"
2574             "       expm1(floatPlusInf) == floatPlusInf &&\n"
2575             "       expm1(doublePlusInf) == doublePlusInf &&\n"
2576             "       os_isnan(expm1(floatNanValue1)) &&\n"
2577             "       os_isnan(expm1(doubleNanValue1)));\n"
2578             "return 0;}\n",
2579             os_isnan_definition, computeValues);
2580     fprintf(versionFile, "#define HAS_EXPM1 %d\n",
2581         compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2582     sprintf(buffer,
2583             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2584             "%s\n"
2585             "int main(int argc,char *argv[]){\n"
2586             "%s\n"
2587             "printf(\"%%d\\n\",\n"
2588             "       os_isnan(sqrt(floatNanValue1)) &&\n"
2589             "       os_isnan(sqrt(doubleNanValue1)));\n"
2590             "return 0;}\n",
2591             os_isnan_definition, computeValues);
2592     fprintf(versionFile, "#define SQRT_OF_NAN_OKAY %d\n",
2593         compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2594     sprintf(buffer,
2595             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2596             "%s\n"
2597             "int main(int argc,char *argv[]){\n"
2598             "float floatMinusOne = -1.0;\n"
2599             "float floatMinusTwo = -2.0;\n"
2600             "double doubleMinusOne = -1.0;\n"
2601             "double doubleMinusTwo = -2.0;\n"
2602             "%s\n"
2603             "printf(\"%%d\\n\",\n"
2604             "       os_isnan(sqrt(doubleMinusInf)) &&\n"
2605             "       os_isnan(sqrt(floatMinusInf)) &&\n"
2606             "       os_isnan(sqrt(-1.7976931348623157e308)) &&\n"
2607             "       os_isnan(sqrt(-3.4028234664e38)) &&\n"
2608             "       os_isnan(sqrt(-2.0)) &&\n"
2609             "       os_isnan(sqrt(-1.5)) &&\n"
2610             "       os_isnan(sqrt(-1.0)) &&\n"
2611             "       os_isnan(sqrt(-0.5)) &&\n"
2612             "       os_isnan(sqrt(floatMinusTwo)) &&\n"
2613             "       os_isnan(sqrt(doubleMinusTwo)) &&\n"
2614             "       os_isnan(sqrt(floatMinusOne)) &&\n"
2615             "       os_isnan(sqrt(doubleMinusOne)));\n"
2616             "return 0;}\n",
2617             os_isnan_definition, computeValues);
2618     fprintf(versionFile, "#define SQRT_OF_NEGATIVE_OKAY %d\n",
2619         compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2620     sprintf(buffer,
2621             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2622             "%s\n"
2623             "int main(int argc,char *argv[]){\n"
2624             "%s\n"
2625             "printf(\"%%d\\n\",\n"
2626             "       os_isnan(exp(floatNanValue1)) &&\n"
2627             "       os_isnan(exp(doubleNanValue1)));\n"
2628             "return 0;}\n",
2629             os_isnan_definition, computeValues);
2630     fprintf(versionFile, "#define EXP_OF_NAN_OKAY %d\n",
2631         compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2632     sprintf(buffer,
2633             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2634             "%s\n"
2635             "int main(int argc,char *argv[]){\n"
2636             "%s\n"
2637             "printf(\"%%d\\n\",\n"
2638             "       os_isnan(ldexp(doubleNanValue1, -1000)) &&\n"
2639             "       os_isnan(ldexp(doubleNanValue1,  0)) &&\n"
2640             "       os_isnan(ldexp(doubleNanValue1, 1000)));\n"
2641             "return 0;}\n",
2642             os_isnan_definition, computeValues);
2643     fprintf(versionFile, "#define LDEXP_OF_NAN_OKAY %d\n",
2644         compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2645     sprintf(buffer,
2646             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2647             "%s\n"
2648             "int main(int argc,char *argv[]){\n"
2649             "int exponent1 = 999999;\n"
2650             "int exponent2 = 999999;\n"
2651             "int exponent3 = 999999;\n"
2652             "int exponent4 = 999999;\n"
2653             "int exponent5 = 999999;\n"
2654             "int exponent6 = 999999;\n"
2655             "int frexp_okay = 1;\n"
2656             "%s\n"
2657             "if (frexp(floatMinusInf,  &exponent1) != doubleMinusInf ||\n"
2658             "    frexp(doubleMinusInf, &exponent2) != doubleMinusInf ||\n"
2659             "    frexp(floatPlusInf,   &exponent3) != doublePlusInf  ||\n"
2660             "    frexp(doublePlusInf,  &exponent4) != doublePlusInf  ||\n"
2661             "    !os_isnan(frexp(floatNanValue1,  &exponent5)) ||\n"
2662             "    !os_isnan(frexp(doubleNanValue1, &exponent6))) {\n"
2663             "  frexp_okay = 0;\n"
2664             "}\n"
2665             "if (exponent1 != 0 || exponent2 != 0 ||\n"
2666             "    exponent3 != 0 || exponent4 != 0 ||\n"
2667             "    exponent5 != 0 || exponent6 != 0) {\n"
2668             "  frexp_okay = 0;\n"
2669             "}\n"
2670             "printf(\"%%d\\n\", frexp_okay);\n"
2671             "return 0;}\n",
2672             os_isnan_definition, computeValues);
2673     fprintf(versionFile, "#define FREXP_INFINITY_NAN_OKAY %d\n",
2674             compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) ? doTest() : 0);
2675     sprintf(buffer,
2676             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2677             "int main(int argc,char *argv[]){\n"
2678             "int exponent1 = 999999;\n"
2679             "int exponent2 = 999999;\n"
2680             "int frexp_okay = 1;\n"
2681             "if (frexp(5.0e-324,                &exponent1) != 0.5 ||\n"
2682             "    frexp(2.2250738585072009e-308, &exponent2) != 0.9999999999999998) {\n"
2683             "  frexp_okay = 0;\n"
2684             "}\n"
2685             "if (exponent1 != -1073 || exponent2 != -1022) {\n"
2686             "  frexp_okay = 0;\n"
2687             "}\n"
2688             "printf(\"%%d\\n\", frexp_okay);\n"
2689             "return 0;}\n");
2690     fprintf(versionFile, "#define FREXP_SUBNORMAL_OKAY %d\n",
2691             compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) ? doTest() : 0);
2692     sprintf(buffer,
2693             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2694             "%s\n"
2695             "int main(int argc,char *argv[]){\n"
2696             "%s\n"
2697             "printf(\"%%d\\n\",\n"
2698             "       os_isnan(fmod(doubleNanValue1, -13.25)) &&\n"
2699             "       os_isnan(fmod(doubleNanValue1, 13.25)) &&\n"
2700             "       os_isnan(fmod(doubleNanValue1, doubleMinusInf)) &&\n"
2701             "       os_isnan(fmod(doubleNanValue1, doublePlusInf)) &&\n"
2702             "       os_isnan(fmod(doubleNanValue1, doubleNanValue1)));\n"
2703             "return 0;}\n",
2704             os_isnan_definition, computeValues);
2705     fprintf(versionFile, "#define FMOD_DIVIDEND_NAN_OKAY %d\n",
2706         compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2707     sprintf(buffer,
2708             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2709             "%s\n"
2710             "int main(int argc,char *argv[]){\n"
2711             "%s\n"
2712             "printf(\"%%d\\n\",\n"
2713             "       os_isnan(fmod(-31.125, doubleNanValue1)) &&\n"
2714             "       os_isnan(fmod(31.125, doubleNanValue1)) &&\n"
2715             "       os_isnan(fmod(doubleMinusInf, doubleNanValue1)) &&\n"
2716             "       os_isnan(fmod(doublePlusInf, doubleNanValue1)) &&\n"
2717             "       os_isnan(fmod(doubleNanValue1, doubleNanValue1)));\n"
2718             "return 0;}\n",
2719             os_isnan_definition, computeValues);
2720     fprintf(versionFile, "#define FMOD_DIVISOR_NAN_OKAY %d\n",
2721         compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2722     sprintf(buffer,
2723             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2724             "%s\n"
2725             "int main(int argc,char *argv[]){\n"
2726             "%s\n"
2727             "printf(\"%%d\\n\",\n"
2728             "       os_isnan(fmod(doubleMinusInf, -13.25)) &&\n"
2729             "       os_isnan(fmod(doublePlusInf, -13.25)) &&\n"
2730             "       os_isnan(fmod(doubleMinusInf, 13.25)) &&\n"
2731             "       os_isnan(fmod(doublePlusInf, 13.25)) &&\n"
2732             "       os_isnan(fmod(doubleMinusInf, doubleMinusInf)) &&\n"
2733             "       os_isnan(fmod(doubleMinusInf, doublePlusInf)) &&\n"
2734             "       os_isnan(fmod(doublePlusInf, doubleMinusInf)) &&\n"
2735             "       os_isnan(fmod(doublePlusInf, doublePlusInf)));\n"
2736             "return 0;}\n",
2737             os_isnan_definition, computeValues);
2738     fprintf(versionFile, "#define FMOD_DIVIDEND_INFINITY_OKAY %d\n",
2739         compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2740     sprintf(buffer,
2741             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2742             "%s\n"
2743             "int main(int argc,char *argv[]){\n"
2744             "%s\n"
2745             "printf(\"%%d\\n\",\n"
2746             "       fmod(-31.125, doubleMinusInf) == -31.125 &&\n"
2747             "       fmod(-31.125, doublePlusInf) == -31.125 &&\n"
2748             "       fmod(31.125, doubleMinusInf) == 31.125 &&\n"
2749             "       fmod(31.125, doublePlusInf) == 31.125 &&\n"
2750             "       os_isnan(fmod(doubleMinusInf, doubleMinusInf)) &&\n"
2751             "       os_isnan(fmod(doubleMinusInf, doublePlusInf)) &&\n"
2752             "       os_isnan(fmod(doublePlusInf, doubleMinusInf)) &&\n"
2753             "       os_isnan(fmod(doublePlusInf, doublePlusInf)));\n"
2754             "return 0;}\n",
2755             os_isnan_definition, computeValues);
2756     fprintf(versionFile, "#define FMOD_DIVISOR_INFINITY_OKAY %d\n",
2757         compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2758     sprintf(buffer,
2759             "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2760             "%s\n"
2761             "int main(int argc,char *argv[]){\n"
2762             "%s\n"
2763             "printf(\"%%d\\n\",\n"
2764             "       os_isnan(fmod(-31.125, 0.0)) &&\n"
2765             "       os_isnan(fmod(0.0, 0.0)) &&\n"
2766             "       os_isnan(fmod(31.125, 0.0)) &&\n"
2767             "       os_isnan(fmod(doubleMinusInf, 0.0)) &&\n"
2768             "       os_isnan(fmod(doublePlusInf, 0.0)));\n"
2769             "return 0;}\n",
2770             os_isnan_definition, computeValues);
2771     fprintf(versionFile, "#define FMOD_DIVISOR_ZERO_OKAY %d\n",
2772         compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS) && doTest() == 1);
2773     sprintf(buffer,
2774             "#include<stdio.h>\n#include<string.h>\n"
2775             "#include<float.h>\n#include<math.h>\n"
2776             "%s\n"
2777             "int doubleCompare (double num1, double num2){\n"
2778             "return memcmp(&num1, &num2, sizeof(double));}\n"
2779             "double getMaxOddFloat(int exponent){\n"
2780             "double base = (double) FLT_RADIX;\n"
2781             "double power;\n"
2782             "for (power=1.0; exponent>0; exponent--) power*=base;\n"
2783             "if ((FLT_RADIX & 1) == 0) power = floor(power-1.0);\n"
2784             "return power;}\n"
2785             "int main(int argc,char *argv[]){\n"
2786             "float floatOne = 1.0;\n"
2787             "float floatTwo = 2.0;\n"
2788             "double doubleOne = 1.0;\n"
2789             "double doubleTwo = 2.0;\n"
2790             "double doubleMinusOne = -1.0;\n"
2791             "double doubleMinusTwo = 2.0;\n"
2792             "%s"
2793             "printf(\"#define FLOAT_ZERO_TIMES_INFINITE_OKAY %%d\\n\",\n"
2794             "    0.0 * floatPlusInf != floatNanValue1 ||\n"
2795             "    0.0 * floatMinusInf != floatNanValue1 ||\n"
2796             "    floatPlusInf * 0.0 != floatNanValue1 ||\n"
2797             "    floatMinusInf * 0.0 != floatNanValue1 ||\n"
2798             "    0.0 * doublePlusInf != doubleNanValue1 ||\n"
2799             "    0.0 * doubleMinusInf != doubleNanValue1 ||\n"
2800             "    doublePlusInf * 0.0 != doubleNanValue1 ||\n"
2801             "    doubleMinusInf * 0.0 != doubleNanValue1);\n"
2802             "printf(\"#define NAN_MULTIPLICATION_OKAY %%d\\n\",\n"
2803             "    os_isnan(floatNanValue1 * 1.0) &&\n"
2804             "    os_isnan(floatNanValue1 * floatOne) &&\n"
2805             "    os_isnan(1.0 * floatNanValue1) &&\n"
2806             "    os_isnan(floatOne * floatNanValue1) &&\n"
2807             "    os_isnan(floatNanValue1 * floatNanValue2) &&\n"
2808             "    os_isnan(doubleNanValue1 * 1.0) &&\n"
2809             "    os_isnan(doubleNanValue1 * doubleOne) &&\n"
2810             "    os_isnan(1.0 * doubleNanValue1) &&\n"
2811             "    os_isnan(doubleOne * doubleNanValue1) &&\n"
2812             "    os_isnan(doubleNanValue1 * doubleNanValue2));\n"
2813             "printf(\"#define NAN_DIVISION_OKAY %%d\\n\",\n"
2814             "    os_isnan(floatNanValue1 / 1.0) &&\n"
2815             "    os_isnan(floatNanValue1 / floatOne) &&\n"
2816             "    os_isnan(1.0 / floatNanValue1) &&\n"
2817             "    os_isnan(floatOne / floatNanValue1) &&\n"
2818             "    os_isnan(floatMinusInf / floatNanValue1) &&\n"
2819             "    os_isnan(floatPlusInf / floatNanValue1) &&\n"
2820             "    os_isnan(floatNanValue1 / floatNanValue2) &&\n"
2821             "    os_isnan(doubleNanValue1 / 1.0) &&\n"
2822             "    os_isnan(doubleNanValue1 / doubleOne) &&\n"
2823             "    os_isnan(1.0 / doubleNanValue1) &&\n"
2824             "    os_isnan(doubleOne / doubleNanValue1) &&\n"
2825             "    os_isnan(doubleMinusInf / doubleNanValue1) &&\n"
2826             "    os_isnan(doublePlusInf / doubleNanValue1) &&\n"
2827             "    os_isnan(doubleNanValue1 / doubleNanValue2));\n"
2828             "printf(\"#define MAX_ODD_FLOAT %%0.1f\\n\", getMaxOddFloat(FLT_MANT_DIG));\n"
2829             "printf(\"#define MAX_ODD_DOUBLE %%0.1f\\n\", getMaxOddFloat(DBL_MANT_DIG));\n"
2830             "printf(\"#define POW_OF_NAN_OKAY %%d\\n\",\n"
2831             "    os_isnan(pow(floatNanValue1, floatMinusInf)) &&\n"
2832             "    os_isnan(pow(floatNanValue1, -1.0E37)) &&\n"
2833             "    os_isnan(pow(floatNanValue1, -1.0)) &&\n"
2834             "    os_isnan(pow(floatNanValue1, -0.5)) &&\n"
2835             "    pow(floatNanValue1, 0.0) == 1.0 &&\n"
2836             "    pow(floatNanValue1, floatZero) == 1.0 &&\n"
2837             "    os_isnan(pow(floatNanValue1, 0.5)) &&\n"
2838             "    os_isnan(pow(floatNanValue1, 1.0)) &&\n"
2839             "    os_isnan(pow(floatNanValue1, 1.0E37)) &&\n"
2840             "    os_isnan(pow(floatNanValue1, floatPlusInf)) &&\n"
2841             "    os_isnan(pow(doubleNanValue1, doubleMinusInf)) &&\n"
2842             "    os_isnan(pow(doubleNanValue1, -1.0E37)) &&\n"
2843             "    os_isnan(pow(doubleNanValue1, -1.0)) &&\n"
2844             "    os_isnan(pow(doubleNanValue1, -0.5)) &&\n"
2845             "    pow(doubleNanValue1, 0.0) == 1.0 &&\n"
2846             "    pow(doubleNanValue1, doubleZero) == 1.0 &&\n"
2847             "    os_isnan(pow(doubleNanValue1, 0.5)) &&\n"
2848             "    os_isnan(pow(doubleNanValue1, 1.0)) &&\n"
2849             "    os_isnan(pow(doubleNanValue1, 1.0E37)) &&\n"
2850             "    os_isnan(pow(doubleNanValue1, doublePlusInf)));\n"
2851             "printf(\"#define POW_OF_ZERO_OKAY %%d\\n\",\n"
2852             "    pow(floatZero, -1.0) == floatPlusInf &&\n"
2853             "    pow(floatZero, -2.0) == floatPlusInf &&\n"
2854             "    pow(floatNegativeZero, -1.0) == floatMinusInf &&\n"
2855             "    pow(floatNegativeZero, -2.0) == floatPlusInf &&\n"
2856             "    pow(floatNegativeZero, -getMaxOddFloat(FLT_MANT_DIG)) == floatMinusInf &&\n"
2857             "    pow(doubleZero, -1.0) == doublePlusInf &&\n"
2858             "    pow(doubleZero, -2.0) == doublePlusInf &&\n"
2859             "    pow(doubleZero, doubleMinusOne) == doublePlusInf &&\n"
2860             "    pow(doubleZero, doubleMinusTwo) == doublePlusInf &&\n"
2861             "    pow(doubleNegativeZero, -1.0) == doubleMinusInf &&\n"
2862             "    pow(doubleNegativeZero, -2.0) == doublePlusInf &&\n"
2863             "    pow(doubleNegativeZero, -getMaxOddFloat(DBL_MANT_DIG)) == doubleMinusInf);\n"
2864             "printf(\"#define POW_OF_NEGATIVE_OKAY %%d\\n\",\n"
2865             "    os_isnan(pow(-2.0, -1.5)) &&\n"
2866             "    os_isnan(pow(-1.5, -0.5)) &&\n"
2867             "    os_isnan(pow(-1.0, 0.5)) &&\n"
2868             "    os_isnan(pow(-0.5, 1.5)));\n"
2869             "printf(\"#define POW_OF_ONE_OKAY %%d\\n\",\n"
2870             "    pow(1.0, floatNanValue1) == 1.0 &&\n"
2871             "    pow(1.0, doubleNanValue1) == 1.0 &&\n"
2872             "    pow(floatOne, floatNanValue1) == 1.0 &&\n"
2873             "    pow(doubleOne, doubleNanValue1) == 1.0);\n"
2874             "printf(\"#define POW_EXP_NAN_OKAY %%d\\n\",\n"
2875             "    os_isnan(pow(doubleMinusInf, doubleNanValue1)) &&\n"
2876             "    os_isnan(pow(-1.0, doubleNanValue1)) &&\n"
2877             "    os_isnan(pow(0.0, doubleNanValue1)) &&\n"
2878             "    os_isnan(pow(doubleZero, doubleNanValue1)) &&\n"
2879             "    os_isnan(pow(2.0, doubleNanValue1)) &&\n"
2880             "    os_isnan(pow(doubleTwo, doubleNanValue1)) &&\n"
2881             "    os_isnan(pow(10.0, doubleNanValue1)) &&\n"
2882             "    os_isnan(pow(doublePlusInf, doubleNanValue1)));\n"
2883             "printf(\"#define POW_EXP_MINUS_INFINITY_OKAY %%d\\n\",\n"
2884             "    pow(2.0, floatMinusInf) == 0.0 &&\n"
2885             "    pow(floatTwo, floatMinusInf) == 0.0 &&\n"
2886             "    pow(0.9, floatMinusInf) == floatPlusInf &&\n"
2887             "    pow(2.0, doubleMinusInf) == 0.0 &&\n"
2888             "    pow(doubleTwo, doubleMinusInf) == 0.0 &&\n"
2889             "    pow(0.9, doubleMinusInf) == doublePlusInf);\n"
2890             "printf(\"#define POW_UNDERFLOW_WITH_SIGN %%d\\n\",\n"
2891             "    doubleCompare(pow(-2.0, -2147483649.0), doubleNegativeZero) == 0 &&\n"
2892             "    doubleCompare(pow(-doubleTwo, -2147483649.0), doubleNegativeZero) == 0);\n"
2893             "printf(\"#define LOG_OF_NAN_OKAY %%d\\n\",\n"
2894             "    os_isnan(log(floatNanValue1)) &&\n"
2895             "    os_isnan(log(doubleNanValue1)));\n"
2896             "printf(\"#define LOG_OF_ZERO_OKAY %%d\\n\",\n"
2897             "    log(floatZero) == floatMinusInf &&\n"
2898             "    log(floatNegativeZero) == floatMinusInf &&\n"
2899             "    log(doubleZero) == doubleMinusInf &&\n"
2900             "    log(doubleNegativeZero) == doubleMinusInf);\n"
2901             "printf(\"#define LOG_OF_NEGATIVE_OKAY %%d\\n\",\n"
2902             "    os_isnan(log(floatMinusInf)) &&\n"
2903             "    os_isnan(log(doubleMinusInf)) &&\n"
2904             "    os_isnan(log(-1.0)));\n"
2905             "printf(\"#define LOG10_OF_NAN_OKAY %%d\\n\",\n"
2906             "    os_isnan(log10(floatNanValue1)) &&\n"
2907             "    os_isnan(log10(doubleNanValue1)));\n"
2908             "printf(\"#define LOG10_OF_ZERO_OKAY %%d\\n\",\n"
2909             "    log10(floatZero) == floatMinusInf &&\n"
2910             "    log10(floatNegativeZero) == floatMinusInf &&\n"
2911             "    log10(doubleZero) == doubleMinusInf &&\n"
2912             "    log10(doubleNegativeZero) == doubleMinusInf);\n"
2913             "printf(\"#define LOG10_OF_NEGATIVE_OKAY %%d\\n\",\n"
2914             "    os_isnan(log10(floatMinusInf)) &&\n"
2915             "    os_isnan(log10(doubleMinusInf)) &&\n"
2916             "    os_isnan(log10(-1.0)));\n"
2917             "#if %d\n"
2918             "printf(\"#define LOG2_OF_NAN_OKAY %%d\\n\",\n"
2919             "    os_isnan(log2(floatNanValue1)) &&\n"
2920             "    os_isnan(log2(doubleNanValue1)));\n"
2921             "printf(\"#define LOG2_OF_ZERO_OKAY %%d\\n\",\n"
2922             "    log2(floatZero) == floatMinusInf &&\n"
2923             "    log2(floatNegativeZero) == floatMinusInf &&\n"
2924             "    log2(doubleZero) == doubleMinusInf &&\n"
2925             "    log2(doubleNegativeZero) == doubleMinusInf);\n"
2926             "printf(\"#define LOG2_OF_NEGATIVE_OKAY %%d\\n\",\n"
2927             "    os_isnan(log2(floatMinusInf)) &&\n"
2928             "    os_isnan(log2(doubleMinusInf)) &&\n"
2929             "    os_isnan(log2(-1.0)));\n"
2930             "#else\n"
2931             "fputs(\"#define LOG2_OF_NAN_OKAY 0\\n\", stdout);\n"
2932             "fputs(\"#define LOG2_OF_ZERO_OKAY 0\\n\", stdout);\n"
2933             "fputs(\"#define LOG2_OF_NEGATIVE_OKAY 0\\n\", stdout);\n"
2934             "#endif\n"
2935             "{ char buffer[1024]; sprintf(buffer, \"%%1.1f\", floatNegativeZero);\n"
2936             "printf(\"#define PRINTS_NEGATIVE_ZERO %%d\\n\", buffer[0] == '-'); }\n"
2937             "return 0;}\n", os_isnan_definition, computeValues, has_log2);
2938     if (assertCompAndLnkWithOptions(buffer, "", SYSTEM_LIBS " " SYSTEM_MATH_LIBS)) {
2939       testOutputToVersionFile(versionFile);
2940     } /* if */
2941     if (compileAndLinkOk("#include<float.h>\n#include<math.h>\nint main(int argc,char *argv[])"
2942                           "{float f=0.0; isinf(f); return 0;}\n")) {
2943       fputs("#define os_isinf isinf\n", versionFile);
2944     } else {
2945       if (compileAndLinkOk("#include<float.h>\n#include<math.h>\nint main(int argc,char *argv[])"
2946                            "{float f=0.0; _isinf(f); return 0;}\n")) {
2947         fputs("#define os_isinf _isinf\n", versionFile);
2948       } else {
2949         sprintf(buffer,
2950                 "#include<stdio.h>\n#include<float.h>\n#include<math.h>\n"
2951                 "int main(int argc,char *argv[]){\n"
2952                 "%s"
2953                 "printf(\"%%d\\n\", fabs(floatPlusInf) > DBL_MAX && fabs(floatMinusInf) > DBL_MAX);\n"
2954                 "return 0;}\n", computeValues);
2955         if (assertCompAndLnk(buffer)) {
2956           if (doTest() == 1) {
2957             fputs("#define os_isinf(x) (fabs(x) > DBL_MAX)\n", versionFile);
2958           } /* if */
2959         } /* if */
2960       } /* if */
2961     } /* if */
2962     if (compileAndLinkOk("#include<stdlib.h>\n#include<stdio.h>\n#include<float.h>\n#include<signal.h>\n"
2963                          "void handleSig(int sig){puts(\"2\");exit(0);}\n"
2964                          "int main(int argc,char *argv[]){\n"
2965 #ifdef TURN_OFF_FP_EXCEPTIONS
2966                          "_control87(MCW_EM, MCW_EM);\n"
2967 #endif
2968                          "signal(SIGFPE,handleSig);\nsignal(SIGILL,handleSig);\n"
2969                          "signal(SIGINT,handleSig);\n"
2970                          "printf(\"%d\\n\",(int) 1.0E37);return 0;}\n")) {
2971       testResult = doTest();
2972       if ((sizeof(int) == 4 && (long) testResult == 2147483647L) ||
2973           (sizeof(int) == 2 && testResult == 32767)) {
2974         fputs("#define FLOAT_TO_INT_OVERFLOW_SATURATES\n", versionFile);
2975       } else if (testResult == 2) {
2976         fputs("#define FLOAT_TO_INT_OVERFLOW_SIGNALS\n", versionFile);
2977       } else if (testResult == 0) {
2978         fputs("#define FLOAT_TO_INT_OVERFLOW_ZERO\n", versionFile);
2979       } else {
2980         fprintf(versionFile, "#define FLOAT_TO_INT_OVERFLOW_GARBAGE %d\n", testResult);
2981       } /* if */
2982     } /* if */
2983     strcpy(buffer,
2984            "#include<stdio.h>\n#include<float.h>\n"
2985            "double dblPower(double base, int exponent){\n"
2986            "double power;\n"
2987            "for(power=1.0;exponent>0;exponent--)power*=base;\n"
2988            "return power;}\n"
2989            "int main(int argc,char *argv[]){\n"
2990            "int floatRadixFactor;\n"
2991            "double power;\n");
2992     defineTransferUnions(buffer);
2993     strcat(buffer,
2994 #ifdef TURN_OFF_FP_EXCEPTIONS
2995            "_control87(MCW_EM, MCW_EM);\n"
2996 #endif
2997            "if (FLT_RADIX == 2) floatRadixFactor = 1;\n"
2998            "else if (FLT_RADIX == 4) floatRadixFactor = 2;\n"
2999            "else if (FLT_RADIX == 8) floatRadixFactor = 3;\n"
3000            "else if (FLT_RADIX == 16) floatRadixFactor = 4;\n"
3001            "power = dblPower((double) FLT_RADIX, FLT_MANT_DIG);\n"
3002            "printf(\"#define INT_RANGE_IN_FLOAT_MAX %0.0f\\n\", power);\n"
3003            "printf(\"#define FLOAT_MANTISSA_FACTOR %0.1f\\n\", power);\n"
3004            "printf(\"#define FLOAT_MANTISSA_SHIFT %u\\n\", "
3005                    "FLT_MANT_DIG * floatRadixFactor);\n"
3006            "fltTransfer.f = 1.0;\n"
3007            "printf(\"#define FLOAT_EXPONENT_OFFSET %d\\n\", "
3008                    "fltTransfer.i >> (FLT_MANT_DIG * floatRadixFactor - 1));\n"
3009            "power = dblPower((double) FLT_RADIX, DBL_MANT_DIG);\n"
3010            "printf(\"#define INT_RANGE_IN_DOUBLE_MAX %0.0f\\n\", power);\n"
3011            "printf(\"#define DOUBLE_MANTISSA_FACTOR %0.1f\\n\", power);\n"
3012            "printf(\"#define DOUBLE_MANTISSA_SHIFT %u\\n\", "
3013                    "DBL_MANT_DIG * floatRadixFactor);\n"
3014            "dblTransfer.f = 1.0;\n"
3015            "printf(\"#define DOUBLE_EXPONENT_OFFSET %d\\n\", "
3016                    "dblTransfer.i >> (DBL_MANT_DIG * floatRadixFactor - 1));\n"
3017            "return 0;}\n");
3018     if (assertCompAndLnk(buffer)) {
3019       testOutputToVersionFile(versionFile);
3020     } /* if */
3021     sprintf(buffer,
3022             "#include<stdio.h>\n#include<float.h>\n"
3023             "typedef %s int64Type;\n"
3024             "double minFltValues[] = { -9223372036854773760.0,\n"
3025             "  -9223372036854774784.0, -9223372036854775808.0 };\n"
3026             "double maxFltValues[] = { 9223372036854773760.0,\n"
3027             "   9223372036854774784.0, 9223372036854775808.0 };\n"
3028             "int64Type minIntValues[] = { -9223372036854773760,\n"
3029             "  -9223372036854774784, -9223372036854775807-1 };\n"
3030             "int64Type maxIntValues[] = { 9223372036854773760,\n"
3031             "   9223372036854774784, 9223372036854775807 };\n"
3032             "int main(int argc,char *argv[]){\n"
3033             "int64Type minimumTruncArgument;\n"
3034             "int64Type maximumTruncArgument;\n"
3035             "int pos;\n"
3036 #ifdef TURN_OFF_FP_EXCEPTIONS
3037             "_control87(MCW_EM, MCW_EM);\n"
3038 #endif
3039             "for (pos = 0; pos < 3; pos++) {\n"
3040             "  if ((int64Type) minFltValues[pos] == minIntValues[pos]) {\n"
3041             "    minimumTruncArgument = minIntValues[pos];\n"
3042             "  }\n"
3043             "}\n"
3044             "printf(\"#define MINIMUM_TRUNC_ARGUMENT %%%sd\\n\",\n"
3045             "       minimumTruncArgument);\n"
3046             "for (pos = 0; pos < 3; pos++) {\n"
3047             "  if ((int64Type) maxFltValues[pos] == maxIntValues[pos]) {\n"
3048             "    maximumTruncArgument = maxIntValues[pos];\n"
3049             "  }\n"
3050             "}\n"
3051             "printf(\"#define MAXIMUM_TRUNC_ARGUMENT %%%sd\\n\",\n"
3052             "       maximumTruncArgument);\n"
3053             "return 0;}\n",
3054             int64TypeStri, int64TypeFormat, int64TypeFormat);
3055     if (assertCompAndLnk(buffer)) {
3056       testOutputToVersionFile(versionFile);
3057     } /* if */
3058     if (assertCompAndLnk("#include<stdio.h>\n#include<string.h>\n"
3059                          "int main(int argc,char *argv[]){\n"
3060                          "char buffer[100010];\n"
3061                          "sprintf(buffer, \"%1.100000e\", 1.0);\n"
3062                          "printf(\"%lu\\n\", (unsigned long) (strchr(buffer, 'e') - buffer));\n"
3063                          "return 0;}\n")) {
3064       testResult = doTest();
3065       if (testResult == -1) {
3066         /* The test program crashed. Assume a low precision limit. */
3067         testResult = 102;
3068         fputs("#define LIMIT_FMT_E_MAXIMUM_FLOAT_PRECISION \"100\"\n", versionFile);
3069       } /* if */
3070       if (testResult >= 2 && testResult < 100002) {
3071         testResult -= 2;
3072 #ifdef PRINTF_MAXIMUM_FLOAT_PRECISION
3073         fprintf(versionFile, "/* PRINTF_FMT_E_MAXIMUM_FLOAT_PRECISION %d */\n", testResult);
3074         testResult = PRINTF_MAXIMUM_FLOAT_PRECISION;
3075 #endif
3076         fprintf(versionFile, "#define PRINTF_FMT_E_MAXIMUM_FLOAT_PRECISION %d\n", testResult);
3077       } /* if */
3078     } /* if */
3079     if (assertCompAndLnk("#include<stdio.h>\n#include<string.h>\n"
3080                          "int main(int argc,char *argv[]){\n"
3081                          "char buffer[100010];\n"
3082                          "sprintf(buffer, \"%1.100000f\", 1.0);\n"
3083                          "printf(\"%lu\\n\", (unsigned long) strlen(buffer));\n"
3084                          "return 0;}\n")) {
3085       testResult = doTest();
3086       if (testResult == -1) {
3087         /* The test program crashed. Assume a low precision limit. */
3088         testResult = 102;
3089         fputs("#define LIMIT_FMT_F_MAXIMUM_FLOAT_PRECISION \"100\"\n", versionFile);
3090       } /* if */
3091       if (testResult >= 2 && testResult < 100002) {
3092         testResult -= 2;
3093 #ifdef PRINTF_MAXIMUM_FLOAT_PRECISION
3094         fprintf(versionFile, "/* PRINTF_FMT_F_MAXIMUM_FLOAT_PRECISION %d */\n", testResult);
3095         testResult = PRINTF_MAXIMUM_FLOAT_PRECISION;
3096 #endif
3097         fprintf(versionFile, "#define PRINTF_FMT_F_MAXIMUM_FLOAT_PRECISION %d\n", testResult);
3098       } /* if */
3099     } /* if */
3100     if (assertCompAndLnk("#include<stdio.h>\n#include<stdlib.h>\n"
3101                          "int main(int argc,char *argv[]){\n"
3102                          "printf(\"%d\\n\", strtod(\"0x123\", NULL) != 0.0);\n"
3103                          "return 0;}\n")) {
3104       fprintf(versionFile, "#define STRTOD_ACCEPTS_HEX_NUMBERS %d\n", doTest());
3105     } /* if */
3106     if (assertCompAndLnk("#include<stdio.h>\n#include<stdlib.h>\n"
3107                          "int main(int argc,char *argv[]){\n"
3108                          "printf(\"%d\\n\", atof(\"0x123\") != 0.0);\n"
3109                          "return 0;}\n")) {
3110       fprintf(versionFile, "#define ATOF_ACCEPTS_HEX_NUMBERS %d\n", doTest());
3111     } /* if */
3112     if (assertCompAndLnk("#include<stdio.h>\n#include<stdlib.h>\n#include <float.h>\n"
3113                          "int main(int argc,char *argv[]){\n"
3114                          "double num = DBL_MIN; char buffer[1024];\n"
3115                          "sprintf(buffer, \"%1.20e\", num / 2.0);\n"
3116                          "printf(\"%d\\n\", strtod(buffer, NULL) != 0.0);\n"
3117                          "return 0;}\n")) {
3118       fprintf(versionFile, "#define STRTOD_ACCEPTS_DENORMAL_NUMBERS %d\n", doTest());
3119     } /* if */
3120     if (assertCompAndLnk("#include<stdio.h>\n#include<stdlib.h>\n#include <float.h>\n"
3121                          "int main(int argc,char *argv[]){\n"
3122                          "double num = DBL_MIN; char buffer[1024];\n"
3123                          "sprintf(buffer, \"%1.20e\", num / 2.0);\n"
3124                          "printf(\"%d\\n\", atof(buffer) != 0.0);\n"
3125                          "return 0;}\n")) {
3126       fprintf(versionFile, "#define ATOF_ACCEPTS_DENORMAL_NUMBERS %d\n", doTest());
3127     } /* if */
3128     fprintf(logFile, " determined\n");
3129   } /* numericProperties */
3130 
3131 
3132 
determineMallocProperties(FILE * versionFile)3133 static void determineMallocProperties (FILE *versionFile)
3134 
3135   {
3136     int alignment = -1;
3137     int mallocOf0ReturnsNull = -1;
3138 
3139   /* determineMallocProperties */
3140     if (compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
3141                          "static const int alignmentTable[] = {\n"
3142                          "    6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n"
3143                          "    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n"
3144                          "    5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n"
3145                          "    4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,\n"
3146                          "  };\n"
3147                          "int main(int argc, char *argv[])"
3148                          "{\n"
3149                          "  int count;\n"
3150                          "  unsigned long malloc_result;\n"
3151                          "  int alignment;\n"
3152                          "  int minAlignment = 7;\n"
3153                          "  for (count = 1; count <= 64; count++) {\n"
3154                          "    malloc_result = (unsigned long) (size_t) malloc(count);\n"
3155                          "    alignment = alignmentTable[malloc_result & 0x3f];\n"
3156                          "    if (alignment < minAlignment) {\n"
3157                          "      minAlignment = alignment;\n"
3158                          "    }\n"
3159                          "  }\n"
3160                          "  printf(\"%d\\n\", minAlignment);\n"
3161                          "  return 0;"
3162                          "}\n")) {
3163       alignment = doTest();
3164     } /* if */
3165     if (alignment == -1) {
3166       fprintf(logFile, "\n *** Unable to determine malloc alignment.\n");
3167     } else {
3168       fprintf(versionFile, "#define MALLOC_ALIGNMENT %d\n", alignment);
3169     } /* if */
3170     if (compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
3171                          "int main(int argc, char *argv[])"
3172                          "{\n"
3173                          "  void *malloc_result;\n"
3174                          "  malloc_result = malloc(0);\n"
3175                          "  printf(\"%d\\n\", malloc_result == NULL);\n"
3176                          "  return 0;"
3177                          "}\n")) {
3178       mallocOf0ReturnsNull = doTest();
3179     } /* if */
3180     if (mallocOf0ReturnsNull == -1) {
3181       fprintf(logFile, "\n *** Unable to determine result of malloc(0).\n");
3182     } else {
3183       fprintf(versionFile, "#define MALLOC_OF_0_RETURNS_NULL %d\n", mallocOf0ReturnsNull);
3184     } /* if */
3185   } /* determineMallocProperties */
3186 
3187 
3188 
checkForLimitedStringLiteralLength(FILE * versionFile)3189 static void checkForLimitedStringLiteralLength (FILE *versionFile)
3190 
3191   {
3192     const char *programStart = "#include <stdio.h>\n#include <string.h>\n"
3193                                "int main(int argc, char *argv[]) {\n"
3194                                "char ch = '1';\n"
3195                                "char *chPtr;\n"
3196                                "char *stri =\n";
3197     const char *line = "\"12345678901234567890123456789012345678901234567890"
3198                        "12345678901234567890123456789012345678901234567890\"\n";
3199     const char *programEnd = ";\n"
3200                              "for (chPtr = stri; *chPtr != '\\0'; chPtr++) {\n"
3201                              "  if (*chPtr != ch) {\n"
3202                              "    printf(\"%u\\n\", (unsigned int) (chPtr - stri));\n"
3203                              "    return 0;\n"
3204                              "  }\n"
3205                              "  ch = ch == '9' ? '0' : ch + 1;\n"
3206                              "}\n"
3207                              "printf(\"%u\\n\", strlen(stri));\n"
3208                              "return 0;\n"
3209                              "}\n";
3210     /* The string literal length is repeatCount * charsInLine. */
3211     /* The definitions below correspond to a string literal length of 100000. */
3212     const int repeatCount = 1000;
3213     const int charsInLine = 100;
3214     int lineLength;
3215     int totalLength;
3216     int count;
3217     char *buffer;
3218     char *bufPos;
3219     int testResult;
3220 
3221   /* checkForLimitedStringLiteralLength */
3222 #ifndef LIMITED_CSTRI_LITERAL_LEN
3223     lineLength = strlen(line);
3224     totalLength = strlen(programStart) + lineLength * repeatCount + strlen(programEnd);
3225     buffer = (char *) malloc((totalLength + 1) * sizeof(char));
3226     strcpy(buffer, programStart);
3227     bufPos = &buffer[strlen(buffer)];
3228     for (count = 1; count <= repeatCount; count++) {
3229       strcpy(bufPos, line);
3230       bufPos += lineLength;
3231     } /* for */
3232     strcpy(bufPos, programEnd);
3233     /* printf("\n%s\n", buffer); */
3234     /* Some C compilers limit the maximum string literal length.   */
3235     /* There are limits of 2,048 bytes and 16,384 (16K) bytes.     */
3236     /* Some C compilers accept long string literals, but at        */
3237     /* run-time the string does not contain the correct data.      */
3238     /* If LIMITED_CSTRI_LITERAL_LEN is 0 a string literal with     */
3239     /* repeatCount * charsInLine characters is accepted and works. */
3240     if (compileAndLinkOk(buffer)) {
3241       testResult = doTest();
3242       if (testResult == repeatCount * charsInLine) {
3243         /* At run-time the string literal has the correct value. */
3244         fputs("#define LIMITED_CSTRI_LITERAL_LEN 0\n", versionFile);
3245       } else if (testResult != 0 ) {
3246         /* At run-time the string literal is correct up to a position. */
3247         fprintf(versionFile, "#define LIMITED_CSTRI_LITERAL_LEN %d\n",
3248                 testResult);
3249       } else {
3250         /* At run-time the whole string literal is wrong. */
3251         fputs("#define LIMITED_CSTRI_LITERAL_LEN -2\n", versionFile);
3252       } /* if */
3253     } else {
3254       /* If the compiler prohibits long string literals. */
3255       fputs("#define LIMITED_CSTRI_LITERAL_LEN -1\n", versionFile);
3256     } /* if */
3257     free(buffer);
3258 #endif
3259   } /* checkForLimitedStringLiteralLength */
3260 
3261 
3262 
checkForLimitedArrayLiteralLength(FILE * versionFile)3263 static void checkForLimitedArrayLiteralLength (FILE *versionFile)
3264 
3265   {
3266     const char *programStart = "#include <stdio.h>\n#include <string.h>\n"
3267                                "char stri[] = {\n";
3268     const char *line = "'1','2','3','4','5','6','7','8','9','0',"
3269                        "'1','2','3','4','5','6','7','8','9','0',\n";
3270     const char *programEnd = "};\n"
3271                              "unsigned int doTest (char *stri) {\n"
3272                              "char ch = '1';\n"
3273                              "char *chPtr;\n"
3274                              "for (chPtr = stri; *chPtr != '\\0'; chPtr++) {\n"
3275                              "  if (*chPtr != ch) {\n"
3276                              "    return (unsigned int) (chPtr - stri);\n"
3277                              "  }\n"
3278                              "  ch = ch == '9' ? '0' : ch + 1;\n"
3279                              "}\n"
3280                              "return (unsigned int) strlen(stri);\n"
3281                              "}\n"
3282                              "int main(int argc, char *argv[]) {\n"
3283                              "printf(\"%u\\n\", doTest(stri));\n"
3284                              "return 0;\n"
3285                              "}\n";
3286     /* The array literal length is repeatCount * elementsInLine. */
3287     /* The definitions below correspond to a array literal length of 100000. */
3288     const int repeatCount = 5000;
3289     const int elementsInLine = 20;
3290     int lineLength;
3291     int totalLength;
3292     int count;
3293     char *buffer;
3294     char *bufPos;
3295     int testResult;
3296 
3297   /* checkForLimitedArrayLiteralLength */
3298 #ifndef LIMITED_ARRAY_LITERAL_LEN
3299     lineLength = strlen(line);
3300     totalLength = strlen(programStart) + lineLength * repeatCount + strlen(programEnd);
3301     buffer = (char *) malloc((totalLength + 1) * sizeof(char));
3302     strcpy(buffer, programStart);
3303     bufPos = &buffer[strlen(buffer)];
3304     for (count = 1; count <= repeatCount; count++) {
3305       strcpy(bufPos, line);
3306       bufPos += lineLength;
3307     } /* for */
3308     strcpy(bufPos, programEnd);
3309     /* printf("\n%s\n", buffer); */
3310     /* Some C compilers limit the maximum array literal length.     */
3311     /* If LIMITED_ARRAY_LITERAL_LEN is 0 an array literal with      */
3312     /* repeatCount * elementsInLine elements is accepted and works. */
3313     if (compileAndLinkOk(buffer)) {
3314       testResult = doTest();
3315       if (testResult == repeatCount * elementsInLine) {
3316         /* At run-time the array literal has the correct value. */
3317         fputs("#define LIMITED_ARRAY_LITERAL_LEN 0\n", versionFile);
3318       } else if (testResult != 0 ) {
3319         /* At run-time the array literal is correct up to a position. */
3320         fprintf(versionFile, "#define LIMITED_ARRAY_LITERAL_LEN %d\n",
3321                 testResult);
3322       } else {
3323         /* At run-time the whole array literal is wrong. */
3324         fputs("#define LIMITED_ARRAY_LITERAL_LEN -2\n", versionFile);
3325       } /* if */
3326     } else {
3327       /* If the compiler prohibits long array literals. */
3328       fputs("#define LIMITED_ARRAY_LITERAL_LEN -1\n", versionFile);
3329     } /* if */
3330     free(buffer);
3331 #endif
3332   } /* checkForLimitedArrayLiteralLength */
3333 
3334 
3335 
checkForSwitchWithInt64Type(FILE * versionFile)3336 static void checkForSwitchWithInt64Type (FILE *versionFile)
3337 
3338   {
3339     char buffer[BUFFER_SIZE];
3340 
3341   /* checkForSwitchWithInt64Type */
3342     sprintf(buffer, "#include<stdio.h>\n"
3343                     "int main(int argc,char *argv[]){\n"
3344                     "%s a=1;\n"
3345                     "switch (a) {\n"
3346                     "case 1: printf(\"1\\n\");\n"
3347                     "}return 0;}\n",
3348                     int64TypeStri);
3349     fprintf(versionFile, "#define SWITCH_WORKS_FOR_INT64TYPE %d\n",
3350             compileAndLinkOk(buffer));
3351   } /* checkForSwitchWithInt64Type */
3352 
3353 
3354 
determineStackDirection(FILE * versionFile)3355 static void determineStackDirection (FILE *versionFile)
3356 
3357   {
3358     int stackGrowsUpward;
3359 
3360   /* determineStackDirection */
3361     if (compileAndLinkOk("#include <stdio.h>\n"
3362                          "char *stack_base;\n"
3363                          "void subFunc()\n"
3364                          "{char localVar;\n"
3365                          "printf(\"%d\\n\",stack_base<&localVar);return;}\n"
3366                          "int main(int argc, char *argv[])\n"
3367                          "{char mainVar;stack_base=&mainVar;\n"
3368                          "subFunc();return 0;}\n") &&
3369         (stackGrowsUpward = doTest()) != -1) {
3370       fprintf(versionFile, "#define STACK_GROWS_UPWARD %d\n", stackGrowsUpward);
3371     } /* if */
3372   } /* determineStackDirection */
3373 
3374 
3375 
determineLanguageProperties(FILE * versionFile)3376 static void determineLanguageProperties (FILE *versionFile)
3377 
3378   { /* determineLanguageProperties */
3379     fprintf(versionFile, "#define STMT_BLOCK_IN_PARENTHESES_OK %d\n",
3380             compileAndLinkOk("#include <stdio.h>\n"
3381                              "int main (int argc, char *argv[]){\n"
3382                              "int j = ({int x = 3; x+5;});\n"
3383                              "printf(\"%d\\n\", j == 8);\n"
3384                              "return 0;}\n") &&
3385             doTest() == 1);
3386   } /* determineLanguageProperties */
3387 
3388 
3389 
determinePreprocessorProperties(FILE * versionFile)3390 static void determinePreprocessorProperties (FILE *versionFile)
3391 
3392   { /* determinePreprocessorProperties */
3393     if (assertCompAndLnk("#include <stdio.h>\n#include <string.h>\n"
3394                          "int main(int argc, char *argv[]){\n"
3395                          "printf(\"%d\\n\", strcmp(\"\?\?(\", \"[\") == 0);\n"
3396                          "return 0;}\n")) {
3397       fprintf(versionFile, "#define TRIGRAPH_SEQUENCES_ARE_REPLACED %d\n", doTest() == 1);
3398     } /* if */
3399     fprintf(versionFile, "#define DIGRAPH_SEQUENCES_ARE_REPLACED %d\n",
3400         compileAndLinkOk("%:include <stdio.h>\n"
3401                          "int main (int argc, char *argv<::>)\n"
3402                          "<%printf(\"1\\n\");return 0;%>\n"));
3403     fprintf(versionFile, "#define STRINGIFY_WORKS %d\n",
3404             compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
3405                              "#define STRINGIFY(s) STRINGIFY_HELPER(s)\n"
3406                              "#define STRINGIFY_HELPER(s) #s\n"
3407                              "#define TEST1 1\n"
3408                              "#define TEST2 2 + 3\n"
3409                              "#define TEST3 TEST1 + TEST2\n"
3410                              "int main(int argc, char *argv[]){\n"
3411                              "printf(\"%d\\n\",\n"
3412                              "       strcmp(\"0\", STRINGIFY(0)) == 0 &&\n"
3413                              "       strcmp(\"1\", STRINGIFY(TEST1)) == 0 &&\n"
3414                              "       strcmp(\"2 + 3\", STRINGIFY(TEST2)) == 0 &&\n"
3415                              "       strcmp(\"1 + 2 + 3\", STRINGIFY(TEST3)) == 0);\n"
3416                              "return 0;}\n") &&
3417             doTest() == 1);
3418     fprintf(versionFile, "#define DIRECTIVES_IN_MACRO_ARGUMENTS_OK %d\n",
3419             compileAndLinkOk("#include <stdio.h>\n"
3420                              "#define X(A) A\n"
3421                              "int x = X(\n"
3422                              "#line 3 \"test.c\"\n"
3423                              "0\n"
3424                              ");\n"
3425                              "int main(int argc, char *argv[]) {\n"
3426                              "return 0;}\n"));
3427   } /* determinePreprocessorProperties */
3428 
3429 
3430 
localtimeProperties(FILE * versionFile)3431 static void localtimeProperties (FILE *versionFile)
3432 
3433   { /* localtimeProperties */
3434 #ifdef USE_ALTERNATE_LOCALTIME_R
3435     fputs("#define USE_LOCALTIME_R\n", versionFile);
3436     fprintf(versionFile, "#define LOCALTIME_WORKS_SIGNED %d\n", isSignedType("time_t"));
3437 #else
3438     if (compileAndLinkOk("#include<time.h>\nint main(int argc,char *argv[])\n"
3439                          "{time_t ts;struct tm res;struct tm*lt;\n"
3440                          "lt=localtime_r(&ts,&res);return 0;}\n")) {
3441       fputs("#define USE_LOCALTIME_R\n", versionFile);
3442       if (assertCompAndLnk("#include<stdio.h>\n#include<time.h>\n"
3443                            "int main(int argc,char *argv[])"
3444                            "{time_t ts=-2147483647-1;struct tm res;struct tm*lt;\n"
3445                            "lt=localtime_r(&ts,&res);\n"
3446                            "printf(\"%d\\n\",lt!=NULL&&lt->tm_year==1);return 0;}\n")) {
3447         fprintf(versionFile, "#define LOCALTIME_WORKS_SIGNED %d\n", doTest() == 1);
3448       } /* if */
3449     } else if (compileAndLinkOk("#include<stdio.h>\n#include<time.h>\n"
3450                                 "int main(int argc,char *argv[])\n"
3451                                 "{time_t ts=0;struct tm res;int retval;\n"
3452                                 "retval=localtime_s(&res,&ts);\n"
3453                                 "printf(\"%d\\n\",retval==0);return 0;}\n") && doTest() == 1) {
3454       fputs("#define USE_LOCALTIME_S\n", versionFile);
3455       if (assertCompAndLnk("#include<stdio.h>\n#include<time.h>\n"
3456                            "int main(int argc,char *argv[])"
3457                            "{time_t ts=-2147483647-1;struct tm res;\n"
3458                            "printf(\"%d\\n\",localtime_s(&res,&ts)==0&&res.tm_year==1);return 0;}\n")) {
3459         fprintf(versionFile, "#define LOCALTIME_WORKS_SIGNED %d\n", doTest() == 1);
3460       } /* if */
3461     } else if (assertCompAndLnk("#include<stdio.h>\n#include<time.h>\n"
3462                                 "int main(int argc,char *argv[])"
3463                                 "{time_t ts=-2147483647-1;struct tm*lt;\n"
3464                                 "lt = localtime(&ts);\n"
3465                                 "printf(\"%d\\n\",lt!=NULL&&lt->tm_year==1);return 0;}\n")) {
3466       fprintf(versionFile, "#define LOCALTIME_WORKS_SIGNED %d\n", doTest() == 1);
3467     } /* if */
3468 #endif
3469     if (compileAndLinkOk("#include<time.h>\n"
3470                          "int main(int argc,char *argv[])\n"
3471                          "{time_t ts;struct tm res;struct tm*lt;\n"
3472                          "lt=gmtime_r(&ts,&res);return 0;}\n")) {
3473       fputs("#define HAS_GMTIME_R\n", versionFile);
3474     } else if (compileAndLinkOk("#include<stdio.h>\n#include<time.h>\n"
3475                                 "int main(int argc,char *argv[])\n"
3476                                 "{time_t ts=0;struct tm res;int retval;\n"
3477                                 "retval=gmtime_s(&res,&ts);\n"
3478                                 "printf(\"%d\\n\",retval==0);return 0;}\n") && doTest() == 1) {
3479       fputs("#define HAS_GMTIME_S\n", versionFile);
3480     } /* if */
3481   } /* localtimeProperties */
3482 
3483 
3484 
defineMakeDir(void)3485 static const char *defineMakeDir (void)
3486 
3487   {
3488     const char *makeDirDefinition = NULL;
3489 
3490   /* defineMakeDir */
3491     if (compileAndLinkOk("#include <stdio.h>\n#include <direct.h>\n"
3492                          "int main(int argc,char *argv[])\n"
3493                          "{mkdir(\"tmp_empty_dir1\");return 0;}\n")) {
3494       makeDirDefinition = "#include <direct.h>\n"
3495                           "#define makeDir(path,mode) mkdir(path)\n";
3496     } else if (compileAndLinkOk("#include <stdio.h>\n"
3497                                 "#include <sys/stat.h>\n#include <sys/types.h>\n"
3498                                 "int main(int argc,char *argv[])\n"
3499                                 "{mkdir(\"tmp_empty_dir1\");return 0;}\n")) {
3500       makeDirDefinition = "#include <sys/stat.h>\n#include <sys/types.h>\n"
3501                           "#define makeDir(path,mode) mkdir(path)\n";
3502     } else if (compileAndLinkOk("#include <stdio.h>\n#include <direct.h>\n"
3503                                 "int main(int argc,char *argv[])\n"
3504                                 "{_mkdir(\"tmp_empty_dir1\");return 0;}\n")) {
3505       makeDirDefinition = "#include <direct.h>\n"
3506                           "#define makeDir(path,mode) _mkdir(path)\n";
3507     } else if (compileAndLinkOk("#include <stdio.h>\n"
3508                                 "#include <sys/stat.h>\n#include <sys/types.h>\n"
3509                                 "int main(int argc,char *argv[])\n"
3510                                 "{_mkdir(\"tmp_empty_dir1\");return 0;}\n")) {
3511       makeDirDefinition = "#include <sys/stat.h>\n#include <sys/types.h>\n"
3512                           "#define makeDir(path,mode) _mkdir(path)\n";
3513     } else if (compileAndLinkOk("#include <stdio.h>\n#include <direct.h>\n"
3514                                 "int main(int argc,char *argv[])\n"
3515                                 "{mkdir(\"tmp_empty_dir1\", 0755);return 0;}\n")) {
3516       makeDirDefinition = "#include <direct.h>\n"
3517                           "#define makeDir(path,mode) mkdir(path,mode)\n";
3518     } else if (compileAndLinkOk("#include <stdio.h>\n"
3519                                 "#include <sys/stat.h>\n#include <sys/types.h>\n"
3520                                 "int main(int argc,char *argv[])\n"
3521                                 "{mkdir(\"tmp_empty_dir1\", 0755);return 0;}\n")) {
3522       makeDirDefinition = "#include <sys/stat.h>\n#include <sys/types.h>\n"
3523                           "#define makeDir(path,mode) mkdir(path,mode)\n";
3524     } /* if */
3525     /* fprintf(logFile, "Internal makeDirDefinition:\n%s\n", makeDirDefinition); */
3526     return makeDirDefinition;
3527   } /* defineMakeDir */
3528 
3529 
3530 
defineRemoveDir(void)3531 static const char *defineRemoveDir (void)
3532 
3533   {
3534     const char *removeDirDefinition = NULL;
3535 
3536   /* defineRemoveDir */
3537     if (compileAndLinkOk("#include <stdio.h>\n#include <direct.h>\n"
3538                          "int main(int argc,char *argv[])\n"
3539                          "{rmdir(\"tmp_empty_dir1\");return 0;}\n")) {
3540       removeDirDefinition = "#include <direct.h>\n"
3541                             "#define removeDir(path) rmdir(path)\n";
3542     } else if (compileAndLinkOk("#include <stdio.h>\n#include <unistd.h>\n"
3543                                 "int main(int argc,char *argv[])\n"
3544                                 "{rmdir(\"tmp_empty_dir1\");return 0;}\n")) {
3545       removeDirDefinition = "#include <unistd.h>\n"
3546                             "#define removeDir(path) rmdir(path)\n";
3547     } else if (compileAndLinkOk("#include <stdio.h>\n#include <direct.h>\n"
3548                                 "int main(int argc,char *argv[])\n"
3549                                 "{_rmdir(\"tmp_empty_dir1\");return 0;}\n")) {
3550       removeDirDefinition = "#include <direct.h>\n"
3551                             "#define removeDir(path) _rmdir(path)\n";
3552     } else if (compileAndLinkOk("#include <stdio.h>\n#include <unistd.h>\n"
3553                                 "int main(int argc,char *argv[])\n"
3554                                 "{_rmdir(\"tmp_empty_dir1\");return 0;}\n")) {
3555       removeDirDefinition = "#include <unistd.h>\n"
3556                             "#define removeDir(path) _rmdir(path)\n";
3557     } /* if */
3558     /* fprintf(logFile, "Internal removeDirDefinition:\n%s\n", removeDirDefinition); */
3559     return removeDirDefinition;
3560   } /* defineRemoveDir */
3561 
3562 
3563 
checkRemoveDir(const char * makeDirDefinition,FILE * versionFile)3564 static void checkRemoveDir (const char *makeDirDefinition, FILE *versionFile)
3565 
3566   {
3567     char buffer[BUFFER_SIZE];
3568 
3569   /* checkRemoveDir */
3570     sprintf(buffer, "#include <stdio.h>\n#include <unistd.h>\n%s"
3571                     "int main(int argc,char *argv[])\n"
3572                     "{int rmFail=0;makeDir(\"tmp_empty_dir1\",0755);\n"
3573                     "if(remove(\"tmp_empty_dir1\")!=0){rmFail=1;rmdir(\"tmp_empty_dir1\");}\n"
3574                     "printf(\"%%d\\n\",rmFail);return 0;}\n",
3575                     makeDirDefinition);
3576     if (compileAndLinkOk(buffer)) {
3577       fprintf(versionFile, "#define REMOVE_FAILS_FOR_EMPTY_DIRS %d\n", doTest() == 1);
3578     } else {
3579       sprintf(buffer, "#include <stdio.h>\n#include <direct.h>\n%s"
3580                       "int main(int argc,char *argv[])\n"
3581                       "{int rmFail=0;makeDir(\"tmp_empty_dir1\",0755);\n"
3582                       "if(remove(\"tmp_empty_dir1\")!=0){rmFail=1;rmdir(\"tmp_empty_dir1\");}\n"
3583                       "printf(\"%%d\\n\",rmFail);return 0;}\n",
3584                       makeDirDefinition);
3585       if (compileAndLinkOk(buffer)) {
3586         fprintf(versionFile, "#define REMOVE_FAILS_FOR_EMPTY_DIRS %d\n", doTest() == 1);
3587       } /* if */
3588     } /* if */
3589   } /* checkRemoveDir */
3590 
3591 
3592 
determineGetaddrlimit(FILE * versionFile)3593 static void determineGetaddrlimit (FILE *versionFile)
3594 
3595   {
3596     int has_getrlimit;
3597 
3598   /* determineGetaddrlimit */
3599     /* In FreeBSD it is necessary to include <sys/types.h> before <sys/resource.h> */
3600     has_getrlimit = compileAndLinkOk("#include <stdio.h>\n"
3601                                      "#include <sys/types.h>\n#include <sys/resource.h>\n"
3602                                      "int main(int argc, char *argv[]){\n"
3603                                      "struct rlimit rlim;\n"
3604                                      "printf(\"%d\\n\", getrlimit(RLIMIT_STACK, &rlim) == 0);\n"
3605                                      "return 0;}\n") && doTest() == 1;
3606     fprintf(versionFile, "#define HAS_GETRLIMIT %d\n", has_getrlimit);
3607     if (has_getrlimit) {
3608       if (assertCompAndLnk("#include <stdio.h>\n"
3609                            "#include <sys/types.h>\n#include <sys/resource.h>\n"
3610                            "int main(int argc, char *argv[]){\n"
3611                            "struct rlimit rlim;\n"
3612                            "if (getrlimit(RLIMIT_STACK, &rlim) == 0) {\n"
3613                            "  if (rlim.rlim_cur == RLIM_INFINITY) {\n"
3614                            "    printf(\"0\\n\");\n"
3615                            "  } else {\n"
3616                            "    printf(\"%d\\n\", (int) (rlim.rlim_cur / 1024));\n"
3617                            "  }\n"
3618                            "} else {\n"
3619                            "  printf(\"-1\\n\");\n"
3620                            "}\n"
3621                            "return 0;}\n")) {
3622         fprintf(versionFile, "#define SOFT_STACK_LIMIT %lu\n", (unsigned long) doTest() * 1024);
3623       } /* if */
3624       if (assertCompAndLnk("#include <stdio.h>\n"
3625                            "#include <sys/types.h>\n#include <sys/resource.h>\n"
3626                            "int main(int argc, char *argv[]){\n"
3627                            "struct rlimit rlim;\n"
3628                            "if (getrlimit(RLIMIT_STACK, &rlim) == 0) {\n"
3629                            "  if (rlim.rlim_max == RLIM_INFINITY) {\n"
3630                            "    printf(\"0\\n\");\n"
3631                            "  } else {\n"
3632                            "    printf(\"%d\\n\", (int) (rlim.rlim_max / 1024));\n"
3633                            "  }\n"
3634                            "} else {\n"
3635                            "  printf(\"-1\\n\");\n"
3636                            "}\n"
3637                            "return 0;}\n")) {
3638         fprintf(versionFile, "#define HARD_STACK_LIMIT %lu\n", (unsigned long) doTest() * 1024);
3639       } /* if */
3640     } /* if */
3641   } /* determineGetaddrlimit */
3642 
3643 
3644 
determineSocketLib(FILE * versionFile)3645 static void determineSocketLib (FILE *versionFile)
3646 
3647   { /* determineSocketLib */
3648     if (compileAndLinkOk("#include <sys/types.h>\n"
3649                          "#include <sys/socket.h>\n"
3650                          "#include <netdb.h>\n"
3651                          "#include <netinet/in.h>\n"
3652                          "int main(int argc,char *argv[])\n"
3653                          "{int sock = socket(AF_INET, SOCK_STREAM, 0);\n"
3654                          "return 0;}\n")) {
3655       fputs("#define UNIX_SOCKETS 1\n", versionFile);
3656       fputs("#define SOCKET_LIB UNIX_SOCKETS\n", versionFile);
3657     } else if (compileAndLinkWithOptionsOk("#include <winsock2.h>\n"
3658                                            "int main(int argc,char *argv[])\n"
3659                                            "{unsigned int sock;\n"
3660                                            "sock = socket(AF_INET, SOCK_STREAM, 0);\n"
3661                                            "closesocket(sock); return 0;}\n",
3662                                            "", SYSTEM_LIBS)) {
3663       fputs("#define WINSOCK_SOCKETS 2\n", versionFile);
3664       fputs("#define SOCKET_LIB WINSOCK_SOCKETS\n", versionFile);
3665     } else {
3666       fputs("#define NO_SOCKETS -1\n", versionFile);
3667       fputs("#define SOCKET_LIB NO_SOCKETS\n", versionFile);
3668     } /* if */
3669     fprintf(versionFile, "#define HAS_GETADDRINFO %d\n",
3670         compileAndLinkOk("#include <sys/types.h>\n"
3671                          "#include <sys/socket.h>\n"
3672                          "#include <netdb.h>\n"
3673                          "int main(int argc,char *argv[]){\n"
3674                          "struct addrinfo *res;\n"
3675                          "struct addrinfo hints;\n"
3676                          "getaddrinfo(\"localhost\", \"80\", &hints, &res);\n"
3677                          "return 0;}\n") ||
3678         compileAndLinkWithOptionsOk("#include <winsock2.h>\n"
3679                                     "#include <ws2tcpip.h>\n"
3680                                     "int main(int argc,char *argv[]){\n"
3681                                     "struct addrinfo *res;\n"
3682                                     "struct addrinfo hints;\n"
3683                                     "getaddrinfo(\"localhost\", \"80\", &hints, &res);\n"
3684                                     "return 0;}\n",
3685                                     "", SYSTEM_LIBS));
3686   } /* determineSocketLib */
3687 
3688 
3689 
determineOsDirAccess(FILE * versionFile)3690 static void determineOsDirAccess (FILE *versionFile)
3691 
3692   {
3693     const char *directory_lib = NULL;
3694     int lib_number;
3695 
3696   /* determineOsDirAccess */
3697     if (compileAndLinkOk("#include <stdio.h>\n#include <windows.h>\n"
3698                          "#include <direct.h>\n"
3699                          "int main (int argc, char *argv[]) {\n"
3700                          "HANDLE dirHandle;\n"
3701                          "WIN32_FIND_DATAW findData;\n"
3702                          "dirHandle = FindFirstFileW(L\"./*\", &findData);\n"
3703                          "if (dirHandle != INVALID_HANDLE_VALUE) {\n"
3704                          "  FindNextFileW(dirHandle, &findData);\n"
3705                          "  FindClose(dirHandle);\n"
3706                          "} printf(\"%d\\n\", dirHandle != INVALID_HANDLE_VALUE);\n"
3707                          "return 0;}\n")) {
3708       /* This is checked first, because DIRWIN_DIRECTORY */
3709       /* should be used, even if opendir() is available. */
3710       directory_lib = "DIRWIN_DIRECTORY";
3711       lib_number = 4;
3712       fputs("#define os_DIR WDIR\n", versionFile);
3713       fputs("#define os_dirent_struct struct wdirent\n", versionFile);
3714       fputs("#define os_opendir wopendir\n", versionFile);
3715       fputs("#define os_readdir wreaddir\n", versionFile);
3716       fputs("#define os_closedir wclosedir\n", versionFile);
3717     } else if (compileAndLinkOk("#include <stdio.h>\n#include <dirent.h>\n"
3718                                 "int main(int argc,char *argv[])\n"
3719                                 "{DIR *directory; struct dirent *dirEntry;\n"
3720                                 "printf(\"%d\\n\", (directory = opendir(\".\")) != NULL &&\n"
3721                                 "(dirEntry = readdir(directory)) != NULL &&\n"
3722                                 "closedir(directory) == 0);\n"
3723                                 "return 0;}\n")) {
3724       directory_lib = "DIRENT_DIRECTORY";
3725       lib_number = 1;
3726     } else if (compileAndLinkOk("#include <stdio.h>\n#include <direct.h>\n"
3727                                 "int main(int argc,char *argv[])\n"
3728                                 "{DIR *directory; struct dirent *dirEntry;\n"
3729                                 "printf(\"%d\\n\", (directory = opendir(\".\")) != NULL &&\n"
3730                                 "(dirEntry = readdir(directory)) != NULL &&\n"
3731                                 "closedir(directory) == 0);\n"
3732                                 "return 0;}\n")) {
3733       directory_lib = "DIRECT_DIRECTORY";
3734       lib_number = 2;
3735     } /* if */
3736     if (directory_lib != NULL) {
3737       fprintf(versionFile, "#define %s %d\n", directory_lib, lib_number);
3738       fprintf(versionFile, "#define DIR_LIB %s\n", directory_lib);
3739     } else {
3740       fprintf(logFile, "\n *** Cannot define DIR_LIB.\n");
3741       fputs("#define NO_DIRECTORY -1\n", versionFile);
3742       fputs("#define DIR_LIB NO_DIRECTORY\n", versionFile);
3743     } /* if */
3744   } /* determineOsDirAccess */
3745 
3746 
3747 
determineFseekFunctions(FILE * versionFile,const char * fileno)3748 static void determineFseekFunctions (FILE *versionFile, const char *fileno)
3749 
3750   {
3751     int sizeof_off_t;
3752     int sizeof_long;
3753     int os_off_t_size;
3754     const char *os_off_t_stri = NULL;
3755     const char *os_fseek_stri = NULL;
3756     const char *os_ftell_stri = NULL;
3757     char buffer[BUFFER_SIZE];
3758 
3759   /* determineFseekFunctions */
3760 #ifndef os_fseek
3761     if (compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
3762                          "int main(int argc,char *argv[])\n"
3763                          "{FILE *aFile;\n"
3764                          "int fseek_result = -1;\n"
3765                          "off_t ftell_result = -1;\n"
3766                          "char buffer1[10];\n"
3767                          "char buffer2[10];\n"
3768                          "aFile = fopen(\"tst_vers.h\", \"rb\");\n"
3769                          "if (aFile != NULL) {\n"
3770                          "  fread(buffer1, 1, 10, aFile);\n"
3771                          "  fseek_result = fseeko(aFile, (off_t) 0, SEEK_SET);\n"
3772                          "  fread(buffer2, 1, 10, aFile);\n"
3773                          "  ftell_result = ftello(aFile);\n"
3774                          "  fclose(aFile);\n"
3775                          "}\n"
3776                          "printf(\"%d\\n\", fseek_result == 0 && ftell_result == 10 &&\n"
3777                          "       memcmp(buffer1, buffer2, 10) == 0);\n"
3778                          "return 0;}\n") && doTest() == 1) {
3779       if (compileAndLinkOk("#include <stdio.h>\n"
3780                            "int main(int argc,char *argv[])\n"
3781                            "{printf(\"%d\\n\", sizeof(off_t));\n"
3782                            "return 0;}\n")) {
3783         sizeof_off_t = doTest();
3784         if (sizeof_off_t == 4) {
3785           if (compileAndLinkOk("#define _FILE_OFFSET_BITS 64\n"
3786                                "#include <stdio.h>\n"
3787                                "int main(int argc,char *argv[])\n"
3788                                "{printf(\"%d\\n\", sizeof(off_t));\n"
3789                                "return 0;}\n")) {
3790             sizeof_off_t = doTest();
3791             if (sizeof_off_t == 8) {
3792               fputs("#define _FILE_OFFSET_BITS 64\n", versionFile);
3793             } else {
3794               sizeof_off_t = 4;
3795             } /* if */
3796           } /* if */
3797         } /* if */
3798         if (sizeof_off_t == 8) {
3799           os_off_t_size = 64;
3800           os_off_t_stri = "off_t";
3801           os_fseek_stri = "fseeko";
3802           os_ftell_stri = "ftello";
3803         } /* if */
3804       } /* if */
3805     } /* if */
3806     if (os_fseek_stri == NULL &&
3807         compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
3808                          "int main(int argc,char *argv[])\n"
3809                          "{FILE *aFile;\n"
3810                          "int fseek_result = -1;\n"
3811                          "off64_t ftell_result = -1;\n"
3812                          "char buffer1[10];\n"
3813                          "char buffer2[10];\n"
3814                          "aFile = fopen(\"tst_vers.h\", \"rb\");\n"
3815                          "if (aFile != NULL) {\n"
3816                          "  fread(buffer1, 1, 10, aFile);\n"
3817                          "  fseek_result = fseeko64(aFile, (off64_t) 0, SEEK_SET);\n"
3818                          "  fread(buffer2, 1, 10, aFile);\n"
3819                          "  ftell_result = ftello64(aFile);\n"
3820                          "  fclose(aFile);\n"
3821                          "}\n"
3822                          "printf(\"%d\\n\", fseek_result == 0 && ftell_result == 10 &&\n"
3823                          "       memcmp(buffer1, buffer2, 10) == 0);\n"
3824                          "return 0;}\n") && doTest() == 1) {
3825       os_off_t_size = 64;
3826       os_off_t_stri = "off64_t";
3827       os_fseek_stri = "fseeko64";
3828       os_ftell_stri = "ftello64";
3829     } /* if */
3830     if (os_fseek_stri == NULL &&
3831         compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
3832                          "int main(int argc,char *argv[])\n"
3833                          "{FILE *aFile;\n"
3834                          "int fseek_result = -1;\n"
3835                          "__int64 ftell_result = -1;\n"
3836                          "char buffer1[10];\n"
3837                          "char buffer2[10];\n"
3838                          "aFile = fopen(\"tst_vers.h\", \"rb\");\n"
3839                          "if (aFile != NULL) {\n"
3840                          "  fread(buffer1, 1, 10, aFile);\n"
3841                          "  fseek_result = _fseeki64(aFile, (__int64) 0, SEEK_SET);\n"
3842                          "  fread(buffer2, 1, 10, aFile);\n"
3843                          "  ftell_result = _ftelli64(aFile);\n"
3844                          "  fclose(aFile);\n"
3845                          "}\n"
3846                          "printf(\"%d\\n\", fseek_result == 0 && ftell_result == 10 &&\n"
3847                          "       memcmp(buffer1, buffer2, 10) == 0);\n"
3848                          "return 0;}\n") && doTest() == 1) {
3849       os_off_t_size = 64;
3850       os_off_t_stri = "__int64";
3851       os_fseek_stri = "_fseeki64";
3852       os_ftell_stri = "_ftelli64";
3853     } /* if */
3854     if (os_fseek_stri == NULL) {
3855       sprintf(buffer,
3856               "#include <stdio.h>\n#include <string.h>\n"
3857               "int main(int argc,char *argv[])\n"
3858               "{FILE *aFile;\n"
3859               "int fseek_result = -1;\n"
3860               "%s ftell_result = -1;\n"
3861               "char buffer1[10];\n"
3862               "char buffer2[10];\n"
3863               "aFile = fopen(\"tst_vers.h\", \"rb\");\n"
3864               "if (aFile != NULL) {\n"
3865               "  fread(buffer1, 1, 10, aFile);\n"
3866               "  fseek_result = _fseeki64(aFile, (%s) 0, SEEK_SET);\n"
3867               "  fread(buffer2, 1, 10, aFile);\n"
3868               "  ftell_result = _ftelli64(aFile);\n"
3869               "  fclose(aFile);\n"
3870               "}\n"
3871               "printf(\"%%d\\n\", fseek_result == 0 && ftell_result == 10 &&\n"
3872               "       memcmp(buffer1, buffer2, 10) == 0);\n"
3873               "return 0;}\n", int64TypeStri, int64TypeStri);
3874       if (compileAndLinkOk(buffer) && doTest() == 1) {
3875         os_off_t_size = 64;
3876         os_off_t_stri = int64TypeStri;
3877         os_fseek_stri = "_fseeki64";
3878         os_ftell_stri = "_ftelli64";
3879       } /* if */
3880     } /* if */
3881     if (os_fseek_stri == NULL &&
3882         compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
3883                          "extern int __cdecl _fseeki64(FILE *, __int64, int);\n"
3884                          "extern __int64 __cdecl _ftelli64(FILE *);\n"
3885                          "int main(int argc,char *argv[])\n"
3886                          "{FILE *aFile;\n"
3887                          "int fseek_result = -1;\n"
3888                          "__int64 ftell_result = -1;\n"
3889                          "char buffer1[10];\n"
3890                          "char buffer2[10];\n"
3891                          "aFile = fopen(\"tst_vers.h\", \"rb\");\n"
3892                          "if (aFile != NULL) {\n"
3893                          "  fread(buffer1, 1, 10, aFile);\n"
3894                          "  fseek_result = _fseeki64(aFile, (__int64) 0, SEEK_SET);\n"
3895                          "  fread(buffer2, 1, 10, aFile);\n"
3896                          "  ftell_result = _ftelli64(aFile);\n"
3897                          "  fclose(aFile);\n"
3898                          "}\n"
3899                          "printf(\"%d\\n\", fseek_result == 0 && ftell_result == 10 &&\n"
3900                          "       memcmp(buffer1, buffer2, 10) == 0);\n"
3901                          "return 0;}\n") && doTest() == 1) {
3902       fputs("#define DEFINE_FSEEKI64_PROTOTYPE\n", versionFile);
3903       fputs("#define DEFINE_FTELLI64_PROTOTYPE\n", versionFile);
3904       os_off_t_size = 64;
3905       os_off_t_stri = "__int64";
3906       os_fseek_stri = "_fseeki64";
3907       os_ftell_stri = "_ftelli64";
3908     } /* if */
3909     if (os_fseek_stri == NULL &&
3910         compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
3911                          "int main(int argc,char *argv[])\n"
3912                          "{FILE *aFile;\n"
3913                          "int fseek_result = -1;\n"
3914                          "__int64 ftell_result = -1;\n"
3915                          "fpos_t pos;\n"
3916                          "char buffer1[10];\n"
3917                          "char buffer2[10];\n"
3918                          "aFile = fopen(\"tst_vers.h\", \"rb\");\n"
3919                          "if (aFile != NULL) {\n"
3920                          "  fread(buffer1, 1, 10, aFile);\n"
3921                          "  fseek_result = _fseeki64(aFile, (__int64) 0, SEEK_SET);\n"
3922                          "  fread(buffer2, 1, 10, aFile);\n"
3923                          "  if (fgetpos(aFile, &pos) == 0) {\n"
3924                          "    memcpy(&ftell_result, &pos, sizeof(ftell_result));\n"
3925                          "  } else {\n"
3926                          "    ftell_result = -1;\n"
3927                          "  }\n"
3928                          "  fclose(aFile);\n"
3929                          "}\n"
3930                          "printf(\"%d\\n\", fseek_result == 0 && ftell_result == 10 &&\n"
3931                          "       memcmp(buffer1, buffer2, 10) == 0 &&\n"
3932                          "       sizeof(fpos_t) == sizeof(__int64));\n"
3933                          "return 0;}\n") && doTest() == 1) {
3934       fputs("#define DEFINE_FTELLI64_EXT 1\n", versionFile);
3935       os_off_t_size = 64;
3936       os_off_t_stri = "__int64";
3937       os_fseek_stri = "_fseeki64";
3938       os_ftell_stri = "ftelli64Ext";
3939     } /* if */
3940     if (os_fseek_stri == NULL) {
3941       sprintf(buffer,
3942               "#include <stdio.h>\n#include <string.h>\n"
3943               "#include <io.h>\n"
3944               "int main(int argc,char *argv[])\n"
3945               "{FILE *aFile;\n"
3946               "int fseek_result = -1;\n"
3947               "__int64 ftell_result = -1;\n"
3948               "fpos_t pos;\n"
3949               "char buffer1[10];\n"
3950               "char buffer2[10];\n"
3951               "aFile = fopen(\"tst_vers.h\", \"rb\");\n"
3952               "if (aFile != NULL) {\n"
3953               "  fread(buffer1, 1, 10, aFile);\n"
3954               "  fseek_result = _fseeki64(aFile, (__int64) 0, SEEK_SET);\n"
3955               "  fread(buffer2, 1, 10, aFile);\n"
3956               "  if (fgetpos(aFile, &pos) == 0 && fsetpos(aFile, &pos) == 0) {\n"
3957               "    ftell_result = _telli64(%s(aFile));\n"
3958               "  } else {\n"
3959               "    ftell_result = -1;\n"
3960               "  }\n"
3961               "  fclose(aFile);\n"
3962               "}\n"
3963               "printf(\"%%d\\n\", fseek_result == 0 && ftell_result == 10 &&\n"
3964               "       memcmp(buffer1, buffer2, 10) == 0);\n"
3965               "return 0;}\n", fileno);
3966       if (compileAndLinkOk(buffer) && doTest() == 1) {
3967         fputs("#define DEFINE_FTELLI64_EXT 2\n", versionFile);
3968         os_off_t_size = 64;
3969         os_off_t_stri = "__int64";
3970         os_fseek_stri = "_fseeki64";
3971         os_ftell_stri = "ftelli64Ext";
3972       } /* if */
3973     } /* if */
3974     if (os_fseek_stri == NULL) {
3975       sprintf(buffer,
3976               "#include <stdio.h>\n#include <string.h>\n"
3977               "int main(int argc,char *argv[])\n"
3978               "{FILE *aFile;\n"
3979               "int fseek_result = -1;\n"
3980               "%s ftell_result = -1;\n"
3981               "char buffer1[10];\n"
3982               "char buffer2[10];\n"
3983               "aFile = fopen(\"tst_vers.h\", \"rb\");\n"
3984               "if (aFile != NULL) {\n"
3985               "  fread(buffer1, 1, 10, aFile);\n"
3986               "  fseek_result = _fseek64(aFile, (%s) 0, SEEK_SET);\n"
3987               "  fread(buffer2, 1, 10, aFile);\n"
3988               "  ftell_result = _ftell64(aFile);\n"
3989               "  fclose(aFile);\n"
3990               "}\n"
3991               "printf(\"%%d\\n\", fseek_result == 0 && ftell_result == 10 &&\n"
3992               "       memcmp(buffer1, buffer2, 10) == 0);\n"
3993               "return 0;}\n", int64TypeStri, int64TypeStri);
3994       if (compileAndLinkOk(buffer) && doTest() == 1) {
3995         os_off_t_size = 64;
3996         os_off_t_stri = int64TypeStri;
3997         os_fseek_stri = "_fseek64";
3998         os_ftell_stri = "_ftell64";
3999       } /* if */
4000     } /* if */
4001     if (os_fseek_stri == NULL &&
4002         compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
4003                          "int main(int argc,char *argv[])\n"
4004                          "{FILE *aFile;\n"
4005                          "int fseek_result = -1;\n"
4006                          "long ftell_result = -1;\n"
4007                          "char buffer1[10];\n"
4008                          "char buffer2[10];\n"
4009                          "aFile = fopen(\"ctstfile.txt\", \"wb\");\n"
4010                          "if (aFile != NULL) {\n"
4011                          "  fputs(\"abcdefghijklmnopqrstuvwxyz\\n\", aFile);\n"
4012                          "  fclose(aFile);\n"
4013                          "}\n"
4014                          "aFile = fopen(\"ctstfile.txt\", \"rb\");\n"
4015                          "if (aFile != NULL) {\n"
4016                          "  fread(buffer1, 1, 10, aFile);\n"
4017                          "  fseek_result = fseek(aFile, (long) 0, SEEK_SET);\n"
4018                          "  fread(buffer2, 1, 10, aFile);\n"
4019                          "  ftell_result = ftell(aFile);\n"
4020                          "  fclose(aFile);\n"
4021                          "}\n"
4022                          "printf(\"%d\\n\", fseek_result == 0 && ftell_result == 10 &&\n"
4023                          "       memcmp(buffer1, buffer2, 10) == 0);\n"
4024                          "return 0;}\n") && doTest() == 1) {
4025       sizeof_long = getSizeof("long");
4026       if (compileAndLinkOk("#include <stdio.h>\n"
4027                            "int main (int argc, char *argv[])\n"
4028                            "{printf(\"%d\\n\", sizeof(ftell(NULL)));\n"
4029                            "return 0;}\n") &&
4030           (sizeof_off_t = doTest()) >= 1) {
4031         /* The classic fseek() and ftell() functions work for long, */
4032         /* but some strange implementations use a different type. */
4033         if (sizeof_off_t == sizeof_long) {
4034           os_off_t_size = 8 * sizeof_long;
4035           os_off_t_stri = "long";
4036         } else if (sizeof_off_t == 2) {
4037           os_off_t_size = 16;
4038           os_off_t_stri = int16TypeStri;
4039         } else if (sizeof_off_t == 4) {
4040           os_off_t_size = 32;
4041           os_off_t_stri = int32TypeStri;
4042         } else if (sizeof_off_t == 8) {
4043           os_off_t_size = 64;
4044           os_off_t_stri = int64TypeStri;
4045         } else if (sizeof_off_t == 16) {
4046           os_off_t_size = 128;
4047           os_off_t_stri = int128TypeStri;
4048         } else {
4049           fprintf(logFile, "\n *** sizeof(ftell(NULL)) is %d.\n", sizeof_off_t);
4050         } /* if */
4051       } else {
4052         os_off_t_size = 8 * sizeof_long;
4053         os_off_t_stri = "long";
4054       } /* if */
4055       if (os_off_t_stri != NULL) {
4056         os_fseek_stri = "fseek";
4057         os_ftell_stri = "ftell";
4058       } /* if */
4059     } /* if */
4060     if (os_fseek_stri != NULL) {
4061       fprintf(versionFile, "#define OS_OFF_T_SIZE %d\n", os_off_t_size);
4062       fprintf(versionFile, "#define os_off_t %s\n", os_off_t_stri);
4063       fprintf(versionFile, "#define os_fseek %s\n", os_fseek_stri);
4064       fprintf(versionFile, "#define os_ftell %s\n", os_ftell_stri);
4065       sprintf(buffer,
4066               "#include <stdio.h>\n#include <string.h>\n"
4067               "int main(int argc,char *argv[])\n"
4068               "{FILE *aFile;\n"
4069               "int eofResult = -1;\n"
4070               "aFile = fopen(\"tst_vers.h\", \"rb\");\n"
4071               "if (aFile != NULL) {\n"
4072               "  while (getc(aFile) != EOF) ;\n"
4073               "  if (%s(aFile, (%s) 0, SEEK_SET) == 0) {\n"
4074               "    eofResult = feof(aFile);\n"
4075               "  }\n"
4076               "  fclose(aFile);\n"
4077               "}\n"
4078               "printf(\"%%d\\n\", eofResult == 0);\n"
4079               "return 0;}\n", os_fseek_stri, os_off_t_stri);
4080       fprintf(versionFile, "#define OS_FSEEK_RESETS_EOF_FLAG %d\n",
4081               compileAndLinkOk(buffer) && doTest() == 1);
4082     } else {
4083       fprintf(logFile, "\n *** Cannot define os_fseek and os_ftell.\n");
4084     } /* if */
4085     doRemove("ctstfile.txt");
4086 #else
4087       fprintf(versionFile, "#define OS_OFF_T_SIZE %d\n", 8 * getSizeof("os_off_t"));
4088 #endif
4089   } /* determineFseekFunctions */
4090 
4091 
4092 
determineLseekFunction(FILE * versionFile)4093 static void determineLseekFunction (FILE *versionFile)
4094 
4095   { /* determineLseekFunction */
4096     if (compileAndLinkOk("#include <stdio.h>\n#include <io.h>\n"
4097                          "int main(int argc,char *argv[])\n"
4098                          "{printf(\"%d\\n\", lseeki64(0, 0, SEEK_CUR) != -1);\n"
4099                          "return 0;}\n")) {
4100       fputs("#define LSEEK_INCLUDE_IO_H\n", versionFile);
4101       fprintf(versionFile, "#define os_lseek lseeki64\n");
4102     } else if (compileAndLinkOk("#include <stdio.h>\n#include <io.h>\n"
4103                          "int main(int argc,char *argv[])\n"
4104                          "{printf(\"%d\\n\", _lseeki64(0, 0, SEEK_CUR) != -1);\n"
4105                          "return 0;}\n")) {
4106       fputs("#define LSEEK_INCLUDE_IO_H\n", versionFile);
4107       fprintf(versionFile, "#define os_lseek _lseeki64\n");
4108     } else if (compileAndLinkOk("#include <stdio.h>\n#include <io.h>\n"
4109                          "int main(int argc,char *argv[])\n"
4110                          "{printf(\"%d\\n\", lseek(0, 0, SEEK_CUR) != -1);\n"
4111                          "return 0;}\n")) {
4112       fputs("#define LSEEK_INCLUDE_IO_H\n", versionFile);
4113       fprintf(versionFile, "#define os_lseek lseek\n");
4114     } else if (compileAndLinkOk("#include <stdio.h>\n#include <io.h>\n"
4115                          "int main(int argc,char *argv[])\n"
4116                          "{printf(\"%d\\n\", _lseek(0, 0, SEEK_CUR) != -1);\n"
4117                          "return 0;}\n")) {
4118       fputs("#define LSEEK_INCLUDE_IO_H\n", versionFile);
4119       fprintf(versionFile, "#define os_lseek _lseek\n");
4120     } else if (compileAndLinkOk("#include <stdio.h>\n#include <sys/types.h>\n"
4121                          "#include <unistd.h>\n"
4122                          "int main(int argc,char *argv[])\n"
4123                          "{printf(\"%d\\n\", lseek(0, 0, SEEK_CUR) != -1);\n"
4124                          "return 0;}\n")) {
4125       fprintf(versionFile, "#define os_lseek lseek\n");
4126     } else if (compileAndLinkOk("#include <stdio.h>\n#include <sys/types.h>\n"
4127                          "#include <unistd.h>\n"
4128                          "int main(int argc,char *argv[])\n"
4129                          "{printf(\"%d\\n\", _lseek(0, 0, SEEK_CUR) != -1);\n"
4130                          "return 0;}\n")) {
4131       fprintf(versionFile, "#define os_lseek _lseek\n");
4132     } else {
4133       fprintf(logFile, "\n *** Cannot define os_lseek.\n");
4134     } /* if */
4135   } /* determineLseekFunction */
4136 
4137 
4138 
determineFtruncate(FILE * versionFile,const char * fileno)4139 static void determineFtruncate (FILE *versionFile, const char *fileno)
4140 
4141   {
4142     char buffer[BUFFER_SIZE];
4143     const char *os_ftruncate_stri = NULL;
4144     const char *ftruncate_size_in_bits;
4145     char size_buffer[10];
4146 
4147   /* determineFtruncate */
4148     sprintf(buffer, "#include <stdio.h>\n#include <unistd.h>\n"
4149                     "int main(int argc, char *argv[])\n"
4150                     "{FILE *aFile; int file_no; char buffer[5];\n"
4151                     "char *stri = NULL; int func_res = -1;\n"
4152                     "aFile = fopen(\"ctstfile.txt\", \"w+\");\n"
4153                     "if (aFile != NULL) {\n"
4154                     "  file_no = %s(aFile);\n"
4155                     "  if (file_no != -1) {\n"
4156                     "    fprintf(aFile, \"abcd\");\n"
4157                     "    fflush(aFile);\n"
4158                     "    func_res = ftruncate(file_no, 1);\n"
4159                     "    fseek(aFile, 0, SEEK_SET);\n"
4160                     "    stri = fgets(buffer, 4, aFile);\n"
4161                     "  }\n"
4162                     "  fclose(aFile);\n"
4163                     "}\n"
4164                     "printf(\"%%d\\n\", func_res == 0 && stri != NULL &&\n"
4165                     "       stri[0] == 'a' && stri[1] == '\\0' && sizeof(off_t) == 8);\n"
4166                     "return 0;}\n", fileno);
4167     if (compileAndLinkOk(buffer) && doTest() == 1) {
4168       os_ftruncate_stri = "ftruncate";
4169       ftruncate_size_in_bits = "OS_OFF_T_SIZE";
4170     } /* if */
4171     doRemove("ctstfile.txt");
4172     if (os_ftruncate_stri == NULL) {
4173       sprintf(buffer, "#include <stdio.h>\n#include <io.h>\n"
4174                       "int main(int argc, char *argv[])\n"
4175                       "{FILE *aFile; int file_no; char buffer[5];\n"
4176                       "char *stri = NULL; int func_res = -1;\n"
4177                       "aFile = fopen(\"ctstfile.txt\", \"w+\");\n"
4178                       "if (aFile != NULL) {\n"
4179                       "  file_no = %s(aFile);\n"
4180                       "  if (file_no != -1) {\n"
4181                       "    fprintf(aFile, \"abcd\");\n"
4182                       "    fflush(aFile);\n"
4183                       "    func_res = _chsize_s(file_no, 1);\n"
4184                       "    fseek(aFile, 0, SEEK_SET);\n"
4185                       "    stri = fgets(buffer, 4, aFile);\n"
4186                       "  }\n"
4187                       "  fclose(aFile);\n"
4188                       "}\n"
4189                       "printf(\"%%d\\n\", func_res == 0 && stri != NULL &&\n"
4190                       "       stri[0] == 'a' && stri[1] == '\\0');\n"
4191                       "return 0;}\n", fileno);
4192       if (compileAndLinkOk(buffer) && doTest() == 1) {
4193         os_ftruncate_stri = "_chsize_s";
4194         ftruncate_size_in_bits = "64";
4195         fputs("#define FTRUNCATE_INCLUDE_IO_H\n", versionFile);
4196       } /* if */
4197       doRemove("ctstfile.txt");
4198     } /* if */
4199     if (os_ftruncate_stri == NULL) {
4200       sprintf(buffer, "#include <stdio.h>\n"
4201                       "extern int _chsize_s(int fd, %s size);\n"
4202                       "int main(int argc, char *argv[])\n"
4203                       "{FILE *aFile; int file_no; char buffer[5];\n"
4204                       "char *stri = NULL; int func_res = -1;\n"
4205                       "aFile = fopen(\"ctstfile.txt\", \"w+\");\n"
4206                       "if (aFile != NULL) {\n"
4207                       "  file_no = %s(aFile);\n"
4208                       "  if (file_no != -1) {\n"
4209                       "    fprintf(aFile, \"abcd\");\n"
4210                       "    fflush(aFile);\n"
4211                       "    func_res = _chsize_s(file_no, 1);\n"
4212                       "    fseek(aFile, 0, SEEK_SET);\n"
4213                       "    stri = fgets(buffer, 4, aFile);\n"
4214                       "  }\n"
4215                       "  fclose(aFile);\n"
4216                       "}\n"
4217                       "printf(\"%%d\\n\", func_res == 0 && stri != NULL &&\n"
4218                       "       stri[0] == 'a' && stri[1] == '\\0');\n"
4219                       "return 0;}\n", int64TypeStri, fileno);
4220       if (compileAndLinkOk(buffer) && doTest() == 1) {
4221         os_ftruncate_stri = "_chsize_s";
4222         ftruncate_size_in_bits = "64";
4223         fputs("#define DEFINE_CHSIZE_S_PROTOTYPE\n", versionFile);
4224       } /* if */
4225       doRemove("ctstfile.txt");
4226     } /* if */
4227     if (os_ftruncate_stri == NULL) {
4228       sprintf(buffer, "#include <stdio.h>\n#include <unistd.h>\n"
4229                       "int main(int argc, char *argv[])\n"
4230                       "{FILE *aFile; int file_no; char buffer[5];\n"
4231                       "char *stri = NULL; int func_res = -1;\n"
4232                       "aFile = fopen(\"ctstfile.txt\", \"w+\");\n"
4233                       "if (aFile != NULL) {\n"
4234                       "  file_no = %s(aFile);\n"
4235                       "  if (file_no != -1) {\n"
4236                       "    fprintf(aFile, \"abcd\");\n"
4237                       "    fflush(aFile);\n"
4238                       "    func_res = ftruncate(file_no, 1);\n"
4239                       "    fseek(aFile, 0, SEEK_SET);\n"
4240                       "    stri = fgets(buffer, 4, aFile);\n"
4241                       "  }\n"
4242                       "  fclose(aFile);\n"
4243                       "}\n"
4244                       "printf(\"%%d\\n\", func_res == 0 && stri != NULL &&\n"
4245                       "       stri[0] == 'a' && stri[1] == '\\0' && sizeof(off_t) == 4);\n"
4246                       "return 0;}\n", fileno);
4247       if (compileAndLinkOk(buffer) && doTest() == 1) {
4248         os_ftruncate_stri = "ftruncate";
4249         ftruncate_size_in_bits = "32";
4250       } /* if */
4251       doRemove("ctstfile.txt");
4252     } /* if */
4253     if (os_ftruncate_stri == NULL) {
4254       sprintf(buffer, "#include <stdio.h>\n#include <io.h>\n"
4255                       "int main(int argc, char *argv[])\n"
4256                       "{FILE *aFile; int file_no; char buffer[5];\n"
4257                       "char *stri = NULL; int func_res = -1;\n"
4258                       "aFile = fopen(\"ctstfile.txt\", \"w+\");\n"
4259                       "if (aFile != NULL) {\n"
4260                       "  file_no = %s(aFile);\n"
4261                       "  if (file_no != -1) {\n"
4262                       "    fprintf(aFile, \"abcd\");\n"
4263                       "    fflush(aFile);\n"
4264                       "    func_res = _chsize(file_no, 1);\n"
4265                       "    fseek(aFile, 0, SEEK_SET);\n"
4266                       "    stri = fgets(buffer, 4, aFile);\n"
4267                       "  }\n"
4268                       "  fclose(aFile);\n"
4269                       "}\n"
4270                       "printf(\"%%d\\n\", func_res == 0 && stri != NULL &&\n"
4271                       "       stri[0] == 'a' && stri[1] == '\\0');\n"
4272                       "return 0;}\n", fileno);
4273       if (compileAndLinkOk(buffer) && doTest() == 1) {
4274         os_ftruncate_stri = "_chsize";
4275         sprintf(size_buffer, "%d", getSizeof("long") * 8);
4276         ftruncate_size_in_bits = size_buffer;
4277         fputs("#define FTRUNCATE_INCLUDE_IO_H\n", versionFile);
4278       } /* if */
4279       doRemove("ctstfile.txt");
4280     } /* if */
4281     if (os_ftruncate_stri == NULL) {
4282       sprintf(buffer, "#include <stdio.h>\n#include <io.h>\n"
4283                       "int main(int argc, char *argv[])\n"
4284                       "{FILE *aFile; int file_no; char buffer[5];\n"
4285                       "char *stri = NULL; int func_res = -1;\n"
4286                       "aFile = fopen(\"ctstfile.txt\", \"w+\");\n"
4287                       "if (aFile != NULL) {\n"
4288                       "  file_no = %s(aFile);\n"
4289                       "  if (file_no != -1) {\n"
4290                       "    fprintf(aFile, \"abcd\");\n"
4291                       "    fflush(aFile);\n"
4292                       "    func_res = chsize(file_no, 1);\n"
4293                       "    fseek(aFile, 0, SEEK_SET);\n"
4294                       "    stri = fgets(buffer, 4, aFile);\n"
4295                       "  }\n"
4296                       "  fclose(aFile);\n"
4297                       "}\n"
4298                       "printf(\"%%d\\n\", func_res == 0 && stri != NULL &&\n"
4299                       "       stri[0] == 'a' && stri[1] == '\\0');\n"
4300                       "return 0;}\n", fileno);
4301       if (compileAndLinkOk(buffer) && doTest() == 1) {
4302         os_ftruncate_stri = "chsize";
4303         sprintf(size_buffer, "%d", getSizeof("long") * 8);
4304         ftruncate_size_in_bits = size_buffer;
4305         fputs("#define FTRUNCATE_INCLUDE_IO_H\n", versionFile);
4306       } /* if */
4307       doRemove("ctstfile.txt");
4308     } /* if */
4309     if (os_ftruncate_stri == NULL) {
4310       sprintf(buffer, "#include <stdio.h>\n"
4311                       "extern int _chsize(int fd, long size);\n"
4312                       "int main(int argc, char *argv[])\n"
4313                       "{FILE *aFile; int file_no; char buffer[5];\n"
4314                       "char *stri = NULL; int func_res = -1;\n"
4315                       "aFile = fopen(\"ctstfile.txt\", \"w+\");\n"
4316                       "if (aFile != NULL) {\n"
4317                       "  file_no = %s(aFile);\n"
4318                       "  if (file_no != -1) {\n"
4319                       "    fprintf(aFile, \"abcd\");\n"
4320                       "    fflush(aFile);\n"
4321                       "    func_res = _chsize(file_no, 1);\n"
4322                       "    fseek(aFile, 0, SEEK_SET);\n"
4323                       "    stri = fgets(buffer, 4, aFile);\n"
4324                       "  }\n"
4325                       "  fclose(aFile);\n"
4326                       "}\n"
4327                       "printf(\"%%d\\n\", func_res == 0 && stri != NULL &&\n"
4328                       "       stri[0] == 'a' && stri[1] == '\\0');\n"
4329                       "return 0;}\n", fileno);
4330       if (compileAndLinkOk(buffer) && doTest() == 1) {
4331         os_ftruncate_stri = "_chsize";
4332         sprintf(size_buffer, "%d", getSizeof("long") * 8);
4333         ftruncate_size_in_bits = size_buffer;
4334         fputs("#define DEFINE_CHSIZE_PROTOTYPE\n", versionFile);
4335       } /* if */
4336       doRemove("ctstfile.txt");
4337     } /* if */
4338     if (os_ftruncate_stri != NULL) {
4339       fprintf(versionFile, "#define os_ftruncate %s\n", os_ftruncate_stri);
4340       fprintf(versionFile, "#define FTRUNCATE_SIZE %s\n", ftruncate_size_in_bits);
4341     } /* if */
4342   } /* determineFtruncate */
4343 
4344 
4345 
4346 /**
4347  *  Determine values for DECLARE_OS_ENVIRON, USE_GET_ENVIRONMENT,
4348  *  INITIALIZE_OS_ENVIRON, DEFINE_WGETENV, DEFINE_WSETENV, os_environ.
4349  *  os_getenv, os_setenv, os_putenv and DELETE_PUTENV_ARGUMENT.
4350  */
determineEnvironDefines(FILE * versionFile)4351 static void determineEnvironDefines (FILE *versionFile)
4352 
4353   {
4354     char buffer[BUFFER_SIZE];
4355     char getenv_definition[BUFFER_SIZE];
4356     char setenv_definition[BUFFER_SIZE];
4357     const char *os_environ_stri = NULL;
4358     int declare_os_environ = 0;
4359     int use_get_environment = 0;
4360     int initialize_os_environ = 0;
4361     int define_wgetenv = 0;
4362     int define_wsetenv = 0;
4363     int define_wunsetenv = 0;
4364     int test_result;
4365     int putenv_can_remove_keys = 0;
4366     int getenv_is_case_sensitive = -1;
4367     const char *os_getenv_stri = NULL;
4368     const char *os_putenv_stri = NULL;
4369     const char *os_setenv_stri = NULL;
4370     const char *os_unsetenv_stri = NULL;
4371 
4372   /* determineEnvironDefines */
4373     buffer[0] = '\0';
4374 #ifdef EMULATE_ENVIRONMENT
4375     os_environ_stri = "environ7";
4376     declare_os_environ = 1;
4377 #else
4378 #ifdef OS_STRI_WCHAR
4379     if (compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4380                          "int main(int argc,char *argv[])\n"
4381                          "{printf(\"%d\\n\", _wenviron != NULL);return 0;}\n")) {
4382       strcat(buffer, "#include <stdlib.h>\n");
4383       os_environ_stri = "_wenviron";
4384     } else if (compileAndLinkOk("#include <stdio.h>\n#include <unistd.h>\n"
4385                                 "int main(int argc,char *argv[])\n"
4386                                 "{printf(\"%d\\n\", _wenviron != NULL);return 0;}\n")) {
4387       strcat(buffer, "#include <unistd.h>\n");
4388       os_environ_stri = "_wenviron";
4389     } else if (compileAndLinkOk("#include <stdio.h>\n"
4390                                 "int main(int argc,char *argv[])\n"
4391                                 "{extern wchar_t **_wenviron;\n"
4392                                 "printf(\"%d\\n\", _wenviron != NULL);return 0;}\n")) {
4393       declare_os_environ = 1;
4394       os_environ_stri = "_wenviron";
4395 #else
4396     if (compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4397                          "int main(int argc,char *argv[])\n"
4398                          "{printf(\"%d\\n\", environ != NULL);return 0;}\n")) {
4399       strcat(buffer, "#include <stdlib.h>\n");
4400       os_environ_stri = "environ";
4401     } else if (compileAndLinkOk("#include <stdio.h>\n#include <unistd.h>\n"
4402                                 "int main(int argc,char *argv[])\n"
4403                                 "{printf(\"%d\\n\", environ != NULL);return 0;}\n")) {
4404       strcat(buffer, "#include <unistd.h>\n");
4405       os_environ_stri = "environ";
4406     } else if (compileAndLinkOk("#include <stdio.h>\n"
4407                                 "int main(int argc,char *argv[])\n"
4408                                 "{extern char **environ;\n"
4409                                 "printf(\"%d\\n\", environ != NULL);return 0;}\n")) {
4410       declare_os_environ = 1;
4411       os_environ_stri = "environ";
4412 #endif
4413     } else {
4414       use_get_environment = 1;
4415     } /* if */
4416     if (!use_get_environment) {
4417       strcat(buffer, "#include <stdio.h>\n");
4418       strcat(buffer, "#include \"tst_vers.h\"\n");
4419 #ifdef OS_STRI_WCHAR
4420       strcat(buffer, "typedef wchar_t *os_striType;\n");
4421 #else
4422       strcat(buffer, "typedef char *os_striType;\n");
4423 #endif
4424       if (declare_os_environ) {
4425         strcat(buffer, "extern os_striType *");
4426         strcat(buffer, os_environ_stri);
4427         strcat(buffer, ";\n");
4428       } /* if */
4429 #ifdef USE_WMAIN
4430       strcat(buffer, "int wmain(int argc,wchar_t *argv[])");
4431 #else
4432       strcat(buffer, "int main(int argc,char *argv[])");
4433 #endif
4434       strcat(buffer, "{printf(\"%d\\n\",");
4435       strcat(buffer, os_environ_stri);
4436       strcat(buffer, "==(os_striType *)0);return 0;}\n");
4437       if (!compileAndLinkOk(buffer) || doTest() == 1) {
4438         initialize_os_environ = 1;
4439       } /* if */
4440     } /* if */
4441 #endif
4442     if (os_environ_stri != NULL) {
4443       fprintf(versionFile, "#define os_environ %s\n", os_environ_stri);
4444     } /* if */
4445     fprintf(versionFile, "#define DECLARE_OS_ENVIRON %d\n", declare_os_environ);
4446     fprintf(versionFile, "#define USE_GET_ENVIRONMENT %d\n", use_get_environment);
4447     fprintf(versionFile, "#define INITIALIZE_OS_ENVIRON %d\n", initialize_os_environ);
4448 #ifdef EMULATE_ENVIRONMENT
4449     os_getenv_stri = "getenv7";
4450 #elif defined OS_STRI_WCHAR
4451     if (compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4452                          "int main(int argc,char *argv[])\n"
4453                          "{printf(\"%d\\n\",\n"
4454                          "  _wgetenv(L\"PATH\") != NULL ||\n"
4455                          "  _wgetenv(L\"HOME\") != NULL ||\n"
4456                          "  _wgetenv(L\"TERM\") != NULL ||\n"
4457                          "  _wgetenv(L\"LOGNAME\") != NULL ||\n"
4458                          "  _wgetenv(L\"PROMPT\") != NULL ||\n"
4459                          "  _wgetenv(L\"HOMEPATH\") != NULL ||\n"
4460                          "  _wgetenv(L\"USERNAME\") != NULL ||\n"
4461                          "  _wgetenv(L\"TEMP\") != NULL ||\n"
4462                          "  _wgetenv(L\"TMP\") != NULL ||\n"
4463                          "  _wgetenv(L\"OS\") != NULL);\n"
4464                          "return 0;}\n") && doTest() == 1) {
4465       os_getenv_stri = "_wgetenv";
4466     } else if (compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4467                          "int main(int argc,char *argv[])\n"
4468                          "{printf(\"%d\\n\",\n"
4469                          "  wgetenv(L\"PATH\") != NULL ||\n"
4470                          "  wgetenv(L\"HOME\") != NULL ||\n"
4471                          "  wgetenv(L\"TERM\") != NULL ||\n"
4472                          "  wgetenv(L\"LOGNAME\") != NULL ||\n"
4473                          "  wgetenv(L\"PROMPT\") != NULL ||\n"
4474                          "  wgetenv(L\"HOMEPATH\") != NULL ||\n"
4475                          "  wgetenv(L\"USERNAME\") != NULL ||\n"
4476                          "  wgetenv(L\"TEMP\") != NULL ||\n"
4477                          "  wgetenv(L\"TMP\") != NULL ||\n"
4478                          "  wgetenv(L\"OS\") != NULL);\n"
4479                          "return 0;}\n") && doTest() == 1) {
4480       os_getenv_stri = "wgetenv";
4481     } else if (compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4482                                 "#include <windows.h>\n"
4483                                 "int main(int argc,char *argv[])\n"
4484                                 "{wchar_t buf[4096];\n"
4485                                 "printf(\"%d\\n\",\n"
4486                                 "  GetEnvironmentVariableW(L\"PATH\", buf, 4096) != 0 ||\n"
4487                                 "  GetEnvironmentVariableW(L\"HOME\", buf, 4096) != 0 ||\n"
4488                                 "  GetEnvironmentVariableW(L\"TERM\", buf, 4096) != 0 ||\n"
4489                                 "  GetEnvironmentVariableW(L\"LOGNAME\", buf, 4096) != 0 ||\n"
4490                                 "  GetEnvironmentVariableW(L\"PROMPT\", buf, 4096) != 0 ||\n"
4491                                 "  GetEnvironmentVariableW(L\"HOMEPATH\", buf, 4096) != 0 ||\n"
4492                                 "  GetEnvironmentVariableW(L\"USERNAME\", buf, 4096) != 0 ||\n"
4493                                 "  GetEnvironmentVariableW(L\"TEMP\", buf, 4096) != 0 ||\n"
4494                                 "  GetEnvironmentVariableW(L\"TMP\", buf, 4096) != 0 ||\n"
4495                                 "  GetEnvironmentVariableW(L\"OS\", buf, 4096) != 0);\n"
4496                                 "return 0;}\n") && doTest() == 1) {
4497       define_wgetenv = 1;
4498       os_getenv_stri = "wgetenv";
4499     } else {
4500       fprintf(logFile, "\nAssume that wgetenv() should be defined.\n");
4501       define_wgetenv = 1;
4502       os_getenv_stri = "wgetenv";
4503     } /* if */
4504 #else
4505     if (compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4506                          "int main(int argc,char *argv[])\n"
4507                          "{printf(\"%d\\n\",\n"
4508                          "  getenv(\"PATH\") != NULL ||\n"
4509                          "  getenv(\"HOME\") != NULL ||\n"
4510                          "  getenv(\"TERM\") != NULL ||\n"
4511                          "  getenv(\"LOGNAME\") != NULL ||\n"
4512                          "  getenv(\"PROMPT\") != NULL ||\n"
4513                          "  getenv(\"HOMEPATH\") != NULL ||\n"
4514                          "  getenv(\"USERNAME\") != NULL ||\n"
4515                          "  getenv(\"TEMP\") != NULL ||\n"
4516                          "  getenv(\"TMP\") != NULL ||\n"
4517                          "  getenv(\"OS\") != NULL);\n"
4518                          "return 0;}\n") && doTest() == 1) {
4519       os_getenv_stri = "getenv";
4520     } /* if */
4521 #endif
4522 #ifdef EMULATE_ENVIRONMENT
4523 #ifdef EMULATE_NODE_ENVIRONMENT
4524     os_setenv_stri = "setenvForNodeJs";
4525     os_unsetenv_stri = "unsetenvForNodeJs";
4526 #else
4527     os_setenv_stri = "setenv7";
4528     os_unsetenv_stri = "unsetenv7";
4529 #endif
4530     getenv_is_case_sensitive = 1;
4531 #elif defined OS_STRI_WCHAR
4532     if (compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4533                          "#include <string.h>\n"
4534                          "int main(int argc,char *argv[])\n"
4535                          "{printf(\"%d\\n\",\n"
4536                          "    (_wsetenv(L\"AsDfGhJkL\", L\"asdfghjkl\", 1) == 0 &&\n"
4537                          "     getenv(\"AsDfGhJkL\") != NULL &&\n"
4538                          "     strcmp(getenv(\"AsDfGhJkL\"), \"asdfghjkl\") == 0) +\n"
4539                          "    (getenv(\"ASDFGHJKL\") != NULL &&\n"
4540                          "     strcmp(getenv(\"ASDFGHJKL\"), \"asdfghjkl\") == 0));\n"
4541                          "return 0;}\n") && (test_result = doTest()) >= 1) {
4542       os_setenv_stri = "_wsetenv";
4543       getenv_is_case_sensitive = test_result == 1;
4544     } else if (compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4545                                 "#include <string.h>\n"
4546                                 "int main(int argc,char *argv[])\n"
4547                                 "{printf(\"%d\\n\",\n"
4548                                 "    (wsetenv(L\"AsDfGhJkL\", L\"asdfghjkl\", 1) == 0 &&\n"
4549                                 "     getenv(\"AsDfGhJkL\") != NULL &&\n"
4550                                 "     strcmp(getenv(\"AsDfGhJkL\"), \"asdfghjkl\") == 0) +\n"
4551                                 "    (getenv(\"ASDFGHJKL\") != NULL &&\n"
4552                                 "     strcmp(getenv(\"ASDFGHJKL\"), \"asdfghjkl\") == 0));\n"
4553                                 "return 0;}\n") && (test_result = doTest()) >= 1) {
4554       os_setenv_stri = "wsetenv";
4555       getenv_is_case_sensitive = test_result == 1;
4556     } /* if */
4557     if (os_setenv_stri != NULL) {
4558       sprintf(buffer, "#include <stdio.h>\n#include <stdlib.h>\n"
4559                       "#include <string.h>\n"
4560                       "int main(int argc,char *argv[])\n"
4561                       "{printf(\"%%d\\n\",\n"
4562                       "    (%s(L\"AsDfGhJkL\", L\"asdfghjkl\", 1) == 0 &&\n"
4563                       "     getenv(\"AsDfGhJkL\") != NULL &&\n"
4564                       "     _wunsetenv(L\"AsDfGhJkL\") == 0 &&\n"
4565                       "     getenv(\"AsDfGhJkL\") == NULL));\n"
4566                       "return 0;}\n", os_setenv_stri);
4567       if (compileAndLinkOk(buffer) && doTest() == 1) {
4568         os_unsetenv_stri = "_wunsetenv";
4569       } else {
4570         sprintf(buffer, "#include <stdio.h>\n#include <stdlib.h>\n"
4571                         "#include <string.h>\n"
4572                         "int main(int argc,char *argv[])\n"
4573                         "{printf(\"%%d\\n\",\n"
4574                         "    (%s(L\"AsDfGhJkL\", L\"asdfghjkl\", 1) == 0 &&\n"
4575                         "     getenv(\"AsDfGhJkL\") != NULL &&\n"
4576                         "     wunsetenv(L\"AsDfGhJkL\") == 0 &&\n"
4577                         "     getenv(\"AsDfGhJkL\") == NULL));\n"
4578                         "return 0;}\n", os_setenv_stri);
4579         if (compileAndLinkOk(buffer) && doTest() == 1) {
4580           os_unsetenv_stri = "wunsetenv";
4581         } /* if */
4582       } /* if */
4583     } /* if */
4584     if (os_setenv_stri != NULL && os_unsetenv_stri != NULL) {
4585       /* No need to consider putenv(). */
4586     } else if (!define_wgetenv &&
4587                compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4588                                 "#include <string.h>\n"
4589                                 "wchar_t *key_value = L\"AsDfGhJkL=asdfghjkl\";\n"
4590                                 "int main(int argc,char *argv[])\n"
4591                                 "{printf(\"%d\\n\",\n"
4592                                 "    (_wputenv(key_value) == 0 &&\n"
4593                                 "     getenv(\"AsDfGhJkL\") != NULL &&\n"
4594                                 "     strcmp(getenv(\"AsDfGhJkL\"), \"asdfghjkl\") == 0) +\n"
4595                                 "    (getenv(\"ASDFGHJKL\") != NULL &&\n"
4596                                 "     strcmp(getenv(\"ASDFGHJKL\"), \"asdfghjkl\") == 0));\n"
4597                                 "return 0;}\n") && (test_result = doTest()) >= 1) {
4598       os_putenv_stri = "_wputenv";
4599       getenv_is_case_sensitive = test_result == 1;
4600     } else if (!define_wgetenv &&
4601                compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4602                                 "#include <string.h>\n"
4603                                 "wchar_t *key_value = L\"AsDfGhJkL=asdfghjkl\";\n"
4604                                 "int main(int argc,char *argv[])\n"
4605                                 "{printf(\"%d\\n\",\n"
4606                                 "    (wputenv(key_value) == 0 &&\n"
4607                                 "     getenv(\"AsDfGhJkL\") != NULL &&\n"
4608                                 "     strcmp(getenv(\"AsDfGhJkL\"), \"asdfghjkl\") == 0) +\n"
4609                                 "    (getenv(\"ASDFGHJKL\") != NULL &&\n"
4610                                 "     strcmp(getenv(\"ASDFGHJKL\"), \"asdfghjkl\") == 0));\n"
4611                                 "return 0;}\n") && (test_result = doTest()) >= 1) {
4612       os_putenv_stri = "wputenv";
4613       getenv_is_case_sensitive = test_result == 1;
4614     } else if (!define_wgetenv &&
4615                compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4616                                 "#include <string.h>\n#include <windows.h>\n"
4617                                 "int main(int argc,char *argv[])\n"
4618                                 "{printf(\"%d\\n\",\n"
4619                                 "    (SetEnvironmentVariableW(L\"AsDfGhJkL\", L\"asdfghjkl\") != 0 &&\n"
4620                                 "     getenv(\"AsDfGhJkL\") != NULL &&\n"
4621                                 "     strcmp(getenv(\"AsDfGhJkL\"), \"asdfghjkl\") == 0) +\n"
4622                                 "    (getenv(\"ASDFGHJKL\") != NULL &&\n"
4623                                 "     strcmp(getenv(\"ASDFGHJKL\"), \"asdfghjkl\") == 0));\n"
4624                                 "return 0;}\n") && (test_result = doTest()) >= 1) {
4625       define_wsetenv = 1;
4626       os_setenv_stri = "wsetenv";
4627       getenv_is_case_sensitive = test_result == 1;
4628     } else if (compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4629                                 "#include <string.h>\n#include <windows.h>\n"
4630                                 "int main(int argc,char *argv[])\n"
4631                                 "{char buf1[10], buf2[10];\n"
4632                                 "printf(\"%d\\n\",\n"
4633                                 "    (SetEnvironmentVariableW(L\"AsDfGhJkL\", L\"asdfghjkl\") != 0 &&\n"
4634                                 "     GetEnvironmentVariable(\"AsDfGhJkL\", buf1, 10) == 9 &&\n"
4635                                 "     strcmp(buf1, \"asdfghjkl\") == 0) +\n"
4636                                 "    (GetEnvironmentVariable(\"ASDFGHJKL\", buf2, 10) == 9 &&\n"
4637                                 "     strcmp(buf2, \"asdfghjkl\") == 0));\n"
4638                                 "return 0;}\n") && (test_result = doTest()) >= 1) {
4639       define_wsetenv = 1;
4640       os_setenv_stri = "wsetenv";
4641       getenv_is_case_sensitive = test_result == 1;
4642     } else {
4643       fprintf(logFile, "\nAssume that wsetenv() should be defined.\n");
4644       define_wsetenv = 1;
4645       os_setenv_stri = "wsetenv";
4646     } /* if */
4647     if (os_putenv_stri != NULL) {
4648       sprintf(buffer, "#include <stdio.h>\n#include <stdlib.h>\n"
4649                       "#include <string.h>\n"
4650                       "wchar_t *key_value = L\"AsDfGhJkL=asdfghjkl\";\n"
4651                       "wchar_t *key_no_value = L\"AsDfGhJkL=\";\n"
4652                       "wchar_t *key_missing = L\"QqAaWwSsEeDdRrFfTtGg=\";\n"
4653                       "int main(int argc,char *argv[])\n"
4654                       "{printf(\"%%d\\n\",\n"
4655                       "    %s(key_value) == 0 &&\n"
4656                       "    getenv(\"AsDfGhJkL\") != NULL &&\n"
4657                       "    %s(key_no_value) == 0 &&\n"
4658                       "    getenv(\"AsDfGhJkL\") == NULL &&\n"
4659                       "    %s(key_missing) == 0);\n"
4660                       "return 0;}\n", os_putenv_stri, os_putenv_stri, os_putenv_stri);
4661       if (compileAndLinkOk(buffer) && doTest() == 1) {
4662         putenv_can_remove_keys = 1;
4663       } /* if */
4664     } else if (define_wsetenv) {
4665       if (os_getenv_stri != NULL && !define_wgetenv) {
4666         sprintf(buffer, "#include <stdio.h>\n#include <stdlib.h>\n"
4667                         "#include <string.h>\n#include <windows.h>\n"
4668                         "int main(int argc,char *argv[])\n"
4669                         "{printf(\"%%d\\n\",\n"
4670                         "    SetEnvironmentVariableW(L\"AsDfGhJkL\", L\"asdfghjkl\") != 0 &&\n"
4671                         "    %s(L\"AsDfGhJkL\") != NULL &&\n"
4672                         "    SetEnvironmentVariableW(L\"AsDfGhJkL\", NULL) != 0 &&\n"
4673                         "    %s(L\"AsDfGhJkL\") == NULL);\n"
4674                         "return 0;}\n", os_getenv_stri, os_getenv_stri);
4675         if (compileAndLinkOk(buffer) && doTest() == 1) {
4676           define_wunsetenv = 1;
4677           os_unsetenv_stri = "wunsetenv";
4678         } /* if */
4679       } /* if */
4680       if (!define_wunsetenv &&
4681           compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4682                            "#include <string.h>\n#include <windows.h>\n"
4683                            "int main(int argc,char *argv[])\n"
4684                            "{wchar_t buf1[10], buf2[10];\n"
4685                            "printf(\"%d\\n\",\n"
4686                            "    SetEnvironmentVariableW(L\"AsDfGhJkL\", L\"asdfghjkl\") != 0 &&\n"
4687                            "    GetEnvironmentVariableW(L\"AsDfGhJkL\", buf1, 10) == 9 &&\n"
4688                            "    SetEnvironmentVariableW(L\"AsDfGhJkL\", NULL) != 0 &&\n"
4689                            "    GetEnvironmentVariableW(L\"AsDfGhJkL\", buf2, 10) == 0);\n"
4690                            "return 0;}\n") && doTest() == 1) {
4691         /* Either define_wgetenv is already active or os_getenv_stri() */
4692         /* is not able to receive the correct result after */
4693         /* SetEnvironmentVariableW() has been called. */
4694         define_wgetenv = 1;
4695         os_getenv_stri = "wgetenv";
4696         define_wunsetenv = 1;
4697         os_unsetenv_stri = "wunsetenv";
4698       } /* if */
4699     } /* if */
4700 #else
4701     if (compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4702                          "#include <string.h>\n"
4703                          "int main(int argc,char *argv[])\n"
4704                          "{printf(\"%d\\n\",\n"
4705                          "    (setenv(\"AsDfGhJkL\", \"asdfghjkl\", 1) == 0 &&\n"
4706                          "     getenv(\"AsDfGhJkL\") != NULL &&\n"
4707                          "     strcmp(getenv(\"AsDfGhJkL\"), \"asdfghjkl\") == 0) +\n"
4708                          "    (getenv(\"ASDFGHJKL\") != NULL &&\n"
4709                          "     strcmp(getenv(\"ASDFGHJKL\"), \"asdfghjkl\") == 0));\n"
4710                          "return 0;}\n") && (test_result = doTest()) >= 1) {
4711       os_setenv_stri = "setenv";
4712       getenv_is_case_sensitive = test_result == 1;
4713     } else if (compileAndLinkOk("#include <stdio.h>\n#include <stdlib.h>\n"
4714                                 "#include <string.h>\n"
4715                                 "char *key_value = \"AsDfGhJkL=asdfghjkl\";\n"
4716                                 "int main(int argc,char *argv[])\n"
4717                                 "{printf(\"%d\\n\",\n"
4718                                 "    (putenv(key_value) == 0 &&\n"
4719                                 "     getenv(\"AsDfGhJkL\") != NULL &&\n"
4720                                 "     strcmp(getenv(\"AsDfGhJkL\"), \"asdfghjkl\") == 0) +\n"
4721                                 "    (getenv(\"ASDFGHJKL\") != NULL &&\n"
4722                                 "     strcmp(getenv(\"ASDFGHJKL\"), \"asdfghjkl\") == 0));\n"
4723                                 "return 0;}\n") && (test_result = doTest()) >= 1) {
4724       os_putenv_stri = "putenv";
4725       getenv_is_case_sensitive = test_result == 1;
4726     } /* if */
4727     if (os_setenv_stri != NULL) {
4728       sprintf(buffer, "#include <stdio.h>\n#include <stdlib.h>\n"
4729                       "#include <string.h>\n"
4730                       "int main(int argc,char *argv[])\n"
4731                       "{printf(\"%%d\\n\",\n"
4732                       "    (%s(\"AsDfGhJkL\", \"asdfghjkl\", 1) == 0 &&\n"
4733                       "     getenv(\"AsDfGhJkL\") != NULL &&\n"
4734                       "     unsetenv(\"AsDfGhJkL\") == 0 &&\n"
4735                       "     getenv(\"AsDfGhJkL\") == NULL));\n"
4736                       "return 0;}\n", os_setenv_stri);
4737       if (compileAndLinkOk(buffer) && doTest() == 1) {
4738         os_unsetenv_stri = "unsetenv";
4739       } /* if */
4740     } /* if */
4741 #endif
4742     if (define_wgetenv) {
4743       fputs("#define DEFINE_WGETENV\n", versionFile);
4744     } /* if */
4745     if (os_getenv_stri != NULL) {
4746       fprintf(versionFile, "#define os_getenv %s\n", os_getenv_stri);
4747     } else {
4748       fprintf(logFile, "\n *** Cannot define os_getenv.\n");
4749     } /* if */
4750     if (getenv_is_case_sensitive != -1) {
4751       fprintf(versionFile, "#define GETENV_IS_CASE_SENSITIVE %d\n",
4752               getenv_is_case_sensitive);
4753     } /* if */
4754     if (os_setenv_stri != NULL) {
4755       if (define_wsetenv) {
4756         fputs("#define DEFINE_WSETENV\n", versionFile);
4757       } /* if */
4758       fprintf(versionFile, "#define os_setenv %s\n", os_setenv_stri);
4759 #ifndef EMULATE_ENVIRONMENT
4760       if (define_wgetenv) {
4761         sprintf(getenv_definition,
4762                 "#ifndef WINDOWS_H_INCLUDED\n"
4763                 "#include <windows.h>\n"
4764                 "#define WINDOWS_H_INCLUDED\n"
4765                 "#endif\n"
4766                 "wchar_t *wgetenv (wchar_t *name) {\n"
4767                 "  size_t value_size;\n"
4768                 "  wchar_t *value;\n"
4769                 "  value_size = GetEnvironmentVariableW(name, NULL, 0);\n"
4770                 "  if (value_size == 0) {\n"
4771                 "    value = NULL;\n"
4772                 "  } else {\n"
4773                 "    if ((value = malloc(value_size * sizeof(wchar_t))) != NULL) {\n"
4774                 "      if (GetEnvironmentVariableW(name, value, value_size) != value_size - 1) {\n"
4775                 "        free(value);\n"
4776                 "        value = NULL;\n"
4777                 "      } /* if */\n"
4778                 "    } /* if */\n"
4779                 "  } /* if */\n"
4780                 "  return value;\n"
4781                 "}\n");
4782       } else {
4783         getenv_definition[0] = '\0';
4784       } /* if */
4785       if (define_wsetenv) {
4786         sprintf(setenv_definition,
4787                 "#ifndef WINDOWS_H_INCLUDED\n"
4788                 "#include <windows.h>\n"
4789                 "#define WINDOWS_H_INCLUDED\n"
4790                 "#endif\n"
4791                 "int wsetenv (wchar_t *name, wchar_t *value, int overwrite) {\n"
4792                 "return !SetEnvironmentVariableW(name, value);\n"
4793                 "}\n");
4794       } else {
4795         setenv_definition[0] = '\0';
4796       } /* if */
4797       sprintf(buffer, "#include <stdio.h>\n"
4798                       "#include <stdlib.h>\n"
4799                       "#include <string.h>\n"
4800                       "#include <wchar.h>\n"
4801                       "%s\n"
4802                       "%s\n"
4803                       "int main(int argc,char *argv[]){\n"
4804                       "int setenv_result;\n"
4805                       "int setenv_okay;\n"
4806                       "int getenv_okay = 0;\n"
4807 #ifdef OS_STRI_WCHAR
4808                       "wchar_t *key = L\"ASDF=ghjkl\";\n"
4809                       "wchar_t *value = L\"asdfghjkl\";\n"
4810                       "wchar_t *getenv_result;\n"
4811 #else
4812                       "char *key = \"ASDF=ghjkl\";\n"
4813                       "char *value = \"asdfghjkl\";\n"
4814                       "char *getenv_result;\n"
4815 #endif
4816                       "setenv_result = %s(key, value, 1);\n"
4817                       "setenv_okay = setenv_result == 0;\n"
4818                       "getenv_result = %s(key);\n"
4819                       "getenv_okay = getenv_result != NULL;\n"
4820                       "if (setenv_okay && getenv_okay) {\n"
4821 #ifdef OS_STRI_WCHAR
4822                       "  getenv_okay = wcscmp(getenv_result, value);\n"
4823 #else
4824                       "  getenv_okay = strcmp(getenv_result, value);\n"
4825 #endif
4826                       "}\n"
4827                       "printf(\"%%d\\n\", setenv_okay + 2 * getenv_okay);\n"
4828                       "return 0;}\n",
4829                       getenv_definition, setenv_definition,
4830                       os_setenv_stri, os_getenv_stri);
4831       if (assertCompAndLnk(buffer) && (test_result = doTest()) >= 0) {
4832         fprintf(versionFile, "#define SETENV_ALLOWS_KEY_WITH_EQUALS_SIGN %d\n",
4833                 test_result & 1);
4834         fprintf(versionFile, "#define GETENV_ALLOWS_KEY_WITH_EQUALS_SIGN %d\n",
4835                 test_result >> 1);
4836       } /* if */
4837 #endif
4838     } /* if */
4839     if ((os_setenv_stri == NULL || os_unsetenv_stri == NULL) &&
4840         os_putenv_stri != NULL && os_getenv_stri != NULL && !define_wgetenv) {
4841       fprintf(versionFile, "#define os_putenv %s\n", os_putenv_stri);
4842       sprintf(buffer, "#include <stdio.h>\n"
4843                       "#include <stdlib.h>\n"
4844                       "#include <string.h>\n"
4845                       "#include <wchar.h>\n"
4846                       "int main(int argc,char *argv[]){\n"
4847 #ifdef OS_STRI_WCHAR
4848                       "wchar_t *key_value = L\"ASDFGHJKL=asdfghjkl\";\n"
4849                       "wchar_t *value;\n"
4850                       "%s(key_value);\n"
4851                       "value = %s(L\"ASDFGHJKL\");\n"
4852                       "printf(\"%%d\\n\", value != NULL &&\n"
4853                       "  wcschr(key_value, '=') + 1 != value);\n"
4854 #else
4855                       "char *key_value = \"ASDFGHJKL=asdfghjkl\";\n"
4856                       "char *value;\n"
4857                       "%s(key_value);\n"
4858                       "value = %s(\"ASDFGHJKL\");\n"
4859                       "printf(\"%%d\\n\", value != NULL &&\n"
4860                       "  strchr(key_value, '=') + 1 != value);\n"
4861 #endif
4862                       "return 0;}\n", os_putenv_stri, os_getenv_stri);
4863       if (assertCompAndLnk(buffer)) {
4864         /* There are two possible implementations of putenv():  */
4865         /* 1. Putenv inserts its argument into the environment. */
4866         /*    In this case the argument of putenv() must not be */
4867         /*    changed afterwards.                               */
4868         /* 2. Putenv inserts a copy of its argument into the    */
4869         /*    environment. In this case it is okay to delete    */
4870         /*    the argument of putenv() afterwards.              */
4871         fprintf(versionFile, "#define DELETE_PUTENV_ARGUMENT %d\n", doTest());
4872       } /* if */
4873       fprintf(versionFile, "#define PUTENV_CAN_REMOVE_KEYS %d\n",
4874               putenv_can_remove_keys);
4875     } else if (os_setenv_stri == NULL) {
4876       fprintf(logFile, "\n *** Cannot define os_setenv or os_putenv.\n");
4877     } /* if */
4878     if (os_unsetenv_stri != NULL) {
4879       if (define_wunsetenv) {
4880         fputs("#define DEFINE_WUNSETENV\n", versionFile);
4881       } /* if */
4882       fprintf(versionFile, "#define os_unsetenv %s\n", os_unsetenv_stri);
4883     } /* if */
4884   } /* determineEnvironDefines */
4885 
4886 
4887 
4888 static void determineOsUtime (FILE *versionFile)
4889 
4890   {
4891     const char *utime_include = NULL;
4892     const char *os_utimbuf_struct_stri = NULL;
4893     const char *os_utime_stri = NULL;
4894     char buffer[BUFFER_SIZE];
4895 
4896   /* determineOsUtime */
4897     if (compileAndLinkOk("#include <stdio.h>\n#include <utime.h>\n"
4898                          "int main(int argc,char *argv[])\n"
4899                          "{struct _utimbuf buf; buf.actime = 0, buf.modtime = 0;\n"
4900                          "printf(\"%d\\n\", &buf != NULL); return 0;}\n")) {
4901       utime_include = "utime.h";
4902       os_utimbuf_struct_stri = "struct _utimbuf";
4903     } else if (compileAndLinkOk("#include <stdio.h>\n#include <utime.h>\n"
4904                          "int main(int argc,char *argv[])\n"
4905                          "{struct utimbuf buf; buf.actime = 0, buf.modtime = 0;\n"
4906                          "printf(\"%d\\n\", &buf != NULL); return 0;}\n")) {
4907       utime_include = "utime.h";
4908       os_utimbuf_struct_stri = "struct utimbuf";
4909     } else if (compileAndLinkOk("#include <stdio.h>\n#include <sys/utime.h>\n"
4910                          "int main(int argc,char *argv[])\n"
4911                          "{struct _utimbuf buf; buf.actime = 0, buf.modtime = 0;\n"
4912                          "printf(\"%d\\n\", &buf != NULL); return 0;}\n")) {
4913       utime_include = "sys/utime.h";
4914       os_utimbuf_struct_stri = "struct _utimbuf";
4915       fputs("#define INCLUDE_SYS_UTIME\n", versionFile);
4916     } else if (compileAndLinkOk("#include <stdio.h>\n#include <sys/utime.h>\n"
4917                          "int main(int argc,char *argv[])\n"
4918                          "{struct utimbuf buf; buf.actime = 0, buf.modtime = 0;\n"
4919                          "printf(\"%d\\n\", &buf != NULL); return 0;}\n")) {
4920       utime_include = "sys/utime.h";
4921       os_utimbuf_struct_stri = "struct utimbuf";
4922       fputs("#define INCLUDE_SYS_UTIME\n", versionFile);
4923     } /* if */
4924     if (utime_include == NULL || os_utimbuf_struct_stri == NULL) {
4925       fprintf(logFile, "\n *** Cannot find utime.h include and os_utimbuf_struct.\n");
4926     } else {
4927       fprintf(versionFile, "#define os_utimbuf_struct %s\n", os_utimbuf_struct_stri);
4928       sprintf(buffer, "#include <stdio.h>\n#include <%s>\n"
4929                       "int main(int argc,char *argv[])\n"
4930                       "{%s buf; buf.actime = 0, buf.modtime = 0;\n"
4931                       "printf(\"%%d\\n\", _wutime(L\"testfile\", &buf) != -1);return 0;}\n",
4932                       utime_include, os_utimbuf_struct_stri);
4933       if (compileAndLinkOk(buffer)) {
4934         os_utime_stri = "_wutime";
4935       } else {
4936         sprintf(buffer, "#include <stdio.h>\n#include <%s>\n"
4937                         "int main(int argc,char *argv[])\n"
4938                         "{%s buf; buf.actime = 0, buf.modtime = 0;\n"
4939                         "printf(\"%%d\\n\", wutime(L\"testfile\", &buf) != -1);return 0;}\n",
4940                         utime_include, os_utimbuf_struct_stri);
4941         if (compileAndLinkOk(buffer)) {
4942           os_utime_stri = "wutime";
4943         } /* if */
4944       } /* if */
4945       if (os_utime_stri != NULL) {
4946         sprintf(buffer,
4947                 "#include <stdio.h>\n#include <%s>\n#include <errno.h>\n%s\n%s"
4948                 "int main(int argc,char *argv[])"
4949                 "{%s utime_buf;makeDir(\"tmp_empty_dir2\",0755);\n"
4950                 "utime_buf.actime=1234567890;utime_buf.modtime=1234567890;\n"
4951                 "printf(\"%%d\\n\",utime(\"tmp_empty_dir2\",&utime_buf)!=0&&errno==EACCES);\n"
4952                 "if(remove(\"tmp_empty_dir2\")!=0)removeDir(\"tmp_empty_dir2\");return 0;}\n",
4953                 utime_include, makeDirDefinition, removeDirDefinition, os_utimbuf_struct_stri);
4954         if (compileAndLinkOk(buffer) && doTest() == 1) {
4955           fputs("#define USE_ALTERNATE_UTIME\n", versionFile);
4956           fprintf(versionFile, "#define os_utime_orig %s\n", os_utime_stri);
4957           fputs("#define os_utime alternate_utime\n", versionFile);
4958         } else {
4959           fprintf(versionFile, "#define os_utime %s\n", os_utime_stri);
4960         } /* if */
4961       } else {
4962         fputs("#define USE_ALTERNATE_UTIME\n", versionFile);
4963         fputs("#define os_utime alternate_utime\n", versionFile);
4964       } /* if */
4965     } /* if */
4966   } /* determineOsUtime */
4967 
4968 
4969 
4970 #ifdef OS_STRI_WCHAR
4971 static void determineStatFunctions (FILE *versionFile)
4972 
4973   {
4974     char buffer[BUFFER_SIZE];
4975     char *os_stat_struct_stri = NULL;
4976     char *os_fstat_func = NULL;
4977     char *os_fstat_struct_stri = NULL;
4978     char *os_fstat_orig_func = NULL;
4979     char *os_fstat_struct_orig_stri = NULL;
4980     int has_struct_stati64 = 0;
4981 
4982   /* determineStatFunctions */
4983 #if !defined os_lstat || !defined os_stat
4984     fputs("#define DEFINE_WSTATI64_EXT\n", versionFile);
4985 #endif
4986 #ifndef os_lstat
4987     fputs("#define os_lstat wstati64Ext\n", versionFile);
4988 #endif
4989 #ifndef os_stat
4990     fputs("#define os_stat wstati64Ext\n", versionFile);
4991 #endif
4992 #ifndef os_stat_struct
4993     if (compileAndLinkWithOptionsOk("#include <sys/types.h>\n"
4994                                     "#include <sys/stat.h>\n"
4995                                     "int main(int argc,char *argv[])\n"
4996                                     "{struct _stati64 statData;\n"
4997                                     "return 0;}\n", "", SYSTEM_LIBS)) {
4998       has_struct_stati64 = 1;
4999       os_stat_struct_stri = "struct _stati64";
5000     } else if (compileAndLinkWithOptionsOk("#include <sys/types.h>\n"
5001                                            "#include <sys/stat.h>\n"
5002                                            "int main(int argc,char *argv[])\n"
5003                                            "{struct stati64 statData;\n"
5004                                            "return 0;}\n", "", SYSTEM_LIBS)) {
5005       has_struct_stati64 = 1;
5006       os_stat_struct_stri = "struct stati64";
5007     } else {
5008       fputs("#define DEFINE_STRUCT_STATI64_EXT\n", versionFile);
5009       os_stat_struct_stri = "struct stati64Ext";
5010     } /* if */
5011     if (has_struct_stati64) {
5012       sprintf(buffer, "#include <stdio.h>\n"
5013                       "#include <sys/types.h>\n"
5014                       "#include <sys/stat.h>\n"
5015                       "int main(int argc,char *argv[])\n"
5016                       "{%s statData;\n"
5017                       "printf(\"%%d\\n\",\n"
5018                       "    _wstati64(L\".\", &statData) == 0);\n"
5019                       "return 0;}\n",
5020                       os_stat_struct_stri);
5021       if (compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS)) {
5022         fputs("#define os_stat_orig _wstati64\n", versionFile);
5023       } else {
5024         sprintf(buffer, "#include <stdio.h>\n"
5025                         "#include <sys/types.h>\n"
5026                         "#include <sys/stat.h>\n"
5027                         "int main(int argc,char *argv[])\n"
5028                         "{%s statData;\n"
5029                         "printf(\"%%d\\n\",\n"
5030                         "    wstati64(L\".\", &statData) == 0);\n"
5031                         "return 0;}\n",
5032                         os_stat_struct_stri);
5033         if (compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS)) {
5034           fputs("#define os_stat_orig wstati64\n", versionFile);
5035         } /* if */
5036       } /* if */
5037     } /* if */
5038     fprintf(versionFile, "#define os_stat_struct %s\n", os_stat_struct_stri);
5039 #endif
5040 #ifndef os_fstat
5041     if (has_struct_stati64) {
5042       sprintf(buffer, "#include <stdio.h>\n"
5043                       "#include <sys/types.h>\n#include <sys/stat.h>\n"
5044                       "int main(int argc,char *argv[])\n"
5045                       "{%s statData;\n"
5046                       "printf(\"%%d\\n\",\n"
5047                       "    _fstati64(0, &statData) == 0);\n"
5048                       "return 0;}\n",
5049                       os_stat_struct_stri);
5050       if (compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS)) {
5051         os_fstat_func ="_fstati64";
5052         os_fstat_struct_stri = os_stat_struct_stri;
5053       } else {
5054         sprintf(buffer, "#include <stdio.h>\n"
5055                         "#include <sys/types.h>\n#include <sys/stat.h>\n"
5056                         "int main(int argc,char *argv[])\n"
5057                         "{%s statData;\n"
5058                         "printf(\"%%d\\n\",\n"
5059                         "    fstati64(0, &statData) == 0);\n"
5060                         "return 0;}\n",
5061                         os_stat_struct_stri);
5062         if (compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS)) {
5063           os_fstat_func ="fstati64";
5064           os_fstat_struct_stri = os_stat_struct_stri;
5065         } /* if */
5066       } /* if */
5067     } /* if */
5068     if (os_fstat_struct_stri == NULL) {
5069       if (compileAndLinkWithOptionsOk("#include <stdio.h>\n"
5070                                       "#include <sys/types.h>\n"
5071                                       "#include <sys/stat.h>\n"
5072                                       "int main(int argc,char *argv[])\n"
5073                                       "{struct _stat statData;\n"
5074                                       "printf(\"%d\\n\",\n"
5075                                       "    _fstat(0, &statData) == 0);\n"
5076                                       "return 0;}\n", "", SYSTEM_LIBS)) {
5077         os_fstat_orig_func = "_fstat";
5078         os_fstat_struct_orig_stri = "struct _stat";
5079         if (!has_struct_stati64) {
5080           os_fstat_func ="_fstat";
5081           os_fstat_struct_stri = "struct _stat";
5082         } /* if */
5083       } else if (compileAndLinkWithOptionsOk("#include <stdio.h>\n"
5084                                              "#include <sys/types.h>\n"
5085                                              "#include <sys/stat.h>\n"
5086                                              "int main(int argc,char *argv[])\n"
5087                                              "{struct stat statData;\n"
5088                                              "printf(\"%d\\n\",\n"
5089                                              "    _fstat(0, &statData) == 0);\n"
5090                                              "return 0;}\n", "", SYSTEM_LIBS)) {
5091         os_fstat_orig_func = "_fstat";
5092         os_fstat_struct_orig_stri = "struct stat";
5093         if (!has_struct_stati64) {
5094           os_fstat_func ="_fstat";
5095           os_fstat_struct_stri = "struct stat";
5096         } /* if */
5097       } else if (compileAndLinkWithOptionsOk("#include <stdio.h>\n"
5098                                              "#include <sys/types.h>\n"
5099                                              "#include <sys/stat.h>\n"
5100                                              "int main(int argc,char *argv[])\n"
5101                                              "{struct _stat statData;\n"
5102                                              "printf(\"%d\\n\",\n"
5103                                              "    fstat(0, &statData) == 0);\n"
5104                                              "return 0;}\n", "", SYSTEM_LIBS)) {
5105         os_fstat_orig_func = "fstat";
5106         os_fstat_struct_orig_stri = "struct _stat";
5107         if (!has_struct_stati64) {
5108           os_fstat_func ="fstat";
5109           os_fstat_struct_stri = "struct _stat";
5110         } /* if */
5111       } else if (compileAndLinkWithOptionsOk("#include <stdio.h>\n"
5112                                              "#include <sys/types.h>\n"
5113                                              "#include <sys/stat.h>\n"
5114                                              "int main(int argc,char *argv[])\n"
5115                                              "{struct stat statData;\n"
5116                                              "printf(\"%d\\n\",\n"
5117                                              "    fstat(0, &statData) == 0);\n"
5118                                              "return 0;}\n", "", SYSTEM_LIBS)) {
5119         os_fstat_orig_func = "fstat";
5120         os_fstat_struct_orig_stri = "struct stat";
5121         if (!has_struct_stati64) {
5122           os_fstat_func ="fstat";
5123           os_fstat_struct_stri = "struct stat";
5124         } /* if */
5125       } /* if */
5126     } /* if */
5127     if (os_fstat_struct_stri == NULL) {
5128       if (os_fstat_orig_func != NULL && os_fstat_struct_orig_stri != NULL) {
5129         fprintf(versionFile, "#define os_fstat_orig %s\n", os_fstat_orig_func);
5130         fprintf(versionFile, "#define os_fstat_struct_orig %s\n", os_fstat_struct_orig_stri);
5131       } /* if */
5132       os_fstat_struct_stri = os_stat_struct_stri;
5133       fputs("#define DEFINE_FSTATI64_EXT\n", versionFile);
5134       os_fstat_func ="fstati64Ext";
5135     } else if (os_fstat_orig_func != NULL && os_fstat_struct_orig_stri != NULL) {
5136       sprintf(buffer, "#include <stdio.h>\n"
5137                       "#include <sys/types.h>\n#include <sys/stat.h>\n"
5138                       "int main(int argc,char *argv[])\n"
5139                       "{%s statData;\n"
5140                       "printf(\"%%d\\n\", sizeof(statData.st_size));\n"
5141                       "return 0;}\n",
5142                       os_fstat_struct_orig_stri);
5143       if (compileAndLinkWithOptionsOk(buffer, "", SYSTEM_LIBS) ||
5144           doTest() != 8) {
5145         fprintf(versionFile, "#define os_fstat_orig %s\n", os_fstat_orig_func);
5146         fprintf(versionFile, "#define os_fstat_struct_orig %s\n", os_fstat_struct_orig_stri);
5147         os_fstat_struct_stri = os_stat_struct_stri;
5148         fputs("#define DEFINE_FSTATI64_EXT\n", versionFile);
5149         os_fstat_func ="fstati64Ext";
5150       } /* if */
5151     } /* if */
5152     if (os_fstat_func != NULL) {
5153       fprintf(versionFile, "#define os_fstat %s\n", os_fstat_func);
5154     } /* if */
5155     if (os_stat_struct_stri != NULL && os_fstat_struct_stri != NULL &&
5156         strcmp(os_stat_struct_stri, os_fstat_struct_stri) != 0) {
5157       fprintf(versionFile, "#define os_fstat_struct %s\n", os_fstat_struct_stri);
5158     } /* if */
5159 #endif
5160   } /* determineStatFunctions */
5161 
5162 
5163 
5164 static void determineOsWCharFunctions (FILE *versionFile)
5165 
5166   { /* determineOsWCharFunctions */
5167     determineStatFunctions(versionFile);
5168 #ifndef os_chdir
5169     if (compileAndLinkWithOptionsOk("#include <stdio.h>\n#include <direct.h>\n"
5170                                     "int main(int argc,char *argv[])\n"
5171                                     "{printf(\"%d\\n\",\n"
5172                                     "    _wchdir(L\"..\") != -1);\n"
5173                                     "return 0;}\n", "", SYSTEM_LIBS)) {
5174       fputs("#define os_chdir _wchdir\n", versionFile);
5175     } else {
5176       fprintf(logFile, "\n *** Cannot define os_chdir.\n");
5177       showErrors();
5178     } /* if */
5179 #endif
5180 #ifndef os_getcwd
5181     if (compileAndLinkWithOptionsOk("#include <stdio.h>\n#include <wchar.h>\n"
5182                                     "#include <direct.h>\n"
5183                                     "int main(int argc,char *argv[])\n"
5184                                     "{wchar_t buffer[1024];\n"
5185                                     "printf(\"%d\\n\",\n"
5186                                     "    _wgetcwd(buffer, 1024) != NULL);\n"
5187                                     "return 0;}\n", "", SYSTEM_LIBS)) {
5188       fputs("#define OS_GETCWD_MAX_BUFFER_SIZE INT_MAX\n", versionFile);
5189       fputs("#define os_getcwd(buf,size) _wgetcwd((buf),(int)(size))\n", versionFile);
5190     } else {
5191       fprintf(logFile, "\n *** Cannot define os_getcwd.\n");
5192       showErrors();
5193     } /* if */
5194 #endif
5195 #ifndef os_mkdir
5196     if (compileAndLinkWithOptionsOk("#include <stdio.h>\n#include <direct.h>\n"
5197                                     "int main(int argc,char *argv[])\n"
5198                                     "{printf(\"%d\\n\",\n"
5199                                     "    _wmkdir(L\"testdir\") != -1);\n"
5200                                     "return 0;}\n", "", SYSTEM_LIBS)) {
5201       fputs("#define os_mkdir(path,mode) _wmkdir(path)\n", versionFile);
5202     } else {
5203       fprintf(logFile, "\n *** Cannot define os_mkdir.\n");
5204       showErrors();
5205     } /* if */
5206 #endif
5207 #ifndef os_rmdir
5208     if (compileAndLinkWithOptionsOk("#include <stdio.h>\n#include <direct.h>\n"
5209                                     "int main(int argc,char *argv[])\n"
5210                                     "{printf(\"%d\\n\",\n"
5211                                     "    _wrmdir(L\"testdir\") != -1);\n"
5212                                     "return 0;}\n", "", SYSTEM_LIBS)) {
5213       fputs("#define os_rmdir _wrmdir\n", versionFile);
5214     } else {
5215       fprintf(logFile, "\n *** Cannot define os_rmdir.\n");
5216       showErrors();
5217     } /* if */
5218 #endif
5219 #ifndef os_chmod
5220     if (compileAndLinkWithOptionsOk("#include <stdio.h>\n#include <direct.h>\n"
5221                                     "int main(int argc,char *argv[])\n"
5222                                     "{printf(\"%d\\n\",\n"
5223                                     "    _wchmod(L\"testfile\",0777) != -1);\n"
5224                                     "return 0;}\n", "", SYSTEM_LIBS)) {
5225       fputs("#define os_chmod _wchmod\n", versionFile);
5226     } else if (compileAndLinkWithOptionsOk("#include <stdio.h>\n#include <direct.h>\n\n"
5227                                            "#include <io.h>\n"
5228                                            "int main(int argc,char *argv[])\n"
5229                                            "{printf(\"%d\\n\",\n"
5230                                            "    _wchmod(L\"testfile\",0777) != -1);\n"
5231                                            "return 0;}\n", "", SYSTEM_LIBS)) {
5232       fputs("#define OS_CHMOD_INCLUDE_IO_H\n", versionFile);
5233       fputs("#define os_chmod _wchmod\n", versionFile);
5234     } else {
5235       fprintf(logFile, "\n *** Cannot define os_chmod.\n");
5236       showErrors();
5237     } /* if */
5238 #endif
5239 #ifndef os_chown
5240     fputs("#define os_chown(name,uid,gid)\n", versionFile);
5241 #endif
5242 #ifndef os_utime
5243     determineOsUtime(versionFile);
5244 #endif
5245 #ifndef os_remove
5246     if (compileAndLinkWithOptionsOk("#include <stdio.h>\n"
5247                                     "int main(int argc,char *argv[])\n"
5248                                     "{printf(\"%d\\n\", _wremove(L\"testfile\") != -1);\n"
5249                                     "return 0;}\n", "", SYSTEM_LIBS)) {
5250       fputs("#define os_remove _wremove\n", versionFile);
5251     } else {
5252       fprintf(logFile, "\n *** Cannot define os_remove.\n");
5253       showErrors();
5254     } /* if */
5255 #endif
5256 #ifndef os_rename
5257     if (compileAndLinkWithOptionsOk("#include <stdio.h>\n"
5258                                     "int main(int argc,char *argv[])\n"
5259                                     "{printf(\"%d\\n\",\n"
5260                                     "    _wrename(L\"testfile\", L\"newname\") == 0);\n"
5261                                     "return 0;}\n", "", SYSTEM_LIBS)) {
5262       fputs("#define os_rename _wrename\n", versionFile);
5263     } else {
5264       fprintf(logFile, "\n *** Cannot define os_rename.\n");
5265       showErrors();
5266     } /* if */
5267 #endif
5268 #ifndef os_system
5269     if (compileAndLinkWithOptionsOk("#include <stdio.h>\n#include <stdlib.h>\n"
5270                                     "int main(int argc,char *argv[])\n"
5271                                     "{printf(\"%d\\n\",\n"
5272                                     "    _wsystem(L\"pwd\") != -1);\n"
5273                                     "return 0;}\n", "", SYSTEM_LIBS)) {
5274       fputs("#define os_system _wsystem\n", versionFile);
5275     } else {
5276       fprintf(logFile, "\n *** Cannot define os_system.\n");
5277       showErrors();
5278     } /* if */
5279 #endif
5280 #ifndef os_fopen
5281     if (compileAndLinkWithOptionsOk("#include <stdio.h>\n"
5282                                     "int main(int argc,char *argv[])\n"
5283                                     "{printf(\"%d\\n\",\n"
5284                                     "    _wfopen(L\"testfile\", L\"r\") != NULL);\n"
5285                                     "return 0;}\n", "", SYSTEM_LIBS)) {
5286       fputs("#define os_fopen _wfopen\n", versionFile);
5287     } else if (compileAndLinkWithOptionsOk("#include <stdio.h>\n"
5288                                            "int main(int argc,char *argv[])\n"
5289                                            "{printf(\"%d\\n\",\n"
5290                                            "    wfopen(L\"testfile\", L\"r\") != NULL);\n"
5291                                            "return 0;}\n", "", SYSTEM_LIBS)) {
5292       fputs("#define os_fopen wfopen\n", versionFile);
5293     } else {
5294       fprintf(logFile, "\n *** Cannot define os_fopen.\n");
5295       showErrors();
5296     } /* if */
5297 #endif
5298 #ifndef os_popen
5299     if (compileAndLinkOk("#include <stdio.h>\n"
5300                          "int main(int argc,char *argv[])\n"
5301                          "{printf(\"%d\\n\", _wpopen(L\"pwd\", L\"r\") != NULL);return 0;}\n")) {
5302       fputs("#define os_popen _wpopen\n", versionFile);
5303     } else if (compileAndLinkOk("#include <stdio.h>\n"
5304                          "int main(int argc,char *argv[])\n"
5305                          "{printf(\"%d\\n\", wpopen(L\"pwd\", L\"r\") != NULL);return 0;}\n")) {
5306       fputs("#define os_popen wpopen\n", versionFile);
5307     } else {
5308       fputs("#define DEFINE_WPOPEN FILE *wpopen (const wchar_t *command, const wchar_t *mode) { return NULL; }\n", versionFile);
5309       fputs("#define os_popen wpopen\n", versionFile);
5310     } /* if */
5311 #endif
5312 #ifndef os_pclose
5313     if (compileAndLinkOk("#include <stdio.h>\n"
5314                          "int main(int argc,char *argv[])\n"
5315                          "{printf(\"%d\\n\", _pclose(NULL) != -1);return 0;}\n")) {
5316       fputs("#define os_pclose _pclose\n", versionFile);
5317     } else {
5318       fprintf(logFile, "\n *** Cannot define os_pclose.\n");
5319       showErrors();
5320     } /* if */
5321 #endif
5322   } /* determineOsWCharFunctions */
5323 #endif
5324 
5325 
5326 
5327 static void determineIsattyFunction (FILE *versionFile)
5328 
5329   { /* determineIsattyFunction */
5330     if (!compileAndLinkOk("#include <stdio.h>\n#include <unistd.h>\n"
5331                           "int main(int argc,char *argv[]){\n"
5332                           "printf(\"%d\\n\", isatty(0)==0);\n"
5333                           "return 0;}\n")) {
5334       if (compileAndLinkOk("#include <stdio.h>\n#include <io.h>\n"
5335                            "int main(int argc,char *argv[]){\n"
5336                            "printf(\"%d\\n\", isatty(0)==0);\n"
5337                            "return 0;}\n")) {
5338         fprintf(versionFile, "#define ISATTY_INCLUDE_IO_H\n");
5339       } else if (compileAndLinkOk("#include <stdio.h>\n#include <io.h>\n"
5340                                   "int main(int argc,char *argv[]){\n"
5341                                   "printf(\"%d\\n\", _isatty(0)==0);\n"
5342                                   "return 0;}\n")) {
5343         fprintf(versionFile, "#define ISATTY_INCLUDE_IO_H\n");
5344         fprintf(versionFile, "#define os_isatty _isatty\n");
5345       } /* if */
5346     } /* if */
5347   } /* determineIsattyFunction */
5348 
5349 
5350 
5351 static const char *determineFilenoFunction (FILE *versionFile)
5352 
5353   {
5354     char buffer[BUFFER_SIZE];
5355     const char *fileno = "fileno";
5356 
5357   /* determineFilenoFunction */
5358     if (!compileAndLinkOk("#include <stdio.h>\n"
5359                           "int main(int argc,char *argv[]){\n"
5360                           "printf(\"%d\\n\", fileno(stdin)==0);\n"
5361                           "return 0;}\n") &&
5362         compileAndLinkOk("#include <stdio.h>\n"
5363                          "int main(int argc,char *argv[]){\n"
5364                          "printf(\"%d\\n\", _fileno(stdin)==0);\n"
5365                          "return 0;}\n")) {
5366       fileno = "_fileno";
5367       fprintf(versionFile, "#define os_fileno _fileno\n");
5368     } /* if */
5369 #ifndef FILENO_WORKS_FOR_NULL
5370     sprintf(buffer, "#include <stdlib.h>\n#include <stdio.h>\n#include <signal.h>\n"
5371                     "void handleSig(int sig){puts(\"2\");exit(0);}\n"
5372                     "int main(int argc, char *argv[]){\n"
5373                     "FILE *aFile = NULL;\n"
5374                     "signal(SIGSEGV,handleSig);\n"
5375                     "printf(\"%%d\\n\", %s(aFile) == -1); return 0;}\n", fileno);
5376     if (assertCompAndLnk(buffer)) {
5377       fprintf(versionFile, "#define FILENO_WORKS_FOR_NULL %d\n", doTest() == 1);
5378     } /* if */
5379 #endif
5380     return fileno;
5381   } /* determineFilenoFunction */
5382 
5383 
5384 
5385 static void determineOsFunctions (FILE *versionFile)
5386 
5387   {
5388     char buffer[BUFFER_SIZE];
5389     const char *fileno;
5390 
5391   /* determineOsFunctions */
5392     determineIsattyFunction(versionFile);
5393     fileno = determineFilenoFunction(versionFile);
5394     determineSocketLib(versionFile);
5395     determineOsDirAccess(versionFile);
5396     determineFseekFunctions(versionFile, fileno);
5397     determineLseekFunction(versionFile);
5398     determineFtruncate(versionFile, fileno);
5399 #if defined OS_STRI_WCHAR
5400     determineOsWCharFunctions(versionFile);
5401 #elif PATH_DELIMITER == '\\'
5402     if (compileAndLinkOk("#include <stdio.h>\n#include <direct.h>\n"
5403                          "#include <string.h>\n"
5404                          "int main(int argc,char *argv[])\n"
5405                          "{char buffer[1024];\n"
5406                          "printf(\"%d\\n\", getcwd(buffer, 1024) != NULL &&\n"
5407                          "    strchr(buffer, '\\\\') == NULL);\n"
5408                          "return 0;}\n") && doTest() == 1) {
5409       fprintf(versionFile, "#define OS_GETCWD_RETURNS_SLASH\n");
5410     } /* if */
5411 #endif
5412     determineEnvironDefines(versionFile);
5413     if (!compileAndLinkOk("#include <stdio.h>\n"
5414                           "int main(int argc,char *argv[]){\n"
5415                           "flockfile(stdin);\n"
5416                           "printf(\"%d\\n\", getc_unlocked(stdin)==' ');\n"
5417                           "funlockfile(stdin);\n"
5418                           "return 0;}\n")) {
5419       fprintf(versionFile, "#define flockfile(aFile)\n");
5420       fprintf(versionFile, "#define funlockfile(aFile)\n");
5421       fprintf(versionFile, "#define getc_unlocked(aFile) getc(aFile)\n");
5422     } /* if */
5423     if (compileAndLinkOk("#include <stdio.h>\n#include <windows.h>\n"
5424                          "int main(int argc,char *argv[])\n"
5425                          "{SetErrorMode(SEM_NOGPFAULTERRORBOX);\n"
5426                          "printf(\"%d\\n\", fopen(\"ctstfile.txt\", \"we\") != NULL);\n"
5427                          "return 0;}\n")) {
5428       fprintf(versionFile, "#define FOPEN_SUPPORTS_CLOEXEC_MODE %d\n", doTest() == 1);
5429     } else if (assertCompAndLnk("#include <stdio.h>\n"
5430                                 "int main(int argc,char *argv[])\n"
5431                                 "{printf(\"%d\\n\", fopen(\"ctstfile.txt\", \"we\") != NULL);"
5432                                 "return 0;}\n")) {
5433       fprintf(versionFile, "#define FOPEN_SUPPORTS_CLOEXEC_MODE %d\n", doTest() == 1);
5434     } /* if */
5435     doRemove("ctstfile.txt");
5436     sprintf(buffer, "#include <stdio.h>\n#include <unistd.h>\n"
5437                     "#include <fcntl.h>\n"
5438                     "int main(int argc,char *argv[])\n"
5439                     "{FILE *aFile;int fd;\n"
5440                     "printf(\"%%d\\n\",\n"
5441                     "(aFile = fopen(\"ctstfile.txt\", \"w\")) != NULL &&\n"
5442                     "(fd = %s(aFile)) != -1 &&\n"
5443                     "fcntl(fd,F_SETFD,FD_CLOEXEC) == 0);\n"
5444                     "return 0;}\n", fileno);
5445     doRemove("ctstfile.txt");
5446     fprintf(versionFile, "#define HAS_FCNTL_SETFD_CLOEXEC %d\n",
5447             compileAndLinkOk(buffer) && doTest() == 1);
5448     fprintf(versionFile,
5449             "#define HAS_PIPE2 %d\n",
5450             compileAndLinkOk("#include <stdio.h>\n#include <unistd.h>\n"
5451                              "int main(int argc,char *argv[])\n"
5452                              "{int pipefd[2];\n"
5453                              "printf(\"%d\\n\", pipe2(pipefd, 0) == 0);\n"
5454                              "return 0;}\n") &&
5455             doTest() == 1);
5456     fprintf(versionFile,
5457             "#define HAS_SNPRINTF %d\n",
5458             compileAndLinkOk("#include <stdio.h>\n"
5459                              "int main(int argc,char *argv[])\n"
5460                              "{printf(\"%d\\n\", snprintf(NULL, 0, \"asdf\") == 4);\n"
5461                              "return 0;}\n") &&
5462             doTest() == 1);
5463     fprintf(versionFile,
5464             "#define HAS_VSNPRINTF %d\n",
5465             compileAndLinkOk("#include <stdio.h>\n#include <stdarg.h>\n"
5466                              "int test(const char *format, ...)\n"
5467                              "{int result;va_list ap;va_start(ap, format);\n"
5468                              "result = vsnprintf(NULL, 0, format, ap);\n"
5469                              "va_end(ap);return result;}\n"
5470                              "int main(int argc,char *argv[])\n"
5471                              "{printf(\"%d\\n\", test(\"asdf\") == 4);\n"
5472                              "return 0;}\n") &&
5473             doTest() == 1);
5474   } /* determineOsFunctions */
5475 
5476 
5477 
5478 static int linkerOptionAllowed (const char *linkerOption)
5479 
5480   {
5481     int optionAllowed;
5482 
5483   /* linkerOptionAllowed */
5484     optionAllowed = compileAndLinkWithOptionsOk(
5485         "#include <stdio.h>\n"
5486         "int main(int argc,char *argv[]){\n"
5487         "printf(\"hello world\\n\");\n"
5488         "return 0;}\n", "", linkerOption);
5489     return optionAllowed;
5490   } /* linkerOptionAllowed */
5491 
5492 
5493 
5494 static void appendToFile (const char *fileName, const char *data)
5495 
5496   {
5497     FILE *outFile;
5498 
5499   /* appendToFile */
5500     outFile = fopen(fileName, "a");
5501     if (outFile != NULL) {
5502       fputs(data, outFile);
5503       fclose(outFile);
5504     } /* if */
5505   } /* appendToFile */
5506 
5507 
5508 
5509 static void determineOptionForLinkTimeOptimization (FILE *versionFile)
5510 
5511   {
5512     char command[BUFFER_SIZE];
5513     char buffer[BUFFER_SIZE];
5514     char libraryName[NAME_SIZE];
5515     char executableName[NAME_SIZE];
5516     int returncode;
5517     int canDoLinkTimeOptimization = 0;
5518     int linkerOptLtoMandatory = 0;
5519     int canDoNoLinkTimeOptimization = 0;
5520 
5521   /* determineOptionForLinkTimeOptimization */
5522     fprintf(logFile, "Check for link time optimization: ");
5523 #ifdef CC_OPT_LINK_TIME_OPTIMIZATION
5524     if (compileAndLinkWithOptionsOk("#include <stdio.h>\n"
5525                                     "int main (int argc, char *argv[]) {\n"
5526                                     "printf(\"%d\\n\", 1);\n"
5527                                     "return 0; }\n",
5528                                     CC_OPT_LINK_TIME_OPTIMIZATION,
5529                                     CC_OPT_LINK_TIME_OPTIMIZATION) &&
5530         doTest() == 1) {
5531       if (compileWithOptionsOk("#include <stdio.h>\n"
5532                                "int main (int argc, char *argv[]) {\n"
5533                                "printf(\"%d\\n\", 1);\n"
5534                                "return 0; }\n",
5535                                CC_OPT_LINK_TIME_OPTIMIZATION)) {
5536         sprintf(libraryName, "ctest%d%s", testNumber, LIBRARY_FILE_EXTENSION);
5537         doRemove(libraryName);
5538         sprintf(command, "%s %s%s ctest%d%s",
5539                 ARCHIVER, ARCHIVER_OPT_REPLACE, libraryName,
5540                 testNumber, OBJECT_FILE_EXTENSION);
5541         sprintf(&command[strlen(command)], " %s%s %s%s",
5542                 REDIRECT_FILEDES_1, nullDevice, REDIRECT_FILEDES_2, nullDevice);
5543         /* fprintf(logFile, "command: %s\n", command); */
5544         returncode = system(command);
5545         /* fprintf(logFile, "returncode: %d\n", returncode); */
5546         if (fileIsRegular(libraryName)) {
5547           /* fprintf(logFile, " Library present.\n"); */
5548           if (doLink(libraryName, "")) {
5549             canDoLinkTimeOptimization = doTest() == 1;
5550           } else if (doLink(libraryName, CC_OPT_LINK_TIME_OPTIMIZATION)) {
5551             if (doTest() == 1) {
5552               canDoLinkTimeOptimization = 1;
5553               linkerOptLtoMandatory = 1;
5554             } /* if */
5555           } /* if */
5556 #ifdef LINKER_OPT_NO_LTO
5557           if (canDoLinkTimeOptimization) {
5558             sprintf(executableName, "ctest%d%s", testNumber, LINKED_PROGRAM_EXTENSION);
5559             doRemove(executableName);
5560             if (doLink(libraryName, LINKER_OPT_NO_LTO)) {
5561               canDoNoLinkTimeOptimization = doTest() == 1;
5562             } /* if */
5563           } /* if */
5564 #endif
5565           doRemove(libraryName);
5566         } /* if */
5567       } /* if */
5568     } /* if */
5569     if (canDoLinkTimeOptimization) {
5570       fprintf(logFile, " Done with the option: %s\n", CC_OPT_LINK_TIME_OPTIMIZATION);
5571       fprintf(versionFile, "#define CC_OPT_LINK_TIME_OPTIMIZATION \"%s\"\n",
5572               CC_OPT_LINK_TIME_OPTIMIZATION);
5573       sprintf(buffer, "CC_OPT_LINK_TIME_OPTIMIZATION = %s\n",
5574               CC_OPT_LINK_TIME_OPTIMIZATION);
5575       appendToFile("macros", buffer);
5576       fprintf(versionFile, "#define LINKER_OPT_LTO_MANDATORY %d\n", linkerOptLtoMandatory);
5577 #ifdef LINKER_OPT_NO_LTO
5578       if (canDoNoLinkTimeOptimization) {
5579         fprintf(versionFile, "#define LINKER_OPT_NO_LTO \"%s\"\n", LINKER_OPT_NO_LTO);
5580         sprintf(buffer, "LINKER_OPT_NO_LTO = %s\n", LINKER_OPT_NO_LTO);
5581         appendToFile("macros", buffer);
5582       } /* if */
5583 #endif
5584     } else {
5585       fprintf(logFile, " Not available.\n");
5586     } /* if */
5587 #else
5588     fprintf(logFile, "Not available.\n");
5589 #endif
5590   } /* determineOptionForLinkTimeOptimization */
5591 
5592 
5593 
5594 static void escapeString (FILE *versionFile, const char *text)
5595 
5596   { /* escapeString */
5597     while (*text != '\0') {
5598       if (*text == '\"' || *text == '\\') {
5599         putc('\\', versionFile);
5600         putc(*text, versionFile);
5601       } else if (*text == '\n') {
5602         fputs("\\n", versionFile);
5603       } else {
5604         putc(*text, versionFile);
5605       } /* if */
5606       text++;
5607     } /* while */
5608   } /* escapeString */
5609 
5610 
5611 
5612 static void appendOption (char *options, const char *optionToAppend)
5613 
5614   { /* appendOption */
5615     if (optionToAppend[0] != '\0') {
5616       if (strstr(options, optionToAppend) == NULL) {
5617         if (options[0] != '\0') {
5618           strcat(options, "\n");
5619         } /* if */
5620         strcat(options, optionToAppend);
5621       } /* if */
5622     } /* if */
5623   } /* appendOption */
5624 
5625 
5626 
5627 static const char *findIncludeFile (const char *scopeName, char *testProgram,
5628     const char *baseDir, const char **inclDirList, size_t inclDirListLength,
5629     const char *inclName, char *includeOption)
5630 
5631   {
5632     unsigned int dirIndex;
5633     char dirPath[BUFFER_SIZE];
5634     char filePath[BUFFER_SIZE];
5635     char inclOption[BUFFER_SIZE];
5636     const char *includeFileName = NULL;
5637 
5638   /* findIncludeFile */
5639     /* fprintf(logFile, "baseDir=%s\n", baseDir); */
5640     for (dirIndex = 0;
5641          includeFileName == NULL && dirIndex < inclDirListLength;
5642          dirIndex++) {
5643       sprintf(dirPath, "%s%s", baseDir, inclDirList[dirIndex]);
5644       /* printf("dirPath: %s\n", dirPath); */
5645       if (fileIsDir(dirPath)) {
5646         /* printf("fileIsDir(%s)\n", dirPath); */
5647         sprintf(filePath, "%s/%s", dirPath, inclName);
5648         /* printf("filePath: %s\n", filePath); */
5649         if (fileIsRegular(filePath)) {
5650           /* printf("fileIsRegular(%s)\n", filePath); */
5651           sprintf(inclOption, "-I\"%s\"", dirPath);
5652           /* fprintf(logFile, "inclOption=%s\n", inclOption); */
5653           if (compileAndLinkWithOptionsOk(testProgram, inclOption, "")) {
5654             includeFileName = inclName;
5655             fprintf(logFile, "\r%s: %s found in %s\n",
5656                     scopeName, includeFileName, dirPath);
5657             strcpy(includeOption, inclOption);
5658           } else {
5659             fprintf(logFile, "\r%s: The C compiler cannot include %s\n",
5660                     scopeName, filePath);
5661           } /* if */
5662         } /* if */
5663       } /* if */
5664     } /* for */
5665     return includeFileName;
5666   } /* findIncludeFile */
5667 
5668 
5669 
5670 static int findStaticLib (const char *scopeName, const char *testProgram,
5671     const char *includeOption, const char *libraryOption, const char *baseDir,
5672     const char **libDirList, size_t libDirListLength,
5673     const char **libNameList, size_t libNameListLength, char *system_libs)
5674 
5675   {
5676     unsigned int dirIndex;
5677     unsigned int nameIndex;
5678     char dirPath[BUFFER_SIZE];
5679     char filePath[BUFFER_SIZE];
5680     char linkParam[BUFFER_SIZE];
5681     char linkOption[BUFFER_SIZE];
5682     int libFound = 0;
5683 
5684   /* findStaticLib */
5685     for (dirIndex = 0;
5686          !libFound && dirIndex < libDirListLength;
5687          dirIndex++) {
5688       sprintf(dirPath, "%s%s", baseDir, libDirList[dirIndex]);
5689       /* printf("dirPath: %s\n", dirPath); */
5690       if (fileIsDir(dirPath)) {
5691         /* printf("fileIsDir(%s)\n", dirPath); */
5692         for (nameIndex = 0;
5693              !libFound && nameIndex < libNameListLength;
5694              nameIndex++) {
5695           sprintf(filePath, "%s/%s", dirPath, libNameList[nameIndex]);
5696           /* printf("filePath: %s\n", filePath); */
5697           if (fileIsRegular(filePath)) {
5698             /* printf("fileIsRegular(%s)\n", filePath); */
5699             sprintf(linkParam, "\"%s\"", filePath);
5700             linkOption[0] = '\0';
5701             appendOption(linkOption, libraryOption);
5702             appendOption(linkOption, linkParam);
5703             /* fprintf(logFile, "includeOption: \"%s\"\n", includeOption);
5704             fprintf(logFile, "linkParam: \"%s\"\n", linkParam); */
5705             if (compileAndLinkWithOptionsOk(testProgram, includeOption, linkOption)) {
5706               if (doTest() == 1) {
5707                 fprintf(logFile, "\r%s: %s found in: %s\n",
5708                         scopeName, libNameList[nameIndex], dirPath);
5709                 appendOption(system_libs, linkParam);
5710                 libFound = 1;
5711               } else {
5712                 fprintf(logFile, "\r%s: Cannot execute with %s\n", scopeName, filePath);
5713               } /* if */
5714             } else {
5715               fprintf(logFile, "\r%s: Cannot link %s\n", scopeName, filePath);
5716             } /* if */
5717           } else {
5718             sprintf(linkParam, "-L%s", dirPath);
5719             linkOption[0] = '\0';
5720             appendOption(linkOption, libraryOption);
5721             appendOption(linkOption, linkParam);
5722             appendOption(linkOption, libNameList[nameIndex]);
5723             /* fprintf(logFile, "includeOption: \"%s\"\n", includeOption);
5724             fprintf(logFile, "linkParam: \"%s\"\n", linkParam); */
5725             if (compileAndLinkWithOptionsOk(testProgram, includeOption, linkOption)) {
5726               if (doTest() == 1) {
5727                 fprintf(logFile, "\r%s: %s found in: %s\n",
5728                         scopeName, libNameList[nameIndex], dirPath);
5729                 sprintf(linkParam, "-L%s", dirPath);
5730                 appendOption(system_libs, linkParam);
5731                 appendOption(system_libs, libNameList[nameIndex]);
5732                 libFound = 1;
5733               } /* if */
5734             } /* if */
5735           } /* if */
5736         } /* for */
5737       } /* if */
5738     } /* for */
5739     return libFound;
5740   } /* findStaticLib */
5741 
5742 
5743 
5744 static int findLinkerOption (const char *scopeName, const char *testProgram,
5745     const char *includeOption, const char *libraryOption, const char **libNameList,
5746     size_t libNameListLength, char *system_libs)
5747 
5748   {
5749     unsigned int nameIndex;
5750     char linkParam[BUFFER_SIZE];
5751     int libFound = 0;
5752 
5753   /* findLinkerOption */
5754     for (nameIndex = 0;
5755          !libFound && nameIndex < libNameListLength;
5756          nameIndex++) {
5757       linkParam[0] = '\0';
5758       appendOption(linkParam, libraryOption);
5759       appendOption(linkParam, libNameList[nameIndex]);
5760       /* fprintf(logFile, "includeOption: \"%s\"\n", includeOption);
5761          fprintf(logFile, "linkParam: \"%s\"\n", linkParam); */
5762       if (compileAndLinkWithOptionsOk(testProgram, includeOption, linkParam)) {
5763         if (doTest() == 1) {
5764           fprintf(logFile, "\r%s: Linker option: %s\n",
5765                   scopeName, libNameList[nameIndex]);
5766           appendOption(system_libs, libraryOption);
5767           appendOption(system_libs, libNameList[nameIndex]);
5768           libFound = 1;
5769         } /* if */
5770       } /* if */
5771     } /* for */
5772     return libFound;
5773   } /* findLinkerOption */
5774 
5775 
5776 
5777 static void listDynamicLibs (const char *scopeName, const char *baseDir,
5778     const char **dllDirList, size_t dllDirListLength,
5779     const char **dllNameList, size_t dllNameListLength, FILE *versionFile)
5780 
5781   {
5782     unsigned int dirIndex;
5783     unsigned int nameIndex;
5784     char dirPath[BUFFER_SIZE];
5785     char filePath[BUFFER_SIZE];
5786 
5787   /* listDynamicLibs */
5788     for (dirIndex = 0;
5789          dirIndex < dllDirListLength;
5790          dirIndex++) {
5791       sprintf(dirPath, "%s%s", baseDir, dllDirList[dirIndex]);
5792       /* printf("dirPath: %s\n", dirPath); */
5793       if (fileIsDir(dirPath)) {
5794         /* printf("fileIsDir(%s)\n", dirPath); */
5795         for (nameIndex = 0;
5796              nameIndex < dllNameListLength;
5797              nameIndex++) {
5798           sprintf(filePath, "%s/%s", dirPath, dllNameList[nameIndex]);
5799           /* printf("filePath: %s\n", filePath); */
5800           if (fileIsRegular(filePath)) {
5801             /* printf("fileIsRegular(%s)\n", filePath); */
5802             fprintf(logFile, "\r%s: DLL / Shared library: %s\n",
5803                     scopeName, filePath);
5804             fprintf(versionFile, " \"");
5805             escapeString(versionFile, filePath);
5806             fprintf(versionFile, "\",");
5807           } /* if */
5808         } /* for */
5809       } /* if */
5810     } /* for */
5811   } /* listDynamicLibs */
5812 
5813 
5814 
5815 static void listDynamicLibsInSameDir (const char *scopeName, const char *baseDllPath,
5816     const char **dllNameList, size_t dllNameListLength, FILE *versionFile)
5817 
5818   {
5819     const char *slashPos;
5820     const char *backslashPos;
5821     const char *dirPathEnd;
5822     unsigned int nameIndex;
5823     char dirPath[BUFFER_SIZE];
5824     char filePath[BUFFER_SIZE];
5825 
5826   /* listDynamicLibsInSameDir */
5827     slashPos = strrchr(baseDllPath, '/');
5828     backslashPos = strrchr(baseDllPath, '\\');
5829     if (slashPos != NULL || backslashPos != NULL) {
5830       if (slashPos != NULL) {
5831         if (backslashPos != NULL) {
5832           if (slashPos > backslashPos) {
5833             dirPathEnd = slashPos;
5834           } else {
5835             dirPathEnd = backslashPos;
5836           } /* if */
5837         } else {
5838           dirPathEnd = slashPos;
5839         } /* if */
5840       } else {
5841         dirPathEnd = backslashPos;
5842       } /* if */
5843       memcpy(dirPath, baseDllPath, dirPathEnd - baseDllPath);
5844       dirPath[dirPathEnd - baseDllPath] = '\0';
5845       for (nameIndex = 0;
5846            nameIndex < dllNameListLength;
5847            nameIndex++) {
5848         sprintf(filePath, "%s/%s", dirPath, dllNameList[nameIndex]);
5849         /* printf("filePath: %s\n", filePath); */
5850         if (fileIsRegular(filePath)) {
5851           /* printf("fileIsRegular(%s)\n", filePath); */
5852           fprintf(logFile, "\r%s: DLL / Shared library: %s\n",
5853                   scopeName, filePath);
5854           fprintf(versionFile, " \"");
5855           escapeString(versionFile, filePath);
5856           fprintf(versionFile, "\",");
5857         } /* if */
5858       } /* for */
5859     } /* if */
5860   } /* listDynamicLibsInSameDir */
5861 
5862 
5863 
5864 static void defineLibraryMacro (const char *scopeName, int dbHomeExists,
5865     char *dbHome, const char *macroName, const char **dllDirList,
5866     size_t dllDirListLength, const char **baseDllNameList,
5867     size_t baseDllNameListLength, const char **dllNameList,
5868     size_t dllNameListLength, FILE *versionFile)
5869 
5870   {
5871     unsigned int nameIndex;
5872 
5873   /* defineLibraryMacro */
5874     fprintf(versionFile, "#define %s", macroName);
5875     if (dbHomeExists) {
5876       listDynamicLibs(scopeName, dbHome,
5877                       dllDirList, dllDirListLength,
5878                       dllNameList, dllNameListLength, versionFile);
5879     } /* if */
5880     for (nameIndex = 0; nameIndex < baseDllNameListLength; nameIndex++) {
5881       listDynamicLibsInSameDir(scopeName, baseDllNameList[nameIndex], dllNameList,
5882                                dllNameListLength, versionFile);
5883     } /* for */
5884     for (nameIndex = 0; nameIndex < dllNameListLength; nameIndex++) {
5885       fprintf(logFile, "\r%s: DLL / Shared library: %s\n",
5886               scopeName, dllNameList[nameIndex]);
5887       fprintf(versionFile, " \"%s\",", dllNameList[nameIndex]);
5888     } /* for */
5889     fprintf(versionFile, "\n");
5890   } /* defineLibraryMacro */
5891 
5892 
5893 
5894 static void defineX11rgbToPixelMacro (FILE *versionFile, const char *x11IncludeCommand,
5895     const char *includeOption, const char *systemDrawLibs)
5896 
5897   {
5898     const char *colorNames[] = {"red", "green", "blue"};
5899     const char *colorNamesUc[] = {"RED", "GREEN", "BLUE"};
5900     char testProgram[BUFFER_SIZE];
5901     char macroPart[BUFFER_SIZE];
5902     char macroBody[BUFFER_SIZE];
5903     int colorIndex;
5904     int testResult;
5905     int highestMaskBit;
5906     int lowZeroBitsInMask;
5907     unsigned long colorMask;
5908     int okay = 1;
5909 
5910   /* defineX11rgbToPixelMacro */
5911     macroBody[0] = '\0';
5912     for (colorIndex = 0; colorIndex < 3; colorIndex++) {
5913       sprintf(testProgram, "#include<stdio.h>\n%s"
5914                            "int getHighestSetBit(unsigned long number)\n"
5915                            "{ int result = 0;\n"
5916                            "while (number != 0) {\n"
5917                            "  number >>= 1;\n"
5918                            "  result++;\n"
5919                            "} return result; }\n"
5920                            "int countLowestZeroBits(unsigned long number)\n"
5921                            "{ int result = 0;\n"
5922                            "while (number != 0 && (number & 1) == 0) {\n"
5923                            "  number >>= 1;\n"
5924                            "  result++;\n"
5925                            "} return result; }\n"
5926                            "int main(int argc,char *argv[]){\n"
5927                            "Display *display;\n"
5928                            "int screen;\n"
5929                            "Visual *defaultVisual;\n"
5930                            "display = XOpenDisplay(\"\");\n"
5931                            "if (display != NULL) {\n"
5932                            "  screen = DefaultScreen(display);\n"
5933                            "  defaultVisual = XDefaultVisual(display, screen);\n"
5934                            "  printf(\"%%d\\n\", getHighestSetBit(defaultVisual->%s_mask) << 8 |\n"
5935                            "          countLowestZeroBits(defaultVisual->%s_mask));\n"
5936                            "} else { printf(\"0\\n\"); }\n"
5937                            "return 0;}\n",
5938               x11IncludeCommand, colorNames[colorIndex], colorNames[colorIndex]);
5939       if (compileAndLinkWithOptionsOk(testProgram, includeOption, systemDrawLibs)) {
5940         testResult = doTest();
5941         if (testResult > 0) {
5942           highestMaskBit = testResult >> 8;
5943           lowZeroBitsInMask = testResult & 0xff;
5944           colorMask = ~((~(unsigned int) 0) << (highestMaskBit - lowZeroBitsInMask)) << lowZeroBitsInMask;
5945           fprintf(versionFile, "#define PIXEL_%s_MASK \"%lx\"\n", colorNamesUc[colorIndex], colorMask);
5946           if (highestMaskBit > 16) {
5947             sprintf(macroPart, "((((unsigned long) (%s)) << %d) & 0x%lx)",
5948                     colorNames[colorIndex], highestMaskBit - 16, colorMask);
5949           } else if (highestMaskBit < 16) {
5950             sprintf(macroPart, "((((unsigned long) (%s)) >> %d) & 0x%lx)",
5951                     colorNames[colorIndex], 16 - highestMaskBit, colorMask);
5952           } else {
5953             sprintf(macroPart, "(((unsigned long) (%s)) & 0x%lx)",
5954                     colorNames[colorIndex], colorMask);
5955           } /* if */
5956           if (macroBody[0] != '\0') {
5957             strcat(macroBody, " | ");
5958           } /* if */
5959           strcat(macroBody, macroPart);
5960         } else {
5961           okay = 0;
5962         } /* if */
5963       } else {
5964         okay = 0;
5965       } /* if */
5966     } /* for */
5967     if (okay) {
5968       fprintf(versionFile, "#define RGB_TO_PIXEL_FLAG_NAME \"useRgbToPixel\"\n");
5969       fprintf(versionFile, "#define rgbToPixel(red, green, blue) (%s)\n", macroBody);
5970     } /* if */
5971   } /* defineX11rgbToPixelMacro */
5972 
5973 
5974 
5975 static void determineX11Defines (FILE *versionFile, char *include_options)
5976 
5977   {
5978     const char *inclDirList[] = {"/usr/local/include"};
5979 #ifdef X11_LIBRARY_PATH
5980     const char *libDirList[] = { X11_LIBRARY_PATH };
5981 #endif
5982 #ifdef X11_LIBS
5983     const char *libNameList[] = { X11_LIBS };
5984 #else
5985     const char *libNameList[] = {"-lX11"};
5986 #endif
5987     const char *xRenderLibNameList[] = {"-lXrender"};
5988 #ifdef X11_DLL
5989     const char *dllNameList[] = { X11_DLL };
5990 #elif LIBRARY_TYPE == UNIX_LIBRARIES
5991     const char *dllNameList[] = {"libX11.so", "libX11.so.6", "libX11.so.5"};
5992     const char *xRenderDllNameList[] = {"libXrender.so", "libXrender.so.1"};
5993 #elif LIBRARY_TYPE == MACOS_LIBRARIES
5994     const char *dllNameList[] = {"libX11.dylib"};
5995     const char *xRenderDllNameList[] = {"libXrender.dylib"};
5996 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
5997     const char *dllNameList[] = {"x11.dll"};
5998     const char *xRenderDllNameList[] = {"xrender.dll"};
5999 #endif
6000     char includeOption[BUFFER_SIZE];
6001     const char *x11Include = NULL;
6002     const char *x11IncludeCommand;
6003     const char *x11XrenderInclude = NULL;
6004     const char *x11XrenderIncludeCommand = "";
6005     char testProgram[BUFFER_SIZE];
6006     unsigned int nameIndex;
6007     int searchForLib = 1;
6008     char makeDefinition[BUFFER_SIZE];
6009     char system_draw_libs[BUFFER_SIZE];
6010 
6011   /* determineX11Defines */
6012 #ifndef NO_X11_SYSTEM_INCLUDES
6013     sprintf(testProgram, "#include <X11/X.h>\n"
6014                          "#include <X11/Xlib.h>\n"
6015                          "#include <X11/Xutil.h>\n"
6016                          "int main(int argc,char *argv[]){\n"
6017                          "Display *display;\n"
6018                          "GC gc;\n"
6019                          "Window window;\n"
6020                          "Pixmap pixmap;\n"
6021                          "return 0;}\n");
6022     if (compileAndLinkWithOptionsOk(testProgram, "", "")) {
6023       includeOption[0] = '\0';
6024       x11Include = "X11/X.h";
6025       fprintf(logFile, "\rX11: %s found in system include directory.\n", x11Include);
6026     } else {
6027       x11Include = findIncludeFile("X11", testProgram, "",
6028                                     inclDirList, sizeof(inclDirList) / sizeof(char *),
6029                                    "X11/X.h", includeOption);
6030       if (x11Include != NULL) {
6031         appendOption(include_options, includeOption);
6032       } /* if */
6033     } /* if */
6034 #endif
6035     if (x11Include != NULL) {
6036       x11IncludeCommand = "#include <X11/X.h>\n"
6037                           "#include <X11/Xlib.h>\n"
6038                           "#include <X11/Xutil.h>\n";
6039 #ifdef ALLOW_REPLACEMENT_OF_SYSTEM_HEADERS
6040     } else {
6041       includeOption[0] = '\0';
6042       x11Include = "x11_x.h";
6043       fprintf(versionFile, "#define X11_INCLUDE \"%s\"\n", x11Include);
6044       fprintf(logFile, "\rX11: %s found in Seed7 include directory.\n", x11Include);
6045       x11IncludeCommand = "#include \"x11_x.h\"\n";
6046 #endif
6047     } /* if */
6048     sprintf(testProgram, "#include<stdio.h>\n%s"
6049                          "#include <X11/extensions/Xrender.h>\n"
6050                          "int main(int argc,char *argv[]){\n"
6051                          "Display *display;\n"
6052                          "int event_basep;\n"
6053                          "int error_basep;\n"
6054                          "display = XOpenDisplay(\"\");\n"
6055                          "printf(\"%%d\\n\", (int)\n"
6056                          "    XRenderQueryExtension(display, &event_basep, &error_basep));\n"
6057                          "return 0;}\n", x11IncludeCommand);
6058     if (compileAndLinkWithOptionsOk(testProgram, "", "")) {
6059       x11XrenderIncludeCommand = "#include <X11/extensions/Xrender.h>\n";
6060 #ifdef ALLOW_REPLACEMENT_OF_SYSTEM_HEADERS
6061     } else {
6062       x11XrenderInclude = "x11_rend.h";
6063       fprintf(versionFile, "#define X11_XRENDER_INCLUDE \"%s\"\n", x11XrenderInclude);
6064       x11XrenderIncludeCommand = "#include \"x11_rend.h\"\n";
6065 #endif
6066     } /* if */
6067     if (x11Include == NULL) {
6068       fprintf(versionFile, "#define SYSTEM_DRAW_LIBS \"\"\n");
6069       appendToFile("macros", "SYSTEM_DRAW_LIBS =\n");
6070       fprintf(versionFile, "#define FORWARD_X11_CALLS 0\n");
6071     } else {
6072       sprintf(testProgram, "#include<stdio.h>\n%s"
6073                            "int main(int argc,char *argv[]){\n"
6074                            "printf(\"%%u\\n\", (unsigned) sizeof(XID));\n"
6075                            "return 0;}\n", x11IncludeCommand);
6076       if (compileAndLinkWithOptionsOk(testProgram, includeOption, "")) {
6077         fprintf(versionFile, "#define XID_SIZE %d\n", 8 * doTest());
6078       } /* if */
6079       sprintf(testProgram, "#include<stdio.h>\n%s"
6080                            "int main(int argc,char *argv[]){\n"
6081                            "printf(\"%%u\\n\", (unsigned) sizeof(Atom));\n"
6082                            "return 0;}\n", x11IncludeCommand);
6083       if (compileAndLinkWithOptionsOk(testProgram, includeOption, "")) {
6084         fprintf(versionFile, "#define ATOM_SIZE %d\n", 8 * doTest());
6085       } /* if */
6086 #ifndef X11_USE_DLL
6087       /* Handle static libraries: */
6088       sprintf(testProgram, "#include<stdio.h>\n%s"
6089                            "int main(int argc,char *argv[]){\n"
6090                            "Display *display;\n"
6091                            "display = XOpenDisplay(\"\");\n"
6092                            "printf(\"1\\n\");\n"
6093                            "return 0;}\n", x11IncludeCommand);
6094       /* fprintf(logFile, "%s\n", testProgram);
6095          fprintf(logFile, "x11Include: \"%s\"\n", x11Include); */
6096       system_draw_libs[0] = '\0';
6097 #ifdef X11_LIBRARY_PATH
6098       if (findStaticLib("X11", testProgram, includeOption, "", "",
6099                         libDirList, sizeof(libDirList) / sizeof(char *),
6100                         libNameList, sizeof(libNameList) / sizeof(char *),
6101                         system_draw_libs)) {
6102         sprintf(testProgram, "#include<stdio.h>\n%s%s"
6103                              "int main(int argc,char *argv[]){\n"
6104                              "Display *display;\n"
6105                              "int event_basep;\n"
6106                              "int error_basep;\n"
6107                              "display = XOpenDisplay(\"\");\n"
6108                              "printf(\"%%d\\n\", (int)\n"
6109                              "    XRenderQueryExtension(display, &event_basep, &error_basep));\n"
6110                              "return 0;}\n", x11IncludeCommand, x11XrenderIncludeCommand);
6111         /* fprintf(logFile, "%s\n", testProgram);
6112            fprintf(logFile, "x11Include: \"%s\"\n", x11Include); */
6113         if (findStaticLib("Xrender", testProgram, includeOption, system_draw_libs, "",
6114                           libDirList, sizeof(libDirList) / sizeof(char *),
6115                           xRenderLibNameList, sizeof(xRenderLibNameList) / sizeof(char *),
6116                           system_draw_libs)) {
6117           fprintf(versionFile, "#define HAS_XRENDER_EXTENSION\n");
6118           searchForLib = 0;
6119         } /* if */
6120         if (!searchForLib) {
6121           sprintf(makeDefinition, "SYSTEM_DRAW_LIBS = %s", system_draw_libs);
6122           replaceNLBySpace(makeDefinition);
6123           strcat(makeDefinition, "\n");
6124           appendToFile("macros", makeDefinition);
6125           fprintf(versionFile, "#define SYSTEM_DRAW_LIBS \"");
6126           /* The SYSTEM_DRAW_LIBS are space separated: */
6127           replaceNLBySpace(system_draw_libs);
6128           escapeString(versionFile, system_draw_libs);
6129           fprintf(versionFile, "\"\n");
6130         } /* if */
6131       } /* if */
6132 #endif
6133       if (searchForLib) {
6134         if (findLinkerOption("X11", testProgram, includeOption, "",
6135                              libNameList, sizeof(libNameList) / sizeof(char *),
6136                              system_draw_libs)) {
6137           sprintf(testProgram, "#include<stdio.h>\n%s%s"
6138                                "int main(int argc,char *argv[]){\n"
6139                                "Display *display;\n"
6140                                "int event_basep;\n"
6141                                "int error_basep;\n"
6142                                "display = XOpenDisplay(\"\");\n"
6143                                "printf(\"%%d\\n\", (int)\n"
6144                                "  XRenderQueryExtension(display, &event_basep, &error_basep));\n"
6145                                "return 0;}\n", x11IncludeCommand, x11XrenderIncludeCommand);
6146           /* fprintf(logFile, "%s\n", testProgram);
6147              fprintf(logFile, "x11Include: \"%s\"\n", x11Include); */
6148           if (findLinkerOption("Xrender", testProgram, includeOption, system_draw_libs,
6149                                xRenderLibNameList, sizeof(xRenderLibNameList) / sizeof(char *),
6150                                system_draw_libs)) {
6151             fprintf(versionFile, "#define HAS_XRENDER_EXTENSION\n");
6152             searchForLib = 0;
6153           } /* if */
6154           if (!searchForLib) {
6155             sprintf(makeDefinition, "SYSTEM_DRAW_LIBS = %s", system_draw_libs);
6156             replaceNLBySpace(makeDefinition);
6157             strcat(makeDefinition, "\n");
6158             appendToFile("macros", makeDefinition);
6159             fprintf(versionFile, "#define SYSTEM_DRAW_LIBS \"");
6160             /* The SYSTEM_DRAW_LIBS are space separated: */
6161             replaceNLBySpace(system_draw_libs);
6162             escapeString(versionFile, system_draw_libs);
6163             fprintf(versionFile, "\"\n");
6164           } /* if */
6165         } /* if */
6166       } /* if */
6167 #endif
6168       if (!searchForLib) {
6169         defineX11rgbToPixelMacro(versionFile, x11IncludeCommand, includeOption, system_draw_libs);
6170       } /* if */
6171       fprintf(versionFile, "#define FORWARD_X11_CALLS %d\n", searchForLib);
6172       if (searchForLib) {
6173         fprintf(versionFile, "#define HAS_XRENDER_EXTENSION\n");
6174         fprintf(versionFile, "#define SYSTEM_DRAW_LIBS \"%s\"\n", LINKER_OPT_DYN_LINK_LIBS);
6175         appendToFile("macros", "SYSTEM_DRAW_LIBS =" LINKER_OPT_DYN_LINK_LIBS "\n");
6176         /* Handle dynamic libraries: */
6177         fprintf(versionFile, "#define X11_DLL");
6178         for (nameIndex = 0;
6179              nameIndex < sizeof(dllNameList) / sizeof(char *);
6180              nameIndex++) {
6181           fprintf(logFile, "\rX11: DLL / Shared library: %s\n", dllNameList[nameIndex]);
6182           fprintf(versionFile, " \"%s\",", dllNameList[nameIndex]);
6183         } /* for */
6184         fprintf(versionFile, "\n");
6185         fprintf(versionFile, "#define X11_XRENDER_DLL");
6186         for (nameIndex = 0;
6187              nameIndex < sizeof(xRenderDllNameList) / sizeof(char *);
6188              nameIndex++) {
6189           fprintf(logFile, "\rX11_XRENDER: DLL / Shared library: %s\n", xRenderDllNameList[nameIndex]);
6190           fprintf(versionFile, " \"%s\",", xRenderDllNameList[nameIndex]);
6191         } /* for */
6192         fprintf(versionFile, "\n");
6193       } /* if */
6194     } /* if */
6195   } /* determineX11Defines */
6196 
6197 
6198 
6199 static void determineConsoleDefines (FILE *versionFile, char *include_options)
6200 
6201   {
6202 #ifdef CONSOLE_LIBS
6203     const char *libNameList[] = { CONSOLE_LIBS };
6204 #else
6205     const char *libNameList[] = {"-lncurses"};
6206 #endif
6207 #ifdef CONSOLE_DLL
6208     const char *dllNameList[] = { CONSOLE_DLL };
6209 #elif LIBRARY_TYPE == UNIX_LIBRARIES
6210     const char *dllNameList[] = {"libtinfo.so", "libtinfo.so.5"};
6211 #elif LIBRARY_TYPE == MACOS_LIBRARIES
6212     const char *dllNameList[] = {"libtinfo.dylib"};
6213 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
6214     const char *dllNameList[] = {"ncurses.dll"};
6215 #endif
6216     const char *consoleInclude = NULL;
6217     int useSystemHeader = 1;
6218     unsigned int nameIndex;
6219     int searchForLib = 1;
6220     char testProgram[BUFFER_SIZE];
6221     char makeDefinition[BUFFER_SIZE];
6222     char system_console_libs[BUFFER_SIZE];
6223 
6224   /* determineConsoleDefines */
6225     if (compileAndLinkOk("#include \"stdio.h\"\n"
6226                          "#include \"termios.h\"\n"
6227                          "int main(int argc,char *argv[]){\n"
6228                          "struct termios termiosData;\n"
6229                          "printf(\"%d\\n\", tcgetattr(0, &termiosData) == 0);\n"
6230                          "return 0;}\n")) {
6231       fprintf(versionFile, "#define HAS_TERMIOS_H\n");
6232     } /* if */
6233     if (compileAndLinkOk("#include \"stdio.h\"\n"
6234                          "#include \"term.h\"\n"
6235                          "int main(int argc,char *argv[]){\n"
6236                          "TERMINAL *aTerminal;\n"
6237                          "return 0;}\n")) {
6238       fprintf(versionFile, "#define USE_TERMINFO\n");
6239       consoleInclude = "term.h";
6240       fprintf(logFile, "\rConsole: %s found in system include directory.\n", consoleInclude);
6241     } else if (compileAndLinkOk("#include \"stdio.h\"\n"
6242                                 "#include \"ncurses/term.h\"\n"
6243                                 "int main(int argc,char *argv[]){\n"
6244                                 "TERMINAL *aTerminal;\n"
6245                                 "return 0;}\n")) {
6246       fprintf(versionFile, "#define USE_TERMINFO\n");
6247       fprintf(versionFile, "#define INCL_NCURSES_TERM\n");
6248       consoleInclude = "ncurses/term.h";
6249       fprintf(logFile, "\rConsole: %s found in system include directory.\n", consoleInclude);
6250     } /* if */
6251 #ifdef ALLOW_REPLACEMENT_OF_SYSTEM_HEADERS
6252     if (consoleInclude == NULL) {
6253       if (compileAndLinkOk("#include \"stdio.h\"\n"
6254                            "#include \"fwd_term.h\"\n"
6255                            "int main(int argc,char *argv[]){\n"
6256                            "TERMINAL *aTerminal;\n"
6257                            "return 0;}\n")) {
6258         useSystemHeader = 0;
6259         fprintf(versionFile, "#define TERM_INCLUDE \"fwd_term.h\"\n");
6260         /* fprintf(versionFile, "#define FORWARD_TERM_CALLS %d\n", 0); */
6261         fprintf(versionFile, "#define USE_TERMINFO\n");
6262         consoleInclude = "fwd_term.h";
6263         fprintf(logFile, "\rConsole: %s found in Seed7 include directory.\n", consoleInclude);
6264       } /* if */
6265     } /* if */
6266 #endif
6267     if (compileAndLinkOk("#include<poll.h>\n"
6268                          "int main(int argc,char *argv[])\n"
6269                          "{struct pollfd pollFd[1];\n"
6270                          "poll(pollFd, 1, 0);\n"
6271                          "return 0;}\n")) {
6272       fprintf(versionFile, "#define USE_KBD_POLL\n");
6273     } else {
6274       fprintf(versionFile, "#define USE_KBD_INF\n");
6275     } /* if */
6276     if (consoleInclude == NULL) {
6277       fprintf(versionFile, "#define SYSTEM_CONSOLE_LIBS___ \"\"\n");
6278       appendToFile("macros", "SYSTEM_CONSOLE_LIBS___ =\n");
6279       fprintf(versionFile, "#define FORWARD_TERM_CALLS 0\n");
6280     } else {
6281       sprintf(testProgram, "#include<stdio.h>\n#include \"%s\"\n"
6282                            "int main(int argc,char *argv[]){\n"
6283                            "TERMINAL *aTerminal;\n"
6284                            "int errret;\n"
6285                            "setupterm(\"vt100\", fileno(stdout), &errret);\n"
6286                            "printf(\"1\\n\");\n"
6287                            "return 0;}\n", consoleInclude);
6288       /* fprintf(logFile, "%s\n", testProgram);
6289          fprintf(logFile, "consoleInclude: \"%s\"\n", consoleInclude); */
6290       system_console_libs[0] = '\0';
6291       if (useSystemHeader) {
6292         if (findLinkerOption("Console", testProgram, "", "",
6293                              libNameList, sizeof(libNameList) / sizeof(char *),
6294                              system_console_libs)) {
6295           sprintf(makeDefinition, "SYSTEM_CONSOLE_LIBS___ = %s", system_console_libs);
6296           replaceNLBySpace(makeDefinition);
6297           strcat(makeDefinition, "\n");
6298           appendToFile("macros", makeDefinition);
6299           fprintf(versionFile, "#define SYSTEM_CONSOLE_LIBS___ \"");
6300           /* The SYSTEM_CONSOLE_LIBS___ are space separated: */
6301           replaceNLBySpace(system_console_libs);
6302           escapeString(versionFile, system_console_libs);
6303           fprintf(versionFile, "\"\n");
6304           searchForLib = 0;
6305         } /* if */
6306 #ifdef ALLOW_REPLACEMENT_OF_SYSTEM_HEADERS
6307         if (searchForLib) {
6308           if (compileAndLinkOk("#include \"stdio.h\"\n"
6309                                "#include \"fwd_term.h\"\n"
6310                                "int main(int argc,char *argv[]){\n"
6311                                "TERMINAL *aTerminal;\n"
6312                                "return 0;}\n")) {
6313             useSystemHeader = 0;
6314             fprintf(versionFile, "#define TERM_INCLUDE \"fwd_term.h\"\n");
6315             /* fprintf(versionFile, "#define FORWARD_TERM_CALLS %d\n", 0); */
6316             consoleInclude = "fwd_term.h";
6317             fprintf(logFile, "\rConsole: %s found in Seed7 include directory.\n", consoleInclude);
6318           } /* if */
6319         } /* if */
6320 #endif
6321       } /* if */
6322       fprintf(versionFile, "#define FORWARD_TERM_CALLS %d\n",
6323               searchForLib && !useSystemHeader);
6324       if (searchForLib && !useSystemHeader) {
6325         fprintf(versionFile, "#define SYSTEM_CONSOLE_LIBS___ \"%s\"\n", LINKER_OPT_DYN_LINK_LIBS);
6326         appendToFile("macros", "SYSTEM_CONSOLE_LIBS___ =" LINKER_OPT_DYN_LINK_LIBS "\n");
6327         /* Handle dynamic libraries: */
6328         fprintf(versionFile, "#define CONSOLE_DLL");
6329         for (nameIndex = 0;
6330              nameIndex < sizeof(dllNameList) / sizeof(char *);
6331              nameIndex++) {
6332           fprintf(logFile, "\rConsole: DLL / Shared library: %s\n", dllNameList[nameIndex]);
6333           fprintf(versionFile, " \"%s\",", dllNameList[nameIndex]);
6334         } /* for */
6335         fprintf(versionFile, "\n");
6336       } /* if */
6337     } /* if */
6338   } /* determineConsoleDefines */
6339 
6340 
6341 
6342 static void determineMySqlDefines (FILE *versionFile,
6343     char *include_options, char *system_database_libs)
6344 
6345   {
6346     const char *dbHomeSys[] = {"MariaDB/MariaDB C Client Library",
6347                                "MariaDB/MariaDB C Client Library 64-bit",
6348                                "MariaDB 10.3",
6349                                "MySQL/MySQL Connector C 6.1"};
6350 #ifdef MYSQL_LIBS
6351     const char *libNameList[] = { MYSQL_LIBS };
6352 #elif LIBRARY_TYPE == UNIX_LIBRARIES || LIBRARY_TYPE == MACOS_LIBRARIES
6353     const char *libNameList[] = {"-lmysqlclient"};
6354 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
6355     const char *libNameList[] = {"mariadbclient.lib", "vs11/mysqlclient.lib"};
6356 #endif
6357 #ifdef MYSQL_DLL
6358     const char *dllNameList[] = { MYSQL_DLL };
6359 #elif LIBRARY_TYPE == UNIX_LIBRARIES
6360     const char *dllNameList[] = {"libmysqlclient.so"};
6361 #elif LIBRARY_TYPE == MACOS_LIBRARIES
6362     const char *dllNameList[] = {"libmysqlclient.dylib"};
6363 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
6364     const char *dllNameList[] = {"libmariadb.dll", "libmysql.dll"};
6365 #endif
6366     const char *inclDirList[] = {"/include"};
6367     const char *libDirList[] = {"/lib"};
6368     const char *dllDirList[] = {"/lib"};
6369     unsigned int dirIndex;
6370     unsigned int nameIndex;
6371     int searchForLib = 1;
6372     const char *programFilesX86 = NULL;
6373     const char *programFiles = NULL;
6374     char dbHome[BUFFER_SIZE];
6375     char includeOption[BUFFER_SIZE];
6376     const char *mySqlInclude = NULL;
6377     char testProgram[BUFFER_SIZE];
6378     int dbHomeExists = 0;
6379 
6380   /* determineMySqlDefines */
6381 #ifdef MYSQL_INCLUDE_OPTIONS
6382     strcpy(includeOption, MYSQL_INCLUDE_OPTIONS);
6383 #else
6384     includeOption[0] = '\0';
6385 #endif
6386     programFilesX86 = getenv("ProgramFiles(x86)");
6387     /* fprintf(logFile, "programFilesX86: %s\n", programFilesX86); */
6388     programFiles = getenv("ProgramFiles");
6389     /* fprintf(logFile, "programFiles: %s\n", programFiles); */
6390     if (programFiles != NULL) {
6391       if (sizeof(char *) == 4 && programFilesX86 != NULL) {
6392         programFiles = programFilesX86;
6393       } /* if */
6394       for (dirIndex = 0; !dbHomeExists && dirIndex < sizeof(dbHomeSys) / sizeof(char *); dirIndex++) {
6395         sprintf(dbHome, "%s/%s", programFiles, dbHomeSys[dirIndex]);
6396         /* fprintf(logFile, "dbHome: <%s>\n", dbHome); */
6397         if (fileIsDir(dbHome)) {
6398           dbHomeExists = 1;
6399         } /* if */
6400       } /* for */
6401     } /* if */
6402     if (dbHomeExists) {
6403       /* fprintf(logFile, "dbHome=%s\n", dbHome); */
6404       sprintf(testProgram, "#include \"stdlib.h\"\n"
6405                            "#include \"mysql.h\"\n"
6406                            "int main(int argc,char *argv[]){"
6407                            "MYSQL *connection; return 0;}\n");
6408       mySqlInclude = findIncludeFile("MySql/MariaDb", testProgram, dbHome,
6409                                      inclDirList, sizeof(inclDirList) / sizeof(char *),
6410                                      "mysql.h", includeOption);
6411       if (mySqlInclude != NULL) {
6412         appendOption(include_options, includeOption);
6413       } /* if */
6414     } /* if */
6415     if (mySqlInclude == NULL) {
6416       if (compileAndLinkWithOptionsOk("#include <mysql.h>\n"
6417                                       "int main(int argc,char *argv[]){"
6418                                       "MYSQL *connection; return 0;}\n",
6419                                       "", "")) {
6420         mySqlInclude = "mysql.h";
6421         fprintf(logFile, "\rMySql/MariaDb: %s found in system include directory.\n", mySqlInclude);
6422       } else if (compileAndLinkWithOptionsOk("#include <mysql/mysql.h>\n"
6423                                              "int main(int argc,char *argv[]){"
6424                                              "MYSQL *connection; return 0;}\n",
6425                                              "", "")) {
6426         mySqlInclude = "mysql/mysql.h";
6427         fprintf(logFile, "\rMySql/MariaDb: %s found in system include directory.\n", mySqlInclude);
6428       } else if (compileAndLinkWithOptionsOk("#include <mysql.h>\n"
6429                                              "int main(int argc,char *argv[]){"
6430                                              "MYSQL *connection; return 0;}\n",
6431                                              includeOption, "")) {
6432         mySqlInclude = "mysql.h";
6433         fprintf(logFile, "\rMySql/MariaDb: %s found with option %s.\n", mySqlInclude, includeOption);
6434         appendOption(include_options, includeOption);
6435       } else if (compileAndLinkWithOptionsOk("#include <mysql/mysql.h>\n"
6436                                              "int main(int argc,char *argv[]){"
6437                                              "MYSQL *connection; return 0;}\n",
6438                                              includeOption, "")) {
6439         mySqlInclude = "mysql/mysql.h";
6440         fprintf(logFile, "\rMySql/MariaDb: %s found with option %s.\n", mySqlInclude, includeOption);
6441         appendOption(include_options, includeOption);
6442       } else if (compileAndLinkWithOptionsOk("#include \"db_my.h\"\n"
6443                                              "int main(int argc,char *argv[]){\n"
6444                                              "MYSQL *connection; return 0;}\n",
6445                                              "", "") ||
6446                  compileAndLinkWithOptionsOk("#define STDCALL\n"
6447                                              "#include \"db_my.h\"\n"
6448                                              "int main(int argc,char *argv[]){\n"
6449                                              "MYSQL *connection; return 0;}\n",
6450                                              "", "")) {
6451         mySqlInclude = "db_my.h";
6452         fprintf(logFile, "\rMySql/MariaDb: %s found in Seed7 include directory.\n", mySqlInclude);
6453       } /* if */
6454     } /* if */
6455     if (mySqlInclude != NULL) {
6456       fprintf(versionFile, "#define MYSQL_INCLUDE \"%s\"\n", mySqlInclude);
6457     } /* if */
6458 #ifndef MYSQL_USE_DLL
6459     /* Handle static libraries: */
6460     sprintf(testProgram, "#include<stdio.h>\n#include<stdlib.h>\n"
6461                          "#include \"%s\"\n"
6462                          "int main(int argc,char *argv[]){\n"
6463                          "MYSQL *conn;\n"
6464                          "conn = mysql_init(NULL);\n"
6465                          "if (conn != NULL) {\n"
6466                          "mysql_real_connect(conn, \"\", \"\", \"\", \"\", 0, NULL, 0);\n"
6467                          "mysql_close(conn);\n"
6468                          "printf(\"1\\n\");\n"
6469                          "}\nreturn 0;\n}\n", mySqlInclude);
6470     /* fprintf(logFile, "%s\n", testProgram);
6471        fprintf(logFile, "mySqlInclude: \"%s\"\n", mySqlInclude); */
6472     if (dbHomeExists) {
6473       if (findStaticLib("MySql/MariaDb", testProgram, includeOption, "", dbHome,
6474                         libDirList, sizeof(libDirList) / sizeof(char *),
6475                         libNameList, sizeof(libNameList) / sizeof(char *),
6476                         system_database_libs)) {
6477         searchForLib = 0;
6478       } /* if */
6479     } /* if */
6480     if (searchForLib) {
6481       if (findLinkerOption("MySql/MariaDb", testProgram, includeOption, MYSQL_LIBRARY_PATH,
6482                            libNameList, sizeof(libNameList) / sizeof(char *),
6483                            system_database_libs)) {
6484         searchForLib = 0;
6485       } /* if */
6486     } /* if */
6487 #endif
6488     if (searchForLib) {
6489       /* Handle dynamic libraries: */
6490       appendOption(system_database_libs, LINKER_OPT_DYN_LINK_LIBS);
6491       fprintf(versionFile, "#define MYSQL_DLL");
6492       if (dbHomeExists) {
6493         listDynamicLibs("MySql/MariaDb", dbHome,
6494                         dllDirList, sizeof(dllDirList) / sizeof(char *),
6495                         dllNameList, sizeof(dllNameList) / sizeof(char *), versionFile);
6496       } /* if */
6497       for (nameIndex = 0; nameIndex < sizeof(dllNameList) / sizeof(char *); nameIndex++) {
6498         fprintf(logFile, "\rMySql/MariaDb: DLL / Shared library: %s\n", dllNameList[nameIndex]);
6499         fprintf(versionFile, " \"%s\",", dllNameList[nameIndex]);
6500       } /* for */
6501       fprintf(versionFile, "\n");
6502     } /* if */
6503   } /* determineMySqlDefines */
6504 
6505 
6506 
6507 static void determineSqliteDefines (FILE *versionFile,
6508     char *include_options, char *system_database_libs)
6509 
6510   {
6511     const char *dbHomeDirs[] = {"C:/sqlite", "D:/sqlite"};
6512 #ifdef SQLITE_LIBS
6513     const char *libNameList[] = { SQLITE_LIBS };
6514 #elif LIBRARY_TYPE == UNIX_LIBRARIES || LIBRARY_TYPE == MACOS_LIBRARIES
6515     const char *libNameList[] = {"-lsqlite3"};
6516 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
6517     const char *libNameList[] = {"sqlite3.lib"};
6518 #endif
6519 #ifdef SQLITE_DLL
6520     const char *dllNameList[] = { SQLITE_DLL };
6521 #elif LIBRARY_TYPE == UNIX_LIBRARIES
6522     const char *dllNameList[] = {"libsqlite3.so"};
6523 #elif LIBRARY_TYPE == MACOS_LIBRARIES
6524     const char *dllNameList[] = {"libsqlite3.dylib"};
6525 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
6526     const char *dllNameList[] = {"sqlite3.dll"};
6527 #endif
6528     const char *libDirList[] = {""};
6529     const char *dllDirList[] = {""};
6530     unsigned int dirIndex;
6531     unsigned int nameIndex;
6532     int searchForLib = 1;
6533     char dbHome[BUFFER_SIZE];
6534     char includeOption[BUFFER_SIZE];
6535     const char *sqliteInclude = NULL;
6536     char testProgram[BUFFER_SIZE];
6537     int dbHomeExists = 0;
6538 
6539   /* determineSqliteDefines */
6540 #ifdef SQLITE_INCLUDE_OPTIONS
6541     strcpy(includeOption, SQLITE_INCLUDE_OPTIONS);
6542 #else
6543     includeOption[0] = '\0';
6544 #endif
6545     for (dirIndex = 0; !dbHomeExists && dirIndex < sizeof(dbHomeDirs) / sizeof(char *); dirIndex++) {
6546       strcpy(dbHome, dbHomeDirs[dirIndex]);
6547       if (fileIsDir(dbHome)) {
6548         dbHomeExists = 1;
6549       } /* if */
6550     } /* for */
6551     if (dbHomeExists) {
6552       /* fprintf(logFile, "dbHome=%s\n", dbHome); */
6553       sprintf(includeOption, "-I\"%s\"", dbHome);
6554       /* fprintf(logFile, "includeOption=%s\n", includeOption); */
6555       if (compileAndLinkWithOptionsOk("#include <sqlite3.h>\n"
6556                                       "int main(int argc,char *argv[]){\n"
6557                                       "sqlite3_stmt *ppStmt;\n"
6558                                       "return 0;}\n",
6559                                       includeOption, "")) {
6560         sqliteInclude = "sqlite3.h";
6561         fprintf(logFile, "\rSQLite: %s found in %s\n", sqliteInclude, dbHome);
6562         appendOption(include_options, includeOption);
6563       } /* if */
6564     } else if (compileAndLinkWithOptionsOk("#include <sqlite3.h>\n"
6565                                            "int main(int argc,char *argv[]){\n"
6566                                            "sqlite3_stmt *ppStmt;\n"
6567                                            "return 0;}\n",
6568                                            includeOption, "")) {
6569       sqliteInclude = "sqlite3.h";
6570       fprintf(logFile, "\rSQLite: %s found in system include directory.\n", sqliteInclude);
6571       appendOption(include_options, includeOption);
6572     } else if (compileAndLinkWithOptionsOk("#include \"tst_vers.h\"\n"
6573                                            "#include \"db_lite.h\"\n"
6574                                            "int main(int argc,char *argv[]){\n"
6575                                            "sqlite3_stmt *ppStmt;\n"
6576                                            "return 0;}\n",
6577                                            "", "") ||
6578                compileAndLinkWithOptionsOk("#define CDECL\n"
6579                                            "#include \"tst_vers.h\"\n"
6580                                            "#include \"db_lite.h\"\n"
6581                                            "int main(int argc,char *argv[]){\n"
6582                                            "sqlite3_stmt *ppStmt;\n"
6583                                            "return 0;}\n",
6584                                            "", "")) {
6585       sqliteInclude = "db_lite.h";
6586       fprintf(logFile, "\rSQLite: %s found in Seed7 include directory.\n", sqliteInclude);
6587     } /* if */
6588     if (sqliteInclude != NULL) {
6589       fprintf(versionFile, "#define SQLITE_INCLUDE \"%s\"\n", sqliteInclude);
6590     } /* if */
6591 #ifndef SQLITE_USE_DLL
6592     /* Handle static libraries: */
6593     sprintf(testProgram, "#include \"tst_vers.h\"\n#include<stdio.h>\n"
6594                          "#include \"%s\"\n"
6595                          "int main(int argc,char *argv[]){\n"
6596                          "sqlite3 *conn;\n"
6597                          "sqlite3_open(\"\", &conn);\n"
6598                          "sqlite3_close(conn);\n"
6599                          "printf(\"1\\n\");\n"
6600                          "return 0;\n}\n", sqliteInclude);
6601     /* fprintf(logFile, "%s\n", testProgram);
6602        fprintf(logFile, "sqliteInclude: \"%s\"\n", sqliteInclude); */
6603     if (dbHomeExists) {
6604       if (findStaticLib("SQLite", testProgram, includeOption, "", dbHome,
6605                         libDirList, sizeof(libDirList) / sizeof(char *),
6606                         libNameList, sizeof(libNameList) / sizeof(char *),
6607                         system_database_libs)) {
6608         searchForLib = 0;
6609       } /* if */
6610     } /* if */
6611     if (searchForLib) {
6612       if (findLinkerOption("SQLite", testProgram, includeOption, SQLITE_LIBRARY_PATH,
6613                            libNameList, sizeof(libNameList) / sizeof(char *),
6614                            system_database_libs)) {
6615         searchForLib = 0;
6616       } /* if */
6617     } /* if */
6618 #endif
6619     if (searchForLib) {
6620       /* Handle dynamic libraries: */
6621       appendOption(system_database_libs, LINKER_OPT_DYN_LINK_LIBS);
6622       fprintf(versionFile, "#define SQLITE_DLL");
6623       if (dbHomeExists) {
6624         listDynamicLibs("SQLite", dbHome,
6625                         dllDirList, sizeof(dllDirList) / sizeof(char *),
6626                         dllNameList, sizeof(dllNameList) / sizeof(char *), versionFile);
6627       } /* if */
6628       for (nameIndex = 0; nameIndex < sizeof(dllNameList) / sizeof(char *); nameIndex++) {
6629         fprintf(logFile, "\rSQLite: DLL / Shared library: %s\n", dllNameList[nameIndex]);
6630         fprintf(versionFile, " \"%s\",", dllNameList[nameIndex]);
6631       } /* for */
6632       fprintf(versionFile, "\n");
6633     } /* if */
6634   } /* determineSqliteDefines */
6635 
6636 
6637 
6638 static int extractPostgresOid (const char* pgTypeFileName)
6639   {
6640     const char *oidNames[] = {
6641       "ABSTIMEOID",     "ACLITEMOID",      "ANYARRAYOID",     "ANYELEMENTOID",    "ANYENUMOID",
6642       "ANYNONARRAYOID", "ANYOID",          "BITOID",          "BOOLOID",          "BOXOID",
6643       "BPCHAROID",      "BYTEAOID",        "CASHOID",         "CHAROID",          "CIDOID",
6644       "CIDROID",        "CIRCLEOID",       "CSTRINGARRAYOID", "CSTRINGOID",       "DATEOID",
6645       "FDW_HANDLEROID", "FLOAT4ARRAYOID",  "FLOAT4OID",       "FLOAT8OID",        "GTSVECTOROID",
6646       "INETOID",        "INT2ARRAYOID",    "INT2OID",         "INT2VECTOROID",    "INT4ARRAYOID",
6647       "INT4OID",        "INT8OID",         "INTERNALOID",     "INTERVALOID",      "LANGUAGE_HANDLEROID",
6648       "LINEOID",        "LSEGOID",         "MACADDROID",      "NAMEOID",          "NUMERICOID",
6649       "OIDARRAYOID",    "OIDOID",          "OIDVECTOROID",    "OPAQUEOID",        "PATHOID",
6650       "PGNODETREEOID",  "POINTOID",        "POLYGONOID",      "RECORDARRAYOID",   "RECORDOID",
6651       "REFCURSOROID",   "REGCLASSOID",     "REGCONFIGOID",    "REGDICTIONARYOID", "REGOPERATOROID",
6652       "REGOPEROID",     "REGPROCEDUREOID", "REGPROCOID",      "REGTYPEARRAYOID",  "REGTYPEOID",
6653       "RELTIMEOID",     "TEXTARRAYOID",    "TEXTOID",         "TIDOID",           "TIMEOID",
6654       "TIMESTAMPOID",   "TIMESTAMPTZOID",  "TIMETZOID",       "TINTERVALOID",     "TRIGGEROID",
6655       "TSQUERYOID",     "TSVECTOROID",     "UNKNOWNOID",      "VARBITOID",        "VARCHAROID",
6656       "VOIDOID",        "XIDOID",          "XMLOID"};
6657     FILE *pgTypeFile;
6658     FILE *oidFile;
6659     char buffer[BUFFER_SIZE];
6660     char *line;
6661     int pos;
6662     int idx;
6663     int spaces;
6664     int anOidWasFound = 0;
6665 
6666   /* extractPostgresOid */
6667     fprintf(logFile, "\rExtracting OIDs from: %s\n", pgTypeFileName);
6668     pgTypeFile = fopen(pgTypeFileName, "r");
6669     if (pgTypeFile != NULL) {
6670       oidFile = fopen("pg_type.h", "w");
6671       if (oidFile != NULL) {
6672         fputs("/* Do not edit this file. It has been generated by chkccomp.c. */\n", oidFile);
6673         fputs("/* The contents of this file have been extracted from: */\n", oidFile);
6674         fprintf(oidFile, "/*   %s */\n", pgTypeFileName);
6675         fputs("\n", oidFile);
6676         while ((line = fgets(buffer, 4096, pgTypeFile)) != NULL) {
6677           pos = 0;
6678           while (line[pos] == ' ' || line[pos] == '\t') {
6679             pos++;
6680           } /* if */
6681           if (line[pos] == '#') {
6682             pos++;
6683             while (line[pos] == ' ' || line[pos] == '\t') {
6684               pos++;
6685             } /* if */
6686             if (strncmp(&line[pos], "define", 6) == 0) {
6687               pos += 6;
6688               while (line[pos] == ' ' || line[pos] == '\t') {
6689                 pos++;
6690               } /* if */
6691               for (idx = 0; idx < sizeof(oidNames) / sizeof(char *); idx++) {
6692                 if (strncmp(&line[pos], oidNames[idx], strlen(oidNames[idx])) == 0) {
6693                   anOidWasFound = 1;
6694                   fprintf(oidFile, "#define %s ", oidNames[idx]);
6695                   pos += strlen(oidNames[idx]);
6696                   while (line[pos] == ' ' || line[pos] == '\t') {
6697                     pos++;
6698                   } /* if */
6699                   spaces = 24 - strlen(oidNames[idx]) - strlen(&line[pos]);
6700                   while (spaces > 0) {
6701                     fputc(' ', oidFile);
6702                     spaces--;
6703                   } /* while */
6704                   fputs(&line[pos], oidFile);
6705                   idx = sizeof(oidNames) / sizeof(char *);
6706                 } /* if */
6707               } /* for */
6708             } /* if */
6709           } /* if */
6710         } /* while */
6711         fclose(oidFile);
6712         if (!anOidWasFound) {
6713           fprintf(logFile, "\rExtracting OIDs failed.\n");
6714           doRemove("pg_type.h");
6715         } /* if */
6716       } /* if */
6717       fclose(pgTypeFile);
6718     } /* if */
6719     return anOidWasFound;
6720   } /* extractPostgresOid */
6721 
6722 
6723 
6724 static int findPgTypeInclude (const char *includeOption, const char *pgTypeInclude)
6725 
6726   {
6727     const char *optionPos;
6728     const char *optionEnd;
6729     size_t optionLen;
6730     char includeDir[BUFFER_SIZE];
6731     char pgTypeFileName[BUFFER_SIZE];
6732     int found = 0;
6733 
6734   /* findPgTypeInclude */
6735     /* fprintf(logFile, "findPgTypeInclude(\"%s\")\n", includeOption); */
6736     while (includeOption != NULL && (optionPos = strstr(includeOption, "-I")) != NULL) {
6737       if (optionPos[2] == '\"') {
6738         optionEnd = strchr(&optionPos[3], '\"');
6739         if (optionEnd == NULL) {
6740           strcpy(includeDir, &optionPos[3]);
6741           includeOption = NULL;
6742         } else {
6743           memcpy(includeDir, &optionPos[3], optionEnd - &optionPos[3]);
6744           includeDir[optionEnd - &optionPos[3]] = '\0';
6745           includeOption = optionEnd + 1;
6746         } /* if */
6747       } else {
6748         optionLen = strcspn(&optionPos[2], " \n");
6749         if (optionLen == 0) {
6750           strcpy(includeDir, &optionPos[2]);
6751           includeOption = NULL;
6752         } else {
6753           memcpy(includeDir, &optionPos[2], optionLen);
6754           includeDir[optionLen] = '\0';
6755           includeOption = &optionPos[2] + optionLen + 1;
6756         } /* if */
6757       } /* if */
6758       /* fprintf(logFile, "includeDir: \"%s\"\n", includeDir); */
6759       if (includeDir[0] != '\0'  && fileIsDir(includeDir)) {
6760         sprintf(pgTypeFileName, "%s/%s", includeDir, pgTypeInclude);
6761         if (fileIsRegular(pgTypeFileName)) {
6762           if (extractPostgresOid(pgTypeFileName)) {
6763             includeOption = NULL;
6764             found = 1;
6765           } /* if */
6766         } /* if */
6767       } /* if */
6768     } /* while */
6769     return found;
6770   } /* findPgTypeInclude */
6771 
6772 
6773 
6774  static const char *findPgTypeH (char *includeOption, char *serverIncludeOption)
6775 
6776   {
6777     char testProgram[BUFFER_SIZE];
6778     const char *pgTypeInclude = NULL;
6779 
6780   /* findPgTypeH */
6781     if (compileAndLinkWithOptionsOk("#include <server/catalog/pg_type.h>\n"
6782                                     "int main(int argc,char *argv[]){"
6783                                     "printf(\"%d\\n\", INT4OID == 23);\n"
6784                                     "return 0;}\n",
6785                                     includeOption, "")) {
6786       pgTypeInclude = "server/catalog/pg_type.h";
6787     } else if (compileAndLinkWithOptionsOk("#include <server/catalog/pg_type_d.h>\n"
6788                                            "int main(int argc,char *argv[]){"
6789                                            "printf(\"%d\\n\", INT4OID == 23);\n"
6790                                            "return 0;}\n",
6791                                            includeOption, "")) {
6792       pgTypeInclude = "server/catalog/pg_type_d.h";
6793     } else if (compileAndLinkWithOptionsOk("#include <catalog/pg_type.h>\n"
6794                                            "int main(int argc,char *argv[]){"
6795                                            "printf(\"%d\\n\", INT4OID == 23);\n"
6796                                            "return 0;}\n",
6797                                            includeOption, "")) {
6798       pgTypeInclude = "catalog/pg_type.h";
6799     } else if (compileAndLinkWithOptionsOk("#include <catalog/pg_type_d.h>\n"
6800                                            "int main(int argc,char *argv[]){"
6801                                            "printf(\"%d\\n\", INT4OID == 23);\n"
6802                                            "return 0;}\n",
6803                                            includeOption, "")) {
6804       pgTypeInclude = "catalog/pg_type_d.h";
6805     } else {
6806       appendOption(includeOption, serverIncludeOption);
6807       if (compileAndLinkWithOptionsOk("#include <server/catalog/pg_type.h>\n"
6808                                       "int main(int argc,char *argv[]){"
6809                                       "printf(\"%d\\n\", INT4OID == 23);\n"
6810                                       "return 0;}\n",
6811                                       includeOption, "")) {
6812         pgTypeInclude = "server/catalog/pg_type.h";
6813       } else if (compileAndLinkWithOptionsOk("#include <server/catalog/pg_type_d.h>\n"
6814                                              "int main(int argc,char *argv[]){"
6815                                              "printf(\"%d\\n\", INT4OID == 23);\n"
6816                                              "return 0;}\n",
6817                                              includeOption, "")) {
6818         pgTypeInclude = "server/catalog/pg_type_d.h";
6819       } else if (compileAndLinkWithOptionsOk("#include <catalog/pg_type.h>\n"
6820                                              "int main(int argc,char *argv[]){"
6821                                              "printf(\"%d\\n\", INT4OID == 23);\n"
6822                                              "return 0;}\n",
6823                                              includeOption, "")) {
6824         pgTypeInclude = "catalog/pg_type.h";
6825       } else if (compileAndLinkWithOptionsOk("#include <catalog/pg_type_d.h>\n"
6826                                              "int main(int argc,char *argv[]){"
6827                                              "printf(\"%d\\n\", INT4OID == 23);\n"
6828                                              "return 0;}\n",
6829                                              includeOption, "")) {
6830         pgTypeInclude = "catalog/pg_type_d.h";
6831       } else {
6832         pgTypeInclude = "server/catalog/pg_type.h";
6833       } /* if */
6834     } /* if */
6835     sprintf(testProgram, "#include <%s>\n"
6836                          "int main(int argc,char *argv[]){"
6837                          "printf(\"%%d\\n\", INT4OID == 23);\n"
6838                          "return 0;}\n",
6839                          pgTypeInclude);
6840     if (compileAndLinkWithOptionsOk(testProgram, includeOption, "")) {
6841       fprintf(logFile, "\rPostgreSQL: %s found in system include directory.\n", pgTypeInclude);
6842     } else if (findPgTypeInclude(includeOption, pgTypeInclude)) {
6843       pgTypeInclude = "pg_type.h";
6844       fprintf(logFile, "\rPostgreSQL: %s found in Seed7 include directory.\n", pgTypeInclude);
6845     } else {
6846       fprintf(logFile, "\rPostgreSQL: %s not found in include directories.\n", pgTypeInclude);
6847       pgTypeInclude = NULL;
6848     } /* if */
6849     return pgTypeInclude;
6850   } /* findPgTypeH */
6851 
6852 
6853 
6854 static void determinePostgresDefines (FILE *versionFile,
6855     char *include_options, char *system_database_libs)
6856 
6857   {
6858     const char *dbVersion[] = {"13", "12", "11", "10",
6859                                "9.6", "9.5", "9.4", "9.3",
6860                                "9.2", "9.1", "9.0", "8.4", "8.3"};
6861 #ifdef POSTGRESQL_LIBS
6862     const char *libNameList[] = { POSTGRESQL_LIBS };
6863 #elif LIBRARY_TYPE == UNIX_LIBRARIES || LIBRARY_TYPE == MACOS_LIBRARIES
6864     const char *libNameList[] = {"-lpq"};
6865 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
6866     const char *libNameList[] = {"libpq.lib"};
6867 #endif
6868 #ifdef POSTGRESQL_DLL
6869     const char *dllNameList[] = { POSTGRESQL_DLL };
6870 #elif LIBRARY_TYPE == UNIX_LIBRARIES
6871     const char *dllNameList[] = {"libpq.so", "libpq.so.5"};
6872 #elif LIBRARY_TYPE == MACOS_LIBRARIES
6873     const char *dllNameList[] = {"libpq.dylib"};
6874 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
6875     const char *dllNameList[] = {"libpq.dll"};
6876 #endif
6877     const char *libDirList[] = {"/lib"};
6878     const char *dllDirList[] = {"/lib", "/bin"};
6879     const char *libIntlDllList[] = {"libintl.dll", "libintl-8.dll", "libintl-9.dll"};
6880     const char *libeay32DllList[] = {"libeay32.dll"};
6881     const char *libcryptoDllList[] = {"libcrypto-1_1-x64.dll"};
6882     const char *libsslDllList[] = {"libssl-1_1-x64.dll"};
6883     unsigned int dirIndex;
6884     unsigned int nameIndex;
6885     int searchForLib = 1;
6886     char filePath[BUFFER_SIZE];
6887     const char *programFilesX86 = NULL;
6888     const char *programFiles = NULL;
6889     char dbHome[BUFFER_SIZE];
6890     char includeOption[BUFFER_SIZE];
6891     char serverIncludeOption[BUFFER_SIZE];
6892     const char *postgresqlInclude = NULL;
6893     const char *pgTypeInclude = NULL;
6894     char testProgram[BUFFER_SIZE];
6895     int dbHomeExists = 0;
6896 
6897   /* determinePostgresDefines */
6898 #ifdef POSTGRESQL_INCLUDE_OPTIONS
6899     strcpy(includeOption, POSTGRESQL_INCLUDE_OPTIONS);
6900 #else
6901     if (fileIsDir("/usr/include/postgresql")) {
6902       strcpy(includeOption, "-I/usr/include/postgresql");
6903     } else if (fileIsDir("/usr/include/pgsql")) {
6904       strcpy(includeOption, "-I/usr/include/pgsql");
6905     } else {
6906       includeOption[0] = '\0';
6907     } /* if */
6908 #endif
6909     if (fileIsDir("/usr/include/postgresql/server")) {
6910       strcpy(serverIncludeOption, "-I/usr/include/postgresql/server");
6911     } else if (fileIsDir("/usr/include/pgsql/server")) {
6912       strcpy(serverIncludeOption, "-I/usr/include/pgsql/server");
6913     } else {
6914       serverIncludeOption[0] = '\0';
6915     } /* if */
6916     programFilesX86 = getenv("ProgramFiles(x86)");
6917     /* fprintf(logFile, "programFilesX86: %s\n", programFilesX86); */
6918     programFiles = getenv("ProgramFiles");
6919     /* fprintf(logFile, "programFiles: %s\n", programFiles); */
6920     if (programFiles != NULL) {
6921       if (sizeof(char *) == 4 && programFilesX86 != NULL) {
6922         programFiles = programFilesX86;
6923       } /* if */
6924       for (dirIndex = 0; !dbHomeExists && dirIndex < sizeof(dbVersion) / sizeof(char *); dirIndex++) {
6925         sprintf(dbHome, "%s/PostgreSQL/%s", programFiles, dbVersion[dirIndex]);
6926         if (fileIsDir(dbHome)) {
6927           dbHomeExists = 1;
6928         } /* if */
6929       } /* for */
6930     } /* if */
6931     if (dbHomeExists) {
6932       /* fprintf(logFile, "dbHome=%s\n", dbHome); */
6933       sprintf(includeOption, "-I\"%s/include\"", dbHome);
6934       sprintf(serverIncludeOption, "-I\"%s/include/server\"", dbHome);
6935       /* fprintf(logFile, "includeOption=%s\n", includeOption); */
6936       if (compileAndLinkWithOptionsOk("#include \"libpq-fe.h\"\n"
6937                                       "int main(int argc,char *argv[]){"
6938                                       "PGconn *connection; return 0;}\n",
6939                                       includeOption, "")) {
6940         postgresqlInclude = "libpq-fe.h";
6941         fprintf(logFile, "\rPostgreSQL: %s found in %s/include\n", postgresqlInclude, dbHome);
6942         pgTypeInclude = findPgTypeH(includeOption, serverIncludeOption);
6943       } else {
6944         sprintf(filePath, "%s/include/libpq-fe.h", dbHome);
6945         if (fileIsRegular(filePath)) {
6946           fprintf(logFile, "\rPostgreSQL: The C compiler cannot include %s\n", filePath);
6947         } /* if */
6948         postgresqlInclude = NULL;
6949       } /* if */
6950     } /* if */
6951     if (postgresqlInclude == NULL &&
6952         compileAndLinkWithOptionsOk("#include <libpq-fe.h>\n"
6953                                     "int main(int argc,char *argv[]){"
6954                                     "PGconn *connection; return 0;}\n",
6955                                     includeOption, "")) {
6956       postgresqlInclude = "libpq-fe.h";
6957       fprintf(logFile, "\rPostgreSQL: %s found in system include directory.\n", postgresqlInclude);
6958       pgTypeInclude = findPgTypeH(includeOption, serverIncludeOption);
6959     } /* if */
6960     if ((postgresqlInclude == NULL || pgTypeInclude == NULL) &&
6961         (compileAndLinkWithOptionsOk("#include \"db_post.h\"\n"
6962                                      "int main(int argc,char *argv[]){\n"
6963                                      "PGconn *connection; return 0;}\n",
6964                                      "", "") ||
6965          compileAndLinkWithOptionsOk("#define CDECL\n"
6966                                      "include \"db_post.h\"\n"
6967                                      "int main(int argc,char *argv[]){\n"
6968                                      "PGconn *connection; return 0;}\n",
6969                                      "", ""))) {
6970       postgresqlInclude = "db_post.h";
6971       fprintf(logFile, "\rPostgreSQL: %s found in Seed7 include directory.\n", postgresqlInclude);
6972       includeOption[0] = '\0';
6973     } /* if */
6974     if (postgresqlInclude != NULL) {
6975       if (includeOption[0] != '\0') {
6976         appendOption(include_options, includeOption);
6977       } /* if */
6978       fprintf(versionFile, "#define POSTGRESQL_INCLUDE \"%s\"\n", postgresqlInclude);
6979     } /* if */
6980     if (pgTypeInclude != NULL) {
6981       fprintf(versionFile, "#define POSTGRESQL_PG_TYPE_H \"%s\"\n", pgTypeInclude);
6982     } /* if */
6983 #ifndef POSTGRESQL_USE_DLL
6984     /* Handle static libraries: */
6985     sprintf(testProgram, "#include<stdio.h>\n#include<stdlib.h>\n"
6986                          "#include \"%s\"\n"
6987                          "int main(int argc,char *argv[]){\n"
6988                          "PGconn *conn;\n"
6989                          "conn = PQsetdbLogin(\"\", NULL, NULL, NULL, \"\", \"\", \"\");\n"
6990                          "PQfinish(conn);\n"
6991                          "printf(\"1\\n\");\n"
6992                          "return 0;\n}\n", postgresqlInclude);
6993     /* fprintf(logFile, "%s\n", testProgram);
6994        fprintf(logFile, "postgresqlInclude: \"%s\"\n", postgresqlInclude); */
6995     if (dbHomeExists) {
6996       if (findStaticLib("PostgreSQL", testProgram, includeOption, "", dbHome,
6997                         libDirList, sizeof(libDirList) / sizeof(char *),
6998                         libNameList, sizeof(libNameList) / sizeof(char *),
6999                         system_database_libs)) {
7000         searchForLib = 0;
7001       } /* if */
7002     } /* if */
7003     if (searchForLib) {
7004       if (findLinkerOption("PostgreSQL", testProgram, includeOption, POSTGRESQL_LIBRARY_PATH,
7005                            libNameList, sizeof(libNameList) / sizeof(char *),
7006                            system_database_libs)) {
7007         searchForLib = 0;
7008       } /* if */
7009     } /* if */
7010 #endif
7011     if (searchForLib) {
7012       /* Handle dynamic libraries: */
7013       appendOption(system_database_libs, LINKER_OPT_DYN_LINK_LIBS);
7014       fprintf(versionFile, "#define POSTGRESQL_DLL");
7015       if (dbHomeExists) {
7016         listDynamicLibs("PostgreSQL", dbHome,
7017                         dllDirList, sizeof(dllDirList) / sizeof(char *),
7018                         dllNameList, sizeof(dllNameList) / sizeof(char *), versionFile);
7019       } /* if */
7020       for (nameIndex = 0; nameIndex < sizeof(dllNameList) / sizeof(char *); nameIndex++) {
7021         fprintf(logFile, "\rPostgreSQL: DLL / Shared library: %s\n", dllNameList[nameIndex]);
7022         fprintf(versionFile, " \"%s\",", dllNameList[nameIndex]);
7023       } /* for */
7024       fprintf(versionFile, "\n");
7025       defineLibraryMacro("PostgreSQL", dbHomeExists, dbHome, "LIBINTL_DLL",
7026                          dllDirList, sizeof(dllDirList) / sizeof(char *),
7027                          dllNameList, sizeof(dllNameList) / sizeof(char *),
7028                          libIntlDllList, sizeof(libIntlDllList) / sizeof(char *),
7029                          versionFile);
7030       defineLibraryMacro("PostgreSQL", dbHomeExists, dbHome, "LIBEAY32_DLL",
7031                          dllDirList, sizeof(dllDirList) / sizeof(char *),
7032                          dllNameList, sizeof(dllNameList) / sizeof(char *),
7033                          libeay32DllList, sizeof(libeay32DllList) / sizeof(char *),
7034                          versionFile);
7035       defineLibraryMacro("PostgreSQL", dbHomeExists, dbHome, "LIBCRYPTO_DLL",
7036                          dllDirList, sizeof(dllDirList) / sizeof(char *),
7037                          dllNameList, sizeof(dllNameList) / sizeof(char *),
7038                          libcryptoDllList, sizeof(libcryptoDllList) / sizeof(char *),
7039                          versionFile);
7040       defineLibraryMacro("PostgreSQL", dbHomeExists, dbHome, "LIBSSL_DLL",
7041                          dllDirList, sizeof(dllDirList) / sizeof(char *),
7042                          dllNameList, sizeof(dllNameList) / sizeof(char *),
7043                          libsslDllList, sizeof(libsslDllList) / sizeof(char *),
7044                          versionFile);
7045     } /* if */
7046   } /* determinePostgresDefines */
7047 
7048 
7049 
7050 static void determineOdbcDefines (FILE *versionFile,
7051     char *include_options, char *system_database_libs)
7052 
7053   {
7054 #ifdef ODBC_LIBS
7055     const char *libNameList[] = { ODBC_LIBS };
7056 #elif LIBRARY_TYPE == UNIX_LIBRARIES
7057     const char *libNameList[] = {"-lodbc"};
7058 #elif LIBRARY_TYPE == MACOS_LIBRARIES
7059     const char *libNameList[] = {"-liodbc"};
7060 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
7061     const char *libNameList[] = {"-lodbc32", "odbc32.lib"};
7062 #endif
7063 #ifdef ODBC_DLL
7064     const char *dllNameList[] = { ODBC_DLL };
7065 #elif LIBRARY_TYPE == UNIX_LIBRARIES
7066     const char *dllNameList[] = {"libodbc.so"};
7067 #elif LIBRARY_TYPE == MACOS_LIBRARIES
7068     const char *dllNameList[] = {"libiodbc.dylib"};
7069 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
7070     const char *dllNameList[] = {"odbc32.dll"};
7071 #endif
7072     unsigned int nameIndex;
7073     int searchForLib = 1;
7074     char includeOption[BUFFER_SIZE];
7075     int windowsOdbc = 0;
7076     int includeSqlext = 0;
7077     const char *odbcInclude = NULL;
7078     char testProgram[BUFFER_SIZE];
7079 
7080   /* determineOdbcDefines */
7081 #ifdef ODBC_INCLUDE_OPTIONS
7082     strcpy(includeOption, ODBC_INCLUDE_OPTIONS);
7083 #else
7084     includeOption[0] = '\0';
7085 #endif
7086     if (compileAndLinkWithOptionsOk("#include <windows.h>\n"
7087                                     "#include <sql.h>\n"
7088                                     "#include <sqlext.h>\n"
7089                                     "int main(int argc,char *argv[]){\n"
7090                                     "SQLHDBC conn; SQLHSTMT stmt;\n"
7091                                     "SQLSMALLINT h = SQL_HANDLE_STMT;\n"
7092                                     "return 0;}\n",
7093                                     includeOption, "")) {
7094       windowsOdbc = 1;
7095       includeSqlext = 1;
7096       odbcInclude = "sql.h";
7097       fprintf(logFile, "\rOdbc: %s found in system include directory.\n",
7098               odbcInclude);
7099     } else if (compileAndLinkWithOptionsOk("#include <sql.h>\n"
7100                                            "#include <sqlext.h>\n"
7101                                            "int main(int argc,char *argv[]){\n"
7102                                            "SQLHDBC conn; SQLHSTMT stmt;\n"
7103                                            "SQLSMALLINT h = SQL_HANDLE_STMT;\n"
7104                                            "return 0;}\n",
7105                                            includeOption, "")) {
7106       includeSqlext = 1;
7107       odbcInclude = "sql.h";
7108       fprintf(logFile, "\rOdbc: %s found in system include directory.\n",
7109               odbcInclude);
7110     } else if (compileAndLinkWithOptionsOk("#include \"tst_vers.h\"\n"
7111                                            "#include \"db_odbc.h\"\n"
7112                                            "int main(int argc,char *argv[]){\n"
7113                                            "SQLHDBC conn; SQLHSTMT stmt;\n"
7114                                            "SQLSMALLINT h = SQL_HANDLE_STMT;\n"
7115                                            "return 0;}\n",
7116                                            "", "") ||
7117                compileAndLinkWithOptionsOk("#define STDCALL\n"
7118                                            "#include \"tst_vers.h\"\n"
7119                                            "#include \"db_odbc.h\"\n"
7120                                            "int main(int argc,char *argv[]){\n"
7121                                            "SQLHDBC conn; SQLHSTMT stmt;\n"
7122                                            "SQLSMALLINT h = SQL_HANDLE_STMT;\n"
7123                                            "return 0;}\n",
7124                                            "", "")) {
7125       odbcInclude = "db_odbc.h";
7126       fprintf(logFile, "\rOdbc: %s found in Seed7 include directory.\n",
7127               odbcInclude);
7128       includeOption[0] = '\0';
7129     } /* if */
7130     if (odbcInclude != NULL) {
7131       fprintf(versionFile, "#define WINDOWS_ODBC %d\n", windowsOdbc);
7132       fprintf(versionFile, "#define ODBC_INCLUDE \"%s\"\n", odbcInclude);
7133       fprintf(versionFile, "#define ODBC_INCLUDE_SQLEXT_H %d\n", includeSqlext);
7134       appendOption(include_options, includeOption);
7135     } /* if */
7136 #ifndef ODBC_USE_DLL
7137     /* Handle static libraries: */
7138     sprintf(testProgram, "#include \"tst_vers.h\"\n#include<stdio.h>\n"
7139                          "%s#include \"%s\"\n%s"
7140                          "int main(int argc,char *argv[]){\n"
7141                          "SQLHENV sql_env;\n"
7142                          "SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sql_env);\n"
7143                          "SQLFreeHandle(SQL_HANDLE_ENV, sql_env);\n"
7144                          "printf(\"1\\n\");\n"
7145                          "return 0;\n}\n",
7146                          windowsOdbc ? "#include \"windows.h\"\n" : "", odbcInclude,
7147                          includeSqlext ? "#include \"sqlext.h\"\n" : "");
7148     /* fprintf(logFile, "%s\n", testProgram);
7149        fprintf(logFile, "odbcInclude: \"%s\"\n", odbcInclude); */
7150     if (findLinkerOption("Odbc", testProgram, includeOption, ODBC_LIBRARY_PATH,
7151                          libNameList, sizeof(libNameList) / sizeof(char *),
7152                          system_database_libs)) {
7153       searchForLib = 0;
7154     } /* if */
7155 #endif
7156     if (searchForLib) {
7157       /* Handle dynamic libraries: */
7158       appendOption(system_database_libs, LINKER_OPT_DYN_LINK_LIBS);
7159       fprintf(versionFile, "#define ODBC_DLL");
7160       for (nameIndex = 0; nameIndex < sizeof(dllNameList) / sizeof(char *); nameIndex++) {
7161         fprintf(logFile, "\rOdbc: DLL / Shared library: %s\n", dllNameList[nameIndex]);
7162         fprintf(versionFile, " \"%s\",", dllNameList[nameIndex]);
7163       } /* for */
7164       fprintf(versionFile, "\n");
7165     } /* if */
7166   } /* determineOdbcDefines */
7167 
7168 
7169 
7170 static void determineOciDefines (FILE *versionFile,
7171     char *include_options, char *system_database_libs, char *rpath)
7172 
7173   {
7174     const char *dbHome;
7175 #ifdef OCI_LIBS
7176     const char *libNameList[] = { OCI_LIBS };
7177 #elif LIBRARY_TYPE == UNIX_LIBRARIES || LIBRARY_TYPE == MACOS_LIBRARIES
7178     const char *libNameList[] = {"-lclntsh"};
7179 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
7180     const char *libNameList[] = {"oci.lib"};
7181 #endif
7182 #ifdef OCI_DLL
7183     const char *dllNameList[] = { OCI_DLL };
7184 #elif LIBRARY_TYPE == UNIX_LIBRARIES
7185     const char *dllNameList[] = {"libclntsh.so"};
7186 #elif LIBRARY_TYPE == MACOS_LIBRARIES
7187     const char *dllNameList[] = {"libclntsh.dylib"};
7188 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
7189     const char *dllNameList[] = {"oci.dll"};
7190 #endif
7191     const char *inclDirList[] = {"/rdbms/public", "/oci/include", "/sdk/include"};
7192     const char *libDirList[] = {"/lib"};
7193     const char *dllDirList[] = {"/lib", "/bin", ""};
7194     unsigned int dirIndex;
7195     unsigned int nameIndex;
7196     int searchForLib = 1;
7197     char dirPath[BUFFER_SIZE];
7198     char filePath[BUFFER_SIZE];
7199     char includeOption[BUFFER_SIZE];
7200     const char *ociInclude = NULL;
7201     char testProgram[BUFFER_SIZE];
7202     int dbHomeExists = 0;
7203     int found = 0;
7204 
7205   /* determineOciDefines */
7206 #ifdef OCI_INCLUDE_OPTIONS
7207     strcpy(includeOption, OCI_INCLUDE_OPTIONS);
7208 #else
7209     includeOption[0] = '\0';
7210 #endif
7211     sprintf(testProgram, "#include \"oci.h\"\n"
7212                          "int main(int argc,char *argv[]){\n"
7213                          "OCIEnv *oci_environment; return 0;}\n");
7214     dbHome = getenv("ORACLE_HOME");
7215     if (dbHome != NULL && fileIsDir(dbHome)) {
7216       fprintf(logFile, "\rOracle: ORACLE_HOME=%s\n", dbHome);
7217       dbHomeExists = 1;
7218       ociInclude = findIncludeFile("Oracle", testProgram, dbHome,
7219                                    inclDirList, sizeof(inclDirList) / sizeof(char *),
7220                                    "oci.h", includeOption);
7221       if (ociInclude != NULL) {
7222         appendOption(include_options, includeOption);
7223       } /* if */
7224     } else if (compileAndLinkWithOptionsOk("#include <oci.h>\n"
7225                                            "int main(int argc,char *argv[]){"
7226                                            "OCIEnv *oci_environment; return 0;}\n",
7227                                            includeOption, "")) {
7228       ociInclude = "oci.h";
7229       fprintf(logFile, "\rOracle: %s found in system include directory.\n", ociInclude);
7230       appendOption(include_options, includeOption);
7231     } /* if */
7232     if (ociInclude == NULL &&
7233         compileAndLinkWithOptionsOk("#include \"tst_vers.h\"\n"
7234                                     "#include \"stdlib.h\"\n"
7235                                     "#include \"db_oci.h\"\n"
7236                                     "int main(int argc,char *argv[]){"
7237                                     "OCIEnv *oci_environment; return 0;}\n",
7238                                     "", "")) {
7239       ociInclude = "db_oci.h";
7240       fprintf(logFile, "\rOracle: %s found in Seed7 include directory.\n", ociInclude);
7241     } /* if */
7242     if (ociInclude != NULL) {
7243       fprintf(versionFile, "#define OCI_INCLUDE \"%s\"\n", ociInclude);
7244     } /* if */
7245 #ifndef OCI_USE_DLL
7246     /* Handle static libraries: */
7247     sprintf(testProgram, "#include \"tst_vers.h\"\n"
7248                          "#include<stdio.h>\n#include<stdlib.h>\n"
7249                          "#include \"%s\"\n"
7250                          "int main(int argc,char *argv[]){\n"
7251                          "OCIEnv *oci_env;\n"
7252                          "OCIEnvCreate(&oci_env, OCI_DEFAULT, NULL, NULL, NULL, NULL, 0, NULL);\n"
7253                          "OCIHandleFree(oci_env, OCI_HTYPE_ENV);\n"
7254                          "printf(\"1\\n\");\n"
7255                          "return 0;\n}\n", ociInclude);
7256     /* fprintf(logFile, "%s\n", testProgram);
7257        fprintf(logFile, "ociInclude: \"%s\"\n", ociInclude); */
7258     if (dbHomeExists) {
7259       if (findStaticLib("Oracle", testProgram, includeOption, "", dbHome,
7260                         libDirList, sizeof(libDirList) / sizeof(char *),
7261                         libNameList, sizeof(libNameList) / sizeof(char *),
7262                         system_database_libs)) {
7263         searchForLib = 0;
7264       } /* if */
7265     } /* if */
7266     if (searchForLib) {
7267       if (findLinkerOption("Oracle", testProgram, includeOption, OCI_LIBRARY_PATH,
7268                            libNameList, sizeof(libNameList) / sizeof(char *),
7269                            system_database_libs)) {
7270         searchForLib = 0;
7271       } /* if */
7272     } /* if */
7273 #endif
7274     if (searchForLib) {
7275       /* Handle dynamic libraries: */
7276       appendOption(system_database_libs, LINKER_OPT_DYN_LINK_LIBS);
7277       fprintf(versionFile, "#define OCI_DLL");
7278       if (dbHomeExists && rpath != NULL) {
7279         listDynamicLibs("Oracle", dbHome,
7280                         dllDirList, sizeof(dllDirList) / sizeof(char *),
7281                         dllNameList, sizeof(dllNameList) / sizeof(char *), versionFile);
7282       } /* if */
7283       for (nameIndex = 0; nameIndex < sizeof(dllNameList) / sizeof(char *); nameIndex++) {
7284         fprintf(logFile, "\rOracle: DLL / Shared library: %s\n", dllNameList[nameIndex]);
7285         fprintf(versionFile, " \"%s\",", dllNameList[nameIndex]);
7286       } /* for */
7287       fprintf(versionFile, "\n");
7288       if (dbHomeExists && rpath != NULL) {
7289         /* The oci library has many dependencies to other shared  */
7290         /* object libraries, which are in the directory of the    */
7291         /* main oci library. To dynamically link with ldopen() at */
7292         /* the run-time of the program either this directory must */
7293         /* be listed in the LD_LIBRARY_PATH or the -rpath option  */
7294         /* must be used. Note that the meaning of the -rpath      */
7295         /* option has changed and it must be combined with the    */
7296         /* option --disable-new-dtags to get the old behavior.    */
7297         for (dirIndex = 0; !found && dirIndex < sizeof(dllDirList) / sizeof(char *); dirIndex++) {
7298           sprintf(dirPath, "%s%s", dbHome, dllDirList[dirIndex]);
7299           if (fileIsDir(dirPath)) {
7300             for (nameIndex = 0; nameIndex < sizeof(dllNameList) / sizeof(char *); nameIndex++) {
7301               sprintf(filePath, "%s/%s", dirPath, dllNameList[nameIndex]);
7302               if (fileIsRegular(filePath)) {
7303                 fprintf(logFile, "\rOracle: %s found in %s\n", dllNameList[nameIndex], dirPath);
7304                 if (rpath[0] != '\0') {
7305                   strcat(rpath, ":");
7306                 } /* if */
7307                 strcat(rpath, dirPath);
7308                 found = 1;
7309               } /* if */
7310             } /* for */
7311           } /* if */
7312         } /* for */
7313       } /* if */
7314     } /* if */
7315   } /* determineOciDefines */
7316 
7317 
7318 
7319 static void determineFireDefines (FILE *versionFile,
7320     char *include_options, char *system_database_libs)
7321 
7322   {
7323     const char *dbHomeSys[] = {"Firebird/Firebird_3_0",
7324                                "Firebird/Firebird_2_0"};
7325 #ifdef FIRE_LIBS
7326     const char *libNameList[] = { FIRE_LIBS };
7327 #elif LIBRARY_TYPE == UNIX_LIBRARIES || LIBRARY_TYPE == MACOS_LIBRARIES
7328     const char *libNameList[] = {"-lfbclient"};
7329 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
7330     const char *libNameList[] = {"-lfbclient", "gds32.lib"};
7331 #endif
7332 #ifdef FIRE_DLL
7333     const char *dllNameList[] = { FIRE_DLL };
7334 #elif LIBRARY_TYPE == UNIX_LIBRARIES
7335     const char *dllNameList[] = {"libfbclient.so"};
7336 #elif LIBRARY_TYPE == MACOS_LIBRARIES
7337     const char *dllNameList[] = {"libfbclient.dylib"};
7338 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
7339     const char *dllNameList[] = {"fbclient.dll", "gds32.dll"};
7340 #endif
7341     const char *inclDirList[] = {"/include"};
7342     const char *dllDirList[] = {""};
7343     unsigned int dirIndex;
7344     unsigned int nameIndex;
7345     int searchForLib = 1;
7346     const char *programFilesX86 = NULL;
7347     const char *programFiles = NULL;
7348     char dbHome[BUFFER_SIZE];
7349     char includeOption[BUFFER_SIZE];
7350     const char *fireInclude = NULL;
7351     char testProgram[BUFFER_SIZE];
7352     int dbHomeExists = 0;
7353 
7354   /* determineFireDefines */
7355 #ifdef FIRE_INCLUDE_OPTIONS
7356     strcpy(includeOption, FIRE_INCLUDE_OPTIONS);
7357 #else
7358     includeOption[0] = '\0';
7359 #endif
7360     programFilesX86 = getenv("ProgramFiles(x86)");
7361     /* fprintf(logFile, "programFilesX86: %s\n", programFilesX86); */
7362     programFiles = getenv("ProgramFiles");
7363     /* fprintf(logFile, "programFiles: %s\n", programFiles); */
7364     if (programFiles != NULL) {
7365       if (sizeof(char *) == 4 && programFilesX86 != NULL) {
7366         programFiles = programFilesX86;
7367       } /* if */
7368       for (dirIndex = 0; !dbHomeExists && dirIndex < sizeof(dbHomeSys) / sizeof(char *); dirIndex++) {
7369         sprintf(dbHome, "%s/%s", programFiles, dbHomeSys[dirIndex]);
7370         /* fprintf(logFile, "dbHome: <%s>\n", dbHome); */
7371         if (fileIsDir(dbHome)) {
7372           dbHomeExists = 1;
7373         } /* if */
7374       } /* for */
7375     } /* if */
7376     if (dbHomeExists) {
7377       /* fprintf(logFile, "dbHome=%s\n", dbHome); */
7378       sprintf(testProgram, "#include \"ibase.h\"\n"
7379                            "int main(int argc,char *argv[]){"
7380                            "isc_db_handle conn;\n"
7381                            "isc_stmt_handle stmt;\n"
7382                            "ISC_STATUS status_vector[20];\n"
7383                            "char name = isc_dpb_user_name;\n"
7384                            "char passwd = isc_dpb_password;\n"
7385                            "return 0;}\n");
7386       fireInclude = findIncludeFile("Firebird", testProgram, dbHome,
7387                                     inclDirList, sizeof(inclDirList) / sizeof(char *),
7388                                     "ibase.h", includeOption);
7389       if (fireInclude != NULL) {
7390         appendOption(include_options, includeOption);
7391       } /* if */
7392     } /* if */
7393     if (fireInclude == NULL) {
7394       if (compileAndLinkWithOptionsOk("#include <ibase.h>\n"
7395                                       "int main(int argc,char *argv[]){\n"
7396                                       "isc_db_handle conn;\n"
7397                                       "isc_stmt_handle stmt;\n"
7398                                       "ISC_STATUS status_vector[20];\n"
7399                                       "char name = isc_dpb_user_name;\n"
7400                                       "char passwd = isc_dpb_password;\n"
7401                                       "return 0;}\n",
7402                                       includeOption, "")) {
7403         fireInclude = "ibase.h";
7404         fprintf(logFile, "\rFirebird: %s found in system include directory.\n",
7405                 fireInclude);
7406         appendOption(include_options, includeOption);
7407       } else if (compileAndLinkWithOptionsOk("#include <firebird/ibase.h>\n"
7408                                              "int main(int argc,char *argv[]){\n"
7409                                              "isc_db_handle conn;\n"
7410                                              "isc_stmt_handle stmt;\n"
7411                                              "ISC_STATUS status_vector[20];\n"
7412                                              "char name = isc_dpb_user_name;\n"
7413                                              "char passwd = isc_dpb_password;\n"
7414                                              "return 0;}\n",
7415                                              includeOption, "")) {
7416         fireInclude = "firebird/ibase.h";
7417         fprintf(logFile, "\rFirebird: %s found in system include directory.\n",
7418                 fireInclude);
7419         appendOption(include_options, includeOption);
7420       } else if (compileAndLinkWithOptionsOk("#include \"tst_vers.h\"\n"
7421                                              "#include \"db_fire.h\"\n"
7422                                              "int main(int argc,char *argv[]){\n"
7423                                              "isc_db_handle conn;\n"
7424                                              "isc_stmt_handle stmt;\n"
7425                                              "ISC_STATUS status_vector[20];\n"
7426                                              "char name = isc_dpb_user_name;\n"
7427                                              "char passwd = isc_dpb_password;\n"
7428                                              "return 0;}\n",
7429                                              "", "") ||
7430                  compileAndLinkWithOptionsOk("#define STDCALL\n"
7431                                              "#include \"tst_vers.h\"\n"
7432                                              "#include \"db_fire.h\"\n"
7433                                              "int main(int argc,char *argv[]){\n"
7434                                              "isc_db_handle conn;\n"
7435                                              "isc_stmt_handle stmt;\n"
7436                                              "ISC_STATUS status_vector[20];\n"
7437                                              "char name = isc_dpb_user_name;\n"
7438                                              "char passwd = isc_dpb_password;\n"
7439                                              "return 0;}\n",
7440                                              "", "")) {
7441         fireInclude = "db_fire.h";
7442         fprintf(logFile, "\rFirebird: %s found in Seed7 include directory.\n",
7443                 fireInclude);
7444         includeOption[0] = '\0';
7445       } /* if */
7446     } /* if */
7447     if (fireInclude != NULL) {
7448       fprintf(versionFile, "#define FIRE_INCLUDE \"%s\"\n", fireInclude);
7449     } /* if */
7450 #ifndef FIRE_USE_DLL
7451     /* Handle static libraries: */
7452     sprintf(testProgram, "#include \"tst_vers.h\"\n#include<stdio.h>\n"
7453                          "#include \"%s\"\n"
7454                          "int main(int argc,char *argv[]){\n"
7455                          "ISC_STATUS status_vector[20];\n"
7456                          "isc_stmt_handle stmt_handle;\n"
7457                          "XSQLDA *out_sqlda;\n"
7458                          "out_sqlda = (XSQLDA *) malloc(XSQLDA_LENGTH(10));\n"
7459                          "isc_dsql_describe(status_vector, &stmt_handle, 1, out_sqlda);\n"
7460                          "printf(\"1\\n\");\n"
7461                          "return 0;\n}\n", fireInclude);
7462     /* fprintf(logFile, "%s\n", testProgram);
7463        fprintf(logFile, "fireInclude: \"%s\"\n", fireInclude); */
7464     if (findLinkerOption("Firebird", testProgram, includeOption, FIRE_LIBRARY_PATH,
7465                          libNameList, sizeof(libNameList) / sizeof(char *),
7466                          system_database_libs)) {
7467       searchForLib = 0;
7468     } /* if */
7469 #endif
7470     if (searchForLib) {
7471       /* Handle dynamic libraries: */
7472       appendOption(system_database_libs, LINKER_OPT_DYN_LINK_LIBS);
7473       fprintf(versionFile, "#define FIRE_DLL");
7474       if (dbHomeExists) {
7475         listDynamicLibs("Firebird", dbHome,
7476                         dllDirList, sizeof(dllDirList) / sizeof(char *),
7477                         dllNameList, sizeof(dllNameList) / sizeof(char *), versionFile);
7478       } /* if */
7479       for (nameIndex = 0; nameIndex < sizeof(dllNameList) / sizeof(char *); nameIndex++) {
7480         fprintf(logFile, "\rFirebird: DLL / Shared library: %s\n", dllNameList[nameIndex]);
7481         fprintf(versionFile, " \"%s\",", dllNameList[nameIndex]);
7482       } /* for */
7483       fprintf(versionFile, "\n");
7484     } /* if */
7485   } /* determineFireDefines */
7486 
7487 
7488 
7489 static void determineDb2Defines (FILE *versionFile,
7490     char *include_options, char *system_database_libs)
7491 
7492   {
7493     const char *dbHome;
7494 #ifdef DB2_LIBS
7495     const char *libNameList[] = { DB2_LIBS };
7496 #elif LIBRARY_TYPE == UNIX_LIBRARIES || LIBRARY_TYPE == MACOS_LIBRARIES
7497     const char *libNameList[] = {"libdb2.a"};
7498 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
7499     const char *libNameList[] = {"db2cli.lib"};
7500 #endif
7501 #ifdef DB2_DLL
7502     const char *dllNameList[] = { DB2_DLL };
7503 #elif LIBRARY_TYPE == UNIX_LIBRARIES
7504     const char *dllNameList[] = {"libdb2.so"};
7505 #elif LIBRARY_TYPE == MACOS_LIBRARIES
7506     const char *dllNameList[] = {"libdb2.dylib"};
7507 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
7508     const char *dllNameList[] = {"db2cli.dll"};
7509 #endif
7510     const char *db2DSDriverDir[] = {"C:/Program Files/IBM/DB2DSDriver",
7511                                     "D:/Program Files/IBM/DB2DSDriver"};
7512     const char *inclDirList[] = {"/include"};
7513     const char *libDirList[] = {"/lib"};
7514     unsigned int driverDirIndex;
7515     unsigned int nameIndex;
7516     int searchForLib = 1;
7517     char includeOption[BUFFER_SIZE];
7518     char makeDefinition[BUFFER_SIZE];
7519     const char *db2Include = NULL;
7520     char testProgram[BUFFER_SIZE];
7521     char db2_libs[BUFFER_SIZE];
7522     int dbHomeExists = 0;
7523 
7524   /* determineDb2Defines */
7525 #ifdef DB2_INCLUDE_OPTIONS
7526     strcpy(includeOption, DB2_INCLUDE_OPTIONS);
7527 #else
7528     includeOption[0] = '\0';
7529 #endif
7530     sprintf(testProgram, "#include <sqlcli1.h>\n"
7531                          "int main(int argc,char *argv[]){\n"
7532                          "SQLHDBC conn; SQLHSTMT stmt;\n"
7533                          "SQLSMALLINT h = SQL_HANDLE_STMT;\n"
7534                          "return 0;}\n");
7535     dbHome = getenv("DB2_HOME");
7536     if (dbHome != NULL && fileIsDir(dbHome)) {
7537       fprintf(logFile, "\rDB2: DB2_HOME=%s\n", dbHome);
7538       dbHomeExists = 1;
7539       db2Include = findIncludeFile("DB2", testProgram, dbHome,
7540                                    inclDirList, sizeof(inclDirList) / sizeof(char *),
7541                                    "sqlcli1.h", includeOption);
7542     } /* if */
7543     for (driverDirIndex = 0;
7544          db2Include == NULL && driverDirIndex < sizeof(db2DSDriverDir) / sizeof(char *);
7545          driverDirIndex++) {
7546       /* printf("driverDir: %s\n", db2DSDriverDir[driverDirIndex]); */
7547       if (fileIsDir(db2DSDriverDir[driverDirIndex])) {
7548         /* printf("fileIsDir(%s)\n", db2DSDriverDir[driverDirIndex]); */
7549         db2Include = findIncludeFile("DB2", testProgram, db2DSDriverDir[driverDirIndex],
7550                                      inclDirList, sizeof(inclDirList) / sizeof(char *),
7551                                      "sqlcli1.h", includeOption);
7552         if (db2Include != NULL) {
7553           dbHome = db2DSDriverDir[driverDirIndex];
7554           dbHomeExists = 1;
7555         } /* if */
7556       } /* if */
7557     } /* for */
7558     if (db2Include == NULL) {
7559       if (compileAndLinkWithOptionsOk("#include \"tst_vers.h\"\n"
7560                                       "#include \"db_odbc.h\"\n"
7561                                       "int main(int argc,char *argv[]){\n"
7562                                       "SQLHDBC conn; SQLHSTMT stmt;\n"
7563                                       "SQLSMALLINT h = SQL_HANDLE_STMT;\n"
7564                                       "return 0;}\n",
7565                                       "", "") ||
7566           compileAndLinkWithOptionsOk("#define STDCALL\n"
7567                                       "#include \"tst_vers.h\"\n"
7568                                       "#include \"db_odbc.h\"\n"
7569                                       "int main(int argc,char *argv[]){\n"
7570                                       "SQLHDBC conn; SQLHSTMT stmt;\n"
7571                                       "SQLSMALLINT h = SQL_HANDLE_STMT;\n"
7572                                       "return 0;}\n",
7573                                       "", "")) {
7574         db2Include = "db_odbc.h";
7575         fprintf(logFile, "\rDB2: %s found in Seed7 include directory.\n",
7576                 db2Include);
7577         includeOption[0] = '\0';
7578       } /* if */
7579     } /* if */
7580     if (db2Include != NULL) {
7581       fprintf(versionFile, "#define DB2_INCLUDE \"%s\"\n", db2Include);
7582       fprintf(versionFile, "#define DB2_INCLUDE_OPTION \"");
7583       escapeString(versionFile, includeOption);
7584       fprintf(versionFile, "\"\n");
7585       sprintf(makeDefinition, "DB2_INCLUDE_OPTION = %s\n", includeOption);
7586       appendToFile("macros", makeDefinition);
7587     } /* if */
7588 #if !defined DB2_USE_DLL && defined SUPPORTS_PARTIAL_LINKING
7589     /* Handle static libraries: */
7590     sprintf(testProgram, "#include \"tst_vers.h\"\n#include<stdio.h>\n"
7591                          "#include \"%s\"\n"
7592                          "int main(int argc,char *argv[]){\n"
7593                          "SQLHENV sql_env;\n"
7594                          "SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sql_env);\n"
7595                          "SQLFreeHandle(SQL_HANDLE_ENV, sql_env);\n"
7596                          "printf(\"1\\n\");\n"
7597                          "return 0;\n}\n",
7598                          db2Include);
7599     /* fprintf(logFile, "%s\n", testProgram);
7600        fprintf(logFile, "db2Include: \"%s\"\n", db2Include); */
7601     db2_libs[0] = '\0';
7602     if (dbHomeExists) {
7603       if (findStaticLib("DB2", testProgram, includeOption, "", dbHome,
7604                         libDirList, sizeof(libDirList) / sizeof(char *),
7605                         libNameList, sizeof(libNameList) / sizeof(char *),
7606                         db2_libs)) {
7607         sprintf(makeDefinition, "DB2_LIBS = %s", db2_libs);
7608         replaceNLBySpace(makeDefinition);
7609         strcat(makeDefinition, "\n");
7610         appendToFile("macros", makeDefinition);
7611         searchForLib = 0;
7612       } /* if */
7613     } /* if */
7614     if (searchForLib) {
7615       if (findLinkerOption("DB2", testProgram, includeOption, DB2_LIBRARY_PATH,
7616                            libNameList, sizeof(libNameList) / sizeof(char *),
7617                            db2_libs)) {
7618         sprintf(makeDefinition, "DB2_LIBS = %s", db2_libs);
7619         replaceNLBySpace(makeDefinition);
7620         strcat(makeDefinition, "\n");
7621         appendToFile("macros", makeDefinition);
7622         searchForLib = 0;
7623       } /* if */
7624     } /* if */
7625 #endif
7626     if (searchForLib) {
7627       /* Handle dynamic libraries: */
7628       appendOption(system_database_libs, LINKER_OPT_DYN_LINK_LIBS);
7629       fprintf(versionFile, "#define DB2_DLL");
7630       for (nameIndex = 0; nameIndex < sizeof(dllNameList) / sizeof(char *); nameIndex++) {
7631         fprintf(logFile, "\rDB2: DLL / Shared library: %s\n", dllNameList[nameIndex]);
7632         fprintf(versionFile, " \"%s\",", dllNameList[nameIndex]);
7633       } /* for */
7634       fprintf(versionFile, "\n");
7635     } /* if */
7636   } /* determineDb2Defines */
7637 
7638 
7639 
7640 static void determineSqlServerDefines (FILE *versionFile,
7641     char *include_options, char *system_database_libs)
7642 
7643   {
7644 #ifdef SQL_SERVER_LIBS
7645     const char *libNameList[] = { SQL_SERVER_LIBS };
7646 #elif LIBRARY_TYPE == UNIX_LIBRARIES || LIBRARY_TYPE == MACOS_LIBRARIES
7647     const char *libNameList[] = {"libtdsodbc.a"};
7648 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
7649     const char *libNameList[] = {"sqlsrv32.lib"};
7650 #endif
7651 #ifdef SQL_SERVER_DLL
7652     const char *dllNameList[] = { SQL_SERVER_DLL };
7653 #elif LIBRARY_TYPE == UNIX_LIBRARIES
7654     const char *dllNameList[] = {"libtdsodbc.so"};
7655 #elif LIBRARY_TYPE == MACOS_LIBRARIES
7656     const char *dllNameList[] = {"libtdsodbc.dylib"};
7657 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
7658     /* sqlncli11.dll is omitted, because it truncates fields. */
7659     const char *dllNameList[] = {"sqlsrv32.dll"};
7660 #endif
7661     unsigned int nameIndex;
7662     int searchForLib = 1;
7663     char includeOption[BUFFER_SIZE];
7664     char makeDefinition[BUFFER_SIZE];
7665     int freeTdsLibrary = 0;
7666     int windowsSqlServer = 0;
7667     int includeSqlext = 0;
7668     const char *sqlServerInclude = NULL;
7669     char testProgram[BUFFER_SIZE];
7670     char sql_server_libs[BUFFER_SIZE];
7671 
7672   /* determineSqlServerDefines */
7673 #if LIBRARY_TYPE == UNIX_LIBRARIES || LIBRARY_TYPE == MACOS_LIBRARIES
7674     freeTdsLibrary = 1;
7675 #endif
7676 #ifdef SQL_SERVER_INCLUDE_OPTIONS
7677     strcpy(includeOption, SQL_SERVER_INCLUDE_OPTIONS);
7678 #else
7679     includeOption[0] = '\0';
7680 #endif
7681     if (compileAndLinkWithOptionsOk("#include <windows.h>\n"
7682                                     "#include <sql.h>\n"
7683                                     "#include <sqlext.h>\n"
7684                                     "int main(int argc,char *argv[]){\n"
7685                                     "SQLHDBC conn; SQLHSTMT stmt;\n"
7686                                     "SQLSMALLINT h = SQL_HANDLE_STMT;\n"
7687                                     "return 0;}\n",
7688                                     includeOption, "")) {
7689       windowsSqlServer = 1;
7690       includeSqlext = 1;
7691       sqlServerInclude = "sql.h";
7692       fprintf(logFile, "\rSQL Server: %s found in system include directory.\n",
7693               sqlServerInclude);
7694     } else if (compileAndLinkWithOptionsOk("#include <sql.h>\n"
7695                                            "#include <sqlext.h>\n"
7696                                            "int main(int argc,char *argv[]){\n"
7697                                            "SQLHDBC conn; SQLHSTMT stmt;\n"
7698                                            "SQLSMALLINT h = SQL_HANDLE_STMT;\n"
7699                                            "return 0;}\n",
7700                                            includeOption, "")) {
7701       includeSqlext = 1;
7702       sqlServerInclude = "sql.h";
7703       fprintf(logFile, "\rSQL Server: %s found in system include directory.\n",
7704               sqlServerInclude);
7705     } else if (compileAndLinkWithOptionsOk("#include \"tst_vers.h\"\n"
7706                                            "#include \"db_odbc.h\"\n"
7707                                            "int main(int argc,char *argv[]){\n"
7708                                            "SQLHDBC conn; SQLHSTMT stmt;\n"
7709                                            "SQLSMALLINT h = SQL_HANDLE_STMT;\n"
7710                                            "return 0;}\n",
7711                                            "", "") ||
7712                compileAndLinkWithOptionsOk("#define STDCALL\n"
7713                                            "#include \"tst_vers.h\"\n"
7714                                            "#include \"db_odbc.h\"\n"
7715                                            "int main(int argc,char *argv[]){\n"
7716                                            "SQLHDBC conn; SQLHSTMT stmt;\n"
7717                                            "SQLSMALLINT h = SQL_HANDLE_STMT;\n"
7718                                            "return 0;}\n",
7719                                            "", "")) {
7720       sqlServerInclude = "db_odbc.h";
7721       fprintf(logFile, "\rSQL Server: %s found in Seed7 include directory.\n",
7722               sqlServerInclude);
7723       includeOption[0] = '\0';
7724     } /* if */
7725     if (sqlServerInclude != NULL) {
7726       fprintf(versionFile, "#define WINDOWS_SQL_SERVER %d\n", windowsSqlServer);
7727       fprintf(versionFile, "#define SQL_SERVER_INCLUDE \"%s\"\n", sqlServerInclude);
7728       fprintf(versionFile, "#define SQL_SERVER_INCLUDE_SQLEXT_H %d\n", includeSqlext);
7729       fprintf(versionFile, "#define SQL_SERVER_INCLUDE_OPTION \"");
7730       escapeString(versionFile, includeOption);
7731       fprintf(versionFile, "\"\n");
7732       sprintf(makeDefinition, "SQL_SERVER_INCLUDE_OPTION = %s\n", includeOption);
7733       appendToFile("macros", makeDefinition);
7734       fprintf(versionFile, "#define FREETDS_SQL_SERVER_CONNECTION %d\n", freeTdsLibrary);
7735       fprintf(versionFile, "#define SPECIFY_SQL_SERVER_PORT_EXPLICIT %d\n", freeTdsLibrary);
7736     } /* if */
7737 #if !defined SQL_SERVER_USE_DLL && defined SUPPORTS_PARTIAL_LINKING
7738     /* Handle static libraries: */
7739     sprintf(testProgram, "#include \"tst_vers.h\"\n#include<stdio.h>\n"
7740                          "%s#include \"%s\"\n%s"
7741                          "int main(int argc,char *argv[]){\n"
7742                          "SQLHENV sql_env;\n"
7743                          "SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &sql_env);\n"
7744                          "SQLFreeHandle(SQL_HANDLE_ENV, sql_env);\n"
7745                          "printf(\"1\\n\");\n"
7746                          "return 0;\n}\n",
7747                          windowsSqlServer ? "#include \"windows.h\"\n" : "", sqlServerInclude,
7748                          includeSqlext ? "#include \"sqlext.h\"\n" : "");
7749     /* fprintf(logFile, "%s\n", testProgram);
7750        fprintf(logFile, "sqlServerInclude: \"%s\"\n", sqlServerInclude); */
7751     sql_server_libs[0] = '\0';
7752     if (findLinkerOption("SQL Server", testProgram, includeOption, SQL_SERVER_LIBRARY_PATH,
7753                          libNameList, sizeof(libNameList) / sizeof(char *),
7754                          sql_server_libs)) {
7755       sprintf(makeDefinition, "SQL_SERVER_LIBS = %s", sql_server_libs);
7756       replaceNLBySpace(makeDefinition);
7757       strcat(makeDefinition, "\n");
7758       appendToFile("macros", makeDefinition);
7759       searchForLib = 0;
7760     } /* if */
7761 #endif
7762     if (searchForLib) {
7763       /* Handle dynamic libraries: */
7764       appendOption(system_database_libs, LINKER_OPT_DYN_LINK_LIBS);
7765       fprintf(versionFile, "#define SQL_SERVER_DLL");
7766       for (nameIndex = 0; nameIndex < sizeof(dllNameList) / sizeof(char *); nameIndex++) {
7767         fprintf(logFile, "\rSQL Server: DLL / Shared library: %s\n", dllNameList[nameIndex]);
7768         fprintf(versionFile, " \"%s\",", dllNameList[nameIndex]);
7769       } /* for */
7770       fprintf(versionFile, "\n");
7771     } /* if */
7772   } /* determineSqlServerDefines */
7773 
7774 
7775 
7776 static void determineTdsDefines (FILE *versionFile,
7777     char *include_options, char *system_database_libs)
7778 
7779   {
7780 #ifdef TDS_LIBS
7781     const char *libNameList[] = { TDS_LIBS };
7782 #elif LIBRARY_TYPE == UNIX_LIBRARIES || LIBRARY_TYPE == MACOS_LIBRARIES
7783     const char *libNameList[] = {"-lsybdb"};
7784 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
7785     const char *libNameList[] = {"-lsybdb"};
7786 #endif
7787 #ifdef TDS_DLL
7788     const char *dllNameList[] = { TDS_DLL };
7789 #elif LIBRARY_TYPE == UNIX_LIBRARIES
7790     const char *dllNameList[] = {"libsybdb.so"};
7791 #elif LIBRARY_TYPE == MACOS_LIBRARIES
7792     const char *dllNameList[] = {"libsybdb.dylib"};
7793 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
7794     const char *dllNameList[] = {"sybdb.dll"};
7795 #endif
7796     unsigned int nameIndex;
7797     int searchForLib = 1;
7798     char includeOption[BUFFER_SIZE];
7799     int includeSybfront = 0;
7800     const char *tdsInclude = NULL;
7801     char testProgram[BUFFER_SIZE];
7802 
7803   /* determineTdsDefines */
7804 #ifdef TDS_INCLUDE_OPTIONS
7805     strcpy(includeOption, TDS_INCLUDE_OPTIONS);
7806 #else
7807     includeOption[0] = '\0';
7808 #endif
7809     if (compileAndLinkWithOptionsOk("#include <sybfront.h>\n"
7810                                     "#include <sybdb.h>\n"
7811                                     "int main(int argc,char *argv[]){\n"
7812                                     "DBINT aDbInt; DBPROCESS *dbproc;\n"
7813                                     "RETCODE rc = NO_MORE_ROWS;\n"
7814                                     "return 0;}\n",
7815                                     includeOption, "")) {
7816       includeSybfront = 1;
7817       tdsInclude = "sybdb.h";
7818       fprintf(logFile, "\rTDS: %s found in system include directory.\n",
7819               tdsInclude);
7820     } else if (compileAndLinkWithOptionsOk("#include \"tst_vers.h\"\n"
7821                                            "#include \"db_tds.h\"\n"
7822                                            "int main(int argc,char *argv[]){\n"
7823                                            "DBINT aDbInt; DBPROCESS *dbproc;\n"
7824                                            "RETCODE rc = NO_MORE_ROWS;\n"
7825                                            "return 0;}\n",
7826                                            "", "")) {
7827       tdsInclude = "db_tds.h";
7828       fprintf(logFile, "\rTDS: %s found in Seed7 include directory.\n",
7829               tdsInclude);
7830       includeOption[0] = '\0';
7831     } /* if */
7832     if (tdsInclude != NULL) {
7833       fprintf(versionFile, "#define TDS_INCLUDE \"%s\"\n", tdsInclude);
7834       fprintf(versionFile, "#define TDS_INCLUDE_SYBFRONT_H %d\n", includeSybfront);
7835     } /* if */
7836 #ifndef TDS_USE_DLL
7837     /* Handle static libraries: */
7838     sprintf(testProgram, "#include \"tst_vers.h\"\n#include<stdio.h>\n"
7839                          "#include \"%s\"\n"
7840                          "int errHandler (DBPROCESS *dbproc, int severity, int dberr,\n"
7841                          "    int oserr, char *dberrstr, char *oserrstr) {\n"
7842                          "  if (dberr==SYBETIME) return INT_TIMEOUT; else return INT_CANCEL;\n"
7843                          "}\n"
7844                          "int msgHandler (DBPROCESS *dbproc, DBINT msgno, int msgstate,\n"
7845                          "    int severity, char *msgtext, char *srvname, char *procname, int line) {\n"
7846                          "  return 0;\n"
7847                          "}\n"
7848                          "int main(int argc,char *argv[]){\n"
7849                          "if (dbinit() != FAIL) {\n"
7850                          "  dberrhandle(errHandler);\n"
7851                          "  dbmsghandle(msgHandler);\n"
7852                          "  dblogin();\n"
7853                          "}\n"
7854                          "printf(\"1\\n\");\n"
7855                          "return 0;\n}\n", tdsInclude);
7856     /* fprintf(logFile, "%s\n", testProgram);
7857        fprintf(logFile, "tdsInclude: \"%s\"\n", tdsInclude); */
7858     if (findLinkerOption("TDS", testProgram, includeOption, TDS_LIBRARY_PATH,
7859                          libNameList, sizeof(libNameList) / sizeof(char *),
7860                          system_database_libs)) {
7861       searchForLib = 0;
7862     } /* if */
7863 #endif
7864     if (searchForLib) {
7865       /* Handle dynamic libraries: */
7866       appendOption(system_database_libs, LINKER_OPT_DYN_LINK_LIBS);
7867       fprintf(versionFile, "#define TDS_DLL");
7868       for (nameIndex = 0; nameIndex < sizeof(dllNameList) / sizeof(char *); nameIndex++) {
7869         fprintf(logFile, "\rTDS: DLL / Shared library: %s\n", dllNameList[nameIndex]);
7870         fprintf(versionFile, " \"%s\",", dllNameList[nameIndex]);
7871       } /* for */
7872       fprintf(versionFile, "\n");
7873     } /* if */
7874   } /* determineTdsDefines */
7875 
7876 
7877 
7878 static void determineBigIntDefines (FILE *versionFile,
7879     char *include_options, char *system_bigint_libs)
7880 
7881   {
7882     const char *gmpLinkerOption;
7883     char linkerOptions[BUFFER_SIZE];
7884 
7885   /* determineBigIntDefines */
7886 #if !defined BIGINT_LIB || BIGINT_LIB != BIG_RTL_LIBRARY
7887 #ifdef BIGINT_LIBS
7888     gmpLinkerOption = BIGINT_LIBS;
7889 #else
7890     gmpLinkerOption = "-lgmp";
7891 #endif
7892     linkerOptions[0] = '\0';
7893 #ifdef LINKER_OPT_STATIC_LINKING
7894     appendOption(linkerOptions, LINKER_OPT_STATIC_LINKING);
7895 #endif
7896     appendOption(linkerOptions, gmpLinkerOption);
7897     if (compileAndLinkWithOptionsOk("#include<stdio.h>\n#include<stdlib.h>\n#include<gmp.h>\n"
7898                                     "int main(int argc,char *argv[]){\n"
7899                                     "mpz_ptr aBigInteger;\n"
7900                                     "aBigInteger=(mpz_ptr) malloc(sizeof(__mpz_struct));\n"
7901                                     "mpz_init_set_si(aBigInteger, 12345);\n"
7902                                     "mpz_add_ui(aBigInteger, aBigInteger, 87655);\n"
7903                                     "printf(\"%d\\n\", 100000 == mpz_get_si(aBigInteger));\n"
7904                                     "return 0;}\n",
7905                                     "", linkerOptions) &&
7906         doTest() == 1) {
7907       fputs("#define BIG_GMP_LIBRARY 2\n", versionFile);
7908       fputs("#define BIGINT_LIB BIG_GMP_LIBRARY\n", versionFile);
7909       appendOption(system_bigint_libs, gmpLinkerOption);
7910     } else {
7911       fputs("#define BIG_RTL_LIBRARY 1\n", versionFile);
7912       fputs("#define BIGINT_LIB BIG_RTL_LIBRARY\n", versionFile);
7913     } /* if */
7914 #endif
7915   } /* determineBigIntDefines */
7916 
7917 
7918 
7919 static void determineIncludesAndLibs (FILE *versionFile)
7920 
7921   {
7922     char include_options[BUFFER_SIZE];
7923     char system_database_libs[BUFFER_SIZE];
7924     char system_bigint_libs[BUFFER_SIZE];
7925     char rpath_buffer[BUFFER_SIZE];
7926     char *rpath = NULL;
7927     char rpathOption[BUFFER_SIZE];
7928     char buffer[BUFFER_SIZE];
7929 
7930   /* determineIncludesAndLibs */
7931 #if LIBRARY_TYPE == UNIX_LIBRARIES
7932     fprintf(logFile, "\rUsing Linux/Unix/BSD libraries\n");
7933 #elif LIBRARY_TYPE == MACOS_LIBRARIES
7934     fprintf(logFile, "\rUsing Mac OS libraries\n");
7935 #elif LIBRARY_TYPE == WINDOWS_LIBRARIES
7936     fprintf(logFile, "\rUsing Windows libraries\n");
7937 #endif
7938     include_options[0] = '\0';
7939     system_database_libs[0] = '\0';
7940     system_bigint_libs[0] = '\0';
7941     if (linkerOptionAllowed("-Wl,--disable-new-dtags")) {
7942       rpath_buffer[0] = '\0';
7943       rpath = rpath_buffer;
7944     } /* if */
7945 #if LIBRARY_TYPE == UNIX_LIBRARIES || LIBRARY_TYPE == MACOS_LIBRARIES
7946     determineX11Defines(versionFile, include_options);
7947     determineConsoleDefines(versionFile, include_options);
7948 #elif defined OS_STRI_WCHAR
7949     fputs("#define PIXEL_RED_MASK \"ff\"\n", versionFile);
7950     fputs("#define PIXEL_GREEN_MASK \"ff00\"\n", versionFile);
7951     fputs("#define PIXEL_BLUE_MASK \"ff0000\"\n", versionFile);
7952 #endif
7953     determineMySqlDefines(versionFile, include_options, system_database_libs);
7954     determineSqliteDefines(versionFile, include_options, system_database_libs);
7955     determinePostgresDefines(versionFile, include_options, system_database_libs);
7956     determineOdbcDefines(versionFile, include_options, system_database_libs);
7957     determineOciDefines(versionFile, include_options, system_database_libs, rpath);
7958     determineFireDefines(versionFile, include_options, system_database_libs);
7959     determineDb2Defines(versionFile, include_options, system_database_libs);
7960     determineSqlServerDefines(versionFile, include_options, system_database_libs);
7961     determineTdsDefines(versionFile, include_options, system_database_libs);
7962     determineBigIntDefines(versionFile, include_options, system_bigint_libs);
7963     if (rpath != NULL && rpath[0] != '\0') {
7964       sprintf(rpathOption, "-Wl,--disable-new-dtags,-rpath=%s", rpath);
7965       appendOption(system_database_libs, rpathOption);
7966     } /* if */
7967     sprintf(buffer, "INCLUDE_OPTIONS = %s", include_options);
7968     replaceNLBySpace(buffer);
7969     strcat(buffer, "\n");
7970     appendToFile("macros", buffer);
7971     sprintf(buffer, "SYSTEM_DATABASE_LIBS = %s", system_database_libs);
7972     replaceNLBySpace(buffer);
7973     strcat(buffer, "\n");
7974     appendToFile("macros", buffer);
7975     sprintf(buffer, "SYSTEM_BIGINT_LIBS = %s", system_bigint_libs);
7976     replaceNLBySpace(buffer);
7977     strcat(buffer, "\n");
7978     appendToFile("macros", buffer);
7979     fprintf(versionFile, "#define INCLUDE_OPTIONS \"");
7980     escapeString(versionFile, include_options);
7981     fprintf(versionFile, "\"\n");
7982     fprintf(versionFile, "#define SYSTEM_DATABASE_LIBS \"");
7983     escapeString(versionFile, system_database_libs);
7984     fprintf(versionFile, "\"\n");
7985     fprintf(versionFile, "#define SYSTEM_BIGINT_LIBS \"");
7986     escapeString(versionFile, system_bigint_libs);
7987     fprintf(versionFile, "\"\n");
7988   } /* determineIncludesAndLibs */
7989 
7990 
7991 
7992 static void writeReadBufferEmptyMacro (FILE *versionFile)
7993 
7994   {
7995     const char *define_read_buffer_empty;
7996     int offset_to_count;
7997     char macro_buffer[BUFFER_SIZE];
7998     char buffer[BUFFER_SIZE];
7999 
8000   /* writeReadBufferEmptyMacro */
8001     if (compileAndLinkOk("#include<stdio.h>\nint main(int argc,char *argv[])\n"
8002                          "{FILE*fp;fp->_IO_read_ptr>=fp->_IO_read_end;return 0;}\n")) {
8003       define_read_buffer_empty = "#define read_buffer_empty(fp) "
8004                                  "((fp)->_IO_read_ptr >= (fp)->_IO_read_end)";
8005     } else if (compileAndLinkOk("#include<stdio.h>\nint main(int argc,char *argv[])\n"
8006                                 "{FILE*fp;fp->_cnt <= 0;return 0;}\n")) {
8007       define_read_buffer_empty = "#define read_buffer_empty(fp) ((fp)->_cnt <= 0)";
8008     } else if (compileAndLinkOk("#include<stdio.h>\nint main(int argc,char *argv[])\n"
8009                                 "{FILE*fp;fp->__cnt <= 0;return 0;}\n")) {
8010       define_read_buffer_empty = "#define read_buffer_empty(fp) ((fp)->__cnt <= 0)";
8011     } else if (compileAndLinkOk("#include<stdio.h>\nint main(int argc,char *argv[])\n"
8012                                 "{FILE*fp;fp->level <= 0;return 0;}\n")) {
8013       define_read_buffer_empty = "#define read_buffer_empty(fp) ((fp)->level <= 0)";
8014     } else if (compileAndLinkOk("#include<stdio.h>\nint main(int argc,char *argv[])\n"
8015                                 "{FILE*fp;fp->_r <= 0;return 0;}\n")) {
8016       define_read_buffer_empty = "#define read_buffer_empty(fp) ((fp)->_r <= 0)";
8017     } else if (compileAndLinkOk("#include<stdio.h>\nint main(int argc,char *argv[])\n"
8018                                 "{FILE*fp;fp->ptr >= fp->getend;return 0;}\n")) {
8019       define_read_buffer_empty = "#define read_buffer_empty(fp) ((fp)->ptr >= (fp)->getend)";
8020     } else if (compileAndLinkOk("#include<stdio.h>\nint main(int argc,char *argv[])\n"
8021                                 "{FILE stru; FILE*fp=&stru;char**base;char**pointer;int*count;\n"
8022                                 "_get_stream_buffer_pointers(fp,&base,&pointer,&count);\n"
8023                                 "printf(\"%d\\n\",(int)((char *)count-(char *)fp)); return 0;}\n")) {
8024       if ((offset_to_count = doTest()) != -1) {
8025         sprintf(macro_buffer,
8026                 "#define read_buffer_empty(fp) (*((int *)&((char *)(fp))[%d])==0)",
8027                 offset_to_count);
8028         define_read_buffer_empty = macro_buffer;
8029       } else {
8030         define_read_buffer_empty = NULL;
8031       } /* if */
8032 #if defined FILE_STRUCT_READ_PTR_OFFSET && defined FILE_STRUCT_READ_END_OFFSET
8033     } else {
8034       sprintf(macro_buffer,
8035               "#define read_buffer_empty(fp) "
8036               "(*((int **)&((char *)(fp))[%d]) >= *((int **)&((char *)(fp))[%d]))",
8037               FILE_STRUCT_READ_PTR_OFFSET, FILE_STRUCT_READ_END_OFFSET);
8038       define_read_buffer_empty = macro_buffer;
8039       printf("%s\n", define_read_buffer_empty);
8040 #else
8041     } else if (compileAndLinkOk("#include<stdio.h>\n"
8042                                 "typedef struct {unsigned flags; unsigned char *rpos, *rend;} MY_FILE;\n"
8043                                 "int main(int argc,char *argv[])\n"
8044                                 "{FILE*fp;((MY_FILE*)(fp))->rpos>=((MY_FILE*)(fp))->rend;return 0;}\n")) {
8045       define_read_buffer_empty = "typedef struct {unsigned flags; unsigned char *rpos, *rend;} MY_FILE;\n"
8046                                  "#define read_buffer_empty(fp)"
8047                                  " (((MY_FILE*)(fp))->rpos>=((MY_FILE*)(fp))->rend)";
8048     } else {
8049       define_read_buffer_empty = NULL;
8050 #endif
8051     } /* if */
8052     if (define_read_buffer_empty != NULL) {
8053       sprintf(buffer,
8054               "#include<stdio.h>\n"
8055               "%s\n"
8056               "int main(int argc,char *argv[]){\n"
8057               "FILE *aFile;\n"
8058               "aFile = fopen(\"ctstfile.txt\", \"w\");\n"
8059               "if (aFile != NULL) {\n"
8060               "  fputs(\"abcdefghijklmnopqrstuvwxyz\\n\", aFile);\n"
8061               "  fclose(aFile);\n"
8062               "}\n"
8063               "aFile = fopen(\"ctstfile.txt\", \"r\");\n"
8064               "if (aFile == NULL) {\n"
8065               "  puts(\"0\");\n"
8066               "} else if (!read_buffer_empty(aFile)) {\n"
8067               "  fclose(aFile);\n"
8068               "  puts(\"0\");\n"
8069               "} else {\n"
8070               "  getc(aFile);\n"
8071               "  printf(\"%%d\\n\", read_buffer_empty(aFile)?0:1);\n"
8072               "  fclose(aFile);\n"
8073               "}\n"
8074               "return 0;}\n", define_read_buffer_empty);
8075       if (!compileAndLinkOk(buffer) || doTest() != 1) {
8076         fprintf(logFile, "\n *** %s does not work.\n",
8077                 define_read_buffer_empty);
8078         define_read_buffer_empty = NULL;
8079       } /* if */
8080       doRemove("ctstfile.txt");
8081     } else {
8082       fprintf(logFile, "\n *** Could not define macro read_buffer_empty.\n");
8083     } /* if */
8084     if (define_read_buffer_empty != NULL) {
8085       fprintf(versionFile, "%s\n", define_read_buffer_empty);
8086       fprintf(logFile, "\rMacro read_buffer_empty defined.\n");
8087     } /* if */
8088   } /* writeReadBufferEmptyMacro */
8089 
8090 
8091 
8092 static FILE *openVersionFile (const char *versionFileName)
8093 
8094   {
8095     FILE *versionFile = NULL;
8096 
8097   /* openVersionFile */
8098     if (versionFileName != NULL) {
8099       versionFile = fopen(versionFileName, "a");
8100     } /* if */
8101     if (versionFile == NULL) {
8102       versionFile = stdout;
8103       if (logFile == NULL) {
8104         logFile = fopen("chkccomp.log", "w");
8105         if (logFile == NULL) {
8106           logFile = stdout;
8107         } /* if */
8108       } /* if */
8109     } /* if */
8110     return versionFile;
8111   } /* openVersionFile */
8112 
8113 
8114 
8115 static void closeVersionFile (FILE *versionFile)
8116 
8117   { /* closeVersionFile */
8118     if (versionFile != NULL && versionFile != stdout) {
8119       fclose(versionFile);
8120     } /* if */
8121   } /* closeVersionFile */
8122 
8123 
8124 
8125 /**
8126  *  Program to Check properties of C compiler and runtime.
8127  */
8128 int main (int argc, char **argv)
8129 
8130   {
8131     char *versionFileName = NULL;
8132     FILE *versionFile = NULL;
8133     int driveLetters;
8134 
8135   /* main */
8136     if (!fileIsRegular("settings.h")) {
8137       fprintf(stdout, "\n *** fileIsRegular(\"%s\") fails.\n", "settings.h");
8138     } /* if */
8139     if (argc >= 2) {
8140       versionFileName = argv[1];
8141       if (fileIsRegular(versionFileName)) {
8142         fprintf(stdout, "Truncating existing \"%s\".\n", versionFileName);
8143       } /* if */
8144       copyFile("base.h", versionFileName);
8145       appendFile("settings.h", versionFileName);
8146       copyFile(versionFileName, "tst_vers.h");
8147     } else {
8148       copyFile("base.h", "tst_vers.h");
8149       appendFile("settings.h", "tst_vers.h");
8150     } /* if */
8151     versionFile = openVersionFile(versionFileName);
8152     if (logFile == NULL) {
8153       logFile = stdout;
8154     } /* if */
8155     initializeNullDevice();
8156     fprintf(logFile, "Chkccomp uses %s as null device.\n", nullDevice);
8157     fprintf(logFile, "Prepare compile command: ");
8158     fflush(logFile);
8159     prepareCompileCommand();
8160     determineCompilerVersion(versionFile);
8161     fprintf(logFile, "done\n");
8162     determineOptionForLinkTimeOptimization(versionFile);
8163     numericSizes(versionFile);
8164     fprintf(logFile, "General settings: ");
8165     determineNullDevice(versionFile);
8166     determineCallingConventions(versionFile);
8167     fprintf(versionFile, "#define LINE_DIRECTIVE_ACCEPTS_UTF8 %d\n",
8168             compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
8169                              "int main(int argc, char *argv[]) {\n"
8170                              "#line 1 \"\303\244\303\266\303\274.c\"\n"
8171                              "printf(\"%d\\n\", strcmp(__FILE__,\n"
8172                              "    \"\\303\\244\\303\\266\\303\\274.c\") == 0);\n"
8173                              "return 0; }\n") && doTest() == 1);
8174     fprintf(versionFile, "#define UNISTD_H_PRESENT %d\n",
8175             compileAndLinkOk("#include <unistd.h>\n"
8176                              "int main(int argc,char *argv[]){return 0;}\n"));
8177     fprintf(versionFile, "#define STDINT_H_PRESENT %d\n",
8178             compileAndLinkOk("#include <stdint.h>\n"
8179                              "int main(int argc,char *argv[]){return 0;}\n"));
8180     fprintf(versionFile, "#define ACLAPI_H_PRESENT %d\n",
8181             compileAndLinkOk("#include <aclapi.h>\n"
8182                              "int main(int argc,char *argv[]){return 0;}\n"));
8183     fprintf(versionFile, "#define WINDOWSX_H_PRESENT %d\n",
8184             compileAndLinkOk("#include <stdio.h>\n#include <windows.h>\n"
8185                              "#include <windowsx.h>\n"
8186                              "int main(int argc,char *argv[])\n"
8187                              "{printf(\"%d\\n\", GET_X_LPARAM(12345) == 12345);\n"
8188                              "return 0;}\n") && doTest() == 1);
8189     checkSignal(versionFile);
8190     writeMacroDefs(versionFile);
8191     closeVersionFile(versionFile);
8192     copyFile(versionFileName, "tst_vers.h");
8193     versionFile = openVersionFile(versionFileName);
8194     makeDirDefinition = defineMakeDir();
8195     removeDirDefinition = defineRemoveDir();
8196     determineOsFunctions(versionFile);
8197     checkPopen(versionFile);
8198     checkSystemResult(versionFile);
8199     if (assertCompAndLnk("#include <stdio.h>\nint main(int argc, char *argv[])\n"
8200                          "{printf(\"%d\\n\", fseek(stdin, 0,  SEEK_SET) == 0);\n"
8201                          "return 0;}\n")) {
8202       fprintf(versionFile, "#define FSEEK_SUCCEEDS_FOR_STDIN %d\n", doTest() == 1);
8203     } /* if */
8204     if (assertCompAndLnk("#include <stdio.h>\nint main(int argc, char *argv[])\n"
8205                          "{FILE *aFile; aFile=fopen(\".\",\"r\");\n"
8206                          "printf(\"%d\\n\",aFile!=NULL);\n"
8207                          "if(aFile!=NULL)fclose(aFile);return 0;}\n")) {
8208       fprintf(versionFile, "#define FOPEN_OPENS_DIRECTORIES %d\n", doTest() == 1);
8209     } /* if */
8210     if (assertCompAndLnk("#include <stdio.h>\nint main(int argc, char *argv[])\n"
8211                          "{int canWrite=0;FILE *aFile;\n"
8212                          "if((aFile=fopen(\"tmp_test_file\",\"w\"))!=NULL){\n"
8213                          " fwrite(\"asdf\",1,4,aFile);fclose(aFile);\n"
8214                          " if((aFile=fopen(\"tmp_test_file\",\"r\"))!=NULL){\n"
8215                          "  canWrite=fwrite(\"qwert\",1,5,aFile)!=0;fclose(aFile);}\n"
8216                          " remove(\"tmp_test_file\");}\n"
8217                          "printf(\"%d\\n\",canWrite);return 0;}\n")) {
8218       fprintf(versionFile, "#define FWRITE_WRONG_FOR_READ_ONLY_FILES %d\n", doTest() == 1);
8219     } /* if */
8220     if (assertCompAndLnk("#include <stdio.h>\nint main(int argc, char *argv[])\n"
8221                          "{int canRead=0;FILE *aFile;char buffer[5];\n"
8222                          "if((aFile=fopen(\"tmp_test_file\",\"w\"))!=NULL){\n"
8223                          " canRead=fread(buffer,1,4,aFile)!=0||!ferror(aFile);fclose(aFile);\n"
8224                          " remove(\"tmp_test_file\");}\n"
8225                          "printf(\"%d\\n\",canRead);return 0;}\n")) {
8226       fprintf(versionFile, "#define FREAD_WRONG_FOR_WRITE_ONLY_FILES %d\n", doTest() == 1);
8227     } /* if */
8228     checkRemoveDir(makeDirDefinition, versionFile);
8229     if (compileAndLinkOk("#include <stdio.h>\n#include <unistd.h>\n#include <ctype.h>\n"
8230                          "int main(int argc, char *argv[])\n"
8231                          "{char buffer[8192]; char *cwd;\n"
8232                          "cwd = getcwd(buffer, 8192);\n"
8233                          "printf(\"%d\\n\", cwd!=NULL && isalpha(cwd[0]) && cwd[1]==':');\n"
8234                          "return 0;}\n") ||
8235         compileAndLinkOk("#include <stdio.h>\n#include <unistd.h>\n#include <ctype.h>\n"
8236                          "int main(int argc, char *argv[])\n"
8237                          "{char buffer[8192]; char *cwd;\n"
8238                          "cwd = _getcwd(buffer, 8192);\n"
8239                          "printf(\"%d\\n\", cwd!=NULL && isalpha(cwd[0]) && cwd[1]==':');\n"
8240                          "return 0;}\n") ||
8241         compileAndLinkOk("#include <stdio.h>\n#include <direct.h>\n#include <ctype.h>\n"
8242                          "int main(int argc, char *argv[])\n"
8243                          "{char buffer[8192]; char *cwd;\n"
8244                          "cwd = getcwd(buffer, 8192);\n"
8245                          "printf(\"%d\\n\", cwd!=NULL && isalpha(cwd[0]) && cwd[1]==':');\n"
8246                          "return 0;}\n") ||
8247         compileAndLinkOk("#include <stdio.h>\n#include <direct.h>\n#include <ctype.h>\n"
8248                          "int main(int argc, char *argv[])\n"
8249                          "{char buffer[8192]; char *cwd;\n"
8250                          "cwd = _getcwd(buffer, 8192);\n"
8251                          "printf(\"%d\\n\", cwd!=NULL && isalpha(cwd[0]) && cwd[1]==':');\n"
8252                          "return 0;}\n")) {
8253       driveLetters = doTest() == 1;
8254       fprintf(versionFile, "#define OS_PATH_HAS_DRIVE_LETTERS %d\n", driveLetters);
8255       if (driveLetters) {
8256         /* The check for HOME and USERPROFILE is done with a program,         */
8257         /* because some compilers (e.g.: emcc) provide their own environment. */
8258         if (assertCompAndLnk("#include <stdio.h>\n#include <stdlib.h>\n"
8259                              "int main(int argc, char *argv[])\n"
8260                              "{printf(\"%d\\n\", getenv(\"USERPROFILE\") != NULL);\n"
8261                              "return 0;}\n") && doTest() == 1) {
8262           /* If USERPROFILE is defined then it is used, even if HOME is defined. */
8263           fputs("#define HOME_DIR_ENV_VAR {'U', 'S', 'E', 'R', "
8264                 "'P', 'R', 'O', 'F', 'I', 'L', 'E', 0}\n", versionFile);
8265         } else if (assertCompAndLnk("#include <stdio.h>\n#include <stdlib.h>\n"
8266                                     "int main(int argc, char *argv[])\n"
8267                                     "{printf(\"%d\\n\", getenv(\"HOME\") != NULL);\n"
8268                                     "return 0;}\n") && doTest() == 1) {
8269           fputs("#define HOME_DIR_ENV_VAR {'H', 'O', 'M', 'E', 0}\n", versionFile);
8270         } else {
8271           fputs("#define HOME_DIR_ENV_VAR {'H', 'O', 'M', 'E', 0}\n", versionFile);
8272           fputs("#define DEFAULT_HOME_DIR {'C', ':', '\\\\', 0}\n", versionFile);
8273         } /* if */
8274       } else {
8275         fputs("#define HOME_DIR_ENV_VAR {'H', 'O', 'M', 'E', 0}\n", versionFile);
8276       } /* if */
8277     } else {
8278       fputs("#define HOME_DIR_ENV_VAR {'H', 'O', 'M', 'E', 0}\n", versionFile);
8279     } /* if */
8280 #if defined OS_STRI_WCHAR && defined _WIN32
8281     /* Under Windows a rename between different    */
8282     /* devices fails with EACCES instead of EXDEV. */
8283     fputs("#define USE_EACCES_INSTEAD_OF_EXDEV\n", versionFile);
8284     /* Windows uses pending deletes which cause    */
8285     /* problems if a file with the same name is    */
8286     /* created shortly after the delete. To avoid  */
8287     /* problems files are renamed before they are  */
8288     /* removed.                                    */
8289     fputs("#define RENAME_BEFORE_REMOVE\n", versionFile);
8290 #endif
8291     fprintf(logFile, " determined\n");
8292     numericProperties(versionFile);
8293     fprintf(logFile, "Advanced settings: ");
8294     fflush(logFile);
8295     determineMallocProperties(versionFile);
8296     if (compileAndLinkOk("#include<signal.h>\nint main(int argc, char *argv[]){\n"
8297                          "signal(SIGBUS,SIG_DFL); return 0;}\n")) {
8298       if (assertCompAndLnk("#include<stdlib.h>\n#include <stdio.h>\n#include<signal.h>\n"
8299                            "void handleSig(int sig){puts(\"2\");exit(0);}\n"
8300                            "int main(int argc, char *argv[])\n"
8301                            "{int p[3]={12,34,56}, q, *pp;\n"
8302                            "signal(SIGBUS,handleSig);\n"
8303                            "pp=(int *)((char *)&p[1]+1); q=*pp;\n"
8304                            "printf(\"1\\n\"); return 0;}\n")) {
8305         fprintf(versionFile, "#define UNALIGNED_MEMORY_ACCESS_OKAY %d\n", doTest() == 1);
8306       } /* if */
8307     } else if (assertCompAndLnk("#include <stdio.h>\n"
8308                                 "int main(int argc, char *argv[])\n"
8309                                 "{int p[3]={12,34,56}, q, *pp;\n"
8310                                 "pp=(int *)((char *)&p[1]+1); q=*pp;\n"
8311                                 "printf(\"1\\n\"); return 0;}\n")) {
8312       fprintf(versionFile, "#define UNALIGNED_MEMORY_ACCESS_OKAY %d\n", doTest() == 1);
8313     } /* if */
8314     if (assertCompAndLnk("#include <stdio.h>\n#include <string.h>\n"
8315                          "int main(int argc, char *argv[])\n"
8316                          "{union{char ch;unsigned long gen;}aUnion;\n"
8317                          "memset(&aUnion,0,sizeof(aUnion));aUnion.ch='X';\n"
8318                          "printf(\"%d\\n\",aUnion.ch==(char)aUnion.gen);return 0;}\n")) {
8319       fprintf(versionFile, "#define CASTING_GETS_A_UNION_ELEMENT %d\n", doTest() == 1);
8320     } /* if */
8321     if (assertCompAndLnk("#include <stdio.h>\nint main(int argc, char *argv[])\n"
8322                          "{printf(\"%d\\n\", EOF == -1); return 0;}\n")) {
8323       fprintf(versionFile, "#define EOF_IS_MINUS_ONE %d\n", doTest());
8324     } /* if */
8325     fprintf(versionFile, "#define EMPTY_STRUCTS_ALLOWED %d\n",
8326             compileAndLinkOk("#include <stdio.h>\n"
8327                              "typedef struct emptyStruct { } emptyRecord;\n"
8328                              "int main(int argc, char *argv[]){\n"
8329                              "return 0;}\n"));
8330     fprintf(versionFile, "#define INITIALIZING_WITH_ADDRESS_ALLOWED %d\n",
8331             compileAndLinkOk("#include <stdio.h>\n"
8332                              "typedef struct testStruct { int number; } *testType;\n"
8333                              "struct testStruct aRecord;\n"
8334                              "int main(int argc, char *argv[])\n"
8335                              "{ testType aVariable = &aRecord;\n"
8336                              "int counter;\n"
8337                              "printf(\"0\\n\"); return 0;}\n"));
8338     checkForLimitedStringLiteralLength(versionFile);
8339     checkForLimitedArrayLiteralLength(versionFile);
8340     checkForSwitchWithInt64Type(versionFile);
8341     determineStackDirection(versionFile);
8342     determineLanguageProperties(versionFile);
8343     determinePreprocessorProperties(versionFile);
8344 #ifndef STACK_SIZE
8345     if (sizeof(char *) == 8) { /* Machine with 64-bit addresses */
8346       /* Due to alignment some 64-bit machines have huge stack requirements. */
8347       fputs("#define STACK_SIZE 0x1000000\n", versionFile); /* 16777216 bytes */
8348     } else {
8349       fputs("#define STACK_SIZE 0x800000\n", versionFile); /* 8388608 bytes */
8350     } /* if */
8351 #endif
8352     localtimeProperties(versionFile);
8353     /* Make sure that the file version.h up to this position is copied to tst_vers.h. */
8354     closeVersionFile(versionFile);
8355     copyFile(versionFileName, "tst_vers.h");
8356     versionFile = openVersionFile(versionFileName);
8357     determineGetaddrlimit(versionFile);
8358     fprintf(versionFile, "#define MEMCMP_RETURNS_SIGNUM %d\n",
8359         compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
8360                          "int main(int argc, char *argv[]){\n"
8361                          "char stri1[3], stri2[3];\n"
8362                          "strcpy(stri1, \"za\");\n"
8363                          "strcpy(stri2, \"az\");\n"
8364                          "printf(\"%d\\n\",\n"
8365                          "       memcmp(stri1, stri2, 2) == 1 &&\n"
8366                          "       memcmp(stri2, stri1, 2) == -1);\n"
8367                          "return 0;}\n") && doTest() == 1);
8368     fprintf(versionFile, "#define HAS_WMEMCMP %d\n",
8369         compileAndLinkOk("#include <stdio.h>\n#include <wchar.h>\n"
8370                          "int main(int argc, char *argv[]){\n"
8371                          "wchar_t str1[] = {0x0201, 0x0102, 0};\n"
8372                          "wchar_t str2[] = {0x0102, 0x0201, 0};\n"
8373                          "printf(\"%d\\n\", wmemcmp(str1, str2, 2) > 0);\n"
8374                          "return 0;}\n") && doTest() == 1);
8375     fprintf(versionFile, "#define WMEMCMP_RETURNS_SIGNUM %d\n",
8376         compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
8377                          "#include <wchar.h>\n"
8378                          "int main(int argc, char *argv[]){\n"
8379                          "wchar_t str1[] = {0x0201, 0x0102, 0};\n"
8380                          "wchar_t str2[] = {0x0102, 0x0201, 0};\n"
8381                          "wchar_t stri1[3], stri2[3];\n"
8382                          "memcpy(stri1, str1, 2 * sizeof(wchar_t));\n"
8383                          "memcpy(stri2, str2, 2 * sizeof(wchar_t));\n"
8384                          "printf(\"%d\\n\",\n"
8385                          "       wmemcmp(str1, str2, 2) == 1 &&\n"
8386                          "       wmemcmp(str2, str1, 2) == -1);\n"
8387                          "return 0;}\n") && doTest() == 1);
8388     fprintf(versionFile, "#define MEMSET_OF_ZERO_BYTES_DOES_NOTHING %d\n",
8389         compileAndLinkOk("#include <stdio.h>\n#include <string.h>\n"
8390                          "int main(int argc, char *argv[]){\n"
8391                          "char stri1[17];\n"
8392                          "int zero;\n"
8393                          "strcpy(stri1, \"abcdefghijklmnop\");\n"
8394                          "zero = strlen(stri1) - 16;\n"
8395                          "memset(&stri1[8], 0, zero);\n"
8396                          "printf(\"%d\\n\",\n"
8397                          "       memcmp(stri1, \"abcdefghijklmnop\", 17) == 0);\n"
8398                          "return 0;}\n") && doTest() == 1);
8399     fprintf(versionFile, "#define HAS_WMEMSET %d\n",
8400         compileAndLinkOk("#include <stdio.h>\n#include <wchar.h>\n#include <string.h>\n"
8401                          "int main(int argc, char *argv[]){\n"
8402                          "wchar_t str1[4];\n"
8403                          "wchar_t str2[] = {0, 0, 0, 0};\n"
8404                          "wchar_t ch1 = 0x00;\n"
8405                          "wmemset(str1, ch1, 4);\n"
8406                          "printf(\"%d\\n\", memcmp(str1, str2, 4 * sizeof(wchar_t)) == 0);\n"
8407                          "return 0;}\n") && doTest() == 1);
8408     fprintf(versionFile, "#define HAS_WMEMCHR %d\n",
8409         compileAndLinkOk("#include <stdio.h>\n#include <wchar.h>\n"
8410                          "int main(int argc, char *argv[]){\n"
8411                          "wchar_t str1[] = {0x0201, 0x0102, 0};\n"
8412                          "wchar_t ch1 = 0x0102;\n"
8413                          "printf(\"%d\\n\", wmemchr(str1, ch1, 2) ==  &str1[1]);\n"
8414                          "return 0;}\n") && doTest() == 1);
8415     fprintf(versionFile, "#define HAS_WCSNLEN %d\n",
8416         compileAndLinkOk("#include <stdio.h>\n#include <wchar.h>\n"
8417                          "int main(int argc, char *argv[]){\n"
8418                          "wchar_t str1[] = {0x0201, 0x0102, 0x0303, 0, 0x0301, 0};\n"
8419                          "printf(\"%d\\n\", wcsnlen(str1, 5) == 3 &&\n"
8420                          "                  wcsnlen(str1, 4) == 3 &&\n"
8421                          "                  wcsnlen(str1, 3) == 3 &&\n"
8422                          "                  wcsnlen(str1, 2) == 2);\n"
8423                          "return 0;}\n") && doTest() == 1);
8424     fprintf(versionFile, "#define HAS_STRNCASECMP %d\n",
8425         compileAndLinkOk("#include <stdio.h>\n#include <strings.h>\n"
8426                          "int main(int argc, char *argv[]){\n"
8427                          "printf(\"%d\\n\", strncasecmp(\"abc\", \"abcd\", 3) == 0);\n"
8428                          "return 0;}\n") && doTest() == 1);
8429     fprintf(versionFile, "#define HAS_GETGRGID_R %d\n",
8430         compileAndLinkOk("#include <stdio.h>\n#include <sys/types.h>\n"
8431                          "#include <grp.h>\n"
8432                          "int main(int argc, char *argv[]){\n"
8433                          "int funcRes; struct group grp;\n"
8434                          "char buffer[2048]; struct group *grpResult;\n"
8435                          "funcRes = getgrgid_r((gid_t) 0, &grp,\n"
8436                          "buffer, sizeof(buffer), &grpResult);\n"
8437                          "printf(\"%d\\n\", funcRes==0 && grpResult==&grp);\n"
8438                          "return 0;}\n") && doTest() == 1);
8439     fprintf(versionFile, "#define HAS_GETGRGID %d\n",
8440         compileAndLinkOk("#include <stdio.h>\n#include <sys/types.h>\n"
8441                          "#include <grp.h>\n"
8442                          "int main(int argc, char *argv[]){\n"
8443                          "struct group *grpResult;\n"
8444                          "grpResult = getgrgid((gid_t) 0);\n"
8445                          "printf(\"%d\\n\", grpResult!=NULL);\n"
8446                          "return 0;}\n") && doTest() == 1);
8447     fprintf(versionFile, "#define HAS_GETGRNAM_R %d\n",
8448         compileAndLinkOk("#include <stdio.h>\n#include <sys/types.h>\n"
8449                          "#include <grp.h>\n"
8450                          "int main(int argc, char *argv[]){\n"
8451                          "int funcRes; struct group grp;\n"
8452                          "char buffer[2048]; struct group *grpResult;\n"
8453                          "funcRes = getgrnam_r(\"root\", &grp,\n"
8454                          "buffer, sizeof(buffer), &grpResult);\n"
8455                          "printf(\"%d\\n\", funcRes==0 && grpResult==&grp);\n"
8456                          "return 0;}\n") && doTest() == 1);
8457     fprintf(versionFile, "#define HAS_GETGRNAM %d\n",
8458         compileAndLinkOk("#include <stdio.h>\n#include <sys/types.h>\n"
8459                          "#include <grp.h>\n"
8460                          "int main(int argc, char *argv[]){\n"
8461                          "struct group *grpResult;\n"
8462                          "grpResult = getgrnam(\"root\");\n"
8463                          "printf(\"%d\\n\", grpResult!=NULL);\n"
8464                          "return 0;}\n") && doTest() == 1);
8465     fprintf(versionFile, "#define HAS_GETPWUID_R %d\n",
8466         compileAndLinkOk("#include <stdio.h>\n#include <sys/types.h>\n"
8467                          "#include <pwd.h>\n"
8468                          "int main(int argc, char *argv[]){\n"
8469                          "int funcRes; struct passwd pwd;\n"
8470                          "char buffer[2048]; struct passwd *pwdResult;\n"
8471                          "funcRes = getpwuid_r((uid_t) 0, &pwd,\n"
8472                          "    buffer, sizeof(buffer), &pwdResult);\n"
8473                          "printf(\"%d\\n\", funcRes==0 && pwdResult==&pwd &&\n"
8474                          "    pwdResult->pw_uid != -1);\n"
8475                          "return 0;}\n") && doTest() == 1);
8476     fprintf(versionFile, "#define HAS_GETPWUID %d\n",
8477         compileAndLinkOk("#include <stdio.h>\n#include <sys/types.h>\n"
8478                          "#include <pwd.h>\n"
8479                          "int main(int argc, char *argv[]){\n"
8480                          "struct passwd *pwdResult;\n"
8481                          "pwdResult = getpwuid((uid_t) 0);\n"
8482                          "printf(\"%d\\n\", pwdResult!=NULL && pwdResult->pw_uid != -1);\n"
8483                          "return 0;}\n") && doTest() == 1);
8484     fprintf(versionFile, "#define HAS_GETPWNAM_R %d\n",
8485         compileAndLinkOk("#include <stdio.h>\n#include <sys/types.h>\n"
8486                          "#include <pwd.h>\n"
8487                          "int main(int argc, char *argv[]){\n"
8488                          "int funcRes; struct passwd pwd;\n"
8489                          "char buffer[2048]; struct passwd *pwdResult;\n"
8490                          "funcRes = getpwnam_r(\"root\", &pwd,\n"
8491                          "    buffer, sizeof(buffer), &pwdResult);\n"
8492                          "printf(\"%d\\n\", funcRes==0 && pwdResult==&pwd &&\n"
8493                          "    pwdResult->pw_uid != -1);\n"
8494                          "return 0;}\n") && doTest() == 1);
8495     fprintf(versionFile, "#define HAS_GETPWNAM %d\n",
8496         compileAndLinkOk("#include <stdio.h>\n#include <sys/types.h>\n"
8497                          "#include <pwd.h>\n"
8498                          "int main(int argc, char *argv[]){\n"
8499                          "struct passwd *pwdResult;\n"
8500                          "pwdResult = getpwnam(\"root\");\n"
8501                          "printf(\"%d\\n\", pwdResult!=NULL && pwdResult->pw_uid != -1);\n"
8502                          "return 0;}\n") && doTest() == 1);
8503     fprintf(versionFile, "#define HAS_SETJMP %d\n",
8504         compileAndLinkOk("#include <stdio.h>\n#include <setjmp.h>\n"
8505                          "int main(int argc, char *argv[]){\n"
8506                          "jmp_buf env; int ret_code = 4; int count = 2;\n"
8507                          "if ((ret_code=setjmp(env)) == 0) {\n"
8508                          "count--; longjmp(env, count); printf(\"3\\n\");\n"
8509                          "} else printf(\"%d\\n\", ret_code);\n"
8510                          "return 0;}\n") && doTest() == 1);
8511     fprintf(versionFile, "#define HAS_SIGSETJMP %d\n",
8512         compileAndLinkOk("#include <stdio.h>\n#include <setjmp.h>\n"
8513                          "int main(int argc, char *argv[]){\n"
8514                          "sigjmp_buf env; int ret_code = 4; int count = 2;\n"
8515                          "if ((ret_code=sigsetjmp(env, 1)) == 0) {\n"
8516                          "count--; siglongjmp(env, count); printf(\"3\\n\");\n"
8517                          "} else printf(\"%d\\n\", ret_code);\n"
8518                          "return 0;}\n") && doTest() == 1);
8519     fprintf(versionFile, "#define HAS_SYMBOLIC_LINKS %d\n",
8520         compileAndLinkOk("#include <stdio.h>\n#include <unistd.h>\n#include <string.h>\n"
8521                          "int main(int argc, char *argv[]){\n"
8522                          "char buf[256]; ssize_t link_len; int okay=0;\n"
8523                          "if (symlink(\"qwertzuiop\",\"test_symlink\") == 0){;\n"
8524                          "link_len=readlink(\"test_symlink\", buf, 256);\n"
8525                          "okay = link_len == 10 && memcmp(buf,\"qwertzuiop\",10) == 0;\n"
8526                          "remove(\"test_symlink\");}\n"
8527                          "printf(\"%d\\n\", okay);\n"
8528                          "return 0;}\n") && doTest() == 1);
8529     fprintf(versionFile, "#define HAS_READLINK %d\n",
8530         compileAndLinkOk("#include <stdio.h>\n#include <unistd.h>\n"
8531                          "#include <string.h>\n#include <errno.h>\n"
8532                          "int main(int argc, char *argv[]){\n"
8533                          "char buf[256]; ssize_t link_len;\n"
8534                          "link_len = readlink(\" does_not_exist \", buf, 256);\n"
8535                          "printf(\"%d\\n\", link_len == -1);\n"
8536                          "return 0;}\n") && doTest() == 1);
8537     fprintf(versionFile, "#define HAS_FIFO_FILES %d\n",
8538         compileAndLinkOk("#include <sys/types.h>\n#include <sys/stat.h>\n"
8539                          "int main(int argc, char *argv[]){\n"
8540                          "int ret_code;\n"
8541                          "ret_code=mkfifo(\"qwertzuiop\", 0);\n"
8542                          "return 0;}\n"));
8543     fprintf(versionFile, "#define HAS_SELECT %d\n",
8544         compileAndLinkOk("#include<sys/select.h>\n#include<stddef.h>\n"
8545                          "int main(int argc,char *argv[])\n"
8546                          "{fd_set readfds, writefds, exceptfds;\n"
8547                          "select(15, &readfds, &writefds, &exceptfds, NULL);\n"
8548                          "return 0;}\n") ||
8549         compileAndLinkWithOptionsOk("#include<winsock2.h>\n#include<stddef.h>\n"
8550                                     "int main(int argc,char *argv[])\n"
8551                                     "{fd_set readfds, writefds, exceptfds;\n"
8552                                     "select(15, &readfds, &writefds, &exceptfds, NULL);\n"
8553                                     "return 0;}\n", "", SYSTEM_LIBS));
8554     fprintf(versionFile, "#define HAS_POLL %d\n",
8555         compileAndLinkOk("#include<poll.h>\n"
8556                          "int main(int argc,char *argv[])\n"
8557                          "{struct pollfd pollFd[1];\n"
8558                          "poll(pollFd, 1, 0);\n"
8559                          "return 0;}\n"));
8560     fprintf(versionFile, "#define HAS_MMAP %d\n",
8561         compileAndLinkOk("#include<stddef.h>\n#include<sys/mman.h>\n"
8562                          "int main(int argc,char *argv[])\n"
8563                          "{mmap(NULL, 12345, PROT_READ, MAP_PRIVATE, 3, 0);\n"
8564                          "return 0;}\n"));
8565     fprintf(logFile, " determined\n");
8566     determineIncludesAndLibs(versionFile);
8567     writeReadBufferEmptyMacro(versionFile);
8568     cleanUpCompilation(testNumber);
8569     fprintf(versionFile, "#define REMOVE_REATTEMPTS %lu\n", removeReattempts);
8570     closeVersionFile(versionFile);
8571     if (fileIsRegular("tst_vers.h")) {
8572       remove("tst_vers.h");
8573     } /* if */
8574     fprintf(logFile, " \b");
8575     return 0;
8576   } /* main */
8577