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/31aeb8b9
Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/31aeb8b9
Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/31aeb8b9

Branch: refs/heads/c-bindings-wip1
Commit: 31aeb8b98f222e8ae51ce2b2d97dfb60181874ae
Parents: 1998505
Author: Nick Wellnhofer <[email protected]>
Authored: Sun Dec 23 02:25:15 2012 +0100
Committer: Nick Wellnhofer <[email protected]>
Committed: Sun Dec 23 03:32:54 2012 +0100

----------------------------------------------------------------------
 clownfish/compiler/common/charmonizer.c |  451 +++++++++++++++++++++++++-
 clownfish/runtime/common/charmonizer.c  |  344 ++++++++++++++++++++-
 common/charmonizer.c                    |  344 ++++++++++++++++++++-
 3 files changed, 1136 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/31aeb8b9/clownfish/compiler/common/charmonizer.c
----------------------------------------------------------------------
diff --git a/clownfish/compiler/common/charmonizer.c 
b/clownfish/compiler/common/charmonizer.c
index 4e7ba0c..d91aa72 100644
--- a/clownfish/compiler/common/charmonizer.c
+++ b/clownfish/compiler/common/charmonizer.c
@@ -295,6 +295,60 @@ chaz_HeadCheck_contains_member(const char *struct_name, 
const char *member,
 
 /***************************************************************************/
 
+#line 21 "src/Charmonizer/Core/Make.h"
+/* Charmonizer/Core/Compiler.h
+ */
+
+#ifndef H_CHAZ_MAKE
+#define H_CHAZ_MAKE
+
+typedef struct chaz_MakeFile chaz_MakeFile;
+typedef struct chaz_MakeVar chaz_MakeVar;
+typedef struct chaz_MakeRule chaz_MakeRule;
+
+chaz_MakeFile*
+chaz_MakeFile_new();
+
+chaz_MakeVar*
+chaz_MakeFile_add_var(chaz_MakeFile *makefile, const char *name,
+                      const char *value);
+
+chaz_MakeRule*
+chaz_MakeFile_add_rule(chaz_MakeFile *makefile, const char *target,
+                       const char *prereq);
+
+void
+chaz_MakeFile_add_to_cleanup(chaz_MakeFile *makefile, const char *target);
+
+void
+chaz_MakeFile_add_exe(chaz_MakeFile *makefile, const char *exe,
+                      const char *objects);
+
+void
+chaz_MakeFile_write(chaz_MakeFile *makefile);
+
+void
+chaz_MakeVar_append(chaz_MakeVar *var, const char *element);
+
+void
+chaz_MakeRule_add_target(chaz_MakeRule *rule, const char *target);
+
+void
+chaz_MakeRule_add_prereq(chaz_MakeRule *rule, const char *prereq);
+
+void
+chaz_MakeRule_add_command(chaz_MakeRule *rule, const char *command);
+
+void
+chaz_MakeRule_add_command_make(chaz_MakeRule *rule, const char *dir,
+                               const char *target);
+
+#endif /* H_CHAZ_MAKE */
+
+
+
+/***************************************************************************/
+
 #line 21 "src/Charmonizer/Core/OperatingSystem.h"
 /* Charmonizer/Core/OperatingSystem.h - abstract an operating system down to a 
few
  * variables.
@@ -1949,6 +2003,294 @@ chaz_HeadCheck_maybe_add_to_cache(const char 
*header_name, int exists) {
 
 /***************************************************************************/
 
+#line 17 "src/Charmonizer/Core/Make.c"
+#include <string.h>
+/* #include "Charmonizer/Core/Make.h" */
+/* #include "Charmonizer/Core/Compiler.h" */
+/* #include "Charmonizer/Core/Util.h" */
+
+struct chaz_MakeVar {
+    char   *name;
+    char   *value;
+    size_t  num_elements;
+};
+
+struct chaz_MakeRule {
+    char *targets;
+    char *prereqs;
+    char *commands;
+};
+
+struct chaz_MakeFile {
+    chaz_MakeVar  **vars;
+    size_t          num_vars;
+    chaz_MakeRule **rules;
+    size_t          num_rules;
+    char          **cleanups;
+    size_t          num_cleanups;
+};
+
+static const char*
+chaz_CC_link_command() {
+    return "$(CC)";
+}
+
+static const char*
+chaz_CC_link_flags() {
+    return "";
+}
+
+static const char*
+chaz_CC_link_output_flag() {
+    return "-o ";
+}
+
+chaz_MakeFile*
+chaz_MakeFile_new() {
+    chaz_MakeFile *makefile = (chaz_MakeFile*)malloc(sizeof(chaz_MakeFile));
+
+    makefile->vars = (chaz_MakeVar**)malloc(sizeof(chaz_MakeVar*));
+    makefile->vars[0] = NULL;
+    makefile->num_vars = 0;
+
+    makefile->rules = (chaz_MakeRule**)malloc(sizeof(chaz_MakeRule*));
+    makefile->rules[0] = NULL;
+    makefile->num_rules = 0;
+
+    makefile->cleanups = (char**)malloc(sizeof(char*));
+    makefile->cleanups[0] = NULL;
+    makefile->num_cleanups = 0;
+
+    return makefile;
+}
+
+chaz_MakeVar*
+chaz_MakeFile_add_var(chaz_MakeFile *makefile, const char *name,
+                      const char *value) {
+    chaz_MakeVar  *var      = (chaz_MakeVar*)malloc(sizeof(chaz_MakeVar));
+    chaz_MakeVar **vars     = makefile->vars;
+    size_t         num_vars = makefile->num_vars + 1;
+
+    var->name         = chaz_Util_strdup(name);
+    var->value        = NULL;
+    var->num_elements = 0;
+
+    if (value) { chaz_MakeVar_append(var, value); }
+
+    vars = (chaz_MakeVar**)realloc(vars,
+                                   (num_vars + 1) * sizeof(chaz_MakeVar*));
+    vars[num_vars-1] = var;
+    vars[num_vars]   = NULL;
+    makefile->vars = vars;
+    makefile->num_vars = num_vars;
+
+    return var;
+}
+
+chaz_MakeRule*
+chaz_MakeFile_add_rule(chaz_MakeFile *makefile, const char *target,
+                       const char *prereq) {
+    chaz_MakeRule  *rule      = (chaz_MakeRule*)malloc(sizeof(chaz_MakeRule));
+    chaz_MakeRule **rules     = makefile->rules;
+    size_t          num_rules = makefile->num_rules + 1;
+
+    rule->targets  = NULL;
+    rule->prereqs  = NULL;
+    rule->commands = NULL;
+
+    if (target) { chaz_MakeRule_add_target(rule, target); }
+    if (prereq) { chaz_MakeRule_add_prereq(rule, prereq); }
+
+    rules = (chaz_MakeRule**)realloc(rules,
+                                     (num_rules + 1) * sizeof(chaz_MakeRule*));
+    rules[num_rules-1] = rule;
+    rules[num_rules]   = NULL;
+    makefile->rules = rules;
+    makefile->num_rules = num_rules;
+
+    return rule;
+}
+
+void
+chaz_MakeFile_add_to_cleanup(chaz_MakeFile *makefile, const char *target) {
+    char    *cleanup      = chaz_Util_strdup(target);
+    char   **cleanups     = makefile->cleanups;
+    size_t   num_cleanups = makefile->num_cleanups + 1;
+
+    cleanups = (char**)realloc(cleanups, (num_cleanups + 1) * sizeof(char*));
+    cleanups[num_cleanups-1] = cleanup;
+    cleanups[num_cleanups]   = NULL;
+    makefile->cleanups = cleanups;
+    makefile->num_cleanups = num_cleanups;
+}
+
+void
+chaz_MakeFile_add_exe(chaz_MakeFile *makefile, const char *exe,
+                      const char *objects) {
+    const char    *pattern     = "%s %s %s %s%s";
+    const char    *link        = chaz_CC_link_command();
+    const char    *link_flags  = chaz_CC_link_flags();
+    const char    *output_flag = chaz_CC_link_output_flag();
+    chaz_MakeRule *rule;
+    char          *command;
+    size_t         size;
+
+    rule = chaz_MakeFile_add_rule(makefile, exe, objects);
+
+    size = strlen(pattern)
+           + strlen(link)
+           + strlen(link_flags)
+           + strlen(objects)
+           + strlen(output_flag)
+           + strlen(exe)
+           + 50;
+    command = (char*)malloc(size);
+    sprintf(command, pattern, link, link_flags, objects, output_flag, exe);
+    chaz_MakeRule_add_command(rule, command);
+
+    chaz_MakeFile_add_to_cleanup(makefile, exe);
+}
+
+void
+chaz_MakeFile_write(chaz_MakeFile *makefile) {
+    FILE   *file;
+    size_t  i;
+
+    file = fopen("Makefile", "w");
+    if (!file) {
+        chaz_Util_die("Can't open Makefile\n");
+    }
+
+    for (i = 0; makefile->vars[i]; i++) {
+        chaz_MakeVar *var = makefile->vars[i];
+        fprintf(file, "%s = %s\n", var->name, var->value);
+    }
+    fprintf(file, "\n");
+
+    for (i = 0; makefile->rules[i]; i++) {
+        chaz_MakeRule *rule = makefile->rules[i];
+        fprintf(file, "%s :", rule->targets);
+        if (rule->prereqs) {
+            fprintf(file, " %s", rule->prereqs);
+        }
+        fprintf(file, "\n");
+        if (rule->commands) {
+            fprintf(file, "%s", rule->commands);
+        }
+        fprintf(file, "\n");
+    }
+
+    if (makefile->cleanups[0]) {
+        fprintf(file, "clean :\n\trm -f");
+        for (i = 0; makefile->cleanups[i]; i++) {
+            char *cleanup = makefile->cleanups[i];
+            fprintf(file, " \\\n\t    %s", cleanup);
+        }
+        fprintf(file, "\n\n");
+    }
+
+    fprintf(file, "distclean : clean\n");
+    fprintf(file, "\trm -f charmonizer charmony.h Makefile\n\n");
+
+    fclose(file);
+}
+
+void
+chaz_MakeVar_append(chaz_MakeVar *var, const char *element) {
+    char *value;
+
+    if (var->num_elements == 0) {
+        value = chaz_Util_strdup(element);
+    }
+    else {
+        value = (char*)malloc(strlen(var->value) + strlen(element) + 20);
+
+        if (var->num_elements == 1) {
+            sprintf(value, "\\\n    %s \\\n    %s", var->value, element);
+        }
+        else {
+            sprintf(value, "%s \\\n    %s", var->value, element);
+        }
+
+        free(var->value);
+    }
+
+    var->value = value;
+    var->num_elements++;
+}
+
+void
+chaz_MakeRule_add_target(chaz_MakeRule *rule, const char *target) {
+    char *targets;
+
+    if (!rule->targets) {
+        targets = chaz_Util_strdup(target);
+    }
+    else {
+        targets = (char*)malloc(strlen(rule->targets) + strlen(target) + 20);
+        sprintf(targets, "%s %s", rule->targets, target);
+        free(rule->targets);
+    }
+
+    rule->targets = targets;
+}
+
+void
+chaz_MakeRule_add_prereq(chaz_MakeRule *rule, const char *prereq) {
+    char *prereqs;
+
+    if (!rule->prereqs) {
+        prereqs = chaz_Util_strdup(prereq);
+    }
+    else {
+        prereqs = (char*)malloc(strlen(rule->prereqs) + strlen(prereq) + 20);
+        sprintf(prereqs, "%s %s", rule->prereqs, prereq);
+        free(rule->prereqs);
+    }
+
+    rule->prereqs = prereqs;
+}
+
+void
+chaz_MakeRule_add_command(chaz_MakeRule *rule, const char *command) {
+    char *commands;
+
+    if (!rule->commands) {
+        commands = (char*)malloc(strlen(command) + 20);
+        sprintf(commands, "\t%s\n", command);
+    }
+    else {
+        commands = (char*)malloc(strlen(rule->commands) + strlen(command) + 
20);
+        sprintf(commands, "%s\t%s\n", rule->commands, command);
+        free(rule->commands);
+    }
+
+    rule->commands = commands;
+}
+
+void
+chaz_MakeRule_add_command_make(chaz_MakeRule *rule, const char *dir,
+                               const char *target) {
+    char *command;
+
+    if (!target) {
+        command = (char*)malloc(strlen(dir) + 20);
+        sprintf(command, "make -C %s", dir);
+    }
+    else {
+        command = (char*)malloc(strlen(dir) + strlen(target) + 20);
+        sprintf(command, "make -C %s %s", dir, target);
+    }
+
+    chaz_MakeRule_add_command(rule, command);
+
+    free(command);
+}
+
+
+
+/***************************************************************************/
+
 #line 17 "src/Charmonizer/Core/OperatingSystem.c"
 #include <stdlib.h>
 #include <string.h>
@@ -1983,7 +2325,7 @@ chaz_OS_init(void) {
     if (chaz_Util_can_open_file("/dev/null")) {
         strcpy(chaz_OS.dev_null, "/dev/null");
         strcpy(chaz_OS.exe_ext, "");
-        strcpy(chaz_OS.obj_ext, "");
+        strcpy(chaz_OS.obj_ext, ".o");
         strcpy(chaz_OS.local_command_start, "./");
         chaz_OS.shell_type = CHAZ_OS_POSIX;
     }
@@ -2768,6 +3110,8 @@ chaz_Integers_machine_is_big_endian(void) {
 #define MAX_CC_LEN 128
 #define MAX_FLAGS_LEN 2048
 
+#define DIR_SEP "/"
+
 struct CLIArgs {
     char cc_command[MAX_CC_LEN + 1];
     char cc_flags[MAX_FLAGS_LEN + 1];
@@ -2817,7 +3161,105 @@ S_parse_arguments(int argc, char **argv, struct CLIArgs 
*args) {
 
 }
 
+static void
+S_write_makefile() {
+    const char *base_dir  = "..";
+    const char *lemon_dir = ".." DIR_SEP ".." DIR_SEP ".." DIR_SEP "lemon";
+    const char *exe_ext   = chaz_OS_exe_ext();
+    const char *obj_ext   = chaz_OS_obj_ext();
+
+    const char *parse_header_y = "$(SRC_DIR)" DIR_SEP "CFCParseHeader.y";
+    const char *parse_header_h = "$(SRC_DIR)" DIR_SEP "CFCParseHeader.h";
+    const char *parse_header_c = "$(SRC_DIR)" DIR_SEP "CFCParseHeader.c";
+
+    char *src_dir;
+    char *scratch;
+
+    chaz_MakeFile *makefile;
+    chaz_MakeVar  *var;
+    chaz_MakeRule *rule;
+
+    makefile = chaz_MakeFile_new();
+
+    src_dir = (char*)malloc(strlen(base_dir) + 20);
+    sprintf(src_dir, "%s" DIR_SEP "src", base_dir);
+    chaz_MakeFile_add_var(makefile, "SRC_DIR", src_dir);
+    scratch = (char*)malloc(strlen(base_dir) + 20);
+    sprintf(scratch, "%s" DIR_SEP "include", base_dir);
+    chaz_MakeFile_add_var(makefile, "INCLUDE_DIR", scratch);
+    free(scratch);
+    chaz_MakeFile_add_var(makefile, "LEMON_DIR", lemon_dir);
+
+    chaz_MakeFile_add_var(makefile, "EXE_EXT", exe_ext);
+    chaz_MakeFile_add_var(makefile, "OBJ_EXT", obj_ext);
+
+    chaz_MakeFile_add_var(makefile, "LEMON_EXE",
+                          "$(LEMON_DIR)" DIR_SEP "lemon$(EXE_EXT)");
+    chaz_MakeFile_add_var(makefile, "CFC_EXE", "cfc$(EXE_EXT)");
+
+    var = chaz_MakeFile_add_var(makefile, "CFLAGS", NULL);
+    chaz_MakeVar_append(var, "-I.");
+    chaz_MakeVar_append(var, "-I$(INCLUDE_DIR)");
+    chaz_MakeVar_append(var, "-I$(SRC_DIR)");
+
+    var = chaz_MakeFile_add_var(makefile, "CFC_OBJS", NULL);
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCBase$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCBindAliases$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCBindClass$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCBindCore$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCBindFile$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCBindFunction$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCBindMethod$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCCBlock$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCClass$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCDocuComment$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCDumpable$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCFile$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCFileSpec$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCFunction$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCHierarchy$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCLexHeader$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCMemPool$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCMethod$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCParamList$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCParcel$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCParseHeader$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCParser$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCSymbol$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCType$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCUtil$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCVariable$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "$(SRC_DIR)" DIR_SEP "CFCVersion$(OBJ_EXT)");
+    chaz_MakeVar_append(var, "cfc$(OBJ_EXT)");
+
+    chaz_MakeFile_add_rule(makefile, "all", "$(CFC_EXE)");
+
+    rule = chaz_MakeFile_add_rule(makefile, "$(LEMON_EXE)", NULL);
+    chaz_MakeRule_add_command_make(rule, "$(LEMON_DIR)", NULL);
+
+    rule = chaz_MakeFile_add_rule(makefile, parse_header_c, NULL);
+    chaz_MakeRule_add_prereq(rule, "$(LEMON_EXE)");
+    chaz_MakeRule_add_prereq(rule, parse_header_y);
+    scratch = (char*)malloc(strlen(parse_header_y) + 20);
+    sprintf(scratch, "$(LEMON_EXE) -q %s", parse_header_y);
+    chaz_MakeRule_add_command(rule, scratch);
+    free(scratch);
+
+    chaz_MakeFile_add_rule(makefile, "$(CFC_OBJS)", parse_header_c);
+
+    chaz_MakeFile_add_exe(makefile, "$(CFC_EXE)", "$(CFC_OBJS)");
+
+    chaz_MakeFile_add_to_cleanup(makefile, "$(CFC_OBJS)");
+    chaz_MakeFile_add_to_cleanup(makefile, parse_header_h);
+    chaz_MakeFile_add_to_cleanup(makefile, parse_header_c);
+
+    chaz_MakeFile_write(makefile);
+
+    free(src_dir);
+}
+
 int main(int argc, char **argv) {
+    size_t i;
     struct CLIArgs args;
     memset(&args, 0, sizeof(struct CLIArgs));
 
@@ -2831,6 +3273,13 @@ int main(int argc, char **argv) {
     /* Clean up. */
     chaz_Probe_clean_up();
 
+    for (i = 0; i < argc; i++) {
+        if (strncmp(argv[i], "--enable-makefile", 17) == 0) {
+            S_write_makefile();
+            break;
+        }
+    }
+
     return 0;
 }
 

http://git-wip-us.apache.org/repos/asf/lucy/blob/31aeb8b9/clownfish/runtime/common/charmonizer.c
----------------------------------------------------------------------
diff --git a/clownfish/runtime/common/charmonizer.c 
b/clownfish/runtime/common/charmonizer.c
index c17e4cc..2489880 100644
--- a/clownfish/runtime/common/charmonizer.c
+++ b/clownfish/runtime/common/charmonizer.c
@@ -295,6 +295,60 @@ chaz_HeadCheck_contains_member(const char *struct_name, 
const char *member,
 
 /***************************************************************************/
 
+#line 21 "src/Charmonizer/Core/Make.h"
+/* Charmonizer/Core/Compiler.h
+ */
+
+#ifndef H_CHAZ_MAKE
+#define H_CHAZ_MAKE
+
+typedef struct chaz_MakeFile chaz_MakeFile;
+typedef struct chaz_MakeVar chaz_MakeVar;
+typedef struct chaz_MakeRule chaz_MakeRule;
+
+chaz_MakeFile*
+chaz_MakeFile_new();
+
+chaz_MakeVar*
+chaz_MakeFile_add_var(chaz_MakeFile *makefile, const char *name,
+                      const char *value);
+
+chaz_MakeRule*
+chaz_MakeFile_add_rule(chaz_MakeFile *makefile, const char *target,
+                       const char *prereq);
+
+void
+chaz_MakeFile_add_to_cleanup(chaz_MakeFile *makefile, const char *target);
+
+void
+chaz_MakeFile_add_exe(chaz_MakeFile *makefile, const char *exe,
+                      const char *objects);
+
+void
+chaz_MakeFile_write(chaz_MakeFile *makefile);
+
+void
+chaz_MakeVar_append(chaz_MakeVar *var, const char *element);
+
+void
+chaz_MakeRule_add_target(chaz_MakeRule *rule, const char *target);
+
+void
+chaz_MakeRule_add_prereq(chaz_MakeRule *rule, const char *prereq);
+
+void
+chaz_MakeRule_add_command(chaz_MakeRule *rule, const char *command);
+
+void
+chaz_MakeRule_add_command_make(chaz_MakeRule *rule, const char *dir,
+                               const char *target);
+
+#endif /* H_CHAZ_MAKE */
+
+
+
+/***************************************************************************/
+
 #line 21 "src/Charmonizer/Core/OperatingSystem.h"
 /* Charmonizer/Core/OperatingSystem.h - abstract an operating system down to a 
few
  * variables.
@@ -2358,6 +2412,294 @@ chaz_HeadCheck_maybe_add_to_cache(const char 
*header_name, int exists) {
 
 /***************************************************************************/
 
+#line 17 "src/Charmonizer/Core/Make.c"
+#include <string.h>
+/* #include "Charmonizer/Core/Make.h" */
+/* #include "Charmonizer/Core/Compiler.h" */
+/* #include "Charmonizer/Core/Util.h" */
+
+struct chaz_MakeVar {
+    char   *name;
+    char   *value;
+    size_t  num_elements;
+};
+
+struct chaz_MakeRule {
+    char *targets;
+    char *prereqs;
+    char *commands;
+};
+
+struct chaz_MakeFile {
+    chaz_MakeVar  **vars;
+    size_t          num_vars;
+    chaz_MakeRule **rules;
+    size_t          num_rules;
+    char          **cleanups;
+    size_t          num_cleanups;
+};
+
+static const char*
+chaz_CC_link_command() {
+    return "$(CC)";
+}
+
+static const char*
+chaz_CC_link_flags() {
+    return "";
+}
+
+static const char*
+chaz_CC_link_output_flag() {
+    return "-o ";
+}
+
+chaz_MakeFile*
+chaz_MakeFile_new() {
+    chaz_MakeFile *makefile = (chaz_MakeFile*)malloc(sizeof(chaz_MakeFile));
+
+    makefile->vars = (chaz_MakeVar**)malloc(sizeof(chaz_MakeVar*));
+    makefile->vars[0] = NULL;
+    makefile->num_vars = 0;
+
+    makefile->rules = (chaz_MakeRule**)malloc(sizeof(chaz_MakeRule*));
+    makefile->rules[0] = NULL;
+    makefile->num_rules = 0;
+
+    makefile->cleanups = (char**)malloc(sizeof(char*));
+    makefile->cleanups[0] = NULL;
+    makefile->num_cleanups = 0;
+
+    return makefile;
+}
+
+chaz_MakeVar*
+chaz_MakeFile_add_var(chaz_MakeFile *makefile, const char *name,
+                      const char *value) {
+    chaz_MakeVar  *var      = (chaz_MakeVar*)malloc(sizeof(chaz_MakeVar));
+    chaz_MakeVar **vars     = makefile->vars;
+    size_t         num_vars = makefile->num_vars + 1;
+
+    var->name         = chaz_Util_strdup(name);
+    var->value        = NULL;
+    var->num_elements = 0;
+
+    if (value) { chaz_MakeVar_append(var, value); }
+
+    vars = (chaz_MakeVar**)realloc(vars,
+                                   (num_vars + 1) * sizeof(chaz_MakeVar*));
+    vars[num_vars-1] = var;
+    vars[num_vars]   = NULL;
+    makefile->vars = vars;
+    makefile->num_vars = num_vars;
+
+    return var;
+}
+
+chaz_MakeRule*
+chaz_MakeFile_add_rule(chaz_MakeFile *makefile, const char *target,
+                       const char *prereq) {
+    chaz_MakeRule  *rule      = (chaz_MakeRule*)malloc(sizeof(chaz_MakeRule));
+    chaz_MakeRule **rules     = makefile->rules;
+    size_t          num_rules = makefile->num_rules + 1;
+
+    rule->targets  = NULL;
+    rule->prereqs  = NULL;
+    rule->commands = NULL;
+
+    if (target) { chaz_MakeRule_add_target(rule, target); }
+    if (prereq) { chaz_MakeRule_add_prereq(rule, prereq); }
+
+    rules = (chaz_MakeRule**)realloc(rules,
+                                     (num_rules + 1) * sizeof(chaz_MakeRule*));
+    rules[num_rules-1] = rule;
+    rules[num_rules]   = NULL;
+    makefile->rules = rules;
+    makefile->num_rules = num_rules;
+
+    return rule;
+}
+
+void
+chaz_MakeFile_add_to_cleanup(chaz_MakeFile *makefile, const char *target) {
+    char    *cleanup      = chaz_Util_strdup(target);
+    char   **cleanups     = makefile->cleanups;
+    size_t   num_cleanups = makefile->num_cleanups + 1;
+
+    cleanups = (char**)realloc(cleanups, (num_cleanups + 1) * sizeof(char*));
+    cleanups[num_cleanups-1] = cleanup;
+    cleanups[num_cleanups]   = NULL;
+    makefile->cleanups = cleanups;
+    makefile->num_cleanups = num_cleanups;
+}
+
+void
+chaz_MakeFile_add_exe(chaz_MakeFile *makefile, const char *exe,
+                      const char *objects) {
+    const char    *pattern     = "%s %s %s %s%s";
+    const char    *link        = chaz_CC_link_command();
+    const char    *link_flags  = chaz_CC_link_flags();
+    const char    *output_flag = chaz_CC_link_output_flag();
+    chaz_MakeRule *rule;
+    char          *command;
+    size_t         size;
+
+    rule = chaz_MakeFile_add_rule(makefile, exe, objects);
+
+    size = strlen(pattern)
+           + strlen(link)
+           + strlen(link_flags)
+           + strlen(objects)
+           + strlen(output_flag)
+           + strlen(exe)
+           + 50;
+    command = (char*)malloc(size);
+    sprintf(command, pattern, link, link_flags, objects, output_flag, exe);
+    chaz_MakeRule_add_command(rule, command);
+
+    chaz_MakeFile_add_to_cleanup(makefile, exe);
+}
+
+void
+chaz_MakeFile_write(chaz_MakeFile *makefile) {
+    FILE   *file;
+    size_t  i;
+
+    file = fopen("Makefile", "w");
+    if (!file) {
+        chaz_Util_die("Can't open Makefile\n");
+    }
+
+    for (i = 0; makefile->vars[i]; i++) {
+        chaz_MakeVar *var = makefile->vars[i];
+        fprintf(file, "%s = %s\n", var->name, var->value);
+    }
+    fprintf(file, "\n");
+
+    for (i = 0; makefile->rules[i]; i++) {
+        chaz_MakeRule *rule = makefile->rules[i];
+        fprintf(file, "%s :", rule->targets);
+        if (rule->prereqs) {
+            fprintf(file, " %s", rule->prereqs);
+        }
+        fprintf(file, "\n");
+        if (rule->commands) {
+            fprintf(file, "%s", rule->commands);
+        }
+        fprintf(file, "\n");
+    }
+
+    if (makefile->cleanups[0]) {
+        fprintf(file, "clean :\n\trm -f");
+        for (i = 0; makefile->cleanups[i]; i++) {
+            char *cleanup = makefile->cleanups[i];
+            fprintf(file, " \\\n\t    %s", cleanup);
+        }
+        fprintf(file, "\n\n");
+    }
+
+    fprintf(file, "distclean : clean\n");
+    fprintf(file, "\trm -f charmonizer charmony.h Makefile\n\n");
+
+    fclose(file);
+}
+
+void
+chaz_MakeVar_append(chaz_MakeVar *var, const char *element) {
+    char *value;
+
+    if (var->num_elements == 0) {
+        value = chaz_Util_strdup(element);
+    }
+    else {
+        value = (char*)malloc(strlen(var->value) + strlen(element) + 20);
+
+        if (var->num_elements == 1) {
+            sprintf(value, "\\\n    %s \\\n    %s", var->value, element);
+        }
+        else {
+            sprintf(value, "%s \\\n    %s", var->value, element);
+        }
+
+        free(var->value);
+    }
+
+    var->value = value;
+    var->num_elements++;
+}
+
+void
+chaz_MakeRule_add_target(chaz_MakeRule *rule, const char *target) {
+    char *targets;
+
+    if (!rule->targets) {
+        targets = chaz_Util_strdup(target);
+    }
+    else {
+        targets = (char*)malloc(strlen(rule->targets) + strlen(target) + 20);
+        sprintf(targets, "%s %s", rule->targets, target);
+        free(rule->targets);
+    }
+
+    rule->targets = targets;
+}
+
+void
+chaz_MakeRule_add_prereq(chaz_MakeRule *rule, const char *prereq) {
+    char *prereqs;
+
+    if (!rule->prereqs) {
+        prereqs = chaz_Util_strdup(prereq);
+    }
+    else {
+        prereqs = (char*)malloc(strlen(rule->prereqs) + strlen(prereq) + 20);
+        sprintf(prereqs, "%s %s", rule->prereqs, prereq);
+        free(rule->prereqs);
+    }
+
+    rule->prereqs = prereqs;
+}
+
+void
+chaz_MakeRule_add_command(chaz_MakeRule *rule, const char *command) {
+    char *commands;
+
+    if (!rule->commands) {
+        commands = (char*)malloc(strlen(command) + 20);
+        sprintf(commands, "\t%s\n", command);
+    }
+    else {
+        commands = (char*)malloc(strlen(rule->commands) + strlen(command) + 
20);
+        sprintf(commands, "%s\t%s\n", rule->commands, command);
+        free(rule->commands);
+    }
+
+    rule->commands = commands;
+}
+
+void
+chaz_MakeRule_add_command_make(chaz_MakeRule *rule, const char *dir,
+                               const char *target) {
+    char *command;
+
+    if (!target) {
+        command = (char*)malloc(strlen(dir) + 20);
+        sprintf(command, "make -C %s", dir);
+    }
+    else {
+        command = (char*)malloc(strlen(dir) + strlen(target) + 20);
+        sprintf(command, "make -C %s %s", dir, target);
+    }
+
+    chaz_MakeRule_add_command(rule, command);
+
+    free(command);
+}
+
+
+
+/***************************************************************************/
+
 #line 17 "src/Charmonizer/Core/OperatingSystem.c"
 #include <stdlib.h>
 #include <string.h>
@@ -2392,7 +2734,7 @@ chaz_OS_init(void) {
     if (chaz_Util_can_open_file("/dev/null")) {
         strcpy(chaz_OS.dev_null, "/dev/null");
         strcpy(chaz_OS.exe_ext, "");
-        strcpy(chaz_OS.obj_ext, "");
+        strcpy(chaz_OS.obj_ext, ".o");
         strcpy(chaz_OS.local_command_start, "./");
         chaz_OS.shell_type = CHAZ_OS_POSIX;
     }

http://git-wip-us.apache.org/repos/asf/lucy/blob/31aeb8b9/common/charmonizer.c
----------------------------------------------------------------------
diff --git a/common/charmonizer.c b/common/charmonizer.c
index e2ee36f..02d398b 100644
--- a/common/charmonizer.c
+++ b/common/charmonizer.c
@@ -295,6 +295,60 @@ chaz_HeadCheck_contains_member(const char *struct_name, 
const char *member,
 
 /***************************************************************************/
 
+#line 21 "src/Charmonizer/Core/Make.h"
+/* Charmonizer/Core/Compiler.h
+ */
+
+#ifndef H_CHAZ_MAKE
+#define H_CHAZ_MAKE
+
+typedef struct chaz_MakeFile chaz_MakeFile;
+typedef struct chaz_MakeVar chaz_MakeVar;
+typedef struct chaz_MakeRule chaz_MakeRule;
+
+chaz_MakeFile*
+chaz_MakeFile_new();
+
+chaz_MakeVar*
+chaz_MakeFile_add_var(chaz_MakeFile *makefile, const char *name,
+                      const char *value);
+
+chaz_MakeRule*
+chaz_MakeFile_add_rule(chaz_MakeFile *makefile, const char *target,
+                       const char *prereq);
+
+void
+chaz_MakeFile_add_to_cleanup(chaz_MakeFile *makefile, const char *target);
+
+void
+chaz_MakeFile_add_exe(chaz_MakeFile *makefile, const char *exe,
+                      const char *objects);
+
+void
+chaz_MakeFile_write(chaz_MakeFile *makefile);
+
+void
+chaz_MakeVar_append(chaz_MakeVar *var, const char *element);
+
+void
+chaz_MakeRule_add_target(chaz_MakeRule *rule, const char *target);
+
+void
+chaz_MakeRule_add_prereq(chaz_MakeRule *rule, const char *prereq);
+
+void
+chaz_MakeRule_add_command(chaz_MakeRule *rule, const char *command);
+
+void
+chaz_MakeRule_add_command_make(chaz_MakeRule *rule, const char *dir,
+                               const char *target);
+
+#endif /* H_CHAZ_MAKE */
+
+
+
+/***************************************************************************/
+
 #line 21 "src/Charmonizer/Core/OperatingSystem.h"
 /* Charmonizer/Core/OperatingSystem.h - abstract an operating system down to a 
few
  * variables.
@@ -2358,6 +2412,294 @@ chaz_HeadCheck_maybe_add_to_cache(const char 
*header_name, int exists) {
 
 /***************************************************************************/
 
+#line 17 "src/Charmonizer/Core/Make.c"
+#include <string.h>
+/* #include "Charmonizer/Core/Make.h" */
+/* #include "Charmonizer/Core/Compiler.h" */
+/* #include "Charmonizer/Core/Util.h" */
+
+struct chaz_MakeVar {
+    char   *name;
+    char   *value;
+    size_t  num_elements;
+};
+
+struct chaz_MakeRule {
+    char *targets;
+    char *prereqs;
+    char *commands;
+};
+
+struct chaz_MakeFile {
+    chaz_MakeVar  **vars;
+    size_t          num_vars;
+    chaz_MakeRule **rules;
+    size_t          num_rules;
+    char          **cleanups;
+    size_t          num_cleanups;
+};
+
+static const char*
+chaz_CC_link_command() {
+    return "$(CC)";
+}
+
+static const char*
+chaz_CC_link_flags() {
+    return "";
+}
+
+static const char*
+chaz_CC_link_output_flag() {
+    return "-o ";
+}
+
+chaz_MakeFile*
+chaz_MakeFile_new() {
+    chaz_MakeFile *makefile = (chaz_MakeFile*)malloc(sizeof(chaz_MakeFile));
+
+    makefile->vars = (chaz_MakeVar**)malloc(sizeof(chaz_MakeVar*));
+    makefile->vars[0] = NULL;
+    makefile->num_vars = 0;
+
+    makefile->rules = (chaz_MakeRule**)malloc(sizeof(chaz_MakeRule*));
+    makefile->rules[0] = NULL;
+    makefile->num_rules = 0;
+
+    makefile->cleanups = (char**)malloc(sizeof(char*));
+    makefile->cleanups[0] = NULL;
+    makefile->num_cleanups = 0;
+
+    return makefile;
+}
+
+chaz_MakeVar*
+chaz_MakeFile_add_var(chaz_MakeFile *makefile, const char *name,
+                      const char *value) {
+    chaz_MakeVar  *var      = (chaz_MakeVar*)malloc(sizeof(chaz_MakeVar));
+    chaz_MakeVar **vars     = makefile->vars;
+    size_t         num_vars = makefile->num_vars + 1;
+
+    var->name         = chaz_Util_strdup(name);
+    var->value        = NULL;
+    var->num_elements = 0;
+
+    if (value) { chaz_MakeVar_append(var, value); }
+
+    vars = (chaz_MakeVar**)realloc(vars,
+                                   (num_vars + 1) * sizeof(chaz_MakeVar*));
+    vars[num_vars-1] = var;
+    vars[num_vars]   = NULL;
+    makefile->vars = vars;
+    makefile->num_vars = num_vars;
+
+    return var;
+}
+
+chaz_MakeRule*
+chaz_MakeFile_add_rule(chaz_MakeFile *makefile, const char *target,
+                       const char *prereq) {
+    chaz_MakeRule  *rule      = (chaz_MakeRule*)malloc(sizeof(chaz_MakeRule));
+    chaz_MakeRule **rules     = makefile->rules;
+    size_t          num_rules = makefile->num_rules + 1;
+
+    rule->targets  = NULL;
+    rule->prereqs  = NULL;
+    rule->commands = NULL;
+
+    if (target) { chaz_MakeRule_add_target(rule, target); }
+    if (prereq) { chaz_MakeRule_add_prereq(rule, prereq); }
+
+    rules = (chaz_MakeRule**)realloc(rules,
+                                     (num_rules + 1) * sizeof(chaz_MakeRule*));
+    rules[num_rules-1] = rule;
+    rules[num_rules]   = NULL;
+    makefile->rules = rules;
+    makefile->num_rules = num_rules;
+
+    return rule;
+}
+
+void
+chaz_MakeFile_add_to_cleanup(chaz_MakeFile *makefile, const char *target) {
+    char    *cleanup      = chaz_Util_strdup(target);
+    char   **cleanups     = makefile->cleanups;
+    size_t   num_cleanups = makefile->num_cleanups + 1;
+
+    cleanups = (char**)realloc(cleanups, (num_cleanups + 1) * sizeof(char*));
+    cleanups[num_cleanups-1] = cleanup;
+    cleanups[num_cleanups]   = NULL;
+    makefile->cleanups = cleanups;
+    makefile->num_cleanups = num_cleanups;
+}
+
+void
+chaz_MakeFile_add_exe(chaz_MakeFile *makefile, const char *exe,
+                      const char *objects) {
+    const char    *pattern     = "%s %s %s %s%s";
+    const char    *link        = chaz_CC_link_command();
+    const char    *link_flags  = chaz_CC_link_flags();
+    const char    *output_flag = chaz_CC_link_output_flag();
+    chaz_MakeRule *rule;
+    char          *command;
+    size_t         size;
+
+    rule = chaz_MakeFile_add_rule(makefile, exe, objects);
+
+    size = strlen(pattern)
+           + strlen(link)
+           + strlen(link_flags)
+           + strlen(objects)
+           + strlen(output_flag)
+           + strlen(exe)
+           + 50;
+    command = (char*)malloc(size);
+    sprintf(command, pattern, link, link_flags, objects, output_flag, exe);
+    chaz_MakeRule_add_command(rule, command);
+
+    chaz_MakeFile_add_to_cleanup(makefile, exe);
+}
+
+void
+chaz_MakeFile_write(chaz_MakeFile *makefile) {
+    FILE   *file;
+    size_t  i;
+
+    file = fopen("Makefile", "w");
+    if (!file) {
+        chaz_Util_die("Can't open Makefile\n");
+    }
+
+    for (i = 0; makefile->vars[i]; i++) {
+        chaz_MakeVar *var = makefile->vars[i];
+        fprintf(file, "%s = %s\n", var->name, var->value);
+    }
+    fprintf(file, "\n");
+
+    for (i = 0; makefile->rules[i]; i++) {
+        chaz_MakeRule *rule = makefile->rules[i];
+        fprintf(file, "%s :", rule->targets);
+        if (rule->prereqs) {
+            fprintf(file, " %s", rule->prereqs);
+        }
+        fprintf(file, "\n");
+        if (rule->commands) {
+            fprintf(file, "%s", rule->commands);
+        }
+        fprintf(file, "\n");
+    }
+
+    if (makefile->cleanups[0]) {
+        fprintf(file, "clean :\n\trm -f");
+        for (i = 0; makefile->cleanups[i]; i++) {
+            char *cleanup = makefile->cleanups[i];
+            fprintf(file, " \\\n\t    %s", cleanup);
+        }
+        fprintf(file, "\n\n");
+    }
+
+    fprintf(file, "distclean : clean\n");
+    fprintf(file, "\trm -f charmonizer charmony.h Makefile\n\n");
+
+    fclose(file);
+}
+
+void
+chaz_MakeVar_append(chaz_MakeVar *var, const char *element) {
+    char *value;
+
+    if (var->num_elements == 0) {
+        value = chaz_Util_strdup(element);
+    }
+    else {
+        value = (char*)malloc(strlen(var->value) + strlen(element) + 20);
+
+        if (var->num_elements == 1) {
+            sprintf(value, "\\\n    %s \\\n    %s", var->value, element);
+        }
+        else {
+            sprintf(value, "%s \\\n    %s", var->value, element);
+        }
+
+        free(var->value);
+    }
+
+    var->value = value;
+    var->num_elements++;
+}
+
+void
+chaz_MakeRule_add_target(chaz_MakeRule *rule, const char *target) {
+    char *targets;
+
+    if (!rule->targets) {
+        targets = chaz_Util_strdup(target);
+    }
+    else {
+        targets = (char*)malloc(strlen(rule->targets) + strlen(target) + 20);
+        sprintf(targets, "%s %s", rule->targets, target);
+        free(rule->targets);
+    }
+
+    rule->targets = targets;
+}
+
+void
+chaz_MakeRule_add_prereq(chaz_MakeRule *rule, const char *prereq) {
+    char *prereqs;
+
+    if (!rule->prereqs) {
+        prereqs = chaz_Util_strdup(prereq);
+    }
+    else {
+        prereqs = (char*)malloc(strlen(rule->prereqs) + strlen(prereq) + 20);
+        sprintf(prereqs, "%s %s", rule->prereqs, prereq);
+        free(rule->prereqs);
+    }
+
+    rule->prereqs = prereqs;
+}
+
+void
+chaz_MakeRule_add_command(chaz_MakeRule *rule, const char *command) {
+    char *commands;
+
+    if (!rule->commands) {
+        commands = (char*)malloc(strlen(command) + 20);
+        sprintf(commands, "\t%s\n", command);
+    }
+    else {
+        commands = (char*)malloc(strlen(rule->commands) + strlen(command) + 
20);
+        sprintf(commands, "%s\t%s\n", rule->commands, command);
+        free(rule->commands);
+    }
+
+    rule->commands = commands;
+}
+
+void
+chaz_MakeRule_add_command_make(chaz_MakeRule *rule, const char *dir,
+                               const char *target) {
+    char *command;
+
+    if (!target) {
+        command = (char*)malloc(strlen(dir) + 20);
+        sprintf(command, "make -C %s", dir);
+    }
+    else {
+        command = (char*)malloc(strlen(dir) + strlen(target) + 20);
+        sprintf(command, "make -C %s %s", dir, target);
+    }
+
+    chaz_MakeRule_add_command(rule, command);
+
+    free(command);
+}
+
+
+
+/***************************************************************************/
+
 #line 17 "src/Charmonizer/Core/OperatingSystem.c"
 #include <stdlib.h>
 #include <string.h>
@@ -2392,7 +2734,7 @@ chaz_OS_init(void) {
     if (chaz_Util_can_open_file("/dev/null")) {
         strcpy(chaz_OS.dev_null, "/dev/null");
         strcpy(chaz_OS.exe_ext, "");
-        strcpy(chaz_OS.obj_ext, "");
+        strcpy(chaz_OS.obj_ext, ".o");
         strcpy(chaz_OS.local_command_start, "./");
         chaz_OS.shell_type = CHAZ_OS_POSIX;
     }

Reply via email to