[前][次][番号順一覧][スレッド一覧]

ruby-changes:28015

From: akr <ko1@a...>
Date: Tue, 2 Apr 2013 20:29:07 +0900 (JST)
Subject: [ruby-changes:28015] akr:r40067 (trunk): * pack.c: Support Q! and q! for long long.

akr	2013-04-02 20:28:57 +0900 (Tue, 02 Apr 2013)

  New Revision: 40067

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=40067

  Log:
    * pack.c: Support Q! and q! for long long.
      (natstr): Moved to toplevel.  Add q and Q if there is long long type.
      (endstr): Moved to toplevel.
      (NATINT_PACK): Consider long long.
      (NATINT_LEN_Q): New macro.
      (pack_pack): Support Q! and q!.
      (pack_unpack): Ditto.

  Modified files:
    trunk/ChangeLog
    trunk/NEWS
    trunk/pack.c
    trunk/test/ruby/test_pack.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 40066)
+++ ChangeLog	(revision 40067)
@@ -1,3 +1,13 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Apr  2 20:24:52 2013  Tanaka Akira  <akr@f...>
+
+	* pack.c: Support Q! and q! for long long.
+	  (natstr): Moved to toplevel.  Add q and Q if there is long long type.
+	  (endstr): Moved to toplevel.
+	  (NATINT_PACK): Consider long long.
+	  (NATINT_LEN_Q): New macro.
+	  (pack_pack): Support Q! and q!.
+	  (pack_unpack): Ditto.
+
 Tue Apr  2 19:24:26 2013  Tanaka Akira  <akr@f...>
 
 	* ext/-test-/num2int/num2int.c: Define utility methods
Index: pack.c
===================================================================
--- pack.c	(revision 40066)
+++ pack.c	(revision 40067)
@@ -20,7 +20,23 @@ https://github.com/ruby/ruby/blob/trunk/pack.c#L20
    ((__GNUC__ > (major)) ||  \
     (__GNUC__ == (major) && __GNUC_MINOR__ > (minor)) || \
     (__GNUC__ == (major) && __GNUC_MINOR__ == (minor) && __GNUC_PATCHLEVEL__ >= (patchlevel))))
-#if SIZEOF_SHORT != 2 || SIZEOF_LONG != 4
+
+/*
+ * It is intentional that the condition for natstr is HAVE_LONG_LONG
+ * instead of LONG_LONG.
+ * This means q! and Q! means always the standard long long type and
+ * causes ArgumentError for platforms which has no long long type,
+ * even if the platform has an implementation specific 64bit type.
+ * This behavior is consistent with the document of pack/unpack.
+ */
+#ifdef HAVE_LONG_LONG
+static const char natstr[] = "sSiIlLqQ";
+#else
+static const char natstr[] = "sSiIlL";
+#endif
+static const char endstr[] = "sSiIlLqQ";
+
+#if SIZEOF_SHORT != 2 || SIZEOF_LONG != 4 || (defined(HAVE_LONG_LONG) && SIZEOF_LONG_LONG != 8)
 # define NATINT_PACK
 #endif
 
@@ -52,6 +68,12 @@ https://github.com/ruby/ruby/blob/trunk/pack.c#L68
 # define NATINT_LEN(type,len) ((int)sizeof(type))
 #endif
 
+#ifdef HAVE_LONG_LONG
+# define NATINT_LEN_Q NATINT_LEN(long long, 8)
+#else
+# define NATINT_LEN_Q 8
+#endif
+
 #if SIZEOF_LONG == 8
 # define INT64toNUM(x) LONG2NUM(x)
 # define UINT64toNUM(x) ULONG2NUM(x)
@@ -303,24 +325,30 @@ static unsigned long utf8_to_uv(const ch https://github.com/ruby/ruby/blob/trunk/pack.c#L325
  *      S_, S!    | Integer | unsigned short, native endian
  *      I, I_, I! | Integer | unsigned int, native endian
  *      L_, L!    | Integer | unsigned long, native endian
+ *      Q_, Q!    | Integer | unsigned long long, native endian (ArgumentError
+ *                |         | if the platform has no long long type.)
+ *                |         | (Q_ and Q! is available since Ruby 2.1.)
  *                |         |
  *      s_, s!    | Integer | signed short, native endian
  *      i, i_, i! | Integer | signed int, native endian
  *      l_, l!    | Integer | signed long, native endian
+ *      q_, q!    | Integer | signed long long, native endian (ArgumentError
+ *                |         | if the platform has no long long type.)
+ *                |         | (q_ and q! is available since Ruby 2.1.)
  *                |         |
  *      S> L> Q>  | Integer | same as the directives without ">" except
  *      s> l> q>  |         | big endian
  *      S!> I!>   |         | (available since Ruby 1.9.3)
- *      L!>       |         | "S>" is same as "n"
+ *      L!> Q!>   |         | "S>" is same as "n"
  *      s!> i!>   |         | "L>" is same as "N"
- *      l!>       |         |
+ *      l!> q!>   |         |
  *                |         |
  *      S< L< Q<  | Integer | same as the directives without "<" except
  *      s< l< q<  |         | little endian
  *      S!< I!<   |         | (available since Ruby 1.9.3)
- *      L!<       |         | "S<" is same as "v"
+ *      L!< Q!<   |         | "S<" is same as "v"
  *      s!< i!<   |         | "L<" is same as "V"
- *      l!<       |         |
+ *      l!< q!<   |         |
  *                |         |
  *      n         | Integer | 16-bit unsigned, network (big-endian) byte order
  *      N         | Integer | 32-bit unsigned, network (big-endian) byte order
@@ -412,9 +440,6 @@ pack_pack(VALUE ary, VALUE fmt) https://github.com/ruby/ruby/blob/trunk/pack.c#L440
 	}
 
 	{
-	    static const char natstr[] = "sSiIlL";
-	    static const char endstr[] = "sSiIlLqQ";
-
           modifiers:
 	    switch (*p) {
 	      case '_':
@@ -680,13 +705,13 @@ pack_pack(VALUE ary, VALUE fmt) https://github.com/ruby/ruby/blob/trunk/pack.c#L705
             bigendian_p = BIGENDIAN_P();
             goto pack_integer;
 
-	  case 'q':		/* signed quad (64bit) int */
-	    integer_size = 8;
+	  case 'q':		/* signed long long or int64_t */
+	    integer_size = NATINT_LEN_Q;
             bigendian_p = BIGENDIAN_P();
             goto pack_integer;
 
-	  case 'Q':		/* unsigned quad (64bit) int */
-	    integer_size = 8;
+	  case 'Q':		/* unsigned long long or uint64_t */
+	    integer_size = NATINT_LEN_Q;
             bigendian_p = BIGENDIAN_P();
             goto pack_integer;
 
@@ -1249,10 +1274,16 @@ infected_str_new(const char *ptr, long l https://github.com/ruby/ruby/blob/trunk/pack.c#L1274
  *      S_, S!    | Integer | unsigned short, native endian
  *      I, I_, I! | Integer | unsigned int, native endian
  *      L_, L!    | Integer | unsigned long, native endian
+ *      Q_, Q!    | Integer | unsigned long long, native endian (ArgumentError
+ *                |         | if the platform has no long long type.)
+ *                |         | (Q_ and Q! is available since Ruby 2.1.)
  *                |         |
  *      s_, s!    | Integer | signed short, native endian
  *      i, i_, i! | Integer | signed int, native endian
  *      l_, l!    | Integer | signed long, native endian
+ *      q_, q!    | Integer | signed long long, native endian (ArgumentError
+ *                |         | if the platform has no long long type.)
+ *                |         | (q_ and q! is available since Ruby 2.1.)
  *                |         |
  *      S> L> Q>  | Integer | same as the directives without ">" except
  *      s> l> q>  |         | big endian
@@ -1361,9 +1392,6 @@ pack_unpack(VALUE str, VALUE fmt) https://github.com/ruby/ruby/blob/trunk/pack.c#L1392
 
 	star = 0;
 	{
-	    static const char natstr[] = "sSiIlL";
-	    static const char endstr[] = "sSiIlLqQ";
-
           modifiers:
 	    switch (*p) {
 	      case '_':
@@ -1590,13 +1618,13 @@ pack_unpack(VALUE str, VALUE fmt) https://github.com/ruby/ruby/blob/trunk/pack.c#L1618
 
 	  case 'q':
 	    signed_p = 1;
-	    integer_size = 8;
+	    integer_size = NATINT_LEN_Q;
 	    bigendian_p = BIGENDIAN_P();
 	    goto unpack_integer;
 
 	  case 'Q':
 	    signed_p = 0;
-	    integer_size = 8;
+	    integer_size = NATINT_LEN_Q;
 	    bigendian_p = BIGENDIAN_P();
 	    goto unpack_integer;
 
Index: NEWS
===================================================================
--- NEWS	(revision 40066)
+++ NEWS	(revision 40067)
@@ -22,6 +22,9 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L22
   * misc
     * Mutex#owned? is no longer experimental.
 
+* pack/unpack (Array/String)
+  * Q! and q! directives for long long type if platform has the type. 
+
 === Core classes compatibility issues (excluding feature bug fixes)
 
 * Module#ancestors
Index: test/ruby/test_pack.rb
===================================================================
--- test/ruby/test_pack.rb	(revision 40066)
+++ test/ruby/test_pack.rb	(revision 40067)
@@ -403,8 +403,15 @@ class TestPack < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_pack.rb#L403
     assert_equal([578437695752307201, -506097522914230529], s2.unpack("q*"))
     assert_equal([578437695752307201, 17940646550795321087], s1.unpack("Q*"))
 
+    s1 = [578437695752307201, -506097522914230529].pack("q!*")
+    s2 = [578437695752307201, 17940646550795321087].pack("Q!*")
+    assert_equal([578437695752307201, -506097522914230529], s2.unpack("q!*"))
+    assert_equal([578437695752307201, 17940646550795321087], s1.unpack("Q!*"))
+
     assert_equal(8, [1].pack("q").bytesize)
     assert_equal(8, [1].pack("Q").bytesize)
+    assert_operator(8, :<=, [1].pack("q!").bytesize)
+    assert_operator(8, :<=, [1].pack("Q!").bytesize)
   end
 
   def test_pack_unpack_nN

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]