@@ -1655,6 +1655,140 @@ public static RubyInteger _comp_year69(ThreadContext context, IRubyObject self,
1655
1655
return y ;
1656
1656
}
1657
1657
1658
+ @ JRubyMethod (name = "s3e" , meta = true , required = 4 , optional = 1 , visibility = Visibility .PRIVATE )
1659
+ public static IRubyObject _s3e (ThreadContext context , IRubyObject self , IRubyObject [] args ) {
1660
+ final IRubyObject nil = context .nil ;
1661
+
1662
+ final RubyHash hash = (RubyHash ) args [0 ];
1663
+ RubyString y = args [1 ] == nil ? null : (RubyString ) args [1 ];
1664
+ RubyString m = args [2 ] == nil ? null : (RubyString ) args [2 ];
1665
+ RubyString d = args [3 ] == nil ? null : (RubyString ) args [3 ];
1666
+ boolean bc = args .length > 4 ? args [4 ].isTrue () : false ;
1667
+
1668
+ Boolean comp = null ; RubyString oy , om , od ;
1669
+
1670
+ if (d == null && y != null && m != null ) {
1671
+ oy = y ; om = m ; od = d ;
1672
+ y = od ; m = oy ; d = om ;
1673
+ }
1674
+
1675
+ if (y == null ) {
1676
+ if (d != null && d .strLength () > 2 ) {
1677
+ y = d ; d = null ;
1678
+ } else if (d != null && strPtr (d , '\'' )) {
1679
+ y = d ; d = null ;
1680
+ }
1681
+ }
1682
+
1683
+
1684
+ if (y != null ) {
1685
+ int s = skipNonDigitsAndSign (y );
1686
+ int bp = s ;
1687
+ char c = s < y .strLength () ? y .charAt (s ) : '\0' ;
1688
+ if (c == '+' || c == '-' ) s ++;
1689
+ int ep = skipDigits (y , s );
1690
+ if (ep != y .strLength ()) {
1691
+ oy = y ; y = d ;
1692
+ d = (RubyString ) oy .substr19 (context .runtime , bp , ep - bp );
1693
+ }
1694
+ }
1695
+
1696
+ if (m != null ) {
1697
+ if (strPtr (m , '\'' ) || m .strLength () > 2 ) {
1698
+ /* us -> be */
1699
+ oy = y ; om = m ; od = d ;
1700
+ y = om ; m = od ; d = oy ;
1701
+ }
1702
+ }
1703
+
1704
+ if (d != null ) {
1705
+ if (strPtr (d , '\'' ) || d .strLength () > 2 ) {
1706
+ oy = y ; od = d ;
1707
+ y = od ; d = oy ;
1708
+ }
1709
+ }
1710
+
1711
+ if (y != null ) {
1712
+ boolean sign = false ;
1713
+
1714
+ int s = skipNonDigitsAndSign (y );
1715
+
1716
+ int bp = s ;
1717
+ char c = s < y .strLength () ? y .charAt (s ) : '\0' ;
1718
+ if (c == '+' || c == '-' ) {
1719
+ s ++; sign = true ;
1720
+ }
1721
+ if (sign ) comp = false ;
1722
+ int ep = skipDigits (y , s );
1723
+ if (ep - s > 2 ) comp = false ;
1724
+
1725
+ RubyInteger iy = cstr2num (context .runtime , y , bp , ep );
1726
+ if (bc ) iy = (RubyInteger ) iy .negate ().op_plus (context , 1 );
1727
+ set_hash (context , hash , "year" , iy );
1728
+ }
1729
+
1730
+ //if (bc) set_hash("_bc", Qtrue);
1731
+
1732
+ if (m != null ) {
1733
+ int s = skipNonDigitsAndSign (m );
1734
+
1735
+ int bp = s ;
1736
+ int ep = skipDigits (m , s );
1737
+ set_hash (context , hash , "mon" , cstr2num (context .runtime , m , bp , ep ));
1738
+ }
1739
+
1740
+ if (d != null ) {
1741
+ int s = skipNonDigitsAndSign (d );
1742
+
1743
+ int bp = s ;
1744
+ int ep = skipDigits (d , s );
1745
+ set_hash (context , hash , "mday" , cstr2num (context .runtime , d , bp , ep ));
1746
+ }
1747
+
1748
+ if (comp != null ) set_hash (context , hash , "_comp" , context .runtime .newBoolean (comp ));
1749
+
1750
+ return hash ;
1751
+ }
1752
+
1753
+ private static void set_hash (final ThreadContext context , RubyHash hash , String key , IRubyObject val ) {
1754
+ hash .fastASet (context .runtime .newSymbol (key ), val );
1755
+ }
1756
+
1757
+ private static RubyInteger cstr2num (Ruby runtime , RubyString str , int bp , int ep ) {
1758
+ if (bp == ep ) return RubyFixnum .zero (runtime );
1759
+ return ConvertBytes .byteListToInum (runtime , str .getByteList (), bp , ep , 10 , true );
1760
+ }
1761
+
1762
+ private static boolean strPtr (RubyString str , char c ) {
1763
+ return str .strLength () > 0 && str .charAt (0 ) == c ;
1764
+ }
1765
+
1766
+ private static boolean isDigit (char c ) {
1767
+ switch (c ) {
1768
+ case '0' : case '1' : case '2' : case '3' : case '4' : return true ;
1769
+ case '5' : case '6' : case '7' : case '8' : case '9' : return true ;
1770
+ default : return false ;
1771
+ }
1772
+ }
1773
+
1774
+ private static int skipNonDigitsAndSign (RubyString str ) {
1775
+ int s = 0 ;
1776
+ while (s < str .length ()) {
1777
+ char c = str .charAt (s );
1778
+ if (isDigit (c ) || (c == '+' || c == '-' )) break ;
1779
+ s ++;
1780
+ }
1781
+ return s ;
1782
+ }
1783
+
1784
+ private static int skipDigits (RubyString str , int off ) {
1785
+ int i = off ;
1786
+ for (; i < str .length (); i ++) {
1787
+ if (!isDigit (str .charAt (i ))) return i ;
1788
+ }
1789
+ return i ;
1790
+ }
1791
+
1658
1792
// Java API
1659
1793
1660
1794
/**
0 commit comments