replace deprecated API's.

This commit is contained in:
James Roseborough
2007-11-05 19:12:01 +00:00
parent c93301506a
commit cce33612ce
4 changed files with 159 additions and 77 deletions

View File

@@ -2,8 +2,6 @@ package lua.addon.luacompat;
import lua.VM; import lua.VM;
import lua.value.LFunction; import lua.value.LFunction;
import lua.value.LInteger;
import lua.value.LNil;
import lua.value.LNumber; import lua.value.LNumber;
import lua.value.LString; import lua.value.LString;
import lua.value.LTable; import lua.value.LTable;
@@ -22,12 +20,12 @@ public class StrLib {
* @param vm the calling vm * @param vm the calling vm
*/ */
static void byte_( VM vm ) { static void byte_( VM vm ) {
LString ls = vm.getArgAsLuaString(0); LString ls = vm.tolstring(2);
int l = ls.length(); int l = ls.length();
final int nargs = vm.getArgCount(); final int top = vm.gettop();
int i = posrelat( ( nargs > 1 ) ? vm.getArgAsInt(1) : 1, l ); int i = posrelat( ( top >= 3 ) ? vm.tointeger(3) : 1, l );
int j = posrelat( ( nargs > 2 ) ? vm.getArgAsInt(2) : i, l ); int j = posrelat( ( top >= 4 ) ? vm.tointeger(4) : i, l );
vm.setResult(); vm.settop(0);
if ( i <= 0 ) if ( i <= 0 )
i = 1; i = 1;
if ( j > l ) if ( j > l )
@@ -36,7 +34,7 @@ public class StrLib {
return; return;
int n = j - i + 1; int n = j - i + 1;
for ( int k=0; k < n; k++ ) for ( int k=0; k < n; k++ )
vm.push( LInteger.valueOf( ls.luaByte(k+i-1) ) ); vm.pushinteger( ls.luaByte(k+i-1) );
} }
/** /**
@@ -51,11 +49,12 @@ public class StrLib {
* @param vm the calling VM * @param vm the calling VM
*/ */
public static void char_( VM vm) { public static void char_( VM vm) {
int nargs = vm.getArgCount(); int nargs = vm.gettop()-1;
byte[] bytes = new byte[nargs]; byte[] bytes = new byte[nargs];
for ( int i=0; i<nargs; i++ ) for ( int i=0; i<nargs; i++ )
bytes[i] = (byte)( vm.getArgAsInt(i) & 0x0FF ); bytes[i] = (byte)( vm.tointeger(i+2) & 0x0FF );
vm.setResult( new LString( bytes ) ); vm.settop(0);
vm.pushlstring( bytes );
} }
/** /**
@@ -115,7 +114,8 @@ public class StrLib {
* except as arguments to the q option. * except as arguments to the q option.
*/ */
static void format( VM vm ) { static void format( VM vm ) {
vm.setResult( new LString("") ); vm.settop(0);
vm.pushstring( "" );
} }
/** /**
@@ -143,7 +143,8 @@ public class StrLib {
* as this would prevent the iteration. * as this would prevent the iteration.
*/ */
static void gmatch( VM vm ) { static void gmatch( VM vm ) {
vm.setResult( new GMatchAux(vm) ); vm.settop(0);
vm.pushlvalue( new GMatchAux(vm) );
} }
static class GMatchAux extends LFunction { static class GMatchAux extends LFunction {
@@ -152,14 +153,14 @@ public class StrLib {
private final MatchState ms; private final MatchState ms;
private int soffset; private int soffset;
public GMatchAux(VM vm) { public GMatchAux(VM vm) {
this.src = vm.getArgAsLuaString(0); this.src = vm.tolstring(2);
this.pat = vm.getArgAsLuaString(1); this.pat = vm.tolstring(3);
this.srclen = src.length(); this.srclen = src.length();
this.ms = new MatchState(vm, src, pat); this.ms = new MatchState(vm, src, pat);
this.soffset = 0; this.soffset = 0;
} }
public boolean luaStackCall(VM vm) { public boolean luaStackCall(VM vm) {
vm.setResult(); vm.settop(0);
for ( ; soffset<srclen; soffset++ ) { for ( ; soffset<srclen; soffset++ ) {
int res = ms.match(soffset, 0); int res = ms.match(soffset, 0);
if ( res >=0 ) { if ( res >=0 ) {
@@ -169,7 +170,7 @@ public class StrLib {
return false; return false;
} }
} }
vm.push( LNil.NIL ); vm.pushnil();
return false; return false;
} }
} }
@@ -221,11 +222,11 @@ public class StrLib {
* --> x="lua-5.1.tar.gz" * --> x="lua-5.1.tar.gz"
*/ */
static void gsub( VM vm ) { static void gsub( VM vm ) {
LString src = vm.getArgAsLuaString( 0 ); LString src = vm.tolstring(2);
final int srclen = src.length(); final int srclen = src.length();
LString p = vm.getArgAsLuaString( 1 ); LString p = vm.tolstring(3);
LValue repl = vm.getArg( 2 ); LValue repl = vm.topointer( 4 );
int max_s = ( vm.getArgCount() > 3 ? vm.getArgAsInt( 3 ) : srclen + 1 ); int max_s = ( vm.gettop() >= 5 ? vm.tointeger( 5 ) : srclen + 1 );
final boolean anchor = p.length() > 0 && p.charAt( 0 ) == '^'; final boolean anchor = p.length() > 0 && p.charAt( 0 ) == '^';
LBuffer lbuf = new LBuffer( srclen ); LBuffer lbuf = new LBuffer( srclen );
@@ -250,9 +251,9 @@ public class StrLib {
break; break;
} }
lbuf.append( src.substring( soffset, srclen ) ); lbuf.append( src.substring( soffset, srclen ) );
vm.setResult(); vm.settop(0);
vm.push( lbuf.toLuaString() ); vm.pushlstring( lbuf.toLuaString() );
vm.push( LInteger.valueOf( n ) ); vm.pushinteger( n );
} }
/** /**
@@ -262,7 +263,9 @@ public class StrLib {
* Embedded zeros are counted, so "a\000bc\000" has length 5. * Embedded zeros are counted, so "a\000bc\000" has length 5.
*/ */
static void len( VM vm ) { static void len( VM vm ) {
vm.setResult( LInteger.valueOf( vm.getArgAsLuaString(0).length()) ); int l = vm.tostring(2).length();
vm.settop(0);
vm.pushinteger( l );
} }
/** /**
@@ -273,7 +276,9 @@ public class StrLib {
* The definition of what an uppercase letter is depends on the current locale. * The definition of what an uppercase letter is depends on the current locale.
*/ */
static void lower( VM vm ) { static void lower( VM vm ) {
vm.setResult( new LString( vm.getArgAsString(0).toLowerCase() ) ); String s = vm.tostring(2).toLowerCase();
vm.settop(0);
vm.pushstring( s );
} }
/** /**
@@ -295,18 +300,16 @@ public class StrLib {
* Returns a string that is the concatenation of n copies of the string s. * Returns a string that is the concatenation of n copies of the string s.
*/ */
static void rep( VM vm ) { static void rep( VM vm ) {
LString s = vm.getArgAsLuaString( 0 ); LString s = vm.tolstring(2);
int n = vm.getArgAsInt( 1 ); int n = vm.tointeger( 3 );
vm.settop(0);
if ( n >= 0 ) { if ( n >= 0 ) {
final byte[] bytes = new byte[ s.length() * n ]; final byte[] bytes = new byte[ s.length() * n ];
int len = s.length(); int len = s.length();
for ( int offset = 0; offset < bytes.length; offset += len ) { for ( int offset = 0; offset < bytes.length; offset += len ) {
s.copyInto( 0, bytes, offset, len ); s.copyInto( 0, bytes, offset, len );
} }
vm.pushlstring( bytes );
vm.setResult( new LString( bytes ) );
} else {
vm.setResult( LNil.NIL );
} }
} }
@@ -316,12 +319,13 @@ public class StrLib {
* Returns a string that is the string s reversed. * Returns a string that is the string s reversed.
*/ */
static void reverse( VM vm ) { static void reverse( VM vm ) {
LString s = vm.getArgAsLuaString(0); LString s = vm.tolstring(2);
int n = s.length(); int n = s.length();
byte[] b = new byte[n]; byte[] b = new byte[n];
for ( int i=0, j=n-1; i<n; i++, j-- ) for ( int i=0, j=n-1; i<n; i++, j-- )
b[j] = (byte) s.luaByte(i); b[j] = (byte) s.luaByte(i);
vm.setResult( new LString(b) ); vm.settop(0);
vm.pushlstring( b );
} }
/** /**
@@ -336,23 +340,24 @@ public class StrLib {
* returns a suffix of s with length i. * returns a suffix of s with length i.
*/ */
static void sub( VM vm ) { static void sub( VM vm ) {
final int nargs = vm.getArgCount(); final int top = vm.gettop();
final LString s = vm.getArgAsLuaString( 0 ); final LString s = vm.tolstring(2);
final int len = s.length(); final int len = s.length();
int i = posrelat( nargs > 1 ? vm.getArgAsInt( 1 ) : 1, len ); int i = posrelat( top >= 3 ? vm.tointeger( 3 ) : 1, len );
int j = posrelat( nargs > 2 ? vm.getArgAsInt( 2 ) : -1, len ); int j = posrelat( top >= 4 ? vm.tointeger( 4 ) : -1, len );
if ( i < 1 ) if ( i < 1 )
i = 1; i = 1;
if ( j > len ) if ( j > len )
j = len; j = len;
vm.settop(0);
if ( i <= j ) { if ( i <= j ) {
LString result = s.substring( i - 1 , j ); LString result = s.substring( i - 1 , j );
vm.setResult( result ); vm.pushlstring( result );
} else { } else {
vm.setResult( new LString( "" ) ); vm.pushstring( "" );
} }
} }
@@ -364,16 +369,18 @@ public class StrLib {
* The definition of what a lowercase letter is depends on the current locale. * The definition of what a lowercase letter is depends on the current locale.
*/ */
static void upper( VM vm ) { static void upper( VM vm ) {
vm.setResult( new LString( vm.getArgAsString(0).toUpperCase() ) ); String s = vm.tostring(2).toUpperCase();
vm.settop(0);
vm.pushstring(s);
} }
/** /**
* This utility method implements both string.find and string.match. * This utility method implements both string.find and string.match.
*/ */
static void str_find_aux( VM vm, boolean find ) { static void str_find_aux( VM vm, boolean find ) {
LString s = vm.getArgAsLuaString( 0 ); LString s = vm.tolstring(2);
LString pat = vm.getArgAsLuaString( 1 ); LString pat = vm.tolstring(3);
int init = vm.getArgCount() > 2 ? vm.getArgAsInt( 2 ) : 1; int init = vm.gettop() >= 4 ? vm.tointeger( 4 ) : 1;
if ( init > 0 ) { if ( init > 0 ) {
init = Math.min( init - 1, s.length() ); init = Math.min( init - 1, s.length() );
@@ -381,14 +388,14 @@ public class StrLib {
init = Math.max( 0, s.length() + init ); init = Math.max( 0, s.length() + init );
} }
boolean fastMatch = find && ( vm.getArgAsBoolean( 3 ) || pat.indexOfAny( SPECIALS ) == -1 ); boolean fastMatch = find && ( vm.toboolean( 5 ) || pat.indexOfAny( SPECIALS ) == -1 );
vm.setResult(); vm.settop(0);
if ( fastMatch ) { if ( fastMatch ) {
int result = s.indexOf( pat, init ); int result = s.indexOf( pat, init );
if ( result != -1 ) { if ( result != -1 ) {
vm.push( result + 1 ); vm.pushinteger( result + 1 );
vm.push( result + pat.length() ); vm.pushinteger( result + pat.length() );
return; return;
} }
} else { } else {
@@ -407,8 +414,8 @@ public class StrLib {
ms.reset(); ms.reset();
if ( ( res = ms.match( soff, poff ) ) != -1 ) { if ( ( res = ms.match( soff, poff ) ) != -1 ) {
if ( find ) { if ( find ) {
vm.push( soff + 1 ); vm.pushinteger( soff + 1 );
vm.push( res ); vm.pushinteger( res );
ms.push_captures( false, soff, res ); ms.push_captures( false, soff, res );
} else { } else {
ms.push_captures( true, soff, res ); ms.push_captures( true, soff, res );
@@ -417,8 +424,7 @@ public class StrLib {
} }
} while ( soff++ < s.length() && !anchor ); } while ( soff++ < s.length() && !anchor );
} }
vm.pushnil();
vm.setResult( LNil.NIL );
} }
private static int posrelat( int pos, int len ) { private static int posrelat( int pos, int len ) {
@@ -521,7 +527,7 @@ public class StrLib {
add_s( lbuf, repl.luaAsString(), soffset, end ); add_s( lbuf, repl.luaAsString(), soffset, end );
return; return;
} else if ( repl instanceof LFunction ) { } else if ( repl instanceof LFunction ) {
vm.push( repl ); vm.pushlvalue( repl );
int n = push_captures( true, soffset, end ); int n = push_captures( true, soffset, end );
vm.call( n, 1 ); vm.call( n, 1 );
} else if ( repl instanceof LTable ) { } else if ( repl instanceof LTable ) {
@@ -556,7 +562,7 @@ public class StrLib {
private void push_onecapture( int i, int soff, int end ) { private void push_onecapture( int i, int soff, int end ) {
if ( i >= this.level ) { if ( i >= this.level ) {
if ( i == 0 ) { if ( i == 0 ) {
vm.push( s.substring( soff, end ) ); vm.pushlstring( s.substring( soff, end ) );
} else { } else {
vm.error( "invalid capture index" ); vm.error( "invalid capture index" );
} }
@@ -566,10 +572,10 @@ public class StrLib {
vm.error( "unfinished capture" ); vm.error( "unfinished capture" );
} }
if ( l == CAP_POSITION ) { if ( l == CAP_POSITION ) {
vm.push( LInteger.valueOf( cinit[i] + 1 ) ); vm.pushinteger( cinit[i] + 1 );
} else { } else {
int begin = cinit[i]; int begin = cinit[i];
vm.push( s.substring( begin, begin + l ) ); vm.pushlstring( s.substring( begin, begin + l ) );
} }
} }
} }

View File

@@ -59,7 +59,7 @@ final class Builtin extends JavaFunction {
for ( int i=1; i<=n; i++ ) { for ( int i=1; i<=n; i++ ) {
if ( i > 1 ) if ( i > 1 )
stdout.print( "\t" ); stdout.print( "\t" );
stdout.print( vm.topointer(i).toJavaString() ); stdout.print( vm.tostring(i) );
} }
stdout.println(); stdout.println();
return 0; return 0;

View File

@@ -42,20 +42,66 @@ public class LString extends LValue {
} }
/** /**
* Construct a Lua string from the given Java string. Characters are encoded * Construct a Lua string from the given Java string.
* using UTF-8. * Characters are encoded using UTF-8.
*/ */
public LString(String string) { public LString(String string) {
byte[] bytes;
try { // measure bytes required to encode
bytes = string.getBytes( "UTF-8" ); int n = string.length();
} catch ( UnsupportedEncodingException exn ) { int b = n;
bytes = stringToUtf8Bytes( string ); char c;
for ( int i=0; i<n; i++ ) {
if ( (c = string.charAt(i)) >= 0x80 ) {
++b;
if ( c >= 0x800 )
++b;
}
}
byte[] bytes = new byte[b];
int j = 0;
for ( int i=0; i<n; i++ ) {
if ( (c = string.charAt(i)) < 0x80 ) {
bytes[j++] = (byte) c;
} else if ( c < 0x800 ) {
bytes[j++] = (byte) (0xC0 | ((c>>6) & 0x1f));
bytes[j++] = (byte) (0x80 | ( c & 0x3f));
} else {
bytes[j++] = (byte) (0xE0 | ((c>>12) & 0x0f));
bytes[j++] = (byte) (0x80 | ((c>>6) & 0x3f));
bytes[j++] = (byte) (0x80 | ( c & 0x3f));
}
} }
this.m_bytes = bytes; this.m_bytes = bytes;
this.m_offset = 0; this.m_offset = 0;
this.m_length = m_bytes.length; this.m_length = b;
this.m_hash = hashBytes( m_bytes, 0, m_length ); this.m_hash = hashBytes( bytes, 0, b );
}
/**
* Convert to Java string using UTF-8 encoding
*/
public String toJavaString() {
char[] c = new char[m_length];
int n = 0;
int b;
for ( int i=0; i<m_length; i++ ) {
switch ( (b = m_bytes[m_offset+i]) & 0xe0 ) {
default:
if ( b == 0 )
return new String( c, 0, n );
c[n++] = (char) (0xff & b);
break;
case 0xc0:
c[n++] = (char) (((b & 0x1f) << 6) | ( m_bytes[m_offset+(++i)] & 0x3f));
break;
case 0xe0:
c[n++] = (char) (((b & 0xf) << 12) | ((m_bytes[m_offset+i+1] & 0x3f) << 6) | (m_bytes[m_offset+i+2] & 0x3f));
i += 2;
break;
}
}
return new String( c, 0, n );
} }
/** /**
@@ -285,14 +331,6 @@ public class LString extends LValue {
return this; return this;
} }
public String toJavaString() {
try {
return new String( m_bytes, m_offset, m_length, "UTF-8" );
} catch ( UnsupportedEncodingException uee ) {
throw new RuntimeException("toJavaString: UTF-8 decoding not implemented");
}
}
/** Built-in opcode LEN, for Strings and Tables */ /** Built-in opcode LEN, for Strings and Tables */
public int luaLength() { public int luaLength() {
return m_length; return m_length;

View File

@@ -44,4 +44,42 @@ public class LStringTest extends TestCase {
assertEquals( 'e', is.read() ); assertEquals( 'e', is.read() );
} }
private static final String userFriendly( String s ) {
StringBuffer sb = new StringBuffer();
for ( int i=0, n=s.length(); i<n; i++ ) {
int c = s.charAt(i);
if ( c < ' ' || c >= 0x80 ) {
sb.append( "\\u"+Integer.toHexString(0x10000+c).substring(1) );
} else {
sb.append( (char) c );
}
}
return sb.toString();
}
public void testUtf8() {
for ( int i=4; i<0xffff; i+=4 ) {
char[] c = { (char) (i+0), (char) (i+1), (char) (i+2), (char) (i+3) };
String before = new String(c)+" "+i+"-"+(i+4);
LString ls = new LString(before);
String after = ls.toJavaString();
assertEquals( userFriendly( before ), userFriendly( after ) );
}
char[] c = { (char) (1), (char) (2), (char) (3) };
String before = new String(c)+" 1-3";
LString ls = new LString(before);
String after = ls.toJavaString();
assertEquals( userFriendly( before ), userFriendly( after ) );
}
public void testNullTerminated() {
char[] c = { 'a', 'b', 'c', '\0', 'd', 'e', 'f' };
String before = new String(c);
LString ls = new LString(before);
String after = ls.toJavaString();
assertEquals( userFriendly( "abc" ), userFriendly( after ) );
}
} }