Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AVRO-2955: Avro-C: Support all Visual Studio versions from 2010 to 2019 #977

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
4d27d37
AVRO-2955: Only VS2010 or before requires /TP. Use C11 for VS2019 or …
kiyolee Nov 7, 2020
3548687
AVRO-2955: Enforcing that VS2010 or before is not supported.
kiyolee Nov 7, 2020
e67b885
AVRO-2955: Conditional compile GCC only features.
kiyolee Nov 7, 2020
64c9d4e
AVRO-2955: Fix missing typedef of ssize_t for MSVC.
kiyolee Nov 7, 2020
77fad80
AVRO-2955: Newer MSVC has its own stdint.h and inttypes.h.
kiyolee Nov 7, 2020
4e322be
AVRO-2955: Do not define snprintf as macro for VS2019 or later.
kiyolee Nov 7, 2020
1198802
AVRO-2955: Fix strrchr() returns const char* in newer MSVC.
kiyolee Nov 7, 2020
0d5a0c3
AVRO-2955: Fix MSVC does not support empty struct.
kiyolee Nov 7, 2020
a05b929
AVRO-2955: Avoid non-Windows headers.
kiyolee Nov 7, 2020
ef57d06
AVRO-2955: Define _CRT_SECURE_NO_WARNINGS to reduce compiler warnings.
kiyolee Nov 7, 2020
e8686ff
AVRO-2955: MSVC offers _stricmp() instead of strcasecmp().
kiyolee Nov 7, 2020
09acf81
AVRO-2955: Fix running tests with ninja.
kiyolee Nov 7, 2020
4bc1b6a
AVRO-2955: Use opendir()/readdir() from "msdirent.h" for Windows.
kiyolee Nov 7, 2020
b1ba0a6
AVRO-2955: Fix file mode.
kiyolee Nov 7, 2020
716d95f
AVRO-2955: VS2013 or before does not support inline keyword.
kiyolee Nov 7, 2020
8467623
AVRO-2955: Fix C++ compliance for VS2010.
kiyolee Nov 7, 2020
3befe68
AVRO-2955: Fix VS2010 support.
kiyolee Nov 7, 2020
5c92a3a
AVRO-2955: Fix z_stream buffer pointer assignment.
kiyolee Nov 12, 2020
a80f0e4
AVRO-2955: Build avromod and avropipe for Windows
kiyolee Feb 2, 2022
e72ef0f
AVRO-2955: Add copyright notice for getopt
kiyolee Feb 3, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions lang/c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,22 @@ if(APPLE)
endif(APPLE)

if(CMAKE_COMPILER_IS_GNUCC)
add_definitions(-W -Wall)
add_compile_options(-W -Wall)
endif(CMAKE_COMPILER_IS_GNUCC)

if (WIN32)
# Compile win32 in C++ to allow declarations after statements
add_definitions(/TP)
endif(WIN32)
if(MSVC)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
if(MSVC_VERSION LESS 1700)
# VS2010 and earlier.
# Compile as C++ to allow declarations after statements. (C11 feature)
add_compile_options(/TP)
elseif(MSVC_VERSION LESS 1920)
# VS2013|VS2015|VS2017
else()
# VS2019 and later.
add_compile_options(/std:c11)
endif(MSVC_VERSION LESS 1700)
endif(MSVC)

# Uncomment to allow missing fields in the resolved-writer
# add_definitions(-DAVRO_ALLOW_MISSING_FIELDS_IN_RESOLVED_WRITER)
Expand Down
51 changes: 51 additions & 0 deletions lang/c/NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,54 @@ Copyright 2010 The Apache Software Foundation
This product includes software developed at
The Apache Software Foundation (https://www.apache.org/).

lang/c/src/getopt/getopt_long.c and lang/c/src/getopt/getopt.h are taken
from The FreeBSD Project and they have the following copyright notice:
/*
* Copyright (c) 2002 Todd C. Miller <[email protected]>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Sponsored in part by the Defense Advanced Research Projects
* Agency (DARPA) and Air Force Research Laboratory, Air Force
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
*/
/*-
* SPDX-License-Identifier: BSD-2-Clause-NetBSD
*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Dieter Baron and Thomas Klausner.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
3 changes: 3 additions & 0 deletions lang/c/README.maintaining_win32.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ Limitations of Windows Build:
statements were removed, that Avro-C would compile under
Microsoft's C compiler also. I have not tried this.

Note: This is referring to a C11 feature which is supported in VS2013
and later.

2. The shared library, i.e. DLL, for avro has not been built. There
are instructions on how to build DLLs using CMake at
https://www.cmake.org/Wiki/BuildingWinDLL
Expand Down
6 changes: 5 additions & 1 deletion lang/c/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ add_executable(quickstop quickstop.c)
target_link_libraries(quickstop avro-static)

if (WIN32)
set(exec_name ${CMAKE_CURRENT_BINARY_DIR}/Debug/quickstop.exe)
if (CMAKE_GENERATOR MATCHES "Ninja")
set(exec_name ${CMAKE_CURRENT_BINARY_DIR}/quickstop.exe)
else(CMAKE_GENERATOR MATCHES "Ninja")
set(exec_name ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/quickstop.exe)
endif(CMAKE_GENERATOR MATCHES "Ninja")
else (WIN32)
set(exec_name ${CMAKE_CURRENT_BINARY_DIR}/quickstop)
endif (WIN32)
Expand Down
11 changes: 8 additions & 3 deletions lang/c/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -138,13 +138,18 @@ add_executable(avroappend avroappend.c)
target_link_libraries(avroappend avro-static)
install(TARGETS avroappend RUNTIME DESTINATION bin)

if (NOT WIN32)
#TODO: Port getopt() to Windows to compile avropipe.c and avromod.c
if(MSVC)
add_executable(avropipe avropipe.c getopt/getopt_long.c)
else(MSVC)
add_executable(avropipe avropipe.c)
endif(MSVC)
target_link_libraries(avropipe avro-static)
install(TARGETS avropipe RUNTIME DESTINATION bin)

if(MSVC)
add_executable(avromod avromod.c getopt/getopt_long.c)
else(MSVC)
add_executable(avromod avromod.c)
endif(MSVC)
target_link_libraries(avromod avro-static)
install(TARGETS avromod RUNTIME DESTINATION bin)
endif(NOT WIN32)
4 changes: 4 additions & 0 deletions lang/c/src/avro/msinttypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]

#if _MSC_VER >= 1700
#include <inttypes.h>
#else
#ifndef _MSC_INTTYPES_H_ // [
#define _MSC_INTTYPES_H_

Expand Down Expand Up @@ -313,3 +316,4 @@ imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)


#endif // _MSC_INTTYPES_H_ ]
#endif
4 changes: 4 additions & 0 deletions lang/c/src/avro/msstdint.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
#error "Use this header only with Microsoft Visual C++ compilers!"
#endif // _MSC_VER ]

#if _MSC_VER >= 1600
#include <stdint.h>
#else
#ifndef _MSC_STDINT_H_ // [
#define _MSC_STDINT_H_

Expand Down Expand Up @@ -245,3 +248,4 @@ typedef uint64_t uintmax_t;


#endif // _MSC_STDINT_H_ ]
#endif
4 changes: 4 additions & 0 deletions lang/c/src/avro/refcount.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
#include <intrin.h>
#endif

#if defined(_MSC_VER) && _MSC_VER < 1900 && !defined(__cplusplus)
#define inline __inline
#endif

#ifdef __cplusplus
extern "C" {
#define CLOSE_EXTERN }
Expand Down
8 changes: 8 additions & 0 deletions lang/c/src/avro_generic_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ extern "C" {
#include "avro/schema.h"
#include "avro/value.h"

#ifdef _MSC_VER
#ifdef _WIN64
typedef __int64 ssize_t;
#else
typedef int ssize_t;
#endif
#endif

/*
* Each generic value implementation struct defines a couple of extra
* methods that we use to control the lifecycle of the value objects.
Expand Down
2 changes: 1 addition & 1 deletion lang/c/src/avro_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ extern "C" {
#include "config.h"
#endif

#ifdef _WIN32
#if defined(_MSC_VER) && _MSC_VER < 1900 && !defined(snprintf)
#define snprintf _snprintf
#endif

Expand Down
2 changes: 1 addition & 1 deletion lang/c/src/avroappend.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef _WIN32
#ifndef _WIN32
#include <unistd.h>
#endif

Expand Down
18 changes: 16 additions & 2 deletions lang/c/src/avromod.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@
*/

#include <errno.h>
#include <getopt.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include "getopt/getopt.h"
#else
#include <getopt.h>
#endif

#include "avro.h"
#include "avro_private.h"
Expand Down Expand Up @@ -130,6 +134,15 @@ int main(int argc, char **argv)
char *in_filename;
char *out_filename;

#ifdef _MSC_VER
{
const char *cp = argv[0] + strlen(argv[0]);
while (cp > argv[0] && *(cp-1) != '/' && *(cp-1) != '\\' && *(cp-1) != ':')
--cp;
opt_progname = cp;
}
#endif

int ch;
while ((ch = getopt_long(argc, argv, "b:c:", longopts, NULL)) != -1) {
switch (ch) {
Expand Down Expand Up @@ -157,7 +170,8 @@ int main(int argc, char **argv)
in_filename = NULL;
out_filename = argv[0];
} else {
fprintf(stderr, "Can't read from multiple input files.\n");
if (argc > 2)
fprintf(stderr, "Can't read from multiple input files.\n");
usage();
exit(1);
}
Expand Down
16 changes: 14 additions & 2 deletions lang/c/src/avropipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,15 @@

#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <avro/platform.h>
#include <avro/platform.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include "getopt/getopt.h"
#else
#include <getopt.h>
#endif

#include "avro.h"
#include "avro_private.h"
Expand Down Expand Up @@ -400,6 +403,15 @@ int main(int argc, char **argv)
{
char *data_filename;

#ifdef _MSC_VER
{
const char *cp = argv[0] + strlen(argv[0]);
while (cp > argv[0] && *(cp-1) != '/' && *(cp-1) != '\\' && *(cp-1) != ':')
--cp;
opt_progname = cp;
}
#endif

int ch;
while ((ch = getopt_long(argc, argv, "s:", longopts, NULL) ) != -1) {
switch (ch) {
Expand Down
2 changes: 1 addition & 1 deletion lang/c/src/codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ static int decode_deflate(avro_codec_t c, void * data, int64_t len)
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;
}
Expand Down
4 changes: 4 additions & 0 deletions lang/c/src/dump.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,13 @@ extern "C" {

#include <stdio.h>

#ifdef __GNUC__
#pragma GCC visibility push(hidden)
#endif
void dump(FILE * out, const char *addr, const long len);
#ifdef __GNUC__
#pragma GCC visibility pop
#endif

CLOSE_EXTERN
#endif
11 changes: 8 additions & 3 deletions lang/c/src/generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -2850,11 +2850,16 @@ typedef struct avro_generic_record_value_iface {
avro_generic_value_iface_t **field_ifaces;
} avro_generic_record_value_iface_t;

#ifdef _MSC_VER
typedef struct avro_generic_record avro_generic_record_t;
#define SIZEOF_avro_generic_record_t 0
#else
typedef struct avro_generic_record {
/* The rest of the struct is taken up by the inline storage
* needed for each field. */
} avro_generic_record_t;

#define SIZEOF_avro_generic_record_t sizeof(avro_generic_record_t)
#endif

/** Return a pointer to the given field within a record struct. */
#define avro_generic_record_field(iface, rec, index) \
Expand Down Expand Up @@ -3123,11 +3128,11 @@ avro_generic_record_class(avro_schema_t schema, memoize_state_t *state)
}
}

size_t next_offset = sizeof(avro_generic_record_t);
size_t next_offset = SIZEOF_avro_generic_record_t;
#if DEBUG_FIELD_OFFSETS
fprintf(stderr, " Record %s\n Header: Offset 0, size %" PRIsz "\n",
avro_schema_type_name(schema),
sizeof(avro_generic_record_t));
SIZEOF_avro_generic_record_t);
#endif
size_t i;
for (i = 0; i < iface->field_count; i++) {
Expand Down
Loading