From 5dc45e8255a9debca3951537c28067d6baa29adf Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 14 Jun 2016 10:13:11 +0200 Subject: [PATCH] Generate i-cal-forward-declarations.h and use it in the sources To avoid type redefinitions and to have pretty names in the public headers. --- src/libical-glib/CMakeLists.txt | 3 +- src/libical-glib/i-cal-object.c.in | 4 +- src/libical-glib/tools/generator.c | 117 ++++++++++++++------- src/libical-glib/tools/generator.h | 2 + .../tools/header-forward-declarations-template | 34 ++++++ src/libical-glib/tools/header-header-template | 3 +- .../tools/header-structure-boilerplate-template | 1 - src/libical-glib/tools/header-template | 5 +- src/libical-glib/tools/source-template | 2 +- 9 files changed, 124 insertions(+), 47 deletions(-) create mode 100644 src/libical-glib/tools/header-forward-declarations-template diff --git a/src/libical-glib/CMakeLists.txt b/src/libical-glib/CMakeLists.txt index 6d9534c..5ad775a 100644 --- a/src/libical-glib/CMakeLists.txt +++ b/src/libical-glib/CMakeLists.txt @@ -50,6 +50,7 @@ list(APPEND API_FILES list(APPEND LIBICAL_GLIB_HEADERS ${CMAKE_CURRENT_BINARY_DIR}/libical-glib.h ${CMAKE_CURRENT_BINARY_DIR}/i-cal-object.h + ${CMAKE_CURRENT_BINARY_DIR}/i-cal-forward-declarations.h ) # add the command to generate the source code from the api files @@ -65,7 +66,7 @@ foreach(file IN LISTS API_FILES) endforeach() add_custom_command ( - OUTPUT ${LIBICAL_GLIB_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/libical-glib-private.h + OUTPUT ${LIBICAL_GLIB_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/libical-glib-private.h ${CMAKE_CURRENT_BINARY_DIR}/i-cal-forward-declarations.h COMMAND src-generator "${CMAKE_CURRENT_SOURCE_DIR}/tools" "${CMAKE_CURRENT_SOURCE_DIR}/api" DEPENDS src-generator ${xml_files} ) diff --git a/src/libical-glib/i-cal-object.c.in b/src/libical-glib/i-cal-object.c.in index 3967d2a..904f25b 100644 --- a/src/libical-glib/i-cal-object.c.in +++ b/src/libical-glib/i-cal-object.c.in @@ -240,7 +240,7 @@ i_cal_object_construct(ICalObject *iobject, if (owner) g_return_if_fail(G_IS_OBJECT(owner)); - //LOCK_PROPS (iobject); + /* LOCK_PROPS (iobject); */ g_warn_if_fail(iobject->priv->native == NULL); @@ -249,7 +249,7 @@ i_cal_object_construct(ICalObject *iobject, iobject->priv->is_global_memory = is_global_memory; i_cal_object_set_owner(iobject, owner); - //UNLOCK_PROPS (iobject); + /* UNLOCK_PROPS (iobject); */ } /** diff --git a/src/libical-glib/tools/generator.c b/src/libical-glib/tools/generator.c index b47f51c..a748d3b 100644 --- a/src/libical-glib/tools/generator.c +++ b/src/libical-glib/tools/generator.c @@ -902,8 +902,6 @@ void generate_code_from_template(FILE *in, FILE *out, Structure *structure, GHas generate_header_includes(out, structure); } else if (g_strcmp0(buffer, "sourceIncludes") == 0) { generate_source_includes(out, structure); - } else if (g_strcmp0(buffer, "forward_declaration") == 0) { - generate_header_forward_declaration(out, structure); } else if (g_strcmp0(buffer, "header_declaration") == 0) { generate_header_header_declaration(out, structure); } else if (g_hash_table_contains(table, buffer)) { @@ -1092,61 +1090,99 @@ void generate_source_includes(FILE *out, Structure *structure) g_hash_table_destroy(includeNames); } -void generate_header_forward_declaration(FILE *out, Structure *structure) +void generate_forward_declarations_header_file(GList *structures) { + FILE *in, *out; + gint c, len; + gchar buffer[BUFFER_SIZE]; gchar *typeName; gchar *typeKind; Structure *parentStructure; - gchar *upperCamel; - gchar *ownUpperCamel; - GHashTable *includeNames; + GList *link; + GHashTable *typeNames; GHashTableIter iter_table; gpointer key; gpointer value; - g_return_if_fail(out != NULL && structure != NULL); + g_return_if_fail(structures != NULL); - includeNames = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); + in = open_file(templates_dir, HEADER_FORWARD_DECLARATIONS_TEMPLATE); + if (!in) + return; - /* Temporary solution. To be rewritten */ - for (g_hash_table_iter_init(&iter_table, structure->dependencies); - g_hash_table_iter_next(&iter_table, &key, &value);) { - typeName = (gchar *) key; - if (g_hash_table_contains(type2structure, typeName)) { - parentStructure = g_hash_table_lookup(type2structure, typeName); - upperCamel = g_strconcat(parentStructure->nameSpace, parentStructure->name, NULL); - ownUpperCamel = g_strconcat(structure->nameSpace, structure->name, NULL); - if (g_strcmp0(upperCamel, ownUpperCamel) == 0) { - g_free(upperCamel); - g_free(ownUpperCamel); - continue; - } + out = fopen(FORWARD_DECLARATIONS_HEADER, "wb"); + if (!out) { + fclose(in); + fprintf(stderr, "Failed to open '%s' for writing\n", FORWARD_DECLARATIONS_HEADER); + return; + } + + typeNames = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); - typeKind = g_hash_table_lookup(type2kind, typeName); - if (g_strcmp0(typeKind, "std") == 0) { - (void)g_hash_table_insert(includeNames, typeName, (gchar *) "std"); + for (link = structures; link; link = g_list_next (link)) { + Structure *structure = link->data; + + if (!structure) + continue; + + for (g_hash_table_iter_init(&iter_table, structure->dependencies); + g_hash_table_iter_next(&iter_table, &key, &value);) { + typeName = (gchar *) key; + if (g_hash_table_contains(type2structure, typeName)) { + parentStructure = g_hash_table_lookup(type2structure, typeName); + typeKind = g_hash_table_lookup(type2kind, typeName); + if (g_strcmp0(typeKind, "std") == 0 && !g_hash_table_contains(typeNames, typeName)) { + (void)g_hash_table_insert(typeNames, g_strdup (typeName), (gchar *) "std"); + } } - g_free(upperCamel); - g_free(ownUpperCamel); } } - typeName = NULL; + *buffer = '\0'; - for (g_hash_table_iter_init(&iter_table, includeNames); - g_hash_table_iter_next(&iter_table, &key, &value);) { - typeName = (gchar *) key; - write_str(out, "typedef struct _"); - write_str(out, typeName); - write_str(out, " "); - write_str(out, typeName); - write_str(out, ";\n"); - } - if (typeName != NULL) { - write_str(out, "\n"); + while ((c = fgetc(in)) != EOF) { + if (c == '$') { + if ((c = fgetc(in)) != '{' && c != '^') { + printf("The following char is not {"); + g_free (buffer); + fclose(in); + fclose(out); + return; + } + + while ((c = fgetc(in)) != '}') { + len = (gint) strlen(buffer); + buffer[len] = c; + buffer[len + 1] = '\0'; + } + + if (g_strcmp0(buffer, "forward_declarations") == 0) { + g_hash_table_iter_init(&iter_table, typeNames); + while (g_hash_table_iter_next(&iter_table, &key, &value)) { + typeName = (gchar *) key; + write_str(out, "typedef struct _"); + write_str(out, typeName); + write_str(out, " "); + write_str(out, typeName); + write_str(out, ";\n"); + } + } else if (g_strcmp0(buffer, "upperSnake") == 0) { + write_str(out, "I_CAL_FORWARD_DECLARATIONS"); + } else { + fprintf(stderr, "The string '%s' is not recognized, please check the %s\n", + buffer, FORWARD_DECLARATIONS_HEADER); + fflush(stderr); + break; + } + buffer[0] = '\0'; + } else { + fputc(c, out); + } } - g_hash_table_destroy(includeNames); + g_hash_table_destroy(typeNames); + fclose(out); + fclose(in); } void generate_source(FILE *out, Structure *structure, GHashTable *table) @@ -2229,6 +2265,9 @@ static gint generate_library(const gchar *apis_dir) xmlFreeDoc(doc); } + /* Generate the forward declarations header file */ + generate_forward_declarations_header_file(structures); + /* Generate the common header for all the headers, which is libical-glib.h for here */ generate_header_header_file(structures); diff --git a/src/libical-glib/tools/generator.h b/src/libical-glib/tools/generator.h index b94daa7..c42d466 100644 --- a/src/libical-glib/tools/generator.h +++ b/src/libical-glib/tools/generator.h @@ -26,6 +26,7 @@ #define HEADER_TEMPLATE "header-template" #define HEADER_HEADER_TEMPLATE "header-header-template" +#define HEADER_FORWARD_DECLARATIONS_TEMPLATE "header-forward-declarations-template" #define INLINE_TRANSLATION "${translator} (${name})" #define SOURCE_TEMPLATE "source-template" #define COMMON_HEADER "libical-glib/i-cal-object" @@ -38,6 +39,7 @@ #define METHOD_NAME_TAB_COUNT 4 #define COMMENT_LINE_LENGTH 100 #define PRIVATE_HEADER "libical-glib-private.h" +#define FORWARD_DECLARATIONS_HEADER "i-cal-forward-declarations.h" /* Store the default value for bare type */ GHashTable *defaultValues; diff --git a/src/libical-glib/tools/header-forward-declarations-template b/src/libical-glib/tools/header-forward-declarations-template new file mode 100644 index 0000000..11da55a --- /dev/null +++ b/src/libical-glib/tools/header-forward-declarations-template @@ -0,0 +1,34 @@ +/* Generated file (by generator) */ + +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2015 William Yu + * + * This library is free software: you can redistribute it and/or modify it + * under the terms of version 2.1. of the GNU Lesser General Public License + * as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see . + */ + +#if !defined (__LIBICAL_GLIB_H_INSIDE__) && !defined (LIBICAL_GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef ${upperSnake}_H +#define ${upperSnake}_H + +#include + +G_BEGIN_DECLS + +${forward_declarations} +G_END_DECLS + +#endif /* ${upperSnake}_H */ diff --git a/src/libical-glib/tools/header-header-template b/src/libical-glib/tools/header-header-template index 64501a5..559468c 100644 --- a/src/libical-glib/tools/header-header-template +++ b/src/libical-glib/tools/header-header-template @@ -1,4 +1,4 @@ -/* Generated file (by src-generator) */ +/* Generated file (by generator) */ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* @@ -24,6 +24,7 @@ #define __LIBICAL_GLIB_H_INSIDE__ +#include ${allHeaders} #undef __LIBICAL_GLIB_H_INSIDE__ diff --git a/src/libical-glib/tools/header-structure-boilerplate-template b/src/libical-glib/tools/header-structure-boilerplate-template index 374d2b6..f61d56e 100644 --- a/src/libical-glib/tools/header-structure-boilerplate-template +++ b/src/libical-glib/tools/header-structure-boilerplate-template @@ -18,7 +18,6 @@ * * This is the ${upperCamel} instance. */ -typedef struct _${upperCamel} ${upperCamel}; /** * ${upperCamel}Class: diff --git a/src/libical-glib/tools/header-template b/src/libical-glib/tools/header-template index a181060..6f6a4cf 100644 --- a/src/libical-glib/tools/header-template +++ b/src/libical-glib/tools/header-template @@ -1,4 +1,4 @@ -/* Generated file (by src-generator) */ +/* Generated file (by generator) */ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* @@ -24,10 +24,11 @@ #ifndef ${upperSnake}_H #define ${upperSnake}_H +#include ${headerIncludes} G_BEGIN_DECLS -${structure_boilerplate}${header_declaration}${forward_declaration}${enums}${protos} +${structure_boilerplate}${header_declaration}${enums}${protos} G_END_DECLS #endif /* ${upperSnake}_H */ diff --git a/src/libical-glib/tools/source-template b/src/libical-glib/tools/source-template index 3ea6b65..beec00e 100644 --- a/src/libical-glib/tools/source-template +++ b/src/libical-glib/tools/source-template @@ -1,4 +1,4 @@ -/* Generated file (by src-generator) */ +/* Generated file (by generator) */ /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* -- 2.7.4