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)";

Reply via email to