From 94e9315c2885ae390bdf567de671cc70d637960e Mon Sep 17 00:00:00 2001 From: Lars Kanis Date: Fri, 6 Feb 2015 17:38:23 +0100 Subject: [PATCH] Use fixed size arrays in case the compiler doesn't support C99 variable length arrays. This is notably the MSVC compiler. Note: The MSVC build environment is currently not tested on a regular base, so is not fully supported. --- ext/extconf.rb | 4 ++++ ext/pg.h | 9 +++++++++ ext/pg_result.c | 6 +++--- ext/pg_text_decoder.c | 2 +- ext/pg_type_map_by_mri_type.c | 2 +- 5 files changed, 18 insertions(+), 5 deletions(-) diff --git a/ext/extconf.rb b/ext/extconf.rb index 1556ad082..7e5727ba1 100644 --- a/ext/extconf.rb +++ b/ext/extconf.rb @@ -94,6 +94,10 @@ have_header 'unistd.h' have_header 'ruby/st.h' or have_header 'st.h' or abort "pg currently requires the ruby/st.h header" +checking_for "C99 variable length arrays" do + $defs.push( "-DHAVE_VARIABLE_LENGTH_ARRAYS" ) if try_compile('void test_vla(int l){ int vla[l]; }') +end + create_header() create_makefile( "pg_ext" ) diff --git a/ext/pg.h b/ext/pg.h index 3da36c747..cdbaf93c4 100644 --- a/ext/pg.h +++ b/ext/pg.h @@ -133,6 +133,15 @@ typedef long suseconds_t; #endif +#if defined(HAVE_VARIABLE_LENGTH_ARRAYS) + #define PG_VARIABLE_LENGTH_ARRAY(type, name, len, maxlen) type name[(len)]; +#else + #define PG_VARIABLE_LENGTH_ARRAY(type, name, len, maxlen) \ + type name[(maxlen)] = {(len)>(maxlen) ? (rb_raise(rb_eArgError, "Number of " #name " (%d) exceeds allowed maximum of " #maxlen, (len) ), (type)1) : (type)0}; + + #define PG_MAX_COLUMNS 4000 +#endif + /* The data behind each PG::Connection object */ typedef struct { PGconn *pgconn; diff --git a/ext/pg_result.c b/ext/pg_result.c index 038d13f53..fa5710474 100644 --- a/ext/pg_result.c +++ b/ext/pg_result.c @@ -863,7 +863,7 @@ pgresult_each_row(VALUE self) num_fields = PQnfields(this->pgresult); for ( row = 0; row < num_rows; row++ ) { - VALUE row_values[num_fields]; + PG_VARIABLE_LENGTH_ARRAY(VALUE, row_values, num_fields, PG_MAX_COLUMNS) /* populate the row */ for ( field = 0; field < num_fields; field++ ) { @@ -892,7 +892,7 @@ pgresult_values(VALUE self) VALUE results = rb_ary_new2( num_rows ); for ( row = 0; row < num_rows; row++ ) { - VALUE row_values[num_fields]; + PG_VARIABLE_LENGTH_ARRAY(VALUE, row_values, num_fields, PG_MAX_COLUMNS) /* populate the row */ for ( field = 0; field < num_fields; field++ ) { @@ -1176,7 +1176,7 @@ pgresult_stream_each_row(VALUE self) } for ( row = 0; row < ntuples; row++ ) { - VALUE row_values[nfields]; + PG_VARIABLE_LENGTH_ARRAY(VALUE, row_values, nfields, PG_MAX_COLUMNS) int field; /* populate the row */ diff --git a/ext/pg_text_decoder.c b/ext/pg_text_decoder.c index a69565905..3a3c215ba 100644 --- a/ext/pg_text_decoder.c +++ b/ext/pg_text_decoder.c @@ -314,7 +314,7 @@ pg_text_dec_identifier(t_pg_coder *conv, char *val, int len, int tuple, int fiel int word_index = 0; int index; /* Use a buffer of the same length, as that will be the worst case */ - char word[len + 1]; + PG_VARIABLE_LENGTH_ARRAY(char, word, len + 1, NAMEDATALEN) /* The current character in the input string. */ char c; diff --git a/ext/pg_type_map_by_mri_type.c b/ext/pg_type_map_by_mri_type.c index 3bd0c89f7..69cde00e9 100644 --- a/ext/pg_type_map_by_mri_type.c +++ b/ext/pg_type_map_by_mri_type.c @@ -39,7 +39,7 @@ static VALUE rb_cTypeMapByMriType; typedef struct { t_typemap typemap; struct pg_tmbmt_converter { - FOR_EACH_MRI_TYPE( DECLARE_CODER ); + FOR_EACH_MRI_TYPE( DECLARE_CODER ) } coders; } t_tmbmt;