blob: b31ea6eb3eeb1180a01d2317cfb5d86b2672b97b [file] [log] [blame]
/* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Charmonize.c -- Create Charmony.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Charmonizer/Probe.h"
#include "Charmonizer/Probe/AtomicOps.h"
#include "Charmonizer/Probe/DirManip.h"
#include "Charmonizer/Probe/Floats.h"
#include "Charmonizer/Probe/FuncMacro.h"
#include "Charmonizer/Probe/Headers.h"
#include "Charmonizer/Probe/Integers.h"
#include "Charmonizer/Probe/LargeFiles.h"
#include "Charmonizer/Probe/Memory.h"
#include "Charmonizer/Probe/SymbolVisibility.h"
#include "Charmonizer/Probe/UnusedVars.h"
#include "Charmonizer/Probe/VariadicMacros.h"
#include "Charmonizer/Core/HeaderChecker.h"
#include "Charmonizer/Core/ConfWriter.h"
#include "Charmonizer/Core/ConfWriterC.h"
#include "Charmonizer/Core/ConfWriterPerl.h"
#include "Charmonizer/Core/ConfWriterRuby.h"
#define MAX_CC_LEN 128
#define MAX_FLAGS_LEN 2048
struct CLIArgs {
char cc_command[MAX_CC_LEN + 1];
char cc_flags[MAX_FLAGS_LEN + 1];
int enable_c;
int enable_perl;
int enable_ruby;
};
/* Parse command line arguments. */
static void
S_parse_arguments(int argc, char **argv, struct CLIArgs *args) {
int i;
int output_enabled = 0;
/* Parse most args. */
for (i = 1; i < argc; i++) {
char *arg = argv[i];
if (strcmp(arg, "--") == 0) {
/* From here on out, everything will be a compiler flag. */
i++;
break;
}
if (strcmp(arg, "--enable-c") == 0) {
args->enable_c = 1;
output_enabled = 1;
}
else if (strcmp(arg, "--enable-perl") == 0) {
args->enable_perl = 1;
output_enabled = 1;
}
else if (strcmp(arg, "--enable-ruby") == 0) {
args->enable_ruby = 1;
output_enabled = 1;
}
else if (memcmp(arg, "--cc=", 5) == 0) {
if (strlen(arg) > MAX_CC_LEN - 5) {
fprintf(stderr, "Exceeded max length for compiler command");
exit(1);
}
strcpy(args->cc_command, arg + 5);
}
}
/* Accumulate compiler flags. */
for (; i < argc; i++) {
char *arg = argv[i];
if (strlen(arg) + strlen(args->cc_flags) + 2 >= MAX_FLAGS_LEN) {
fprintf(stderr, "Exceeded max length for compiler flags");
exit(1);
}
strcat(args->cc_flags, " ");
strcat(args->cc_flags, arg);
}
/* Validate. */
if (!args->cc_command
|| !strlen(args->cc_command)
|| !output_enabled
) {
fprintf(stderr,
"Usage: ./charmonize --cc=CC_COMMAND [--enable-c] "
"[--enable-perl] [--enable-ruby] -- CC_FLAGS\n");
exit(1);
}
}
int main(int argc, char **argv) {
/* Initialize. */
{
struct chaz_CLIArgs args;
int result = chaz_Probe_parse_cli_args(argc, argv, &args);
if (!result) {
chaz_Probe_die_usage();
}
chaz_Probe_init(&args);
}
/* Run probe modules. */
chaz_DirManip_run();
chaz_Headers_run();
chaz_AtomicOps_run();
chaz_FuncMacro_run();
chaz_Integers_run();
chaz_Floats_run();
chaz_LargeFiles_run();
chaz_Memory_run();
chaz_SymbolVisibility_run();
chaz_UnusedVars_run();
chaz_VariadicMacros_run();
/* Write custom postamble. */
chaz_ConfWriter_append_conf(
"#ifdef CHY_HAS_SYS_TYPES_H\n"
" #include <sys/types.h>\n"
"#endif\n\n"
);
chaz_ConfWriter_append_conf(
"#ifdef CHY_HAS_ALLOCA_H\n"
" #include <alloca.h>\n"
"#elif defined(CHY_HAS_MALLOC_H)\n"
" #include <malloc.h>\n"
"#elif defined(CHY_ALLOCA_IN_STDLIB_H)\n"
" #include <stdlib.h>\n"
"#endif\n\n"
);
chaz_ConfWriter_append_conf(
"#ifdef CHY_HAS_WINDOWS_H\n"
" /* Target Windows XP. */\n"
" #ifndef WINVER\n"
" #define WINVER 0x0500\n"
" #endif\n"
" #ifndef _WIN32_WINNT\n"
" #define _WIN32_WINNT 0x0500\n"
" #endif\n"
"#endif\n\n"
);
/* Clean up. */
chaz_Probe_clean_up();
return 0;
}