From d182f929ee6f7a9eb7df86dd5fd21d67634d83b5 Mon Sep 17 00:00:00 2001 From: Eric Rosenquist Date: Wed, 15 Nov 2017 10:36:04 -0500 Subject: [PATCH] Initial commit of the C API for Apache Avro Avro is a data serialization system. https://avro.apache.org/docs/current/api/c/ A static library is the only build option at the moment. The patch for PR#217 in the Avro repo is included since it contains a vital memory leak fix that has not yet been merged into the Avro code. https://github.com/apache/avro/pull/217 --- ports/avro-c/CONTROL | 4 + ports/avro-c/avro-pr-217.patch | 421 +++++++++++++++++++++++++++++++++ ports/avro-c/avro.patch | 349 +++++++++++++++++++++++++++ ports/avro-c/portfile.cmake | 30 +++ 4 files changed, 804 insertions(+) create mode 100644 ports/avro-c/CONTROL create mode 100644 ports/avro-c/avro-pr-217.patch create mode 100644 ports/avro-c/avro.patch create mode 100644 ports/avro-c/portfile.cmake diff --git a/ports/avro-c/CONTROL b/ports/avro-c/CONTROL new file mode 100644 index 00000000000..3a7334c41f8 --- /dev/null +++ b/ports/avro-c/CONTROL @@ -0,0 +1,4 @@ +Source: avro-c +Version: 1.8.2 +Description: Apache Avro is a data serialization system +Build-Depends: jansson, liblzma, zlib diff --git a/ports/avro-c/avro-pr-217.patch b/ports/avro-c/avro-pr-217.patch new file mode 100644 index 00000000000..9a5ddd3a855 --- /dev/null +++ b/ports/avro-c/avro-pr-217.patch @@ -0,0 +1,421 @@ +diff --git a/lang/c/src/schema.c b/lang/c/src/schema.c +index 3ade1140e..97e3ff354 100644 +--- a/lang/c/src/schema.c ++++ b/lang/c/src/schema.c +@@ -2,17 +2,17 @@ + * 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 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. ++ * permissions and limitations under the License. + */ + + #include "avro/allocation.h" +@@ -61,7 +61,7 @@ static int is_avro_id(const char *name) + } + } + /* +- * starts with [A-Za-z_] subsequent [A-Za-z0-9_] ++ * starts with [A-Za-z_] subsequent [A-Za-z0-9_] + */ + return 1; + } +@@ -199,7 +199,13 @@ static void avro_schema_free(avro_schema_t schema) + case AVRO_LINK:{ + struct avro_link_schema_t *link; + link = avro_schema_to_link(schema); +- avro_schema_decref(link->to); ++ /* Since we didn't increment the ++ * reference count of the target ++ * schema when we created the link, we ++ * should not decrement the reference ++ * count of the target schema when we ++ * free the link. ++ */ + avro_freet(struct avro_link_schema_t, link); + } + break; +@@ -727,7 +733,19 @@ avro_schema_t avro_schema_link(avro_schema_t to) + avro_set_error("Cannot allocate new link schema"); + return NULL; + } +- link->to = avro_schema_incref(to); ++ ++ /* Do not increment the reference count of target schema ++ * pointed to by the AVRO_LINK. AVRO_LINKs are only valid ++ * internal to a schema. The target schema pointed to by a ++ * link will be valid as long as the top-level schema is ++ * valid. Similarly, the link will be valid as long as the ++ * top-level schema is valid. Therefore the validity of the ++ * link ensures the validity of its target, and we don't need ++ * an additional reference count on the target. This mechanism ++ * of an implied validity also breaks reference count cycles ++ * for recursive schemas, which result in memory leaks. ++ */ ++ link->to = to; + avro_schema_init(&link->obj, AVRO_LINK); + return &link->obj; + } +@@ -807,7 +825,7 @@ avro_type_from_json_t(json_t *json, avro_type_t *type, + return EINVAL; + } + /* +- * TODO: gperf/re2c this ++ * TODO: gperf/re2c this + */ + if (strcmp(type_str, "string") == 0) { + *type = AVRO_STRING; +@@ -1259,7 +1277,7 @@ avro_schema_from_json_length(const char *jsontext, size_t length, + return avro_schema_from_json_root(root, schema); + } + +-avro_schema_t avro_schema_copy(avro_schema_t schema) ++avro_schema_t avro_schema_copy_root(avro_schema_t schema, st_table *named_schemas) + { + long i; + avro_schema_t new_schema = NULL; +@@ -1276,7 +1294,7 @@ avro_schema_t avro_schema_copy(avro_schema_t schema) + case AVRO_BOOLEAN: + case AVRO_NULL: + /* +- * No need to copy primitives since they're static ++ * No need to copy primitives since they're static + */ + new_schema = schema; + break; +@@ -1288,6 +1306,10 @@ avro_schema_t avro_schema_copy(avro_schema_t schema) + new_schema = + avro_schema_record(record_schema->name, + record_schema->space); ++ if (save_named_schemas(new_schema, named_schemas)) { ++ avro_set_error("Cannot save enum schema"); ++ return NULL; ++ } + for (i = 0; i < record_schema->fields->num_entries; i++) { + union { + st_data_t data; +@@ -1295,10 +1317,11 @@ avro_schema_t avro_schema_copy(avro_schema_t schema) + } val; + st_lookup(record_schema->fields, i, &val.data); + avro_schema_t type_copy = +- avro_schema_copy(val.field->type); ++ avro_schema_copy_root(val.field->type, named_schemas); + avro_schema_record_field_append(new_schema, + val.field->name, + type_copy); ++ avro_schema_decref(type_copy); + } + } + break; +@@ -1309,6 +1332,10 @@ avro_schema_t avro_schema_copy(avro_schema_t schema) + avro_schema_to_enum(schema); + new_schema = avro_schema_enum_ns(enum_schema->name, + enum_schema->space); ++ if (save_named_schemas(new_schema, named_schemas)) { ++ avro_set_error("Cannot save enum schema"); ++ return NULL; ++ } + for (i = 0; i < enum_schema->symbols->num_entries; i++) { + union { + st_data_t data; +@@ -1329,6 +1356,10 @@ avro_schema_t avro_schema_copy(avro_schema_t schema) + avro_schema_fixed_ns(fixed_schema->name, + fixed_schema->space, + fixed_schema->size); ++ if (save_named_schemas(new_schema, named_schemas)) { ++ avro_set_error("Cannot save fixed schema"); ++ return NULL; ++ } + } + break; + +@@ -1337,11 +1368,12 @@ avro_schema_t avro_schema_copy(avro_schema_t schema) + struct avro_map_schema_t *map_schema = + avro_schema_to_map(schema); + avro_schema_t values_copy = +- avro_schema_copy(map_schema->values); ++ avro_schema_copy_root(map_schema->values, named_schemas); + if (!values_copy) { + return NULL; + } + new_schema = avro_schema_map(values_copy); ++ avro_schema_decref(values_copy); + } + break; + +@@ -1350,11 +1382,12 @@ avro_schema_t avro_schema_copy(avro_schema_t schema) + struct avro_array_schema_t *array_schema = + avro_schema_to_array(schema); + avro_schema_t items_copy = +- avro_schema_copy(array_schema->items); ++ avro_schema_copy_root(array_schema->items, named_schemas); + if (!items_copy) { + return NULL; + } + new_schema = avro_schema_array(items_copy); ++ avro_schema_decref(items_copy); + } + break; + +@@ -1372,12 +1405,13 @@ avro_schema_t avro_schema_copy(avro_schema_t schema) + avro_schema_t schema; + } val; + st_lookup(union_schema->branches, i, &val.data); +- schema_copy = avro_schema_copy(val.schema); ++ schema_copy = avro_schema_copy_root(val.schema, named_schemas); + if (avro_schema_union_append + (new_schema, schema_copy)) { + avro_schema_decref(new_schema); + return NULL; + } ++ avro_schema_decref(schema_copy); + } + } + break; +@@ -1386,12 +1420,12 @@ avro_schema_t avro_schema_copy(avro_schema_t schema) + { + struct avro_link_schema_t *link_schema = + avro_schema_to_link(schema); +- /* +- * TODO: use an avro_schema_copy of to instead of pointing to +- * the same reference +- */ +- avro_schema_incref(link_schema->to); +- new_schema = avro_schema_link(link_schema->to); ++ avro_schema_t to; ++ ++ to = find_named_schemas(avro_schema_name(link_schema->to), ++ avro_schema_namespace(link_schema->to), ++ named_schemas); ++ new_schema = avro_schema_link(to); + } + break; + +@@ -1401,6 +1435,23 @@ avro_schema_t avro_schema_copy(avro_schema_t schema) + return new_schema; + } + ++avro_schema_t avro_schema_copy(avro_schema_t schema) ++{ ++ avro_schema_t new_schema; ++ st_table *named_schemas; ++ ++ named_schemas = st_init_strtable_with_size(DEFAULT_TABLE_SIZE); ++ if (!named_schemas) { ++ avro_set_error("Cannot allocate named schema map"); ++ return NULL; ++ } ++ ++ new_schema = avro_schema_copy_root(schema, named_schemas); ++ st_foreach(named_schemas, HASH_FUNCTION_CAST named_schema_free_foreach, 0); ++ st_free_table(named_schemas); ++ return new_schema; ++} ++ + avro_schema_t avro_schema_get_subschema(const avro_schema_t schema, + const char *name) + { +diff --git a/lang/c/tests/CMakeLists.txt b/lang/c/tests/CMakeLists.txt +index 445e689a7..0870ef5ec 100644 +--- a/lang/c/tests/CMakeLists.txt ++++ b/lang/c/tests/CMakeLists.txt +@@ -48,12 +48,14 @@ add_avro_test(test_data_structures) + add_avro_test(test_avro_schema) + add_avro_test(test_avro_schema_names) + add_avro_test(test_avro_values) ++add_avro_test(test_avro_766) + add_avro_test(test_avro_968) + add_avro_test(test_avro_984) + add_avro_test(test_avro_1034) + add_avro_test(test_avro_1084) + add_avro_test(test_avro_1087) + add_avro_test(test_avro_1165) ++add_avro_test(test_avro_1167) + add_avro_test(test_avro_1237) + add_avro_test(test_avro_1238) + add_avro_test(test_avro_1279) +diff --git a/lang/c/tests/test_avro_1167.c b/lang/c/tests/test_avro_1167.c +new file mode 100644 +index 000000000..869b37d17 +--- /dev/null ++++ b/lang/c/tests/test_avro_1167.c +@@ -0,0 +1,84 @@ ++/* ++ * 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 ++#include ++#include ++ ++/* To see the AVRO-1167 memory leak, run this test program through ++ * valgrind. The specific valgrind commandline to use from the ++ * avro-trunk/lang/c/tests directory is: ++ * valgrind -v --track-origins=yes --leak-check=full ++ * --show-reachable = yes ../build/tests/test_avro_1167 ++ */ ++ ++int main(int argc, char **argv) ++{ ++ const char *json = ++ "{" ++ " \"name\": \"repeated_subrecord_array\"," ++ " \"type\": \"record\"," ++ " \"fields\": [" ++ " { \"name\": \"subrecord_one\"," ++ " \"type\": {" ++ " \"name\": \"SubrecordType\"," ++ " \"type\": \"record\"," ++ " \"fields\": [" ++ " { \"name\": \"x\", \"type\": \"int\" }," ++ " { \"name\": \"y\", \"type\": \"int\" }" ++ " ]" ++ " }" ++ " }," ++ " { \"name\": \"subrecord_two\", \"type\": \"SubrecordType\" }," ++ " { \"name\": \"subrecord_array\", \"type\": {" ++ " \"type\":\"array\"," ++ " \"items\": \"SubrecordType\"" ++ " }" ++ " }" ++ " ]" ++ "}"; ++ ++ int rval; ++ avro_schema_t schema = NULL; ++ avro_schema_t schema_copy = NULL; ++ avro_schema_error_t error; ++ ++ (void) argc; ++ (void) argv; ++ ++ rval = avro_schema_from_json(json, strlen(json), &schema, &error); ++ if ( rval ) ++ { ++ printf("Failed to read schema from JSON.\n"); ++ exit(EXIT_FAILURE); ++ } ++ else ++ { ++ printf("Successfully read schema from JSON.\n"); ++ } ++ ++ schema_copy = avro_schema_copy( schema ); ++ if ( ! avro_schema_equal(schema, schema_copy) ) ++ { ++ printf("Failed avro_schema_equal(schema, schema_copy)\n"); ++ exit(EXIT_FAILURE); ++ } ++ ++ avro_schema_decref(schema); ++ avro_schema_decref(schema_copy); ++ return 0; ++} +diff --git a/lang/c/tests/test_avro_766.c b/lang/c/tests/test_avro_766.c +new file mode 100755 +index 000000000..4e21368c4 +--- /dev/null ++++ b/lang/c/tests/test_avro_766.c +@@ -0,0 +1,76 @@ ++/* ++ * 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 ++#include ++#include ++ ++/* To see the AVRO-766 memory leak, run this test program through ++ * valgrind. The specific valgrind commandline to use from the ++ * avro-trunk/lang/c/tests directory is: ++ * valgrind -v --track-origins=yes --leak-check=full ++ * --show-reachable = yes ../build/tests/test_avro_766 ++ */ ++int main(int argc, char **argv) ++{ ++ const char *json = ++ "{" ++ " \"type\": \"record\"," ++ " \"name\": \"list\"," ++ " \"fields\": [" ++ " { \"name\": \"x\", \"type\": \"int\" }," ++ " { \"name\": \"y\", \"type\": \"int\" }," ++ " { \"name\": \"next\", \"type\": [\"null\",\"list\"]}," ++ " { \"name\": \"arraylist\", \"type\": { \"type\":\"array\", \"items\": \"list\" } }" ++ " ]" ++ "}"; ++ ++ int rval; ++ avro_schema_t schema = NULL; ++ avro_schema_error_t error; ++ ++ (void) argc; ++ (void) argv; ++ ++ rval = avro_schema_from_json(json, strlen(json), &schema, &error); ++ if ( rval ) ++ { ++ printf("Failed to read schema from JSON.\n"); ++ exit(EXIT_FAILURE); ++ } ++ else ++ { ++ printf("Successfully read schema from JSON.\n"); ++ } ++ ++#define TEST_AVRO_1167 (1) ++ #if TEST_AVRO_1167 ++ { ++ avro_schema_t schema_copy = NULL; ++ schema_copy = avro_schema_copy( schema ); ++ if ( ! avro_schema_equal(schema, schema_copy) ) ++ { ++ printf("Failed avro_schema_equal(schema, schema_copy)\n"); ++ exit(EXIT_FAILURE); ++ } ++ avro_schema_decref(schema_copy); ++ } ++ #endif ++ ++ avro_schema_decref(schema); ++ return 0; ++} diff --git a/ports/avro-c/avro.patch b/ports/avro-c/avro.patch new file mode 100644 index 00000000000..50c32a6d3c4 --- /dev/null +++ b/ports/avro-c/avro.patch @@ -0,0 +1,349 @@ +diff -ur a/lang/c/CMakeLists.txt b/lang/c/CMakeLists.txt +--- a/lang/c/CMakeLists.txt 2017-04-17 19:56:17.000000000 -0400 ++++ b/lang/c/CMakeLists.txt 2017-11-12 20:03:13.776973800 -0500 +@@ -50,7 +50,7 @@ + else(UNIX) + # Hard code for win32 -- need to figure out how to port version.sh for + # Windows. +- set(LIBAVRO_VERSION "22:0:0") ++ set(LIBAVRO_VERSION "23:0:0") + endif(UNIX) + + +@@ -151,25 +151,24 @@ + message("Disabled snappy codec. libsnappy not found or zlib not found.") + endif (SNAPPY_FOUND AND ZLIB_FOUND) + +-find_package(PkgConfig) +-pkg_check_modules(LZMA liblzma) +-if (LZMA_FOUND) ++find_package(LIBLZMA) ++if (LIBLZMA_FOUND) + set(LZMA_PKG liblzma) + add_definitions(-DLZMA_CODEC) +- include_directories(${LZMA_INCLUDE_DIRS}) +- link_directories(${LZMA_LIBRARY_DIRS}) ++ include_directories(${LIBLZMA_INCLUDE_DIRS}) ++ link_directories(${LIBLZMA_LIBRARY_DIRS}) + message("Enabled lzma codec") +-else (LZMA_FOUND) ++else (LIBLZMA_FOUND) + set(LZMA_PKG "") + set(LZMA_LIBRARIES "") + message("Disabled lzma codec. liblzma not found.") +-endif (LZMA_FOUND) ++endif (LIBLZMA_FOUND) + +-set(CODEC_LIBRARIES ${ZLIB_LIBRARIES} ${LZMA_LIBRARIES} ${SNAPPY_LIBRARIES}) ++set(CODEC_LIBRARIES ${ZLIB_LIBRARIES} ${LIBLZMA_LIBRARIES} ${SNAPPY_LIBRARIES}) + set(CODEC_PKG "@ZLIB_PKG@ @LZMA_PKG@ @SNAPPY_PKG@") + + # Jansson JSON library +-pkg_check_modules(JANSSON jansson>=2.3) ++find_package(JANSSON REQUIRED) + if (JANSSON_FOUND) + set(JANSSON_PKG libjansson) + include_directories(${JANSSON_INCLUDE_DIR}) +diff -ur a/lang/c/examples/quickstop.c b/lang/c/examples/quickstop.c +--- a/lang/c/examples/quickstop.c 2017-04-17 19:56:17.000000000 -0400 ++++ b/lang/c/examples/quickstop.c 2017-11-10 12:40:59.151301400 -0500 +@@ -16,6 +16,7 @@ + */ + + #include ++#include + #include + #include + +@@ -102,7 +103,7 @@ + + if (avro_record_get(person, "ID", &id_datum) == 0) { + avro_int64_get(id_datum, &i64); +- fprintf(stdout, "%"PRId64" | ", i64); ++ fprintf(stdout, "%" PRId64 " | ", i64); + } + if (avro_record_get(person, "First", &first_datum) == 0) { + avro_string_get(first_datum, &p); +diff -ur a/lang/c/src/avro/msinttypes.h b/lang/c/src/avro/msinttypes.h +--- a/lang/c/src/avro/msinttypes.h 2017-04-17 19:56:17.000000000 -0400 ++++ b/lang/c/src/avro/msinttypes.h 2017-11-10 12:37:30.372271300 -0500 +@@ -54,6 +54,9 @@ + + // 7.8 Format conversion of integer types + ++#if (_MSC_VER >= 1900) ++# include ++#else + typedef struct { + intmax_t quot; + intmax_t rem; +@@ -311,5 +314,6 @@ + #define wcstoimax _wcstoi64 + #define wcstoumax _wcstoui64 + ++#endif + + #endif // _MSC_INTTYPES_H_ ] +diff -ur a/lang/c/src/avro/msstdint.h b/lang/c/src/avro/msstdint.h +--- a/lang/c/src/avro/msstdint.h 2017-04-17 19:56:17.000000000 -0400 ++++ b/lang/c/src/avro/msstdint.h 2017-11-10 10:44:14.011482500 -0500 +@@ -42,6 +42,10 @@ + + #include + ++#if (_MSC_VER >= 1900) ++# include ++#else ++ + // For Visual Studio 6 in C++ mode and for many Visual Studio versions when + // compiling for ARM we should wrap include with 'extern "C++" {}' + // or compiler give many errors like this: +@@ -243,5 +247,6 @@ + + #endif // __STDC_CONSTANT_MACROS ] + ++#endif // _MSC_VER < 1900 + + #endif // _MSC_STDINT_H_ ] +diff -ur a/lang/c/src/avro_private.h b/lang/c/src/avro_private.h +--- a/lang/c/src/avro_private.h 2017-04-17 19:56:17.000000000 -0400 ++++ b/lang/c/src/avro_private.h 2017-11-10 10:32:33.414879700 -0500 +@@ -34,7 +34,7 @@ + #endif + + #ifdef _WIN32 +-#define snprintf _snprintf ++ //#define snprintf _snprintf + #endif + + /* Note that AVRO_PLATFORM_IS_BIG_ENDIAN is *always* defined. It is +diff -ur a/lang/c/src/avroappend.c b/lang/c/src/avroappend.c +--- a/lang/c/src/avroappend.c 2017-04-17 19:56:17.000000000 -0400 ++++ b/lang/c/src/avroappend.c 2017-11-10 12:15:14.878275800 -0500 +@@ -20,7 +20,7 @@ + #include + #include + #ifdef _WIN32 +-#include ++#include + #endif + + #include "avro.h" +diff -ur a/lang/c/src/codec.c b/lang/c/src/codec.c +--- a/lang/c/src/codec.c 2017-04-17 19:56:17.000000000 -0400 ++++ b/lang/c/src/codec.c 2017-11-10 11:09:08.033816100 -0500 +@@ -266,7 +266,7 @@ + s->next_in = (Bytef*)data; + s->avail_in = (uInt)len; + +- s->next_out = c->block_data; ++ s->next_out = (Bytef*)c->block_data; + s->avail_out = (uInt)c->block_size; + + s->total_out = 0; +@@ -310,10 +310,10 @@ + + c->used_size = 0; + +- s->next_in = data; ++ s->next_in = (Bytef*)data; + s->avail_in = len; + +- s->next_out = c->block_data; ++ s->next_out = (Bytef*)c->block_data; + s->avail_out = c->block_size; + + s->total_out = 0; +@@ -334,7 +334,7 @@ + if (err == Z_BUF_ERROR) + { + c->block_data = avro_realloc(c->block_data, c->block_size, c->block_size * 2); +- s->next_out = c->block_data + s->total_out; ++ s->next_out = (Bytef*)c->block_data + s->total_out; + s->avail_out += c->block_size; + c->block_size = c->block_size * 2; + } +@@ -437,7 +437,7 @@ + return 1; + } + +- ret = lzma_raw_buffer_encode(filters, NULL, data, len, codec->block_data, &written, codec->block_size); ++ ret = lzma_raw_buffer_encode(filters, NULL, (const uint8_t *)data, len, (uint8_t *)codec->block_data, &written, codec->block_size); + + codec->used_size = written; + +@@ -468,8 +468,8 @@ + + do + { +- ret = lzma_raw_buffer_decode(filters, NULL, data, +- &read_pos, len, codec->block_data, &write_pos, ++ ret = lzma_raw_buffer_decode(filters, NULL, (const uint8_t *)data, ++ &read_pos, len, (uint8_t *)codec->block_data, &write_pos, + codec->block_size); + + codec->used_size = write_pos; +diff -ur a/lang/c/src/schema.c b/lang/c/src/schema.c +--- a/lang/c/src/schema.c 2017-04-17 19:56:17.000000000 -0400 ++++ b/lang/c/src/schema.c 2017-11-10 11:45:45.268458000 -0500 +@@ -74,7 +74,7 @@ + * namespace (as a newly allocated buffer using Avro's allocator). */ + static char *split_namespace_name(const char *fullname, const char **name_out) + { +- char *last_dot = strrchr(fullname, '.'); ++ const char *last_dot = strrchr(fullname, '.'); + if (last_dot == NULL) { + *name_out = fullname; + return NULL; +@@ -742,12 +742,12 @@ + } + + static const char * +-qualify_name(const char *name, const char *namespace) ++qualify_name(const char *name, const char *namespaceX) + { + char *full_name; +- if (namespace != NULL && strchr(name, '.') == NULL) { +- full_name = avro_str_alloc(strlen(name) + strlen(namespace) + 2); +- sprintf(full_name, "%s.%s", namespace, name); ++ if (namespaceX != NULL && strchr(name, '.') == NULL) { ++ full_name = avro_str_alloc(strlen(name) + strlen(namespaceX) + 2); ++ sprintf(full_name, "%s.%s", namespaceX, name); + } else { + full_name = avro_strdup(name); + } +@@ -758,20 +758,20 @@ + save_named_schemas(const avro_schema_t schema, st_table *st) + { + const char *name = avro_schema_name(schema); +- const char *namespace = avro_schema_namespace(schema); +- const char *full_name = qualify_name(name, namespace); ++ const char *namespaceX = avro_schema_namespace(schema); ++ const char *full_name = qualify_name(name, namespaceX); + int rval = st_insert(st, (st_data_t) full_name, (st_data_t) schema); + return rval; + } + + static avro_schema_t +-find_named_schemas(const char *name, const char *namespace, st_table *st) ++find_named_schemas(const char *name, const char *namespaceX, st_table *st) + { + union { + avro_schema_t schema; + st_data_t data; + } val; +- const char *full_name = qualify_name(name, namespace); ++ const char *full_name = qualify_name(name, namespaceX); + int rval = st_lookup(st, (st_data_t) full_name, &(val.data)); + avro_str_free((char *)full_name); + if (rval) { +@@ -784,7 +784,7 @@ + static int + avro_type_from_json_t(json_t *json, avro_type_t *type, + st_table *named_schemas, avro_schema_t *named_type, +- const char *namespace) ++ const char *namespaceX) + { + json_t *json_type; + const char *type_str; +@@ -835,7 +835,7 @@ + *type = AVRO_MAP; + } else if (strcmp(type_str, "fixed") == 0) { + *type = AVRO_FIXED; +- } else if ((*named_type = find_named_schemas(type_str, namespace, named_schemas))) { ++ } else if ((*named_type = find_named_schemas(type_str, namespaceX, named_schemas))) { + *type = AVRO_LINK; + } else { + avro_set_error("Unknown Avro \"type\": %s", type_str); +@@ -930,12 +930,12 @@ + } + + if (strchr(fullname, '.')) { +- char *namespace = split_namespace_name(fullname, &name); +- *schema = avro_schema_record(name, namespace); +- avro_str_free(namespace); ++ char *namespaceX = split_namespace_name(fullname, &name); ++ *schema = avro_schema_record(name, namespaceX); ++ avro_str_free(namespaceX); + } else if (json_is_string(json_namespace)) { +- const char *namespace = json_string_value(json_namespace); +- *schema = avro_schema_record(fullname, namespace); ++ const char *namespaceX = json_string_value(json_namespace); ++ *schema = avro_schema_record(fullname, namespaceX); + } else { + *schema = avro_schema_record(fullname, parent_namespace); + } +@@ -1026,13 +1026,13 @@ + } + + if (strchr(fullname, '.')) { +- char *namespace; +- namespace = split_namespace_name(fullname, &name); +- *schema = avro_schema_enum_ns(name, namespace); +- avro_str_free(namespace); ++ char *namespaceX; ++ namespaceX = split_namespace_name(fullname, &name); ++ *schema = avro_schema_enum_ns(name, namespaceX); ++ avro_str_free(namespaceX); + } else if (json_is_string(json_namespace)) { +- const char *namespace = json_string_value(json_namespace); +- *schema = avro_schema_enum_ns(fullname, namespace); ++ const char *namespaceX = json_string_value(json_namespace); ++ *schema = avro_schema_enum_ns(fullname, namespaceX); + } else { + *schema = avro_schema_enum_ns(fullname, parent_namespace); + } +@@ -1160,13 +1160,13 @@ + fullname = json_string_value(json_name); + + if (strchr(fullname, '.')) { +- char *namespace; +- namespace = split_namespace_name(fullname, &name); +- *schema = avro_schema_fixed_ns(name, namespace, (int64_t) size); +- avro_str_free(namespace); ++ char *namespaceX; ++ namespaceX = split_namespace_name(fullname, &name); ++ *schema = avro_schema_fixed_ns(name, namespaceX, (int64_t) size); ++ avro_str_free(namespaceX); + } else if (json_is_string(json_namespace)) { +- const char *namespace = json_string_value(json_namespace); +- *schema = avro_schema_fixed_ns(fullname, namespace, (int64_t) size); ++ const char *namespaceX = json_string_value(json_namespace); ++ *schema = avro_schema_fixed_ns(fullname, namespaceX, (int64_t) size); + } else { + *schema = avro_schema_fixed_ns(fullname, parent_namespace, (int64_t) size); + } +@@ -1749,9 +1749,9 @@ + { + int rval; + check(rval, avro_write_str(out, "\"")); +- const char *namespace = avro_schema_namespace(link->to); +- if (namespace && nullstrcmp(namespace, parent_namespace)) { +- check(rval, avro_write_str(out, namespace)); ++ const char *namespaceX = avro_schema_namespace(link->to); ++ if (namespaceX && nullstrcmp(namespaceX, parent_namespace)) { ++ check(rval, avro_write_str(out, namespaceX)); + check(rval, avro_write_str(out, ".")); + } + check(rval, avro_write_str(out, avro_schema_name(link->to))); +diff -ur a/lang/c/tests/test_avro_data.c b/lang/c/tests/test_avro_data.c +--- a/lang/c/tests/test_avro_data.c 2017-04-17 19:56:17.000000000 -0400 ++++ b/lang/c/tests/test_avro_data.c 2017-11-10 12:41:29.924190100 -0500 +@@ -112,7 +112,7 @@ + if (size != avro_writer_tell(writer)) { + fprintf(stderr, + "Unable to calculate size %s validate=%d " +- "(%"PRId64" != %"PRId64")\n %s\n", ++ "(%" PRId64 " != %" PRId64 ")\n %s\n", + type, validate, size, avro_writer_tell(writer), + avro_strerror()); + exit(EXIT_FAILURE); +@@ -142,7 +142,7 @@ + { + char *json = NULL; + avro_datum_to_json(datum, 1, &json); +- if (strcasecmp(json, expected) != 0) { ++ if (stricmp(json, expected) != 0) { + fprintf(stderr, "Unexpected JSON encoding: %s\n", json); + exit(EXIT_FAILURE); + } diff --git a/ports/avro-c/portfile.cmake b/ports/avro-c/portfile.cmake new file mode 100644 index 00000000000..94fcf25ba0d --- /dev/null +++ b/ports/avro-c/portfile.cmake @@ -0,0 +1,30 @@ +include(vcpkg_common_functions) + +vcpkg_from_github( + OUT_SOURCE_PATH SOURCE_PATH + REPO apache/avro + REF release-1.8.2 + SHA512 a48cc353aadd45ad2c8593bf89ec3f1ddb0fcd364b79dd002a60a54d49cab714b46eee8bd6dc47b13588b9eead49c754dfe05f6aff735752fca8d2cd35ae8649 + HEAD_REF master +) + +vcpkg_apply_patches( + SOURCE_PATH ${SOURCE_PATH} + PATCHES + ${CMAKE_CURRENT_LIST_DIR}/avro.patch + ${CMAKE_CURRENT_LIST_DIR}/avro-pr-217.patch) + +vcpkg_configure_cmake( + SOURCE_PATH ${SOURCE_PATH}/lang/c +) + +vcpkg_install_cmake(DISABLE_PARALLEL) + +vcpkg_copy_pdbs() + +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/bin) +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/bin) +file(REMOVE_RECURSE ${CURRENT_PACKAGES_DIR}/debug/include) + +file(COPY ${SOURCE_PATH}/lang/c/LICENSE DESTINATION ${CURRENT_PACKAGES_DIR}/share/avro-c) +file(RENAME ${CURRENT_PACKAGES_DIR}/share/avro-c/LICENSE ${CURRENT_PACKAGES_DIR}/share/avro-c/copyright)