Initial version of cfc command line tool
Project: http://git-wip-us.apache.org/repos/asf/lucy/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy/commit/e65019cc Tree: http://git-wip-us.apache.org/repos/asf/lucy/tree/e65019cc Diff: http://git-wip-us.apache.org/repos/asf/lucy/diff/e65019cc Branch: refs/heads/c-bindings-cfc Commit: e65019ccb4fbf0e55c18623aed10a13891ea2224 Parents: f5bc246 Author: Nick Wellnhofer <[email protected]> Authored: Thu Nov 22 23:17:21 2012 +0100 Committer: Nick Wellnhofer <[email protected]> Committed: Wed Feb 6 23:03:54 2013 +0100 ---------------------------------------------------------------------- clownfish/compiler/c/.gitignore | 5 + clownfish/compiler/c/cfc.c | 202 +++++++++++++++ clownfish/compiler/c/configure | 47 ++++ clownfish/compiler/c/t/cfext/Animal/Rottweiler.cfh | 31 +++ clownfish/compiler/c/t/cfsource/Animal.cfh | 19 ++ clownfish/compiler/c/t/cfsource/Animal.cfp | 4 + clownfish/compiler/c/t/cfsource/Animal/Dog.cfh | 28 ++ clownfish/compiler/c/t/cfsource/Animal/Util.cfh | 23 ++ clownfish/compiler/c/t/lcov.sh | 9 + clownfish/compiler/c/t/test_cfc.c | 31 +++ clownfish/compiler/common/charmonizer.main | 148 +++++++++++ 11 files changed, 547 insertions(+), 0 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy/blob/e65019cc/clownfish/compiler/c/.gitignore ---------------------------------------------------------------------- diff --git a/clownfish/compiler/c/.gitignore b/clownfish/compiler/c/.gitignore new file mode 100644 index 0000000..b5fef9b --- /dev/null +++ b/clownfish/compiler/c/.gitignore @@ -0,0 +1,5 @@ +/Makefile +/cfc +/charmonizer +/charmony.h +/t/test_cfc http://git-wip-us.apache.org/repos/asf/lucy/blob/e65019cc/clownfish/compiler/c/cfc.c ---------------------------------------------------------------------- diff --git a/clownfish/compiler/c/cfc.c b/clownfish/compiler/c/cfc.c new file mode 100644 index 0000000..9fa27f8 --- /dev/null +++ b/clownfish/compiler/c/cfc.c @@ -0,0 +1,202 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "CFCBase.h" +#include "CFCBindCore.h" +#include "CFCC.h" +#include "CFCHierarchy.h" +#include "CFCUtil.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +struct CFCArgs { + char *dest; + int num_source_dirs; + char **source_dirs; + int num_include_dirs; + char **include_dirs; + char *header_filename; + char *footer_filename; +}; +typedef struct CFCArgs CFCArgs; + +static int +S_parse_string_argument(const char *arg, const char *name, char **result) { + size_t arg_len = strlen(arg); + size_t name_len = strlen(name); + + if (arg_len < name_len + || memcmp(arg, name, name_len) != 0 + || arg[name_len] != '=' + ) { + return 0; + } + + if (*result != NULL) { + fprintf(stderr, "Duplicate %s argument\n", name); + exit(EXIT_FAILURE); + } + *result = CFCUtil_strdup(arg + name_len + 1); + + return 1; +} + +static int +S_parse_string_array_argument(const char *arg, const char *name, + int *num_results, char ***results) { + size_t arg_len = strlen(arg); + size_t name_len = strlen(name); + int new_num_results; + char **new_results; + + if (arg_len < name_len + || memcmp(arg, name, name_len) != 0 + || arg[name_len] != '=' + ) { + return 0; + } + + new_num_results = *num_results + 1; + new_results = (char **)REALLOCATE(*results, + (new_num_results + 1) * sizeof(char *)); + new_results[new_num_results-1] = CFCUtil_strdup(arg + name_len + 1); + new_results[new_num_results] = NULL; + *num_results = new_num_results; + *results = new_results; + + return 1; +} + +/* Parse command line arguments. */ +static void +S_parse_arguments(int argc, char **argv, CFCArgs *args) { + int i; + + memset(args, 0, sizeof(CFCArgs)); + args->source_dirs = (char **)MALLOCATE(sizeof(char *)); + args->source_dirs[0] = NULL; + args->include_dirs = (char **)MALLOCATE(sizeof(char *)); + args->include_dirs[0] = NULL; + + for (i = 1; i < argc; i++) { + char *arg = argv[i]; + + if (S_parse_string_argument(arg, "--dest", &args->dest)) { + continue; + } + if (S_parse_string_argument(arg, "--header", &args->header_filename)) { + continue; + } + if (S_parse_string_argument(arg, "--footer", &args->footer_filename)) { + continue; + } + if (S_parse_string_array_argument(arg, "--source", + &args->num_source_dirs, + &args->source_dirs) + ) { + continue; + } + if (S_parse_string_array_argument(arg, "--include", + &args->num_include_dirs, + &args->include_dirs) + ) { + continue; + } + + fprintf(stderr, "Invalid argument '%s'\n", arg); + exit(EXIT_FAILURE); + } + + if (!args->dest) { + fprintf(stderr, "Mandatory argument --dest missing\n"); + exit(EXIT_FAILURE); + } +} + +static void S_free_arguments(CFCArgs *args) { + int i; + + if (args->dest) { FREEMEM(args->dest); } + if (args->header_filename) { FREEMEM(args->header_filename); } + if (args->footer_filename) { FREEMEM(args->footer_filename); } + + for (i = 0; args->source_dirs[i]; ++i) { + FREEMEM(args->source_dirs[i]); + } + FREEMEM(args->source_dirs); + + for (i = 0; args->include_dirs[i]; ++i) { + FREEMEM(args->include_dirs[i]); + } + FREEMEM(args->include_dirs); +} + +int +main(int argc, char **argv) { + int i; + size_t file_len; + CFCArgs args; + CFCHierarchy *hierarchy; + CFCBindCore *core_binding; + CFCC *c_binding; + char *header = NULL; + char *footer = NULL; + + S_parse_arguments(argc, argv, &args); + + hierarchy = CFCHierarchy_new(args.dest); + + for (i = 0; args.source_dirs[i]; ++i) { + CFCHierarchy_add_source_dir(hierarchy, args.source_dirs[i]); + } + for (i = 0; args.include_dirs[i]; ++i) { + CFCHierarchy_add_source_dir(hierarchy, args.include_dirs[i]); + } + + CFCHierarchy_build(hierarchy); + + if (args.header_filename) { + header = CFCUtil_slurp_text(args.header_filename, &file_len); + } + else { + header = CFCUtil_strdup(""); + } + if (args.footer_filename) { + footer = CFCUtil_slurp_text(args.footer_filename, &file_len); + } + else { + footer = CFCUtil_strdup(""); + } + + core_binding = CFCBindCore_new(hierarchy, header, footer); + CFCBindCore_write_all_modified(core_binding, 0); + + c_binding = CFCC_new(hierarchy, header, footer); + CFCC_write_callbacks(c_binding); + + CFCBase_decref((CFCBase*)c_binding); + CFCBase_decref((CFCBase*)core_binding); + CFCBase_decref((CFCBase*)hierarchy); + FREEMEM(header); + FREEMEM(footer); + + S_free_arguments(&args); + + return EXIT_SUCCESS; +} + http://git-wip-us.apache.org/repos/asf/lucy/blob/e65019cc/clownfish/compiler/c/configure ---------------------------------------------------------------------- diff --git a/clownfish/compiler/c/configure b/clownfish/compiler/c/configure new file mode 100755 index 0000000..c8618ce --- /dev/null +++ b/clownfish/compiler/c/configure @@ -0,0 +1,47 @@ +#!/bin/sh + +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +probe_clang() { clang -v; } +probe_gcc() { gcc -v; } + +if [ -z "$CC" ]; then + case $(uname) in + Darwin*) compilers="clang gcc";; + *) compilers="gcc clang";; + esac + + for compiler in $compilers; do + if probe_$compiler >/dev/null 2>&1; then + CC=$compiler + break + fi + done + + if [ -z "$CC" ]; then + CC=cc + fi +fi + +echo "Using C compiler '$CC'" + +command="$CC ../common/charmonizer.c -o charmonizer" +echo $command +$command || exit + +echo Running charmonizer +./charmonizer --cc=$CC --enable-c --enable-makefile $@ + http://git-wip-us.apache.org/repos/asf/lucy/blob/e65019cc/clownfish/compiler/c/t/cfext/Animal/Rottweiler.cfh ---------------------------------------------------------------------- diff --git a/clownfish/compiler/c/t/cfext/Animal/Rottweiler.cfh b/clownfish/compiler/c/t/cfext/Animal/Rottweiler.cfh new file mode 100644 index 0000000..8de5e24 --- /dev/null +++ b/clownfish/compiler/c/t/cfext/Animal/Rottweiler.cfh @@ -0,0 +1,31 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +parcel Animal; + +class Animal::Rottweiler inherits Animal::Dog { + public inert incremented Rottweiler* + new(); + + public inert Rottweiler* + init(Rottweiler *self); + + public void + Bark(Rottweiler *self); + + public void + Bite(Rottweiler *self); +} http://git-wip-us.apache.org/repos/asf/lucy/blob/e65019cc/clownfish/compiler/c/t/cfsource/Animal.cfh ---------------------------------------------------------------------- diff --git a/clownfish/compiler/c/t/cfsource/Animal.cfh b/clownfish/compiler/c/t/cfsource/Animal.cfh new file mode 100644 index 0000000..a4d689a --- /dev/null +++ b/clownfish/compiler/c/t/cfsource/Animal.cfh @@ -0,0 +1,19 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +parcel Animal; + +abstract class Animal { } http://git-wip-us.apache.org/repos/asf/lucy/blob/e65019cc/clownfish/compiler/c/t/cfsource/Animal.cfp ---------------------------------------------------------------------- diff --git a/clownfish/compiler/c/t/cfsource/Animal.cfp b/clownfish/compiler/c/t/cfsource/Animal.cfp new file mode 100644 index 0000000..e2b5ab5 --- /dev/null +++ b/clownfish/compiler/c/t/cfsource/Animal.cfp @@ -0,0 +1,4 @@ +{ + "name": "Animal", + "version": "v0.1.0" +} http://git-wip-us.apache.org/repos/asf/lucy/blob/e65019cc/clownfish/compiler/c/t/cfsource/Animal/Dog.cfh ---------------------------------------------------------------------- diff --git a/clownfish/compiler/c/t/cfsource/Animal/Dog.cfh b/clownfish/compiler/c/t/cfsource/Animal/Dog.cfh new file mode 100644 index 0000000..6d54baa --- /dev/null +++ b/clownfish/compiler/c/t/cfsource/Animal/Dog.cfh @@ -0,0 +1,28 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +parcel Animal; + +class Animal::Dog inherits Animal { + public inert incremented Dog* + new(); + + public inert Dog* + init(Dog *self); + + public void + Bark(Dog *self); +} http://git-wip-us.apache.org/repos/asf/lucy/blob/e65019cc/clownfish/compiler/c/t/cfsource/Animal/Util.cfh ---------------------------------------------------------------------- diff --git a/clownfish/compiler/c/t/cfsource/Animal/Util.cfh b/clownfish/compiler/c/t/cfsource/Animal/Util.cfh new file mode 100644 index 0000000..f5688a5 --- /dev/null +++ b/clownfish/compiler/c/t/cfsource/Animal/Util.cfh @@ -0,0 +1,23 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +parcel Animal; + +inert class Animal::Util { + inert void + groom(Animal *animal); +} + http://git-wip-us.apache.org/repos/asf/lucy/blob/e65019cc/clownfish/compiler/c/t/lcov.sh ---------------------------------------------------------------------- diff --git a/clownfish/compiler/c/t/lcov.sh b/clownfish/compiler/c/t/lcov.sh new file mode 100755 index 0000000..3411f55 --- /dev/null +++ b/clownfish/compiler/c/t/lcov.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +set -ex + +lcov --zerocounters --directory .. +t/test_cfc +lcov --capture --directory .. --rc lcov_branch_coverage=1 --output-file cfc.info +genhtml --branch-coverage --output-directory coverage cfc.info + http://git-wip-us.apache.org/repos/asf/lucy/blob/e65019cc/clownfish/compiler/c/t/test_cfc.c ---------------------------------------------------------------------- diff --git a/clownfish/compiler/c/t/test_cfc.c b/clownfish/compiler/c/t/test_cfc.c new file mode 100644 index 0000000..66fa90a --- /dev/null +++ b/clownfish/compiler/c/t/test_cfc.c @@ -0,0 +1,31 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdlib.h> + +#include "CFCBase.h" +#include "CFCTest.h" + +int +main() { + CFCTest *test = CFCTest_new("clownfish"); + CFCTest_run_all(test); + int pass = CFCTest_finish(test); + CFCBase_decref((CFCBase*)test); + + return pass ? EXIT_SUCCESS : EXIT_FAILURE; +} + http://git-wip-us.apache.org/repos/asf/lucy/blob/e65019cc/clownfish/compiler/common/charmonizer.main ---------------------------------------------------------------------- diff --git a/clownfish/compiler/common/charmonizer.main b/clownfish/compiler/common/charmonizer.main index d083f57..702312d 100644 --- a/clownfish/compiler/common/charmonizer.main +++ b/clownfish/compiler/common/charmonizer.main @@ -23,6 +23,13 @@ #include "Charmonizer/Probe.h" #include "Charmonizer/Probe/Integers.h" +#define DIR_SEP "/" + +typedef struct SourceFileContext { + chaz_MakeVar *common_objs; + chaz_MakeVar *test_cfc_objs; +} SourceFileContext; + static void S_add_compiler_flags(struct chaz_CLIArgs *args) { if (chaz_Probe_gcc_version_num()) { @@ -52,6 +59,137 @@ S_add_compiler_flags(struct chaz_CLIArgs *args) { } } +static void +S_source_file_callback(char *file, void *context) { + SourceFileContext *sfc = (SourceFileContext*)context; + size_t file_len = strlen(file); + size_t obj_file_size; + const char *pattern; + char *obj_file; + + if (strcmp(file, "CFCParseHeader.c") == 0) { return; } + + /* Strip extension */ + if (file_len <= 2 || memcmp(file + file_len - 2, ".c", 2) != 0) { + chaz_Util_warn("Unexpected source file name: %s", file); + return; + } + file[file_len-2] = '\0'; + + pattern = "$(SRC_DIR)" DIR_SEP "%s$(OBJ_EXT)"; + obj_file_size = strlen(pattern) + file_len + 10; + obj_file = (char*)malloc(obj_file_size); + sprintf(obj_file, pattern, file); + + if (strlen(file) >= 7 && memcmp(file, "CFCTest", 7) == 0) { + chaz_MakeVar_append(sfc->test_cfc_objs, obj_file); + } + else { + chaz_MakeVar_append(sfc->common_objs, obj_file); + } + + free(obj_file); +} + +static void +S_write_makefile() { + SourceFileContext sfc; + + 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; + + printf("Creating Makefile...\n"); + + src_dir = (char*)malloc(strlen(base_dir) + 20); + sprintf(src_dir, "%s" DIR_SEP "src", base_dir); + + makefile = chaz_MakeFile_new(); + + /* Variables */ + + 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)"); + + var = chaz_MakeFile_add_var(makefile, "CFLAGS", NULL); + chaz_MakeVar_append(var, chaz_CC_get_cflags()); + chaz_MakeVar_append(var, chaz_CC_get_extra_cflags()); + chaz_MakeVar_append(var, "-I."); + chaz_MakeVar_append(var, "-I$(INCLUDE_DIR)"); + chaz_MakeVar_append(var, "-I$(SRC_DIR)"); + + sfc.common_objs = chaz_MakeFile_add_var(makefile, "COMMON_OBJS", NULL); + sfc.test_cfc_objs = chaz_MakeFile_add_var(makefile, "TEST_CFC_OBJS", NULL); + + chaz_Make_list_files(src_dir, "c", S_source_file_callback, &sfc); + + chaz_MakeVar_append(sfc.common_objs, + "$(SRC_DIR)" DIR_SEP "CFCParseHeader$(OBJ_EXT)"); + chaz_MakeVar_append(sfc.test_cfc_objs, "t" DIR_SEP "test_cfc$(OBJ_EXT)"); + + chaz_MakeFile_add_var(makefile, "CFC_OBJS", "cfc$(OBJ_EXT)"); + chaz_MakeFile_add_var(makefile, "CFC_EXE", "cfc$(EXE_EXT)"); + chaz_MakeFile_add_var(makefile, "TEST_CFC_EXE", + "t" DIR_SEP "test_cfc$(EXE_EXT)"); + + /* Rules */ + + 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, "$(COMMON_OBJS)", parse_header_c); + + chaz_MakeFile_add_exe(makefile, "$(CFC_EXE)", + "$(COMMON_OBJS) $(CFC_OBJS)"); + chaz_MakeFile_add_exe(makefile, "$(TEST_CFC_EXE)", + "$(COMMON_OBJS) $(TEST_CFC_OBJS)"); + + rule = chaz_MakeFile_add_rule(makefile, "test", "$(TEST_CFC_EXE)"); + chaz_MakeRule_add_command(rule, "$(TEST_CFC_EXE)"); + + chaz_MakeFile_add_to_cleanup(makefile, "$(COMMON_OBJS)"); + chaz_MakeFile_add_to_cleanup(makefile, "$(CFC_OBJS)"); + chaz_MakeFile_add_to_cleanup(makefile, "$(TEST_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, const char **argv) { /* Initialize. */ { @@ -71,6 +209,16 @@ int main(int argc, const char **argv) { chaz_Integers_run(); chaz_Strings_run(); + { + int i; + for (i = 0; i < argc; i++) { + if (strncmp(argv[i], "--enable-makefile", 17) == 0) { + S_write_makefile(); + break; + } + } + } + /* Clean up. */ chaz_Probe_clean_up();
