You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by nw...@apache.org on 2012/12/05 00:03:05 UTC

[lucy-commits] [9/9] git commit: refs/heads/c-bindings-wip1 - Initial version of cfc command line tool

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

Branch: refs/heads/c-bindings-wip1
Commit: eb8f895633c2ecda8560f64c53e64edb282d0c27
Parents: 99352ea
Author: Nick Wellnhofer <we...@aevum.de>
Authored: Thu Nov 22 23:17:21 2012 +0100
Committer: Nick Wellnhofer <we...@aevum.de>
Committed: Tue Dec 4 20:57:57 2012 +0100

----------------------------------------------------------------------
 clownfish/compiler/c/.gitignore |    3 +
 clownfish/compiler/c/Makefile   |   73 +++++++++++++
 clownfish/compiler/c/cfc.c      |  196 ++++++++++++++++++++++++++++++++++
 3 files changed, 272 insertions(+), 0 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy/blob/eb8f8956/clownfish/compiler/c/.gitignore
----------------------------------------------------------------------
diff --git a/clownfish/compiler/c/.gitignore b/clownfish/compiler/c/.gitignore
new file mode 100644
index 0000000..ccdc7c7
--- /dev/null
+++ b/clownfish/compiler/c/.gitignore
@@ -0,0 +1,3 @@
+/cfc
+/charmonizer
+/charmony.h

http://git-wip-us.apache.org/repos/asf/lucy/blob/eb8f8956/clownfish/compiler/c/Makefile
----------------------------------------------------------------------
diff --git a/clownfish/compiler/c/Makefile b/clownfish/compiler/c/Makefile
new file mode 100644
index 0000000..efd7332
--- /dev/null
+++ b/clownfish/compiler/c/Makefile
@@ -0,0 +1,73 @@
+CFC_COMMON_DIR = ../common
+CFC_INCLUDE_DIR = ../include
+CFC_SOURCE_DIR = ../src
+LEMON_DIR = ../../../lemon
+
+CFLAGS += -g -I. -I$(CFC_SOURCE_DIR) -I$(CFC_INCLUDE_DIR)
+
+CHARMONY_H = charmony.h
+CHARMONIZER = charmonizer
+CHARMONIZER_C = $(CFC_COMMON_DIR)/charmonizer.c
+
+LEMON = $(LEMON_DIR)/lemon
+CFC_PARSE_HEADER = $(CFC_SOURCE_DIR)/CFCParseHeader
+
+CFC = cfc
+CFC_OBJS = \
+    $(CFC_SOURCE_DIR)/CFCBase.o \
+    $(CFC_SOURCE_DIR)/CFCBindAliases.o \
+    $(CFC_SOURCE_DIR)/CFCBindClass.o \
+    $(CFC_SOURCE_DIR)/CFCBindCore.o \
+    $(CFC_SOURCE_DIR)/CFCBindFile.o \
+    $(CFC_SOURCE_DIR)/CFCBindFunction.o \
+    $(CFC_SOURCE_DIR)/CFCBindMethod.o \
+    $(CFC_SOURCE_DIR)/CFCCBlock.o \
+    $(CFC_SOURCE_DIR)/CFCClass.o \
+    $(CFC_SOURCE_DIR)/CFCDocuComment.o \
+    $(CFC_SOURCE_DIR)/CFCDumpable.o \
+    $(CFC_SOURCE_DIR)/CFCFile.o \
+    $(CFC_SOURCE_DIR)/CFCFileSpec.o \
+    $(CFC_SOURCE_DIR)/CFCFunction.o \
+    $(CFC_SOURCE_DIR)/CFCHierarchy.o \
+    $(CFC_SOURCE_DIR)/CFCLexHeader.o \
+    $(CFC_SOURCE_DIR)/CFCMemPool.o \
+    $(CFC_SOURCE_DIR)/CFCMethod.o \
+    $(CFC_SOURCE_DIR)/CFCParamList.o \
+    $(CFC_SOURCE_DIR)/CFCParcel.o \
+    $(CFC_SOURCE_DIR)/CFCParseHeader.o \
+    $(CFC_SOURCE_DIR)/CFCParser.o \
+    $(CFC_SOURCE_DIR)/CFCSymbol.o \
+    $(CFC_SOURCE_DIR)/CFCType.o \
+    $(CFC_SOURCE_DIR)/CFCUtil.o \
+    $(CFC_SOURCE_DIR)/CFCVariable.o \
+    $(CFC_SOURCE_DIR)/CFCVersion.o \
+    cfc.o
+
+all : $(CFC)
+
+$(CHARMONIZER) : $(CHARMONIZER_C)
+	$(CC) $(CFLAGS) $(CHARMONIZER_C) -o $@
+
+$(CHARMONY_H) : $(CHARMONIZER)
+	./$(CHARMONIZER) --cc=$(CC) -- $(CFLAGS)
+
+$(LEMON) :
+	make -C $(LEMON_DIR)
+
+$(CFC_PARSE_HEADER).c $(CFC_PARSE_HEADER).h: $(LEMON) $(CFC_PARSE_HEADER).y
+	$(LEMON) -q $(CFC_PARSE_HEADER).y
+
+$(CFC_OBJS) : $(CHARMONY_H) $(CFC_PARSE_HEADER).h
+
+$(CFC) : $(CFC_OBJS)
+	$(CC) $(LDFLAGS) $(CFC_OBJS) $(LOADLIBES) $(LDLIBS) -o $@
+
+clean :
+	rm -rf \
+	    $(CFC) \
+	    $(CFC_OBJS) \
+	    $(CFC_PARSE_HEADER).c \
+	    $(CFC_PARSE_HEADER).h \
+	    $(CHARMONY_H) \
+	    $(CHARMONIZER)
+

http://git-wip-us.apache.org/repos/asf/lucy/blob/eb8f8956/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..cf27569
--- /dev/null
+++ b/clownfish/compiler/c/cfc.c
@@ -0,0 +1,196 @@
+/* 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 "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;
+    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);
+    FREEMEM(header);
+    FREEMEM(footer);
+
+    CFCBindCore_write_all_modified(core_binding, 0);
+
+    CFCBase_decref((CFCBase*)core_binding);
+    CFCBase_decref((CFCBase*)hierarchy);
+
+    S_free_arguments(&args);
+
+    return EXIT_SUCCESS;
+}
+