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 <[email protected]> Authored: Thu Nov 22 23:17:21 2012 +0100 Committer: Nick Wellnhofer <[email protected]> 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; +} +
