CFCUri class
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/0a0c7439 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/0a0c7439 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/0a0c7439 Branch: refs/heads/markdown_v2 Commit: 0a0c74391de3a3bc46588709ef2082db85779695 Parents: 65ddb13 Author: Nick Wellnhofer <[email protected]> Authored: Tue Dec 2 02:04:13 2014 +0100 Committer: Nick Wellnhofer <[email protected]> Committed: Tue Dec 2 18:31:14 2014 +0100 ---------------------------------------------------------------------- compiler/src/CFCUri.c | 232 +++++++++++++++++++++++++++++++++++++++++++++ compiler/src/CFCUri.h | 64 +++++++++++++ 2 files changed, 296 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0a0c7439/compiler/src/CFCUri.c ---------------------------------------------------------------------- diff --git a/compiler/src/CFCUri.c b/compiler/src/CFCUri.c new file mode 100644 index 0000000..0f466a6 --- /dev/null +++ b/compiler/src/CFCUri.c @@ -0,0 +1,232 @@ +/* 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 <string.h> + +#define CFC_NEED_BASE_STRUCT_DEF +#include "CFCBase.h" +#include "CFCUri.h" +#include "CFCClass.h" +#include "CFCUtil.h" + +struct CFCUri { + CFCBase base; + int type; + char *prefix; + char *struct_sym; + char *full_struct_sym; + char *func_sym; +}; + +static const CFCMeta CFCURI_META = { + "Clownfish::CFC::Uri", + sizeof(CFCUri), + (CFCBase_destroy_t)CFCUri_destroy +}; + +static char* +S_next_component(const char *uri, const char **comp_ptr, int *num_comps); + +int +CFCUri_is_clownfish_uri(const char *uri) { + return strncmp(uri, "clownfish:", 10) == 0; +} + +CFCUri* +CFCUri_new(const char *uri, CFCClass *klass) { + CFCUri *self = (CFCUri*)CFCBase_allocate(&CFCURI_META); + return CFCUri_init(self, uri, klass); +} + +CFCUri* +CFCUri_init(CFCUri *self, const char *uri, CFCClass *klass) { + CFCUTIL_NULL_CHECK(uri); + + if (strncmp(uri, "clownfish:", 10) != 0) { + CFCUtil_die("Invalid clownfish URI: %s", uri); + } + const char *comp = uri + 10; + + int num_components = 0; + + char *type_str = S_next_component(uri, &comp, &num_components); + char *comp2 = S_next_component(uri, &comp, &num_components); + char *comp3 = S_next_component(uri, &comp, &num_components); + char *comp4 = S_next_component(uri, &comp, &num_components); + + if (num_components == 0 || comp[0] != '\0') { + CFCUtil_die("Invalid clownfish URI: %s", uri); + } + + if (strcmp(type_str, "null") == 0) { + self->type = CFC_URI_NULL; + + if (num_components != 1) { + CFCUtil_die("Invalid clownfish URI: %s", uri); + } + } + else if (strcmp(type_str, "class") == 0) { + self->type = CFC_URI_CLASS; + + if (num_components == 2) { + if (!klass) { + CFCUtil_die("Class needed to complete URI: %s", uri); + } + self->prefix = CFCUtil_strdup(CFCClass_get_prefix(klass)); + self->struct_sym = comp2; + } + else if (num_components == 3) { + self->prefix = CFCUtil_sprintf("%s_", comp2); + self->struct_sym = comp3; + FREEMEM(comp2); + } + else { + CFCUtil_die("Invalid clownfish URI: %s", uri); + } + } + else if (strcmp(type_str, "function") == 0 + || strcmp(type_str, "method") == 0 + ) { + self->type = strcmp(type_str, "function") == 0 + ? CFC_URI_FUNCTION : CFC_URI_METHOD; + + if (num_components == 2) { + if (!klass) { + CFCUtil_die("Class needed to complete URI: %s", uri); + } + self->prefix = CFCUtil_strdup(CFCClass_get_prefix(klass)); + self->struct_sym = CFCUtil_strdup(CFCClass_get_struct_sym(klass)); + self->func_sym = comp2; + } + else if (num_components == 3) { + if (!klass) { + CFCUtil_die("Class needed to complete URI: %s", uri); + } + self->prefix = CFCUtil_strdup(CFCClass_get_prefix(klass)); + self->struct_sym = comp2; + self->func_sym = comp3; + } + else if (num_components == 4) { + self->prefix = CFCUtil_sprintf("%s_", comp2); + self->struct_sym = comp3; + self->func_sym = comp4; + FREEMEM(comp2); + } + else { + CFCUtil_die("Invalid clownfish URI: %s", uri); + } + } + else { + CFCUtil_die("Invalid clownfish URI: %s", uri); + } + + if (self->prefix && self->struct_sym) { + self->full_struct_sym + = CFCUtil_sprintf("%s%s", self->prefix, self->struct_sym); + + if (getenv("CFC_CHECK_LINKS")) { + CFCClass *klass + = CFCClass_fetch_by_struct_sym(self->full_struct_sym); + + if (!klass) { + CFCUtil_warn("No class found for URI: %s", uri); + } + else if (self->type == CFC_URI_FUNCTION) { + if (!CFCClass_function(klass, self->func_sym)) { + const char *class_name = CFCClass_get_class_name(klass); + CFCUtil_warn("No function found for URI %s in %s", uri, + class_name); + } + } + else if (self->type == CFC_URI_METHOD) { + if (!CFCClass_method(klass, self->func_sym)) { + const char *class_name = CFCClass_get_class_name(klass); + CFCUtil_warn("No method found for URI %s in %s", uri, + class_name); + } + } + } + } + + FREEMEM(type_str); + + return self; +} + +void +CFCUri_destroy(CFCUri *self) { + FREEMEM(self->prefix); + FREEMEM(self->struct_sym); + FREEMEM(self->full_struct_sym); + FREEMEM(self->func_sym); + CFCBase_destroy((CFCBase*)self); +} + +static char* +S_next_component(const char *uri, const char **comp_ptr, int *num_comps) { + const char *comp = *comp_ptr; + + if (comp[0] == '\0') { + return NULL; + } + + const char *colon = strchr(comp, ':'); + char *component; + + if (colon) { + size_t len = colon - comp; + if (len == 0) { + CFCUtil_die("Invalid clownfish URI: %s", uri); + } + component = CFCUtil_strndup(comp, len); + *comp_ptr += len + 1; + } + else { + component = CFCUtil_strdup(comp); + *comp_ptr += strlen(comp); + } + + ++*num_comps; + + return component; +} + +int +CFCUri_get_type(CFCUri *self) { + return self->type; +} + +const char* +CFCUri_get_prefix(CFCUri *self) { + return self->prefix; +} + +const char* +CFCUri_get_struct_sym(CFCUri *self) { + return self->struct_sym; +} + +const char* +CFCUri_full_struct_sym(CFCUri *self) { + return self->full_struct_sym; +} + +const char* +CFCUri_get_func_sym(CFCUri *self) { + return self->func_sym; +} + http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/0a0c7439/compiler/src/CFCUri.h ---------------------------------------------------------------------- diff --git a/compiler/src/CFCUri.h b/compiler/src/CFCUri.h new file mode 100644 index 0000000..51784e2 --- /dev/null +++ b/compiler/src/CFCUri.h @@ -0,0 +1,64 @@ +/* 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. + */ + +#ifndef H_CFCURI +#define H_CFCURI + +#ifdef __cplusplus +extern "C" { +#endif + +#define CFC_URI_NULL 1 +#define CFC_URI_CLASS 2 +#define CFC_URI_FUNCTION 3 +#define CFC_URI_METHOD 4 + +typedef struct CFCUri CFCUri; +struct CFCClass; + +int +CFCUri_is_clownfish_uri(const char *uri); + +CFCUri* +CFCUri_new(const char *uri, struct CFCClass *klass); + +CFCUri* +CFCUri_init(CFCUri *self, const char *uri, struct CFCClass *klass); + +void +CFCUri_destroy(CFCUri *self); + +int +CFCUri_get_type(CFCUri *self); + +const char* +CFCUri_get_prefix(CFCUri *self); + +const char* +CFCUri_get_struct_sym(CFCUri *self); + +const char* +CFCUri_full_struct_sym(CFCUri *self); + +const char* +CFCUri_get_func_sym(CFCUri *self); + +#ifdef __cplusplus +} +#endif + +#endif /* H_CFCURI */ +
