Updated Branches: refs/heads/master 9a4efa6eb -> 1dced2235
Regenerate charmonizer.c Project: http://git-wip-us.apache.org/repos/asf/lucy/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/1dced223 Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/1dced223 Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/1dced223 Branch: refs/heads/master Commit: 1dced2235d5d654c613dbe3b94d8e4c504469976 Parents: 8d1abdd Author: Nick Wellnhofer <[email protected]> Authored: Sun Mar 24 17:11:45 2013 +0100 Committer: Nick Wellnhofer <[email protected]> Committed: Sun Mar 24 17:13:47 2013 +0100 ---------------------------------------------------------------------- clownfish/compiler/common/charmonizer.c | 200 ++++++++++++++++-------- clownfish/runtime/common/charmonizer.c | 200 ++++++++++++++++-------- common/charmonizer.c | 225 +++++++++++++++++-------- 3 files changed, 425 insertions(+), 200 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy/blob/1dced223/clownfish/compiler/common/charmonizer.c ---------------------------------------------------------------------- diff --git a/clownfish/compiler/common/charmonizer.c b/clownfish/compiler/common/charmonizer.c index d79f642..bd102f9 100644 --- a/clownfish/compiler/common/charmonizer.c +++ b/clownfish/compiler/common/charmonizer.c @@ -108,6 +108,11 @@ chaz_CC_add_include_dir(const char *dir); void chaz_CC_set_optimization_level(const char *level); +/* Disable strict aliasing. + */ +void +chaz_CC_disable_strict_aliasing(); + /* Accessor for the compiler executable's string representation. */ const char* @@ -133,6 +138,9 @@ int chaz_CC_msvc_version_num(void); const char* +chaz_CC_shared_obj_cflags(void); + +const char* chaz_CC_link_command(void); const char* @@ -144,6 +152,12 @@ chaz_CC_link_shared_obj_flag(void); const char* chaz_CC_link_output_flag(void); +char* +chaz_CC_library_path_flag(const char *directory); + +char* +chaz_CC_link_with_shared_obj_flag(const char *shared_obj); + #endif /* H_CHAZ_COMPILER */ @@ -646,6 +660,11 @@ chaz_Util_slurp_file(const char *file_path, size_t *len_ptr); char* chaz_Util_strdup(const char *string); +/* Join a NULL-terminated list of strings using a separator. + */ +char* +chaz_Util_join(const char *sep, ...); + /* Get the length of a file (may overshoot on text files under DOS). */ long @@ -1105,16 +1124,10 @@ chaz_CC_init(const char *compiler_command, const char *compiler_flags) { chaz_CC.extra_cflags = chaz_Util_strdup(""); /* Set names for the targets which we "try" to compile. */ - { - const char *exe_ext = chaz_OS_exe_ext(); - const char *obj_ext = chaz_OS_obj_ext(); - size_t exe_len = strlen(CHAZ_CC_TRY_BASENAME) + strlen(exe_ext) + 1; - size_t obj_len = strlen(CHAZ_CC_TRY_BASENAME) + strlen(obj_ext) + 1; - chaz_CC.try_exe_name = (char*)malloc(exe_len); - chaz_CC.try_obj_name = (char*)malloc(obj_len); - sprintf(chaz_CC.try_exe_name, "%s%s", CHAZ_CC_TRY_BASENAME, exe_ext); - sprintf(chaz_CC.try_obj_name, "%s%s", CHAZ_CC_TRY_BASENAME, obj_ext); - } + chaz_CC.try_exe_name + = chaz_Util_join("", CHAZ_CC_TRY_BASENAME, chaz_OS_exe_ext(), NULL); + chaz_CC.try_obj_name + = chaz_Util_join("", CHAZ_CC_TRY_BASENAME, chaz_OS_obj_ext(), NULL); /* If we can't compile anything, game over. */ if (chaz_Util_verbosity) { @@ -1358,12 +1371,8 @@ chaz_CC_add_extra_cflags(const char *flags) { chaz_CC.extra_cflags = chaz_Util_strdup(flags); } else { - size_t size = strlen(chaz_CC.extra_cflags) - + 1 // Space separation - + strlen(flags) - + 1; // NULL termination - char *newflags = (char*)malloc(size); - sprintf(newflags, "%s %s", chaz_CC.extra_cflags, flags); + char *newflags + = chaz_Util_join(" ", chaz_CC.extra_cflags, flags, NULL); free(chaz_CC.extra_cflags); chaz_CC.extra_cflags = newflags; } @@ -1371,9 +1380,7 @@ chaz_CC_add_extra_cflags(const char *flags) { void chaz_CC_add_include_dir(const char *dir) { - size_t size = strlen(chaz_CC.include_flag) + strlen(dir) + 1; - char *flag = (char*)malloc(size); - sprintf(flag, "%s%s", chaz_CC.include_flag, dir); + char *flag = chaz_Util_join("", chaz_CC.include_flag, dir, NULL); chaz_CC_add_extra_cflags(flag); free(flag); } @@ -1382,7 +1389,6 @@ void chaz_CC_set_optimization_level(const char *level) { const char *opt_flag; char *flag; - size_t size; if (chaz_CC.intval__MSC_VER) { opt_flag = "/O"; @@ -1390,13 +1396,18 @@ chaz_CC_set_optimization_level(const char *level) { else { opt_flag = "-O"; } - size = strlen(opt_flag) + strlen(level) + 1; - flag = (char*)malloc(size); - sprintf(flag, "%s%s", opt_flag, level); + flag = chaz_Util_join("", opt_flag, level, NULL); chaz_CC_add_extra_cflags(flag); free(flag); } +void +chaz_CC_disable_strict_aliasing() { + if (!chaz_CC.intval__MSC_VER) { + chaz_CC_add_extra_cflags("-fno-strict-aliasing"); + } +} + const char* chaz_CC_get_cc(void) { return chaz_CC.cc_command; @@ -1430,6 +1441,19 @@ chaz_CC_msvc_version_num(void) { } const char* +chaz_CC_shared_obj_cflags() { + if (chaz_CC.intval__MSC_VER) { + return ""; + } + else if (chaz_OS_is_darwin()) { + return "-fno-common"; + } + else { + return "-fPIC"; + } +} + +const char* chaz_CC_link_command() { if (chaz_CC.intval__MSC_VER) { return "link"; @@ -1450,7 +1474,7 @@ chaz_CC_link_shared_obj_flag() { return "/DLL"; } else if (chaz_OS_is_darwin()) { - return "-dynamiclib "; + return "-dynamiclib"; } else { return "-shared"; @@ -1467,6 +1491,36 @@ chaz_CC_link_output_flag() { } } +char* +chaz_CC_library_path_flag(const char *directory) { + char *flag = (char*)malloc(20 + sizeof(directory)); + if (chaz_CC.intval__MSC_VER) { + if (strcmp(directory, ".") == 0) { + /* The MS linker searches the current directory by default. */ + strcpy(flag, ""); + } + else { + sprintf(flag, "/LIBPATH:%s", directory); + } + } + else { + sprintf(flag, "-L%s", directory); + } + return flag; +} + +char* +chaz_CC_link_with_shared_obj_flag(const char *shared_obj) { + char *flag = (char*)malloc(20 + sizeof(shared_obj)); + if (chaz_CC.intval__MSC_VER) { + sprintf(flag, "%s.lib", shared_obj); + } + else { + sprintf(flag, "-l%s", shared_obj); + } + return flag; +} + /***************************************************************************/ @@ -2683,10 +2737,7 @@ chaz_Make_detect(const char *make1, ...) { static int chaz_Make_audition(const char *make) { int succeeded = 0; - const char pattern[] = "%s -f _charm_Makefile"; - size_t size = strlen(make) + sizeof(pattern) + 10; - char *command = (char*)malloc(size); - sprintf(command, pattern, make); + char *command = chaz_Util_join(" ", make, "-f", "_charm_Makefile", NULL); chaz_Util_remove_and_verify("_charm_foo"); chaz_OS_run_redirected(command, "_charm_foo"); @@ -2996,8 +3047,7 @@ chaz_MakeRule_add_target(chaz_MakeRule *rule, const char *target) { targets = chaz_Util_strdup(target); } else { - targets = (char*)malloc(strlen(rule->targets) + strlen(target) + 20); - sprintf(targets, "%s %s", rule->targets, target); + targets = chaz_Util_join(" ", rule->targets, target, NULL); free(rule->targets); } @@ -3012,8 +3062,7 @@ chaz_MakeRule_add_prereq(chaz_MakeRule *rule, const char *prereq) { prereqs = chaz_Util_strdup(prereq); } else { - prereqs = (char*)malloc(strlen(rule->prereqs) + strlen(prereq) + 20); - sprintf(prereqs, "%s %s", rule->prereqs, prereq); + prereqs = chaz_Util_join(" ", rule->prereqs, prereq, NULL); free(rule->prereqs); } @@ -3045,21 +3094,16 @@ chaz_MakeRule_add_command_make(chaz_MakeRule *rule, const char *dir, if (chaz_Make.is_gnu_make) { if (!target) { - size_t size = strlen(dir) + 20; - command = (char*)malloc(size); - sprintf(command, "$(MAKE) -C %s", dir); + command = chaz_Util_join(" ", "$(MAKE)", "-C", dir, NULL); } else { - size_t size = strlen(dir) + strlen(target) + 20; - command = (char*)malloc(size); - sprintf(command, "$(MAKE) -C %s %s", dir, target); + command = chaz_Util_join(" ", "$(MAKE)", "-C", dir, target, NULL); } chaz_MakeRule_add_command(rule, command); free(command); } else if (chaz_Make.is_nmake) { - command = (char*)malloc(strlen(dir) + 20); - sprintf(command, "cd %s", dir); + command = chaz_Util_join(" ", "cd", dir, NULL); chaz_MakeRule_add_command(rule, command); free(command); @@ -3067,9 +3111,7 @@ chaz_MakeRule_add_command_make(chaz_MakeRule *rule, const char *dir, chaz_MakeRule_add_command(rule, "$(MAKE)"); } else { - size_t size = strlen(target) + 20; - command = (char*)malloc(size); - sprintf(command, "$(MAKE) %s", target); + command = chaz_Util_join(" ", "$(MAKE)", target, NULL); chaz_MakeRule_add_command(rule, command); free(command); } @@ -3331,11 +3373,9 @@ chaz_OS_remove(const char *name) { int chaz_OS_run_local_redirected(const char *command, const char *path) { - size_t size = strlen(command) + strlen(chaz_OS.local_command_start) + 20; - char *local_command = (char*)malloc(size); - int retval; - sprintf(local_command, "%s%s", chaz_OS.local_command_start, command); - retval = chaz_OS_run_redirected(local_command, path); + char *local_command + = chaz_Util_join("", chaz_OS.local_command_start, command, NULL); + int retval = chaz_OS_run_redirected(local_command, path); free(local_command); return retval; } @@ -3352,13 +3392,7 @@ chaz_OS_run_redirected(const char *command, const char *path) { if (chaz_OS.shell_type == CHAZ_OS_POSIX || chaz_OS.shell_type == CHAZ_OS_CMD_EXE ) { - char pattern[] = "%s > %s 2>&1"; - size_t size = sizeof(pattern) - + strlen(command) - + strlen(path) - + 10; - quiet_command = (char*)malloc(size); - sprintf(quiet_command, pattern, command, path); + quiet_command = chaz_Util_join(" ", command, ">", path, "2>&1", NULL); } else { chaz_Util_die("Don't know the shell type"); @@ -3383,9 +3417,7 @@ chaz_OS_mkdir(const char *filepath) { if (chaz_OS.shell_type == CHAZ_OS_POSIX || chaz_OS.shell_type == CHAZ_OS_CMD_EXE ) { - unsigned size = sizeof("mkdir") + 1 + strlen(filepath) + 1; - command = (char*)malloc(size); - sprintf(command, "mkdir %s", filepath); + command = chaz_Util_join(" ", "mkdir", filepath, NULL); } else { chaz_Util_die("Don't know the shell type"); @@ -3398,14 +3430,10 @@ void chaz_OS_rmdir(const char *filepath) { char *command = NULL; if (chaz_OS.shell_type == CHAZ_OS_POSIX) { - unsigned size = strlen("rmdir") + 1 + strlen(filepath) + 1; - command = (char*)malloc(size); - sprintf(command, "rmdir %s", filepath); + command = chaz_Util_join(" ", "rmdir", filepath, NULL); } else if (chaz_OS.shell_type == CHAZ_OS_CMD_EXE) { - unsigned size = strlen("rmdir /q") + 1 + strlen(filepath) + 1; - command = (char*)malloc(size); - sprintf(command, "rmdir /q %s", filepath); + command = chaz_Util_join(" ", "rmdir", "/q", filepath, NULL); } else { chaz_Util_die("Don't know the shell type"); @@ -3520,6 +3548,50 @@ chaz_Util_strdup(const char *string) { return copy; } +char* +chaz_Util_join(const char *sep, ...) { + va_list args; + const char *string; + char *result, *p; + size_t sep_len = strlen(sep); + size_t size; + int i; + + /* Determine result size. */ + va_start(args, sep); + size = 1; + string = va_arg(args, const char*); + for (i = 0; string; ++i) { + if (i != 0) { size += sep_len; } + size += strlen(string); + string = va_arg(args, const char*); + } + va_end(args); + + result = (char*)malloc(size); + + /* Create result string. */ + va_start(args, sep); + p = result; + string = va_arg(args, const char*); + for (i = 0; string; ++i) { + size_t len; + if (i != 0) { + memcpy(p, sep, sep_len); + p += sep_len; + } + len = strlen(string); + memcpy(p, string, len); + p += len; + string = va_arg(args, const char*); + } + va_end(args); + + *p = '\0'; + + return result; +} + void chaz_Util_die(const char* format, ...) { va_list args; http://git-wip-us.apache.org/repos/asf/lucy/blob/1dced223/clownfish/runtime/common/charmonizer.c ---------------------------------------------------------------------- diff --git a/clownfish/runtime/common/charmonizer.c b/clownfish/runtime/common/charmonizer.c index d243fe4..8c148c1 100644 --- a/clownfish/runtime/common/charmonizer.c +++ b/clownfish/runtime/common/charmonizer.c @@ -108,6 +108,11 @@ chaz_CC_add_include_dir(const char *dir); void chaz_CC_set_optimization_level(const char *level); +/* Disable strict aliasing. + */ +void +chaz_CC_disable_strict_aliasing(); + /* Accessor for the compiler executable's string representation. */ const char* @@ -133,6 +138,9 @@ int chaz_CC_msvc_version_num(void); const char* +chaz_CC_shared_obj_cflags(void); + +const char* chaz_CC_link_command(void); const char* @@ -144,6 +152,12 @@ chaz_CC_link_shared_obj_flag(void); const char* chaz_CC_link_output_flag(void); +char* +chaz_CC_library_path_flag(const char *directory); + +char* +chaz_CC_link_with_shared_obj_flag(const char *shared_obj); + #endif /* H_CHAZ_COMPILER */ @@ -646,6 +660,11 @@ chaz_Util_slurp_file(const char *file_path, size_t *len_ptr); char* chaz_Util_strdup(const char *string); +/* Join a NULL-terminated list of strings using a separator. + */ +char* +chaz_Util_join(const char *sep, ...); + /* Get the length of a file (may overshoot on text files under DOS). */ long @@ -1410,16 +1429,10 @@ chaz_CC_init(const char *compiler_command, const char *compiler_flags) { chaz_CC.extra_cflags = chaz_Util_strdup(""); /* Set names for the targets which we "try" to compile. */ - { - const char *exe_ext = chaz_OS_exe_ext(); - const char *obj_ext = chaz_OS_obj_ext(); - size_t exe_len = strlen(CHAZ_CC_TRY_BASENAME) + strlen(exe_ext) + 1; - size_t obj_len = strlen(CHAZ_CC_TRY_BASENAME) + strlen(obj_ext) + 1; - chaz_CC.try_exe_name = (char*)malloc(exe_len); - chaz_CC.try_obj_name = (char*)malloc(obj_len); - sprintf(chaz_CC.try_exe_name, "%s%s", CHAZ_CC_TRY_BASENAME, exe_ext); - sprintf(chaz_CC.try_obj_name, "%s%s", CHAZ_CC_TRY_BASENAME, obj_ext); - } + chaz_CC.try_exe_name + = chaz_Util_join("", CHAZ_CC_TRY_BASENAME, chaz_OS_exe_ext(), NULL); + chaz_CC.try_obj_name + = chaz_Util_join("", CHAZ_CC_TRY_BASENAME, chaz_OS_obj_ext(), NULL); /* If we can't compile anything, game over. */ if (chaz_Util_verbosity) { @@ -1663,12 +1676,8 @@ chaz_CC_add_extra_cflags(const char *flags) { chaz_CC.extra_cflags = chaz_Util_strdup(flags); } else { - size_t size = strlen(chaz_CC.extra_cflags) - + 1 // Space separation - + strlen(flags) - + 1; // NULL termination - char *newflags = (char*)malloc(size); - sprintf(newflags, "%s %s", chaz_CC.extra_cflags, flags); + char *newflags + = chaz_Util_join(" ", chaz_CC.extra_cflags, flags, NULL); free(chaz_CC.extra_cflags); chaz_CC.extra_cflags = newflags; } @@ -1676,9 +1685,7 @@ chaz_CC_add_extra_cflags(const char *flags) { void chaz_CC_add_include_dir(const char *dir) { - size_t size = strlen(chaz_CC.include_flag) + strlen(dir) + 1; - char *flag = (char*)malloc(size); - sprintf(flag, "%s%s", chaz_CC.include_flag, dir); + char *flag = chaz_Util_join("", chaz_CC.include_flag, dir, NULL); chaz_CC_add_extra_cflags(flag); free(flag); } @@ -1687,7 +1694,6 @@ void chaz_CC_set_optimization_level(const char *level) { const char *opt_flag; char *flag; - size_t size; if (chaz_CC.intval__MSC_VER) { opt_flag = "/O"; @@ -1695,13 +1701,18 @@ chaz_CC_set_optimization_level(const char *level) { else { opt_flag = "-O"; } - size = strlen(opt_flag) + strlen(level) + 1; - flag = (char*)malloc(size); - sprintf(flag, "%s%s", opt_flag, level); + flag = chaz_Util_join("", opt_flag, level, NULL); chaz_CC_add_extra_cflags(flag); free(flag); } +void +chaz_CC_disable_strict_aliasing() { + if (!chaz_CC.intval__MSC_VER) { + chaz_CC_add_extra_cflags("-fno-strict-aliasing"); + } +} + const char* chaz_CC_get_cc(void) { return chaz_CC.cc_command; @@ -1735,6 +1746,19 @@ chaz_CC_msvc_version_num(void) { } const char* +chaz_CC_shared_obj_cflags() { + if (chaz_CC.intval__MSC_VER) { + return ""; + } + else if (chaz_OS_is_darwin()) { + return "-fno-common"; + } + else { + return "-fPIC"; + } +} + +const char* chaz_CC_link_command() { if (chaz_CC.intval__MSC_VER) { return "link"; @@ -1755,7 +1779,7 @@ chaz_CC_link_shared_obj_flag() { return "/DLL"; } else if (chaz_OS_is_darwin()) { - return "-dynamiclib "; + return "-dynamiclib"; } else { return "-shared"; @@ -1772,6 +1796,36 @@ chaz_CC_link_output_flag() { } } +char* +chaz_CC_library_path_flag(const char *directory) { + char *flag = (char*)malloc(20 + sizeof(directory)); + if (chaz_CC.intval__MSC_VER) { + if (strcmp(directory, ".") == 0) { + /* The MS linker searches the current directory by default. */ + strcpy(flag, ""); + } + else { + sprintf(flag, "/LIBPATH:%s", directory); + } + } + else { + sprintf(flag, "-L%s", directory); + } + return flag; +} + +char* +chaz_CC_link_with_shared_obj_flag(const char *shared_obj) { + char *flag = (char*)malloc(20 + sizeof(shared_obj)); + if (chaz_CC.intval__MSC_VER) { + sprintf(flag, "%s.lib", shared_obj); + } + else { + sprintf(flag, "-l%s", shared_obj); + } + return flag; +} + /***************************************************************************/ @@ -2988,10 +3042,7 @@ chaz_Make_detect(const char *make1, ...) { static int chaz_Make_audition(const char *make) { int succeeded = 0; - const char pattern[] = "%s -f _charm_Makefile"; - size_t size = strlen(make) + sizeof(pattern) + 10; - char *command = (char*)malloc(size); - sprintf(command, pattern, make); + char *command = chaz_Util_join(" ", make, "-f", "_charm_Makefile", NULL); chaz_Util_remove_and_verify("_charm_foo"); chaz_OS_run_redirected(command, "_charm_foo"); @@ -3301,8 +3352,7 @@ chaz_MakeRule_add_target(chaz_MakeRule *rule, const char *target) { targets = chaz_Util_strdup(target); } else { - targets = (char*)malloc(strlen(rule->targets) + strlen(target) + 20); - sprintf(targets, "%s %s", rule->targets, target); + targets = chaz_Util_join(" ", rule->targets, target, NULL); free(rule->targets); } @@ -3317,8 +3367,7 @@ chaz_MakeRule_add_prereq(chaz_MakeRule *rule, const char *prereq) { prereqs = chaz_Util_strdup(prereq); } else { - prereqs = (char*)malloc(strlen(rule->prereqs) + strlen(prereq) + 20); - sprintf(prereqs, "%s %s", rule->prereqs, prereq); + prereqs = chaz_Util_join(" ", rule->prereqs, prereq, NULL); free(rule->prereqs); } @@ -3350,21 +3399,16 @@ chaz_MakeRule_add_command_make(chaz_MakeRule *rule, const char *dir, if (chaz_Make.is_gnu_make) { if (!target) { - size_t size = strlen(dir) + 20; - command = (char*)malloc(size); - sprintf(command, "$(MAKE) -C %s", dir); + command = chaz_Util_join(" ", "$(MAKE)", "-C", dir, NULL); } else { - size_t size = strlen(dir) + strlen(target) + 20; - command = (char*)malloc(size); - sprintf(command, "$(MAKE) -C %s %s", dir, target); + command = chaz_Util_join(" ", "$(MAKE)", "-C", dir, target, NULL); } chaz_MakeRule_add_command(rule, command); free(command); } else if (chaz_Make.is_nmake) { - command = (char*)malloc(strlen(dir) + 20); - sprintf(command, "cd %s", dir); + command = chaz_Util_join(" ", "cd", dir, NULL); chaz_MakeRule_add_command(rule, command); free(command); @@ -3372,9 +3416,7 @@ chaz_MakeRule_add_command_make(chaz_MakeRule *rule, const char *dir, chaz_MakeRule_add_command(rule, "$(MAKE)"); } else { - size_t size = strlen(target) + 20; - command = (char*)malloc(size); - sprintf(command, "$(MAKE) %s", target); + command = chaz_Util_join(" ", "$(MAKE)", target, NULL); chaz_MakeRule_add_command(rule, command); free(command); } @@ -3636,11 +3678,9 @@ chaz_OS_remove(const char *name) { int chaz_OS_run_local_redirected(const char *command, const char *path) { - size_t size = strlen(command) + strlen(chaz_OS.local_command_start) + 20; - char *local_command = (char*)malloc(size); - int retval; - sprintf(local_command, "%s%s", chaz_OS.local_command_start, command); - retval = chaz_OS_run_redirected(local_command, path); + char *local_command + = chaz_Util_join("", chaz_OS.local_command_start, command, NULL); + int retval = chaz_OS_run_redirected(local_command, path); free(local_command); return retval; } @@ -3657,13 +3697,7 @@ chaz_OS_run_redirected(const char *command, const char *path) { if (chaz_OS.shell_type == CHAZ_OS_POSIX || chaz_OS.shell_type == CHAZ_OS_CMD_EXE ) { - char pattern[] = "%s > %s 2>&1"; - size_t size = sizeof(pattern) - + strlen(command) - + strlen(path) - + 10; - quiet_command = (char*)malloc(size); - sprintf(quiet_command, pattern, command, path); + quiet_command = chaz_Util_join(" ", command, ">", path, "2>&1", NULL); } else { chaz_Util_die("Don't know the shell type"); @@ -3688,9 +3722,7 @@ chaz_OS_mkdir(const char *filepath) { if (chaz_OS.shell_type == CHAZ_OS_POSIX || chaz_OS.shell_type == CHAZ_OS_CMD_EXE ) { - unsigned size = sizeof("mkdir") + 1 + strlen(filepath) + 1; - command = (char*)malloc(size); - sprintf(command, "mkdir %s", filepath); + command = chaz_Util_join(" ", "mkdir", filepath, NULL); } else { chaz_Util_die("Don't know the shell type"); @@ -3703,14 +3735,10 @@ void chaz_OS_rmdir(const char *filepath) { char *command = NULL; if (chaz_OS.shell_type == CHAZ_OS_POSIX) { - unsigned size = strlen("rmdir") + 1 + strlen(filepath) + 1; - command = (char*)malloc(size); - sprintf(command, "rmdir %s", filepath); + command = chaz_Util_join(" ", "rmdir", filepath, NULL); } else if (chaz_OS.shell_type == CHAZ_OS_CMD_EXE) { - unsigned size = strlen("rmdir /q") + 1 + strlen(filepath) + 1; - command = (char*)malloc(size); - sprintf(command, "rmdir /q %s", filepath); + command = chaz_Util_join(" ", "rmdir", "/q", filepath, NULL); } else { chaz_Util_die("Don't know the shell type"); @@ -3825,6 +3853,50 @@ chaz_Util_strdup(const char *string) { return copy; } +char* +chaz_Util_join(const char *sep, ...) { + va_list args; + const char *string; + char *result, *p; + size_t sep_len = strlen(sep); + size_t size; + int i; + + /* Determine result size. */ + va_start(args, sep); + size = 1; + string = va_arg(args, const char*); + for (i = 0; string; ++i) { + if (i != 0) { size += sep_len; } + size += strlen(string); + string = va_arg(args, const char*); + } + va_end(args); + + result = (char*)malloc(size); + + /* Create result string. */ + va_start(args, sep); + p = result; + string = va_arg(args, const char*); + for (i = 0; string; ++i) { + size_t len; + if (i != 0) { + memcpy(p, sep, sep_len); + p += sep_len; + } + len = strlen(string); + memcpy(p, string, len); + p += len; + string = va_arg(args, const char*); + } + va_end(args); + + *p = '\0'; + + return result; +} + void chaz_Util_die(const char* format, ...) { va_list args; http://git-wip-us.apache.org/repos/asf/lucy/blob/1dced223/common/charmonizer.c ---------------------------------------------------------------------- diff --git a/common/charmonizer.c b/common/charmonizer.c index 7149c1f..eeab2ca 100644 --- a/common/charmonizer.c +++ b/common/charmonizer.c @@ -108,6 +108,11 @@ chaz_CC_add_include_dir(const char *dir); void chaz_CC_set_optimization_level(const char *level); +/* Disable strict aliasing. + */ +void +chaz_CC_disable_strict_aliasing(); + /* Accessor for the compiler executable's string representation. */ const char* @@ -133,6 +138,9 @@ int chaz_CC_msvc_version_num(void); const char* +chaz_CC_shared_obj_cflags(void); + +const char* chaz_CC_link_command(void); const char* @@ -144,6 +152,12 @@ chaz_CC_link_shared_obj_flag(void); const char* chaz_CC_link_output_flag(void); +char* +chaz_CC_library_path_flag(const char *directory); + +char* +chaz_CC_link_with_shared_obj_flag(const char *shared_obj); + #endif /* H_CHAZ_COMPILER */ @@ -646,6 +660,11 @@ chaz_Util_slurp_file(const char *file_path, size_t *len_ptr); char* chaz_Util_strdup(const char *string); +/* Join a NULL-terminated list of strings using a separator. + */ +char* +chaz_Util_join(const char *sep, ...); + /* Get the length of a file (may overshoot on text files under DOS). */ long @@ -1410,16 +1429,10 @@ chaz_CC_init(const char *compiler_command, const char *compiler_flags) { chaz_CC.extra_cflags = chaz_Util_strdup(""); /* Set names for the targets which we "try" to compile. */ - { - const char *exe_ext = chaz_OS_exe_ext(); - const char *obj_ext = chaz_OS_obj_ext(); - size_t exe_len = strlen(CHAZ_CC_TRY_BASENAME) + strlen(exe_ext) + 1; - size_t obj_len = strlen(CHAZ_CC_TRY_BASENAME) + strlen(obj_ext) + 1; - chaz_CC.try_exe_name = (char*)malloc(exe_len); - chaz_CC.try_obj_name = (char*)malloc(obj_len); - sprintf(chaz_CC.try_exe_name, "%s%s", CHAZ_CC_TRY_BASENAME, exe_ext); - sprintf(chaz_CC.try_obj_name, "%s%s", CHAZ_CC_TRY_BASENAME, obj_ext); - } + chaz_CC.try_exe_name + = chaz_Util_join("", CHAZ_CC_TRY_BASENAME, chaz_OS_exe_ext(), NULL); + chaz_CC.try_obj_name + = chaz_Util_join("", CHAZ_CC_TRY_BASENAME, chaz_OS_obj_ext(), NULL); /* If we can't compile anything, game over. */ if (chaz_Util_verbosity) { @@ -1663,12 +1676,8 @@ chaz_CC_add_extra_cflags(const char *flags) { chaz_CC.extra_cflags = chaz_Util_strdup(flags); } else { - size_t size = strlen(chaz_CC.extra_cflags) - + 1 // Space separation - + strlen(flags) - + 1; // NULL termination - char *newflags = (char*)malloc(size); - sprintf(newflags, "%s %s", chaz_CC.extra_cflags, flags); + char *newflags + = chaz_Util_join(" ", chaz_CC.extra_cflags, flags, NULL); free(chaz_CC.extra_cflags); chaz_CC.extra_cflags = newflags; } @@ -1676,9 +1685,7 @@ chaz_CC_add_extra_cflags(const char *flags) { void chaz_CC_add_include_dir(const char *dir) { - size_t size = strlen(chaz_CC.include_flag) + strlen(dir) + 1; - char *flag = (char*)malloc(size); - sprintf(flag, "%s%s", chaz_CC.include_flag, dir); + char *flag = chaz_Util_join("", chaz_CC.include_flag, dir, NULL); chaz_CC_add_extra_cflags(flag); free(flag); } @@ -1687,7 +1694,6 @@ void chaz_CC_set_optimization_level(const char *level) { const char *opt_flag; char *flag; - size_t size; if (chaz_CC.intval__MSC_VER) { opt_flag = "/O"; @@ -1695,13 +1701,18 @@ chaz_CC_set_optimization_level(const char *level) { else { opt_flag = "-O"; } - size = strlen(opt_flag) + strlen(level) + 1; - flag = (char*)malloc(size); - sprintf(flag, "%s%s", opt_flag, level); + flag = chaz_Util_join("", opt_flag, level, NULL); chaz_CC_add_extra_cflags(flag); free(flag); } +void +chaz_CC_disable_strict_aliasing() { + if (!chaz_CC.intval__MSC_VER) { + chaz_CC_add_extra_cflags("-fno-strict-aliasing"); + } +} + const char* chaz_CC_get_cc(void) { return chaz_CC.cc_command; @@ -1735,6 +1746,19 @@ chaz_CC_msvc_version_num(void) { } const char* +chaz_CC_shared_obj_cflags() { + if (chaz_CC.intval__MSC_VER) { + return ""; + } + else if (chaz_OS_is_darwin()) { + return "-fno-common"; + } + else { + return "-fPIC"; + } +} + +const char* chaz_CC_link_command() { if (chaz_CC.intval__MSC_VER) { return "link"; @@ -1755,7 +1779,7 @@ chaz_CC_link_shared_obj_flag() { return "/DLL"; } else if (chaz_OS_is_darwin()) { - return "-dynamiclib "; + return "-dynamiclib"; } else { return "-shared"; @@ -1772,6 +1796,36 @@ chaz_CC_link_output_flag() { } } +char* +chaz_CC_library_path_flag(const char *directory) { + char *flag = (char*)malloc(20 + sizeof(directory)); + if (chaz_CC.intval__MSC_VER) { + if (strcmp(directory, ".") == 0) { + /* The MS linker searches the current directory by default. */ + strcpy(flag, ""); + } + else { + sprintf(flag, "/LIBPATH:%s", directory); + } + } + else { + sprintf(flag, "-L%s", directory); + } + return flag; +} + +char* +chaz_CC_link_with_shared_obj_flag(const char *shared_obj) { + char *flag = (char*)malloc(20 + sizeof(shared_obj)); + if (chaz_CC.intval__MSC_VER) { + sprintf(flag, "%s.lib", shared_obj); + } + else { + sprintf(flag, "-l%s", shared_obj); + } + return flag; +} + /***************************************************************************/ @@ -2988,10 +3042,7 @@ chaz_Make_detect(const char *make1, ...) { static int chaz_Make_audition(const char *make) { int succeeded = 0; - const char pattern[] = "%s -f _charm_Makefile"; - size_t size = strlen(make) + sizeof(pattern) + 10; - char *command = (char*)malloc(size); - sprintf(command, pattern, make); + char *command = chaz_Util_join(" ", make, "-f", "_charm_Makefile", NULL); chaz_Util_remove_and_verify("_charm_foo"); chaz_OS_run_redirected(command, "_charm_foo"); @@ -3301,8 +3352,7 @@ chaz_MakeRule_add_target(chaz_MakeRule *rule, const char *target) { targets = chaz_Util_strdup(target); } else { - targets = (char*)malloc(strlen(rule->targets) + strlen(target) + 20); - sprintf(targets, "%s %s", rule->targets, target); + targets = chaz_Util_join(" ", rule->targets, target, NULL); free(rule->targets); } @@ -3317,8 +3367,7 @@ chaz_MakeRule_add_prereq(chaz_MakeRule *rule, const char *prereq) { prereqs = chaz_Util_strdup(prereq); } else { - prereqs = (char*)malloc(strlen(rule->prereqs) + strlen(prereq) + 20); - sprintf(prereqs, "%s %s", rule->prereqs, prereq); + prereqs = chaz_Util_join(" ", rule->prereqs, prereq, NULL); free(rule->prereqs); } @@ -3350,21 +3399,16 @@ chaz_MakeRule_add_command_make(chaz_MakeRule *rule, const char *dir, if (chaz_Make.is_gnu_make) { if (!target) { - size_t size = strlen(dir) + 20; - command = (char*)malloc(size); - sprintf(command, "$(MAKE) -C %s", dir); + command = chaz_Util_join(" ", "$(MAKE)", "-C", dir, NULL); } else { - size_t size = strlen(dir) + strlen(target) + 20; - command = (char*)malloc(size); - sprintf(command, "$(MAKE) -C %s %s", dir, target); + command = chaz_Util_join(" ", "$(MAKE)", "-C", dir, target, NULL); } chaz_MakeRule_add_command(rule, command); free(command); } else if (chaz_Make.is_nmake) { - command = (char*)malloc(strlen(dir) + 20); - sprintf(command, "cd %s", dir); + command = chaz_Util_join(" ", "cd", dir, NULL); chaz_MakeRule_add_command(rule, command); free(command); @@ -3372,9 +3416,7 @@ chaz_MakeRule_add_command_make(chaz_MakeRule *rule, const char *dir, chaz_MakeRule_add_command(rule, "$(MAKE)"); } else { - size_t size = strlen(target) + 20; - command = (char*)malloc(size); - sprintf(command, "$(MAKE) %s", target); + command = chaz_Util_join(" ", "$(MAKE)", target, NULL); chaz_MakeRule_add_command(rule, command); free(command); } @@ -3636,11 +3678,9 @@ chaz_OS_remove(const char *name) { int chaz_OS_run_local_redirected(const char *command, const char *path) { - size_t size = strlen(command) + strlen(chaz_OS.local_command_start) + 20; - char *local_command = (char*)malloc(size); - int retval; - sprintf(local_command, "%s%s", chaz_OS.local_command_start, command); - retval = chaz_OS_run_redirected(local_command, path); + char *local_command + = chaz_Util_join("", chaz_OS.local_command_start, command, NULL); + int retval = chaz_OS_run_redirected(local_command, path); free(local_command); return retval; } @@ -3657,13 +3697,7 @@ chaz_OS_run_redirected(const char *command, const char *path) { if (chaz_OS.shell_type == CHAZ_OS_POSIX || chaz_OS.shell_type == CHAZ_OS_CMD_EXE ) { - char pattern[] = "%s > %s 2>&1"; - size_t size = sizeof(pattern) - + strlen(command) - + strlen(path) - + 10; - quiet_command = (char*)malloc(size); - sprintf(quiet_command, pattern, command, path); + quiet_command = chaz_Util_join(" ", command, ">", path, "2>&1", NULL); } else { chaz_Util_die("Don't know the shell type"); @@ -3688,9 +3722,7 @@ chaz_OS_mkdir(const char *filepath) { if (chaz_OS.shell_type == CHAZ_OS_POSIX || chaz_OS.shell_type == CHAZ_OS_CMD_EXE ) { - unsigned size = sizeof("mkdir") + 1 + strlen(filepath) + 1; - command = (char*)malloc(size); - sprintf(command, "mkdir %s", filepath); + command = chaz_Util_join(" ", "mkdir", filepath, NULL); } else { chaz_Util_die("Don't know the shell type"); @@ -3703,14 +3735,10 @@ void chaz_OS_rmdir(const char *filepath) { char *command = NULL; if (chaz_OS.shell_type == CHAZ_OS_POSIX) { - unsigned size = strlen("rmdir") + 1 + strlen(filepath) + 1; - command = (char*)malloc(size); - sprintf(command, "rmdir %s", filepath); + command = chaz_Util_join(" ", "rmdir", filepath, NULL); } else if (chaz_OS.shell_type == CHAZ_OS_CMD_EXE) { - unsigned size = strlen("rmdir /q") + 1 + strlen(filepath) + 1; - command = (char*)malloc(size); - sprintf(command, "rmdir /q %s", filepath); + command = chaz_Util_join(" ", "rmdir", "/q", filepath, NULL); } else { chaz_Util_die("Don't know the shell type"); @@ -3825,6 +3853,50 @@ chaz_Util_strdup(const char *string) { return copy; } +char* +chaz_Util_join(const char *sep, ...) { + va_list args; + const char *string; + char *result, *p; + size_t sep_len = strlen(sep); + size_t size; + int i; + + /* Determine result size. */ + va_start(args, sep); + size = 1; + string = va_arg(args, const char*); + for (i = 0; string; ++i) { + if (i != 0) { size += sep_len; } + size += strlen(string); + string = va_arg(args, const char*); + } + va_end(args); + + result = (char*)malloc(size); + + /* Create result string. */ + va_start(args, sep); + p = result; + string = va_arg(args, const char*); + for (i = 0; string; ++i) { + size_t len; + if (i != 0) { + memcpy(p, sep, sep_len); + p += sep_len; + } + len = strlen(string); + memcpy(p, string, len); + p += len; + string = va_arg(args, const char*); + } + va_end(args); + + *p = '\0'; + + return result; +} + void chaz_Util_die(const char* format, ...) { va_list args; @@ -6086,6 +6158,8 @@ S_write_makefile() { chaz_CC_add_extra_cflags("/nologo"); } chaz_CC_set_optimization_level("2"); + chaz_CC_disable_strict_aliasing(); + chaz_CC_add_extra_cflags(chaz_CC_shared_obj_cflags()); /* TODO: This makes extra_cflags and subsequent probes unusable. Find a * better way to get flags for include dirs. @@ -6190,24 +6264,31 @@ S_write_makefile() { chaz_MakeRule_add_prereq(rule, json_parser_c); chaz_MakeRule_add_prereq(rule, "$(AUTOGEN_DIR)"); - const char *pcre_link_flags = ""; + char *pcre_link_flag; if (chaz_HeadCheck_check_header("pcre.h")) { - pcre_link_flags = "-lpcre"; + pcre_link_flag = chaz_CC_link_with_shared_obj_flag("pcre"); + } + else { + pcre_link_flag = chaz_Util_strdup(""); } - size_t link_flags_size = strlen(math_link_flags) - + strlen(pcre_link_flags) - + 20; - char *link_flags = (char*)malloc(link_flags_size); - sprintf(link_flags, "%s %s", math_link_flags, pcre_link_flags); + char *link_flags + = chaz_Util_join(" ", math_link_flags, pcre_link_flag, NULL); chaz_MakeFile_add_shared_obj(makefile, "$(LUCY_SHOBJ)", "$(LUCY_OBJS)", link_flags); free(link_flags); + free(pcre_link_flag); chaz_MakeFile_add_rule(makefile, "$(TEST_LUCY_OBJS)", "$(AUTOGEN_DIR)"); + char *library_path_flag = chaz_CC_library_path_flag("."); + char *lucy_link_flag = chaz_CC_link_with_shared_obj_flag("lucy"); + link_flags = chaz_Util_join(" ", library_path_flag, lucy_link_flag, NULL); rule = chaz_MakeFile_add_exe(makefile, "$(TEST_LUCY_EXE)", - "$(TEST_LUCY_OBJS)", "-L. -llucy"); + "$(TEST_LUCY_OBJS)", link_flags); chaz_MakeRule_add_prereq(rule, "$(LUCY_SHOBJ)"); + free(link_flags); + free(lucy_link_flag); + free(library_path_flag); rule = chaz_MakeFile_add_rule(makefile, "test", "$(TEST_LUCY_EXE)"); const char *test_command = "$(TEST_LUCY_EXE)";
