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&<->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&<->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