1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* pack.c (pack_unpack): don't use OFF32 for gcc 4.5.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26753 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
akr 2010-02-24 15:32:06 +00:00
parent 7e5f20c842
commit e53e5edab2
3 changed files with 257 additions and 130 deletions

View file

@ -1,3 +1,7 @@
Thu Feb 25 00:29:55 2010 Tanaka Akira <akr@fsij.org>
* pack.c (pack_unpack): don't use OFF32 for gcc 4.5.
Wed Feb 24 22:39:15 2010 Tanaka Akira <akr@fsij.org>
* lib/resolv.rb: fix [ruby-core:28320] reported by Paul Clegg.

381
pack.c
View file

@ -22,6 +22,12 @@
# define NATINT_PACK
#endif
#ifdef WORDS_BIGENDIAN
# define BIGENDIAN_P 1
#else
# define BIGENDIAN_P 0
#endif
#ifdef NATINT_PACK
# define OFF16B(p) ((char*)(p) + (natint?0:(sizeof(short) - SIZE16)))
# define OFF32B(p) ((char*)(p) + (natint?0:(sizeof(long) - SIZE32)))
@ -76,18 +82,6 @@ TOKEN_PASTE(swap,x)(xtype z) \
#ifndef swap16
#define swap16(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
#endif
#if SIZEOF_SHORT == 2
#define swaps(x) swap16(x)
#else
#if SIZEOF_SHORT == 4
#define swaps(x) ((((x)&0xFF)<<24) \
|(((x)>>24)&0xFF) \
|(((x)&0x0000FF00)<<8) \
|(((x)&0x00FF0000)>>8) )
#else
define_swapx(s,short)
#endif
#endif
#ifndef swap32
#define swap32(x) ((((x)&0xFF)<<24) \
@ -95,23 +89,73 @@ define_swapx(s,short)
|(((x)&0x0000FF00)<<8) \
|(((x)&0x00FF0000)>>8) )
#endif
#ifndef swap64
#if SIZEOF_LONG == 8
#define swap64(x) ((((x)&0x00000000000000FFL)<<56) \
|(((x)&0xFF00000000000000L)>>56) \
|(((x)&0x000000000000FF00L)<<40) \
|(((x)&0x00FF000000000000L)>>40) \
|(((x)&0x0000000000FF0000L)<<24) \
|(((x)&0x0000FF0000000000L)>>24) \
|(((x)&0x00000000FF000000L)<<8) \
|(((x)&0x000000FF00000000L)>>8))
#endif
#if defined(HAVE_LONG_LONG) && SIZEOF_LONG_LONG == 8
#define swap64(x) ((((x)&0x00000000000000FFLL)<<56) \
|(((x)&0xFF00000000000000LL)>>56) \
|(((x)&0x000000000000FF00LL)<<40) \
|(((x)&0x00FF000000000000LL)>>40) \
|(((x)&0x0000000000FF0000LL)<<24) \
|(((x)&0x0000FF0000000000LL)>>24) \
|(((x)&0x00000000FF000000LL)<<8) \
|(((x)&0x000000FF00000000LL)>>8))
#endif
#endif
#if SIZEOF_SHORT == 2
#define swaps(x) swap16(x)
#else
#if SIZEOF_SHORT == 4
#define swaps(x) swap32(x)
#else
define_swapx(s,short)
#endif
#endif
#if SIZEOF_INT == 2
#define swapi(x) swap16(x)
#else
#if SIZEOF_INT == 4
#define swapi(x) swap32(x)
#else
define_swapx(i,int)
#endif
#endif
#if SIZEOF_LONG == 4
#define swapl(x) swap32(x)
#else
#if SIZEOF_LONG == 8
#define swapl(x) ((((x)&0x00000000000000FF)<<56) \
|(((x)&0xFF00000000000000)>>56) \
|(((x)&0x000000000000FF00)<<40) \
|(((x)&0x00FF000000000000)>>40) \
|(((x)&0x0000000000FF0000)<<24) \
|(((x)&0x0000FF0000000000)>>24) \
|(((x)&0x00000000FF000000)<<8) \
|(((x)&0x000000FF00000000)>>8))
#define swapl(x) swap64(x)
#else
define_swapx(l,long)
#endif
#endif
#ifdef HAVE_LONG_LONG
#if SIZEOF_LONG_LONG == 4
#define swapll(x) swap32(x)
#else
#if SIZEOF_LONG_LONG == 8
#define swapll(x) swap64(x)
#else
define_swapx(ll,LONG_LONG)
#endif
#endif
#endif
#if SIZEOF_FLOAT == 4
#if SIZEOF_LONG == 4 /* SIZEOF_FLOAT == 4 == SIZEOF_LONG */
#define swapf(x) swapl(x)
@ -357,7 +401,7 @@ num2i32(VALUE x)
#endif
#ifdef HAVE_LONG_LONG
# define QUAD_SIZE sizeof(LONG_LONG)
# define QUAD_SIZE SIZEOF_LONG_LONG
#else
# define QUAD_SIZE 8
#endif
@ -1345,6 +1389,7 @@ pack_unpack(VALUE str, VALUE fmt)
int natint; /* native integer */
#endif
int block_p = rb_block_given_p();
int signed_p, integer_size, bigendian_p;
#define UNPACK_PUSH(item) do {\
VALUE item_val = (item);\
if (block_p) {\
@ -1550,136 +1595,214 @@ pack_unpack(VALUE str, VALUE fmt)
break;
case 's':
PACK_LENGTH_ADJUST(short,2);
while (len-- > 0) {
short tmp = 0;
memcpy(OFF16(&tmp), s, NATINT_LEN(short,2));
EXTEND16(tmp);
s += NATINT_LEN(short,2);
UNPACK_PUSH(INT2FIX(tmp));
}
PACK_ITEM_ADJUST();
break;
signed_p = 1;
integer_size = NATINT_LEN(short, 2);
bigendian_p = BIGENDIAN_P;
goto unpack_integer;
case 'S':
PACK_LENGTH_ADJUST(unsigned short,2);
while (len-- > 0) {
unsigned short tmp = 0;
memcpy(OFF16(&tmp), s, NATINT_LEN(unsigned short,2));
s += NATINT_LEN(unsigned short,2);
UNPACK_PUSH(INT2FIX(tmp));
}
PACK_ITEM_ADJUST();
break;
signed_p = 0;
integer_size = NATINT_LEN(short, 2);
bigendian_p = BIGENDIAN_P;
goto unpack_integer;
case 'i':
PACK_LENGTH_ADJUST(int,sizeof(int));
while (len-- > 0) {
int tmp;
memcpy(&tmp, s, sizeof(int));
s += sizeof(int);
UNPACK_PUSH(INT2NUM(tmp));
}
PACK_ITEM_ADJUST();
break;
signed_p = 1;
integer_size = sizeof(int);
bigendian_p = BIGENDIAN_P;
goto unpack_integer;
case 'I':
PACK_LENGTH_ADJUST(unsigned int,sizeof(unsigned int));
while (len-- > 0) {
unsigned int tmp;
memcpy(&tmp, s, sizeof(unsigned int));
s += sizeof(unsigned int);
UNPACK_PUSH(UINT2NUM(tmp));
}
PACK_ITEM_ADJUST();
break;
signed_p = 0;
integer_size = sizeof(int);
bigendian_p = BIGENDIAN_P;
goto unpack_integer;
case 'l':
PACK_LENGTH_ADJUST(long,4);
while (len-- > 0) {
long tmp = 0;
memcpy(OFF32(&tmp), s, NATINT_LEN(long,4));
EXTEND32(tmp);
s += NATINT_LEN(long,4);
UNPACK_PUSH(LONG2NUM(tmp));
}
PACK_ITEM_ADJUST();
break;
signed_p = 1;
integer_size = NATINT_LEN(long, 4);
bigendian_p = BIGENDIAN_P;
goto unpack_integer;
case 'L':
PACK_LENGTH_ADJUST(unsigned long,4);
while (len-- > 0) {
unsigned long tmp = 0;
memcpy(OFF32(&tmp), s, NATINT_LEN(unsigned long,4));
s += NATINT_LEN(unsigned long,4);
UNPACK_PUSH(ULONG2NUM(tmp));
}
PACK_ITEM_ADJUST();
break;
signed_p = 0;
integer_size = NATINT_LEN(long, 4);
bigendian_p = BIGENDIAN_P;
goto unpack_integer;
case 'q':
PACK_LENGTH_ADJUST_SIZE(QUAD_SIZE);
while (len-- > 0) {
char *tmp = (char*)s;
s += QUAD_SIZE;
UNPACK_PUSH(rb_quad_unpack(tmp, 1));
}
PACK_ITEM_ADJUST();
break;
signed_p = 1;
integer_size = QUAD_SIZE;
bigendian_p = BIGENDIAN_P;
goto unpack_integer;
case 'Q':
PACK_LENGTH_ADJUST_SIZE(QUAD_SIZE);
while (len-- > 0) {
char *tmp = (char*)s;
s += QUAD_SIZE;
UNPACK_PUSH(rb_quad_unpack(tmp, 0));
}
PACK_ITEM_ADJUST();
break;
signed_p = 0;
integer_size = QUAD_SIZE;
bigendian_p = BIGENDIAN_P;
goto unpack_integer;
case 'n':
PACK_LENGTH_ADJUST(unsigned short,2);
while (len-- > 0) {
unsigned short tmp = 0;
memcpy(OFF16B(&tmp), s, NATINT_LEN(unsigned short,2));
s += NATINT_LEN(unsigned short,2);
UNPACK_PUSH(UINT2NUM(ntohs(tmp)));
}
PACK_ITEM_ADJUST();
break;
signed_p = 0;
integer_size = 2;
bigendian_p = 1;
goto unpack_integer;
case 'N':
PACK_LENGTH_ADJUST(unsigned long,4);
while (len-- > 0) {
unsigned long tmp = 0;
memcpy(OFF32B(&tmp), s, NATINT_LEN(unsigned long,4));
s += NATINT_LEN(unsigned long,4);
UNPACK_PUSH(ULONG2NUM(ntohl(tmp)));
}
PACK_ITEM_ADJUST();
break;
signed_p = 0;
integer_size = 4;
bigendian_p = 1;
goto unpack_integer;
case 'v':
PACK_LENGTH_ADJUST(unsigned short,2);
while (len-- > 0) {
unsigned short tmp = 0;
memcpy(&tmp, s, NATINT_LEN(unsigned short,2));
s += NATINT_LEN(unsigned short,2);
UNPACK_PUSH(UINT2NUM(vtohs(tmp)));
}
PACK_ITEM_ADJUST();
break;
signed_p = 0;
integer_size = 2;
bigendian_p = 0;
goto unpack_integer;
case 'V':
PACK_LENGTH_ADJUST(unsigned long,4);
while (len-- > 0) {
unsigned long tmp = 0;
memcpy(&tmp, s, NATINT_LEN(long,4));
s += NATINT_LEN(long,4);
UNPACK_PUSH(ULONG2NUM(vtohl(tmp)));
signed_p = 0;
integer_size = 4;
bigendian_p = 0;
goto unpack_integer;
unpack_integer:
switch (integer_size) {
case SIZEOF_SHORT:
if (signed_p) {
PACK_LENGTH_ADJUST(short,sizeof(short));
while (len-- > 0) {
short tmp;
memcpy(&tmp, s, sizeof(short));
if (bigendian_p ^ BIGENDIAN_P) tmp = swaps(tmp);
s += sizeof(short);
UNPACK_PUSH(INT2FIX(tmp));
}
PACK_ITEM_ADJUST();
}
else {
PACK_LENGTH_ADJUST(unsigned short,sizeof(unsigned short));
while (len-- > 0) {
unsigned short tmp;
memcpy(&tmp, s, sizeof(unsigned short));
if (bigendian_p ^ BIGENDIAN_P) tmp = swaps(tmp);
s += sizeof(unsigned short);
UNPACK_PUSH(INT2FIX(tmp));
}
PACK_ITEM_ADJUST();
}
break;
#if SIZEOF_SHORT != SIZEOF_INT
case SIZEOF_INT:
if (signed_p) {
PACK_LENGTH_ADJUST(int,sizeof(int));
while (len-- > 0) {
int tmp;
memcpy(&tmp, s, sizeof(int));
if (bigendian_p ^ BIGENDIAN_P) tmp = swapi(tmp);
s += sizeof(int);
UNPACK_PUSH(INT2NUM(tmp));
}
PACK_ITEM_ADJUST();
}
else {
PACK_LENGTH_ADJUST(unsigned int,sizeof(unsigned int));
while (len-- > 0) {
unsigned int tmp;
memcpy(&tmp, s, sizeof(unsigned int));
if (bigendian_p ^ BIGENDIAN_P) tmp = swapi(tmp);
s += sizeof(unsigned int);
UNPACK_PUSH(UINT2NUM(tmp));
}
PACK_ITEM_ADJUST();
}
break;
#endif
#if SIZEOF_INT != SIZEOF_LONG
case SIZEOF_LONG:
if (signed_p) {
PACK_LENGTH_ADJUST(long,sizeof(long));
while (len-- > 0) {
long tmp;
memcpy(&tmp, s, sizeof(long));
if (bigendian_p ^ BIGENDIAN_P) tmp = swapl(tmp);
s += sizeof(long);
UNPACK_PUSH(LONG2NUM(tmp));
}
PACK_ITEM_ADJUST();
}
else {
PACK_LENGTH_ADJUST(unsigned long,sizeof(unsigned long));
while (len-- > 0) {
unsigned long tmp;
memcpy(&tmp, s, sizeof(unsigned long));
if (bigendian_p ^ BIGENDIAN_P) tmp = swapl(tmp);
s += sizeof(unsigned long);
UNPACK_PUSH(ULONG2NUM(tmp));
}
PACK_ITEM_ADJUST();
}
break;
#endif
#if defined(HAVE_LONG_LONG) && SIZEOF_LONG != SIZEOF_LONG_LONG
case SIZEOF_LONG_LONG:
if (signed_p) {
PACK_LENGTH_ADJUST(LONG_LONG,sizeof(LONG_LONG));
while (len-- > 0) {
LONG_LONG tmp;
memcpy(&tmp, s, sizeof(LONG_LONG));
if (bigendian_p ^ BIGENDIAN_P) tmp = swapll(tmp);
s += sizeof(LONG_LONG);
UNPACK_PUSH(LL2NUM(tmp));
}
PACK_ITEM_ADJUST();
}
else {
PACK_LENGTH_ADJUST(unsigned LONG_LONG,sizeof(unsigned LONG_LONG));
while (len-- > 0) {
unsigned LONG_LONG tmp;
memcpy(&tmp, s, sizeof(unsigned LONG_LONG));
if (bigendian_p ^ BIGENDIAN_P) tmp = swapll(tmp);
s += sizeof(unsigned LONG_LONG);
UNPACK_PUSH(ULL2NUM(tmp));
}
PACK_ITEM_ADJUST();
}
break;
#endif
#if SIZEOF_LONG != QUAD_SIZE && (!defined(HAVE_LONG_LONG) || SIZEOF_LONG_LONG != QUAD_SIZE)
case QUAD_SIZE:
if (bigendian_p ^ BIGENDIAN_P)
rb_bug("unexpected endian");
if (signed_p) {
PACK_LENGTH_ADJUST_SIZE(QUAD_SIZE);
while (len-- > 0) {
char *tmp = (char*)s;
s += QUAD_SIZE;
UNPACK_PUSH(rb_quad_unpack(tmp, 1));
}
PACK_ITEM_ADJUST();
}
else {
PACK_LENGTH_ADJUST_SIZE(QUAD_SIZE);
while (len-- > 0) {
char *tmp = (char*)s;
s += QUAD_SIZE;
UNPACK_PUSH(rb_quad_unpack(tmp, 0));
}
PACK_ITEM_ADJUST();
}
break;
#endif
default:
rb_bug("unexpected intger size");
}
PACK_ITEM_ADJUST();
break;
case 'f':
case 'F':

View file

@ -493,7 +493,7 @@ class TestPack < Test::Unit::TestCase
end
def test_short_string
%w[n N v V s S l L q Q].each {|fmt|
%w[n N v V s S i I l L q Q s! S! i! I! l! l!].each {|fmt|
str = [1].pack(fmt)
assert_equal([1,nil], str.unpack("#{fmt}2"))
}