From bffc3c18cc6ce6f280ff9f2dbc93e2f6d2c9640a Mon Sep 17 00:00:00 2001 From: SquidDev Date: Mon, 12 Jun 2017 10:28:31 +0100 Subject: [PATCH 1/3] Rewrite argument validation This uses a new utility class ArgumentHelper, which provides convenience methods for parsing arguments from an array of Objects. The format of error messages has also changed. It now follows a format similar to Lua's native error messages - including the invalid argument index, the expected type and the type actually received. --- .../core/apis/ArgumentHelper.java | 246 ++++++++++++++++++ .../computercraft/core/apis/BitAPI.java | 38 +-- .../computercraft/core/apis/BufferAPI.java | 95 ++----- .../dan200/computercraft/core/apis/FSAPI.java | 106 ++------ .../computercraft/core/apis/HTTPAPI.java | 24 +- .../dan200/computercraft/core/apis/OSAPI.java | 68 +---- .../core/apis/PeripheralAPI.java | 16 +- .../computercraft/core/apis/RedstoneAPI.java | 32 +-- .../computercraft/core/apis/TermAPI.java | 72 ++--- .../core/apis/handles/BinaryInputHandle.java | 10 +- .../core/apis/handles/BinaryOutputHandle.java | 3 +- .../shared/computer/apis/CommandAPI.java | 50 +--- .../commandblock/CommandBlockPeripheral.java | 9 +- .../diskdrive/DiskDrivePeripheral.java | 12 +- .../peripheral/modem/ModemPeripheral.java | 8 +- .../shared/peripheral/modem/TileCable.java | 21 +- .../peripheral/monitor/MonitorPeripheral.java | 79 ++---- .../peripheral/printer/PrinterPeripheral.java | 23 +- .../peripheral/speaker/SpeakerPeripheral.java | 82 +----- .../shared/turtle/apis/TurtleAPI.java | 94 ++----- .../upgrades/CraftingTablePeripheral.java | 13 +- 21 files changed, 451 insertions(+), 650 deletions(-) create mode 100644 src/main/java/dan200/computercraft/core/apis/ArgumentHelper.java diff --git a/src/main/java/dan200/computercraft/core/apis/ArgumentHelper.java b/src/main/java/dan200/computercraft/core/apis/ArgumentHelper.java new file mode 100644 index 000000000..3344eece8 --- /dev/null +++ b/src/main/java/dan200/computercraft/core/apis/ArgumentHelper.java @@ -0,0 +1,246 @@ +package dan200.computercraft.core.apis; + +import dan200.computercraft.api.lua.LuaException; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import java.util.Map; + +/** + * Various helpers for arguments + */ +public final class ArgumentHelper +{ + private ArgumentHelper() + { + throw new IllegalStateException( "Cannot instantiate singleton " + getClass().getName() ); + } + + @Nonnull + public static String getType( @Nullable Object type ) + { + if( type == null ) return "nil"; + if( type instanceof String ) return "string"; + if( type instanceof Boolean ) return "boolean"; + if( type instanceof Number ) return "number"; + if( type instanceof Map ) return "table"; + + Class klass = type.getClass(); + if( klass.isArray() ) + { + StringBuilder name = new StringBuilder(); + while( klass.isArray() ) + { + name.append( "[]" ); + klass = klass.getComponentType(); + } + name.insert( 0, klass.getName() ); + return name.toString(); + } + else + { + return klass.getName(); + } + } + + @Nonnull + public static LuaException badArgument( int index, @Nonnull String expected, @Nullable Object actual ) + { + return badArgument( index, expected, getType( actual ) ); + } + + @Nonnull + public static LuaException badArgument( int index, @Nonnull String expected, @Nonnull String actual ) + { + return new LuaException( "bad argument #" + (index + 1) + " (" + expected + " expected, got " + actual + ")" ); + } + + public static double getNumber( @Nonnull Object[] args, int index ) throws LuaException + { + if( index >= args.length ) throw badArgument( index, "number", "no value" ); + Object value = args[ index ]; + if( value instanceof Number ) + { + return ((Number) value).doubleValue(); + } + else + { + throw badArgument( index, "number", value ); + } + } + + public static int getInt( @Nonnull Object[] args, int index ) throws LuaException + { + if( index >= args.length ) throw badArgument( index, "number", "no value" ); + Object value = args[ index ]; + if( value instanceof Number ) + { + return (int) ((Number) value).longValue(); + } + else + { + throw badArgument( index, "number", value ); + } + } + + public static double getReal( @Nonnull Object[] args, int index ) throws LuaException + { + return checkReal( index, getNumber( args, index ) ); + } + + public static boolean getBoolean( @Nonnull Object[] args, int index ) throws LuaException + { + if( index >= args.length ) throw badArgument( index, "boolean", "no value" ); + Object value = args[ index ]; + if( value instanceof Boolean ) + { + return (Boolean) value; + } + else + { + throw badArgument( index, "boolean", value ); + } + } + + @Nonnull + public static String getString( @Nonnull Object[] args, int index ) throws LuaException + { + if( index >= args.length ) throw badArgument( index, "string", "no value" ); + Object value = args[ index ]; + if( value instanceof String ) + { + return (String) value; + } + else + { + throw badArgument( index, "string", value ); + } + } + + @SuppressWarnings("unchecked") + @Nonnull + public static Map getTable( @Nonnull Object[] args, int index ) throws LuaException + { + if( index >= args.length ) throw badArgument( index, "table", "no value" ); + Object value = args[ index ]; + if( value instanceof Map ) + { + return (Map) value; + } + else + { + throw badArgument( index, "table", value ); + } + } + + public static double optNumber( @Nonnull Object[] args, int index, double def ) throws LuaException + { + Object value = index < args.length ? args[ index ] : null; + if( value == null ) + { + return def; + } + else if( value instanceof Number ) + { + return ((Number) value).doubleValue(); + } + else + { + throw badArgument( index, "number", value ); + } + } + + public static int optInt( @Nonnull Object[] args, int index, int def ) throws LuaException + { + Object value = index < args.length ? args[ index ] : null; + if( value == null ) + { + return def; + } + else if( value instanceof Number ) + { + return (int) ((Number) value).longValue(); + } + else + { + throw badArgument( index, "number", value ); + } + } + + public static double optReal( @Nonnull Object[] args, int index, double def ) throws LuaException + { + return checkReal( index, optNumber( args, index, def ) ); + } + + public static boolean optBoolean( @Nonnull Object[] args, int index, boolean def ) throws LuaException + { + Object value = index < args.length ? args[ index ] : null; + if( value == null ) + { + return def; + } + else if( value instanceof Boolean ) + { + return (Boolean) value; + } + else + { + throw badArgument( index, "boolean", value ); + } + } + + public static String optString( @Nonnull Object[] args, int index, String def ) throws LuaException + { + Object value = index < args.length ? args[ index ] : null; + if( value == null ) + { + return def; + } + else if( value instanceof String ) + { + return (String) value; + } + else + { + throw badArgument( index, "string", value ); + } + } + + @SuppressWarnings("unchecked") + public static Map optTable( @Nonnull Object[] args, int index, Map def ) throws LuaException + { + Object value = index < args.length ? args[ index ] : null; + if( value == null ) + { + return def; + } + else if( value instanceof Map ) + { + return (Map) value; + } + else + { + throw badArgument( index, "table", value ); + } + } + + private static double checkReal( int index, double value ) throws LuaException + { + if( Double.isNaN( value ) ) + { + throw badArgument( index, "number", "nan" ); + } + else if( value == Double.POSITIVE_INFINITY ) + { + throw badArgument( index, "number", "inf" ); + } + else if( value == Double.NEGATIVE_INFINITY ) + { + throw badArgument( index, "number", "-inf" ); + } + else + { + return value; + } + } +} diff --git a/src/main/java/dan200/computercraft/core/apis/BitAPI.java b/src/main/java/dan200/computercraft/core/apis/BitAPI.java index 682e3a3ec..8d4021b2c 100644 --- a/src/main/java/dan200/computercraft/core/apis/BitAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/BitAPI.java @@ -11,6 +11,8 @@ import dan200.computercraft.api.lua.LuaException; import javax.annotation.Nonnull; +import static dan200.computercraft.core.apis.ArgumentHelper.getInt; + // Contributed by Nia // Based on LuaBit (http://luaforge.net/projects/bit) @@ -23,25 +25,6 @@ public class BitAPI implements ILuaAPI private static final int BRSHIFT = 4; private static final int BLSHIFT = 5; private static final int BLOGIC_RSHIFT = 6; - - private static int checkInt( Object o, int count ) throws LuaException - { - if( o instanceof Number ) - { - return (int)(((Number)o).longValue()); - } - else - { - if( count == 2 ) - { - throw new LuaException( "Expected number, number" ); - } - else - { - throw new LuaException( "Expected number" ); - } - } - } public BitAPI( IAPIEnvironment _environment ) { @@ -82,31 +65,28 @@ public class BitAPI implements ILuaAPI @Override public Object[] callMethod( @Nonnull ILuaContext context, int method, @Nonnull Object[] args ) throws LuaException { - Object a = args.length>0?args[0]:null; - Object b = args.length>1?args[1]:null; - int ret = 0; switch(method) { case BNOT: - ret = ~checkInt(a, 1); + ret = ~getInt( args, 0 ); break; case BAND: - ret = checkInt(a, 2) & checkInt(b, 2); + ret = getInt( args, 0 ) & getInt( args, 1 ); break; case BOR: - ret = checkInt(a, 2) | checkInt(b, 2); + ret = getInt( args, 0 ) | getInt( args, 1 ); break; case BXOR: - ret = checkInt(a, 2) ^ checkInt(b, 2); + ret = getInt( args, 0 ) ^ getInt( args, 1 ); break; case BRSHIFT: - ret = checkInt(a, 2) >> checkInt(b, 2); + ret = getInt( args, 0 ) >> getInt( args, 1 ); break; case BLSHIFT: - ret = checkInt(a, 2) << checkInt(b, 2); + ret = getInt( args, 0 ) << getInt( args, 1 ); break; case BLOGIC_RSHIFT: - ret = checkInt(a, 2) >>> checkInt(b, 2); + ret = getInt( args, 0 ) >>> getInt( args, 1 ); break; } diff --git a/src/main/java/dan200/computercraft/core/apis/BufferAPI.java b/src/main/java/dan200/computercraft/core/apis/BufferAPI.java index e03fdf212..3035ef763 100644 --- a/src/main/java/dan200/computercraft/core/apis/BufferAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/BufferAPI.java @@ -13,6 +13,9 @@ import dan200.computercraft.core.terminal.TextBuffer; import javax.annotation.Nonnull; +import static dan200.computercraft.core.apis.ArgumentHelper.getString; +import static dan200.computercraft.core.apis.ArgumentHelper.optInt; + public class BufferAPI implements ILuaAPI { private static class BufferLuaObject implements ILuaObject @@ -55,81 +58,25 @@ public class BufferAPI implements ILuaAPI case 2: { // read - int start = 0; - if( arguments.length >= 1 && (arguments[0] != null) ) - { - if( !(arguments[0] instanceof Number) ) - { - throw new LuaException( "Expected number" ); - } - start = ((Number)arguments[1]).intValue() - 1; - } - int end = m_buffer.length(); - if( arguments.length >= 2 && (arguments[1] != null) ) - { - if( !(arguments[1] instanceof Number) ) - { - throw new LuaException( "Expected number, number" ); - } - end = ((Number)arguments[1]).intValue(); - } + int start = optInt( arguments, 0, 0 ); + int end = optInt( arguments, 1, m_buffer.length() ); return new Object[] { m_buffer.read( start, end ) }; } case 3: { // write - if( arguments.length < 1 || !(arguments[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String text = (String)(arguments[0]); - int start = 0; - if( arguments.length >= 2 && (arguments[1] != null) ) - { - if( !(arguments[1] instanceof Number) ) - { - throw new LuaException( "Expected string, number" ); - } - start = ((Number)arguments[1]).intValue() - 1; - } - int end = start + text.length(); - if( arguments.length >= 3 && (arguments[2] != null) ) - { - if( !(arguments[2] instanceof Number) ) - { - throw new LuaException( "Expected string, number, number" ); - } - end = ((Number)arguments[2]).intValue(); - } + String text = getString( arguments, 0 ); + int start = optInt( arguments, 1, 0 ); + int end = optInt( arguments, 2, start + text.length() ); m_buffer.write( text, start, end ); return null; } case 4: { // fill - if( arguments.length < 1 || !(arguments[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String text = (String)(arguments[0]); - int start = 0; - if( arguments.length >= 2 && (arguments[1] != null) ) - { - if( !(arguments[1] instanceof Number) ) - { - throw new LuaException( "Expected string, number" ); - } - start = ((Number)arguments[1]).intValue() - 1; - } - int end = m_buffer.length(); - if( arguments.length >= 3 && (arguments[2] != null) ) - { - if( !(arguments[2] instanceof Number) ) - { - throw new LuaException( "Expected string, number, number" ); - } - end = ((Number)arguments[2]).intValue(); - } + String text = getString( arguments, 0 ); + int start = optInt( arguments, 1, 0 ); + int end = optInt( arguments, 2, m_buffer.length() ); m_buffer.fill( text, start, end ); return null; } @@ -184,23 +131,11 @@ public class BufferAPI implements ILuaAPI { case 0: { - if( arguments.length < 1 || !(arguments[0] instanceof String) ) + String text = getString( arguments, 0 ); + int repetitions = optInt( arguments, 1, 1 ); + if( repetitions < 0 ) { - throw new LuaException( "Expected string" ); - } - String text = (String)(arguments[0]); - int repetitions = 1; - if( arguments.length >= 2 && arguments[1] != null ) - { - if( !(arguments[1] instanceof Number) ) - { - throw new LuaException( "Expected string, number" ); - } - repetitions = ((Number)arguments[1]).intValue(); - if( repetitions < 0 ) - { - throw new LuaException( "Expected positive number" ); - } + throw ArgumentHelper.badArgument( 1, "positive number", Integer.toString( repetitions ) ); } TextBuffer buffer = new TextBuffer( text, repetitions ); return new Object[] { new BufferLuaObject( buffer ) }; diff --git a/src/main/java/dan200/computercraft/core/apis/FSAPI.java b/src/main/java/dan200/computercraft/core/apis/FSAPI.java index d4d38a1d9..e5454c803 100644 --- a/src/main/java/dan200/computercraft/core/apis/FSAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/FSAPI.java @@ -21,6 +21,8 @@ import java.io.OutputStream; import java.util.HashMap; import java.util.Map; +import static dan200.computercraft.core.apis.ArgumentHelper.getString; + public class FSAPI implements ILuaAPI { private IAPIEnvironment m_env; @@ -89,11 +91,7 @@ public class FSAPI implements ILuaAPI case 0: { // list - if( args.length != 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String path = (String)args[0]; + String path = getString( args, 0 ); try { String[] results = m_fileSystem.list( path ); Map table = new HashMap(); @@ -110,32 +108,20 @@ public class FSAPI implements ILuaAPI case 1: { // combine - if( args.length != 2 || args[0] == null || !(args[0] instanceof String) || args[1] == null || !(args[1] instanceof String) ) - { - throw new LuaException( "Expected string, string" ); - } - String pathA = (String)args[0]; - String pathB = (String)args[1]; + String pathA = getString( args, 0 ); + String pathB = getString( args, 1 ); return new Object[] { m_fileSystem.combine( pathA, pathB ) }; } case 2: { // getName - if( args.length != 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String path = (String)args[0]; + String path = getString( args, 0 ); return new Object[]{ FileSystem.getName( path ) }; } case 3: { // getSize - if( args.length != 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String path = (String)args[0]; + String path = getString( args, 0 ); try { return new Object[]{ m_fileSystem.getSize( path ) }; @@ -148,11 +134,7 @@ public class FSAPI implements ILuaAPI case 4: { // exists - if( args.length != 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String path = (String)args[0]; + String path = getString( args, 0 ); try { return new Object[]{ m_fileSystem.exists( path ) }; } catch( FileSystemException e ) { @@ -162,11 +144,7 @@ public class FSAPI implements ILuaAPI case 5: { // isDir - if( args.length != 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String path = (String)args[0]; + String path = getString( args, 0 ); try { return new Object[]{ m_fileSystem.isDir( path ) }; } catch( FileSystemException e ) { @@ -176,11 +154,7 @@ public class FSAPI implements ILuaAPI case 6: { // isReadOnly - if( args.length != 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String path = (String)args[0]; + String path = getString( args, 0 ); try { return new Object[]{ m_fileSystem.isReadOnly( path ) }; } catch( FileSystemException e ) { @@ -190,11 +164,7 @@ public class FSAPI implements ILuaAPI case 7: { // makeDir - if( args.length != 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String path = (String)args[0]; + String path = getString( args, 0 ); try { m_fileSystem.makeDir( path ); return null; @@ -205,12 +175,8 @@ public class FSAPI implements ILuaAPI case 8: { // move - if( args.length != 2 || args[0] == null || !(args[0] instanceof String) || args[1] == null || !(args[1] instanceof String) ) - { - throw new LuaException( "Expected string, string" ); - } - String path = (String)args[0]; - String dest = (String)args[1]; + String path = getString( args, 0 ); + String dest = getString( args, 1 ); try { m_fileSystem.move( path, dest ); return null; @@ -221,12 +187,8 @@ public class FSAPI implements ILuaAPI case 9: { // copy - if( args.length != 2 || args[0] == null || !(args[0] instanceof String) || args[1] == null || !(args[1] instanceof String) ) - { - throw new LuaException( "Expected string, string" ); - } - String path = (String)args[0]; - String dest = (String)args[1]; + String path = getString( args, 0 ); + String dest = getString( args, 1 ); try { m_fileSystem.copy( path, dest ); return null; @@ -237,11 +199,7 @@ public class FSAPI implements ILuaAPI case 10: { // delete - if( args.length != 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String path = (String)args[0]; + String path = getString( args, 0 ); try { m_fileSystem.delete( path ); return null; @@ -252,12 +210,8 @@ public class FSAPI implements ILuaAPI case 11: { // open - if( args.length < 2 || args[0] == null || !(args[0] instanceof String) || args[1] == null || !(args[1] instanceof String) ) - { - throw new LuaException( "Expected string, string" ); - } - String path = (String)args[0]; - String mode = (String)args[1]; + String path = getString( args, 0 ); + String mode = getString( args, 1 ); try { if( mode.equals( "r" ) ) { // Open the file for reading, then create a wrapper around the reader @@ -300,11 +254,7 @@ public class FSAPI implements ILuaAPI case 12: { // getDrive - if( args.length != 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String path = (String)args[0]; + String path = getString( args, 0 ); try { if( !m_fileSystem.exists( path ) ) { @@ -318,11 +268,7 @@ public class FSAPI implements ILuaAPI case 13: { // getFreeSpace - if( args.length != 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String path = (String)args[0]; + String path = getString( args, 0 ); try { long freeSpace = m_fileSystem.getFreeSpace( path ); if( freeSpace >= 0 ) @@ -337,11 +283,7 @@ public class FSAPI implements ILuaAPI case 14: { // find - if( args.length != 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String path = (String)args[0]; + String path = getString( args, 0 ); try { String[] results = m_fileSystem.find( path ); Map table = new HashMap(); @@ -356,11 +298,7 @@ public class FSAPI implements ILuaAPI case 15: { // getDir - if( args.length != 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String path = (String)args[0]; + String path = getString( args, 0 ); return new Object[]{ FileSystem.getDirectory( path ) }; } default: diff --git a/src/main/java/dan200/computercraft/core/apis/HTTPAPI.java b/src/main/java/dan200/computercraft/core/apis/HTTPAPI.java index 71b6119f1..2ff59161f 100644 --- a/src/main/java/dan200/computercraft/core/apis/HTTPAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/HTTPAPI.java @@ -16,6 +16,8 @@ import javax.annotation.Nonnull; import java.io.InputStream; import java.util.*; +import static dan200.computercraft.core.apis.ArgumentHelper.*; + public class HTTPAPI implements ILuaAPI { private final IAPIEnvironment m_apiEnvironment; @@ -155,24 +157,16 @@ public class HTTPAPI implements ILuaAPI { // request // Get URL - if( args.length < 1 || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String urlString = args[0].toString(); + String urlString = getString( args, 0 ); // Get POST - String postString = null; - if( args.length >= 2 && args[1] instanceof String ) - { - postString = args[1].toString(); - } + String postString = optString( args, 1, null ); // Get Headers Map headers = null; - if( args.length >= 3 && args[2] instanceof Map ) + Map table = optTable( args, 2, null ); + if( table != null ) { - Map table = (Map)args[2]; headers = new HashMap( table.size() ); for( Object key : table.keySet() ) { @@ -210,11 +204,7 @@ public class HTTPAPI implements ILuaAPI { // checkURL // Get URL - if( args.length < 1 || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String urlString = args[0].toString(); + String urlString = getString( args, 0 ); // Check URL try diff --git a/src/main/java/dan200/computercraft/core/apis/OSAPI.java b/src/main/java/dan200/computercraft/core/apis/OSAPI.java index 1c28b6b75..612c7c807 100644 --- a/src/main/java/dan200/computercraft/core/apis/OSAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/OSAPI.java @@ -13,6 +13,8 @@ import dan200.computercraft.shared.util.StringUtil; import javax.annotation.Nonnull; import java.util.*; +import static dan200.computercraft.core.apis.ArgumentHelper.*; + public class OSAPI implements ILuaAPI { private IAPIEnvironment m_apiEnvironment; @@ -225,21 +227,13 @@ public class OSAPI implements ILuaAPI case 0: { // queueEvent - if( args.length == 0 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - queueLuaEvent( (String)args[0], trimArray( args, 1 ) ); + queueLuaEvent( getString( args, 0 ), trimArray( args, 1 ) ); return null; } case 1: { // startTimer - if( args.length < 1 || args[0] == null || !(args[0] instanceof Number) ) - { - throw new LuaException( "Expected number" ); - } - double timer = ((Number)args[0]).doubleValue(); + double timer = getReal( args, 0 ); synchronized( m_timers ) { m_timers.put( m_nextTimerToken, new Timer( (int)Math.round( timer / 0.05 ) ) ); @@ -249,11 +243,7 @@ public class OSAPI implements ILuaAPI case 2: { // setAlarm - if( args.length < 1 || args[0] == null || !(args[0] instanceof Number) ) - { - throw new LuaException( "Expected number" ); - } - double time = ((Number)args[0]).doubleValue(); + double time = getReal( args, 0 ); if( time < 0.0 || time >= 24.0 ) { throw new LuaException( "Number out of range" ); @@ -286,16 +276,8 @@ public class OSAPI implements ILuaAPI case 7: { // setComputerLabel - String label = null; - if( args.length > 0 && args[0] != null ) - { - if(!(args[0] instanceof String)) - { - throw new LuaException( "Expected string or nil" ); - } - label = StringUtil.normaliseLabel( (String) args[0] ); - } - m_apiEnvironment.setLabel( label ); + String label = optString( args, 0, null ); + m_apiEnvironment.setLabel( StringUtil.normaliseLabel( label ) ); return null; } case 8: @@ -320,13 +302,7 @@ public class OSAPI implements ILuaAPI case 11: { // time - String param = "ingame"; - if (args.length > 0 && args[0] != null) { - if (!(args[0] instanceof String)) { - throw new LuaException("Expected string"); - } - param = (String)args[0]; - } + String param = optString( args, 0, "ingame" ); if (param.equals("utc")) { // Get Hour of day (UTC) @@ -351,13 +327,7 @@ public class OSAPI implements ILuaAPI case 12: { // day - String param = "ingame"; - if (args.length > 0 && args[0] != null) { - if (!(args[0] instanceof String)) { - throw new LuaException("Expected string"); - } - param = (String)args[0]; - } + String param = optString( args, 0, "ingame" ); if (param.equals("utc")) { // Get numbers of days since 1970-01-01 (utc) Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC")); @@ -381,11 +351,7 @@ public class OSAPI implements ILuaAPI case 13: { // cancelTimer - if( args.length < 1 || args[0] == null || !(args[0] instanceof Number) ) - { - throw new LuaException( "Expected number" ); - } - int token = ((Number)args[0]).intValue(); + int token = getInt( args, 0 ); synchronized( m_timers ) { if( m_timers.containsKey( token ) ) @@ -398,11 +364,7 @@ public class OSAPI implements ILuaAPI case 14: { // cancelAlarm - if( args.length < 1 || args[0] == null || !(args[0] instanceof Number) ) - { - throw new LuaException( "Expected number" ); - } - int token = ((Number)args[0]).intValue(); + int token = getInt( args, 0 ); synchronized( m_alarms ) { if( m_alarms.containsKey( token ) ) @@ -415,13 +377,7 @@ public class OSAPI implements ILuaAPI case 15: { // epoch - String param = "ingame"; - if (args.length > 0 && args[0] != null) { - if (!(args[0] instanceof String)) { - throw new LuaException("Expected string"); - } - param = (String)args[0]; - } + String param = optString( args, 0, "ingame" ); if (param.equals("utc")) { // Get utc epoch Calendar c = Calendar.getInstance(TimeZone.getTimeZone("UTC")); diff --git a/src/main/java/dan200/computercraft/core/apis/PeripheralAPI.java b/src/main/java/dan200/computercraft/core/apis/PeripheralAPI.java index 3465ad5e0..f83aa9f2f 100644 --- a/src/main/java/dan200/computercraft/core/apis/PeripheralAPI.java +++ b/src/main/java/dan200/computercraft/core/apis/PeripheralAPI.java @@ -21,6 +21,8 @@ import dan200.computercraft.core.filesystem.FileSystemException; import javax.annotation.Nonnull; import java.util.*; +import static dan200.computercraft.core.apis.ArgumentHelper.getString; + public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChangeListener { private class PeripheralWrapper implements IComputerAccess @@ -460,14 +462,10 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange case 3: { // call - if( args.length < 2 || args[1] == null || !(args[1] instanceof String) ) - { - throw new LuaException( "Expected string, string" ); - } - String methodName = (String)args[1]; + int side = parseSide( args ); + String methodName = getString( args, 1 ); Object[] methodArgs = trimArray( args, 2 ); - int side = parseSide( args ); if( side >= 0 ) { PeripheralWrapper p; @@ -498,11 +496,7 @@ public class PeripheralAPI implements ILuaAPI, IAPIEnvironment.IPeripheralChange private int parseSide( Object[] args ) throws LuaException { - if( args.length < 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String side = (String)args[0]; + String side = getString( args, 0 ); for( int n=0; n 15 ) { throw new LuaException( "Expected number in range 0-15" ); @@ -183,11 +169,7 @@ public class RedstoneAPI implements ILuaAPI private int parseSide( Object[] args ) throws LuaException { - if( args.length < 1 || args[0] == null || !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - String side = (String)args[0]; + String side = getString( args, 0 ); for( int n=0; n= 4 && args[0] instanceof Double && args[1] instanceof Double && args[2] instanceof Double && args[3] instanceof Double) + else { - int colour = 15 - parseColour( args ); - double r = (Double)args[1]; - double g = (Double)args[2]; - double b = (Double)args[3]; + double r = getReal( args, 1 ); + double g = getReal( args, 2 ); + double b = getReal( args, 3 ); setColour( m_terminal, colour, r, g, b ); - return null; } - - throw new LuaException( "Expected number, number or number, number, number, number" ); + return null; } case 21: case 22: { // getPaletteColour/getPaletteColor - if(args.length < 1 || !(args[0] instanceof Double)) - { - throw new LuaException( "Expected number" ); - } - int colour = 15 - parseColour( args ); synchronized( m_terminal ) { diff --git a/src/main/java/dan200/computercraft/core/apis/handles/BinaryInputHandle.java b/src/main/java/dan200/computercraft/core/apis/handles/BinaryInputHandle.java index 3ad196c06..25cdaca5e 100644 --- a/src/main/java/dan200/computercraft/core/apis/handles/BinaryInputHandle.java +++ b/src/main/java/dan200/computercraft/core/apis/handles/BinaryInputHandle.java @@ -9,6 +9,8 @@ import java.io.IOException; import java.io.InputStream; import java.util.Arrays; +import static dan200.computercraft.core.apis.ArgumentHelper.getInt; + public class BinaryInputHandle extends HandleGeneric { private final InputStream m_stream; @@ -42,13 +44,7 @@ public class BinaryInputHandle extends HandleGeneric { if( args.length > 0 && args[ 0 ] != null ) { - if( !(args[ 0 ] instanceof Number) ) - { - throw new LuaException( "Expected number" ); - } - - int count = ((Number) args[ 0 ]).intValue(); - + int count = getInt( args, 0 ); if( count <= 0 || count >= 1024 * 16 ) { throw new LuaException( "Count out of range" ); diff --git a/src/main/java/dan200/computercraft/core/apis/handles/BinaryOutputHandle.java b/src/main/java/dan200/computercraft/core/apis/handles/BinaryOutputHandle.java index 63c148718..ae90b677d 100644 --- a/src/main/java/dan200/computercraft/core/apis/handles/BinaryOutputHandle.java +++ b/src/main/java/dan200/computercraft/core/apis/handles/BinaryOutputHandle.java @@ -2,6 +2,7 @@ package dan200.computercraft.core.apis.handles; import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; +import dan200.computercraft.core.apis.ArgumentHelper; import dan200.computercraft.shared.util.StringUtil; import javax.annotation.Nonnull; @@ -51,7 +52,7 @@ public class BinaryOutputHandle extends HandleGeneric } else { - throw new LuaException( "Expected number" ); + throw ArgumentHelper.badArgument( 0, "string or number", args.length > 0 ? args[ 0 ] : null ); } return null; } diff --git a/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java b/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java index fa708a193..7cc279310 100644 --- a/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java +++ b/src/main/java/dan200/computercraft/shared/computer/apis/CommandAPI.java @@ -28,6 +28,9 @@ import javax.annotation.Nonnull; import java.util.HashMap; import java.util.Map; +import static dan200.computercraft.core.apis.ArgumentHelper.getInt; +import static dan200.computercraft.core.apis.ArgumentHelper.getString; + public class CommandAPI implements ILuaAPI { private TileCommandComputer m_computer; @@ -151,11 +154,7 @@ public class CommandAPI implements ILuaAPI case 0: { // exec - if( arguments.length < 1 || !(arguments[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - final String command = (String)arguments[0]; + final String command = getString( arguments, 0 ); return context.executeMainThreadTask( new ILuaTask() { @Override @@ -168,11 +167,7 @@ public class CommandAPI implements ILuaAPI case 1: { // execAsync - if( arguments.length < 1 || !(arguments[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - final String command = (String)arguments[0]; + final String command = getString( arguments, 0 ); long taskID = context.issueMainThreadTask( new ILuaTask() { @Override @@ -234,22 +229,12 @@ public class CommandAPI implements ILuaAPI case 4: { // getBlockInfos - if( arguments.length < 6 || - !(arguments[0] instanceof Number) || - !(arguments[1] instanceof Number) || - !(arguments[2] instanceof Number) || - !(arguments[3] instanceof Number) || - !(arguments[4] instanceof Number) || - !(arguments[5] instanceof Number) ) - { - throw new LuaException( "Expected number, number, number, number, number, number" ); - } - final int minx = ((Number)arguments[0]).intValue(); - final int miny = ((Number)arguments[1]).intValue(); - final int minz = ((Number)arguments[2]).intValue(); - final int maxx = ((Number)arguments[3]).intValue(); - final int maxy = ((Number)arguments[4]).intValue(); - final int maxz = ((Number)arguments[5]).intValue(); + final int minx = getInt( arguments, 0 ); + final int miny = getInt( arguments, 1 ); + final int minz = getInt( arguments, 2 ); + final int maxx = getInt( arguments, 3 ); + final int maxy = getInt( arguments, 4 ); + final int maxz = getInt( arguments, 5 ); return context.executeMainThreadTask( new ILuaTask() { @Override @@ -295,16 +280,9 @@ public class CommandAPI implements ILuaAPI case 5: { // getBlockInfo - if( arguments.length < 3 || - !(arguments[0] instanceof Number) || - !(arguments[1] instanceof Number) || - !(arguments[2] instanceof Number) ) - { - throw new LuaException( "Expected number, number, number" ); - } - final int x = ((Number)arguments[0]).intValue(); - final int y = ((Number)arguments[1]).intValue(); - final int z = ((Number)arguments[2]).intValue(); + final int x = getInt( arguments, 0 ); + final int y = getInt( arguments, 1 ); + final int z = getInt( arguments, 2 ); return context.executeMainThreadTask( new ILuaTask() { @Override diff --git a/src/main/java/dan200/computercraft/shared/peripheral/commandblock/CommandBlockPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/commandblock/CommandBlockPeripheral.java index 39960ded9..563dc67dd 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/commandblock/CommandBlockPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/commandblock/CommandBlockPeripheral.java @@ -16,6 +16,8 @@ import net.minecraft.util.math.BlockPos; import javax.annotation.Nonnull; +import static dan200.computercraft.core.apis.ArgumentHelper.getString; + public class CommandBlockPeripheral implements IPeripheral { private final TileEntityCommandBlock m_commandBlock; @@ -67,12 +69,7 @@ public class CommandBlockPeripheral implements IPeripheral case 1: { // setCommand - if( arguments.length < 1 || !(arguments[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - - final String command = (String) arguments[ 0 ]; + final String command = getString( arguments, 0 ); context.issueMainThreadTask( new ILuaTask() { @Override diff --git a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDrivePeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDrivePeripheral.java index d2854b88b..59ffea4bf 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDrivePeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/diskdrive/DiskDrivePeripheral.java @@ -18,6 +18,8 @@ import net.minecraft.item.ItemStack; import javax.annotation.Nonnull; +import static dan200.computercraft.core.apis.ArgumentHelper.optString; + public class DiskDrivePeripheral implements IPeripheral { private final TileDiskDrive m_diskDrive; @@ -78,15 +80,7 @@ public class DiskDrivePeripheral implements IPeripheral case 2: { // setDiskLabel - String label = null; - if( arguments.length > 0 ) - { - if( arguments[0] != null && !(arguments[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - label = (String)arguments[0]; - } + String label = optString( arguments, 0, null ); IMedia media = m_diskDrive.getDiskMedia(); if( media != null ) diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java index c5daff739..ec05ae783 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/ModemPeripheral.java @@ -21,6 +21,8 @@ import net.minecraft.world.World; import javax.annotation.Nonnull; +import static dan200.computercraft.core.apis.ArgumentHelper.getInt; + public abstract class ModemPeripheral implements IPeripheral, IPacketSender, IPacketReceiver { @@ -147,11 +149,7 @@ public abstract class ModemPeripheral private static int parseChannel( Object[] arguments, int index ) throws LuaException { - if( arguments.length <= index || !(arguments[index] instanceof Double) ) - { - throw new LuaException( "Expected number" ); - } - int channel = (int)((Double)arguments[index]).doubleValue(); + int channel = getInt( arguments, index ); if( channel < 0 || channel > 65535 ) { throw new LuaException( "Expected number in range 0-65535" ); diff --git a/src/main/java/dan200/computercraft/shared/peripheral/modem/TileCable.java b/src/main/java/dan200/computercraft/shared/peripheral/modem/TileCable.java index fc8502378..aea40409c 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/modem/TileCable.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/modem/TileCable.java @@ -40,6 +40,8 @@ import javax.annotation.Nonnull; import java.io.File; import java.util.*; +import static dan200.computercraft.core.apis.ArgumentHelper.getString; + public class TileCable extends TileModemBase implements IPacketNetwork { @@ -116,15 +118,6 @@ public class TileCable extends TileModemBase return newMethods; } - private String parseString( Object[] arguments, int index ) throws LuaException - { - if( arguments.length < (index + 1) || !(arguments[index] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - return (String)arguments[index]; - } - @Override public Object[] callMethod( @Nonnull IComputerAccess computer, @Nonnull ILuaContext context, int method, @Nonnull Object[] arguments ) throws LuaException, InterruptedException { @@ -148,13 +141,13 @@ public class TileCable extends TileModemBase case 1: { // isPresentRemote - String type = m_entity.getTypeRemote( parseString( arguments, 0 ) ); + String type = m_entity.getTypeRemote( getString( arguments, 0 ) ); return new Object[] { type != null }; } case 2: { // getTypeRemote - String type = m_entity.getTypeRemote( parseString( arguments, 0 ) ); + String type = m_entity.getTypeRemote( getString( arguments, 0 ) ); if( type != null ) { return new Object[] { type }; @@ -164,7 +157,7 @@ public class TileCable extends TileModemBase case 3: { // getMethodsRemote - String[] methodNames = m_entity.getMethodNamesRemote( parseString( arguments, 0 ) ); + String[] methodNames = m_entity.getMethodNamesRemote( getString( arguments, 0 ) ); if( methodNames != null ) { Map table = new HashMap(); @@ -178,8 +171,8 @@ public class TileCable extends TileModemBase case 4: { // callRemote - String remoteName = parseString( arguments, 0 ); - String methodName = parseString( arguments, 1 ); + String remoteName = getString( arguments, 0 ); + String methodName = getString( arguments, 1 ); Object[] methodArgs = new Object[ arguments.length - 2 ]; System.arraycopy( arguments, 2, methodArgs, 0, arguments.length - 2 ); return m_entity.callMethodRemote( remoteName, context, methodName, methodArgs ); diff --git a/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorPeripheral.java index e9dc35547..a063bef2f 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/monitor/MonitorPeripheral.java @@ -10,14 +10,15 @@ import dan200.computercraft.api.lua.ILuaContext; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.peripheral.IComputerAccess; import dan200.computercraft.api.peripheral.IPeripheral; +import dan200.computercraft.core.apis.TermAPI; import dan200.computercraft.core.terminal.Terminal; import dan200.computercraft.shared.util.Palette; import org.apache.commons.lang3.ArrayUtils; -import java.util.HashMap; - import javax.annotation.Nonnull; +import static dan200.computercraft.core.apis.ArgumentHelper.*; + public class MonitorPeripheral implements IPeripheral { private final TileMonitor m_monitor; @@ -90,23 +91,16 @@ public class MonitorPeripheral implements IPeripheral case 1: { // scroll - if( args.length < 1 || !(args[0] instanceof Number) ) - { - throw new LuaException( "Expected number" ); - } + int value = getInt( args, 0 ); Terminal terminal = m_monitor.getTerminal().getTerminal(); - terminal.scroll( ((Number)(args[0])).intValue() ); + terminal.scroll( value ); return null; } case 2: { // setCursorPos - if( args.length < 2 || !(args[0] instanceof Number) || !(args[1] instanceof Number) ) - { - throw new LuaException( "Expected number, number" ); - } - int x = ((Number)args[0]).intValue() - 1; - int y = ((Number)args[1]).intValue() - 1; + int x = getInt( args, 0 ) - 1; + int y = getInt( args, 1 ) - 1; Terminal terminal = m_monitor.getTerminal().getTerminal(); terminal.setCursorPos( x, y ); return null; @@ -114,12 +108,9 @@ public class MonitorPeripheral implements IPeripheral case 3: { // setCursorBlink - if( args.length < 1 || !(args[0] instanceof Boolean) ) - { - throw new LuaException( "Expected boolean" ); - } + boolean blink = getBoolean( args, 0 ); Terminal terminal = m_monitor.getTerminal().getTerminal(); - terminal.setCursorBlink( (Boolean) args[ 0 ] ); + terminal.setCursorBlink( blink ); return null; } case 4: @@ -157,11 +148,7 @@ public class MonitorPeripheral implements IPeripheral case 8: { // setTextScale - if( args.length < 1 || !(args[0] instanceof Number) ) - { - throw new LuaException( "Expected number" ); - } - int scale = (int)(((Number)args[0]).doubleValue() * 2.0); + int scale = (int) (getReal( args, 0 ) * 2.0); if( scale < 1 || scale > 10 ) { throw new LuaException( "Expected number in range 0.5-5" ); @@ -173,7 +160,7 @@ public class MonitorPeripheral implements IPeripheral case 10: { // setTextColour/setTextColor - int colour = dan200.computercraft.core.apis.TermAPI.parseColour( args ); + int colour = TermAPI.parseColour( args ); Terminal terminal = m_monitor.getTerminal().getTerminal(); terminal.setTextColour( colour ); return null; @@ -182,7 +169,7 @@ public class MonitorPeripheral implements IPeripheral case 12: { // setBackgroundColour/setBackgroundColor - int colour = dan200.computercraft.core.apis.TermAPI.parseColour( args ); + int colour = TermAPI.parseColour( args ); Terminal terminal = m_monitor.getTerminal().getTerminal(); terminal.setBackgroundColour( colour ); return null; @@ -200,26 +187,21 @@ public class MonitorPeripheral implements IPeripheral { // getTextColour/getTextColor Terminal terminal = m_monitor.getTerminal().getTerminal(); - return dan200.computercraft.core.apis.TermAPI.encodeColour( terminal.getTextColour() ); + return TermAPI.encodeColour( terminal.getTextColour() ); } case 17: case 18: { // getBackgroundColour/getBackgroundColor Terminal terminal = m_monitor.getTerminal().getTerminal(); - return dan200.computercraft.core.apis.TermAPI.encodeColour( terminal.getBackgroundColour() ); + return TermAPI.encodeColour( terminal.getBackgroundColour() ); } case 19: { // blit - if( args.length < 3 || !(args[0] instanceof String) || !(args[1] instanceof String) || !(args[2] instanceof String) ) - { - throw new LuaException( "Expected string, string, string" ); - } - - String text = (String)args[0]; - String textColour = (String)args[1]; - String backgroundColour = (String)args[2]; + String text = getString( args, 0 ); + String textColour = getString( args, 1 ); + String backgroundColour = getString( args, 2 ); if( textColour.length() != text.length() || backgroundColour.length() != text.length() ) { throw new LuaException( "Arguments must be the same length" ); @@ -236,26 +218,21 @@ public class MonitorPeripheral implements IPeripheral // setPaletteColour/setPaletteColor Terminal terminal = m_monitor.getTerminal().getTerminal(); - if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double) + int colour = 15 - TermAPI.parseColour( args ); + if( args.length == 2 ) { - int colour = 15 - dan200.computercraft.core.apis.TermAPI.parseColour( args ); - int hex = ((Double)args[1]).intValue(); + int hex = getInt( args, 1 ); double[] rgb = Palette.decodeRGB8( hex ); - dan200.computercraft.core.apis.TermAPI.setColour( terminal, colour, rgb[0], rgb[1], rgb[2] ); - return null; + TermAPI.setColour( terminal, colour, rgb[ 0 ], rgb[ 1 ], rgb[ 2 ] ); } - - if (args.length >= 4 && args[0] instanceof Double && args[1] instanceof Double && args[2] instanceof Double && args[3] instanceof Double) + else { - int colour = 15 - dan200.computercraft.core.apis.TermAPI.parseColour( args ); - double r = (Double)args[1]; - double g = (Double)args[2]; - double b = (Double)args[3]; - dan200.computercraft.core.apis.TermAPI.setColour( terminal, colour, r, g, b ); - return null; + double r = getReal( args, 1 ); + double g = getReal( args, 2 ); + double b = getReal( args, 3 ); + TermAPI.setColour( terminal, colour, r, g, b ); } - - throw new LuaException( "Expected number, number, number, number" ); + return null; } case 22: case 23: @@ -264,7 +241,7 @@ public class MonitorPeripheral implements IPeripheral Terminal terminal = m_monitor.getTerminal().getTerminal(); Palette palette = terminal.getPalette(); - int colour = 15 - dan200.computercraft.core.apis.TermAPI.parseColour( args ); + int colour = 15 - TermAPI.parseColour( args ); if( palette != null ) { diff --git a/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterPeripheral.java index 8269e205a..a9e446d69 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/printer/PrinterPeripheral.java @@ -14,6 +14,9 @@ import dan200.computercraft.core.terminal.Terminal; import javax.annotation.Nonnull; +import static dan200.computercraft.core.apis.ArgumentHelper.getInt; +import static dan200.computercraft.core.apis.ArgumentHelper.optString; + public class PrinterPeripheral implements IPeripheral { private final TilePrinter m_printer; @@ -70,13 +73,8 @@ public class PrinterPeripheral implements IPeripheral case 1: { // setCursorPos - if( args.length != 2 || args[0] == null || !(args[0] instanceof Number) || args[1] == null || !(args[1] instanceof Number) ) - { - throw new LuaException( "Expected number, number" ); - } - - int x = ((Number)args[0]).intValue() - 1; - int y = ((Number)args[1]).intValue() - 1; + int x = getInt( args, 0 ) - 1; + int y = getInt( args, 1 ) - 1; Terminal page = getCurrentPage(); page.setCursorPos( x, y ); return null; @@ -116,16 +114,7 @@ public class PrinterPeripheral implements IPeripheral case 7: { // setPageTitle - String title = ""; - if( args.length > 0 && args[0] != null ) - { - if( !(args[0] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - title = (String)args[0]; - } - + String title = optString( args, 0, "" ); getCurrentPage(); m_printer.setPageTitle( title ); return null; diff --git a/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java b/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java index 98f75ee39..9b42b8c6e 100644 --- a/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java +++ b/src/main/java/dan200/computercraft/shared/peripheral/speaker/SpeakerPeripheral.java @@ -17,9 +17,13 @@ import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundEvent; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; + import javax.annotation.Nonnull; import javax.annotation.Nullable; +import static dan200.computercraft.core.apis.ArgumentHelper.getString; +import static dan200.computercraft.core.apis.ArgumentHelper.optReal; + public class SpeakerPeripheral implements IPeripheral { private TileSpeaker m_speaker; private long m_clock; @@ -127,47 +131,20 @@ public class SpeakerPeripheral implements IPeripheral { @Nonnull private synchronized Object[] playNote( Object[] arguments, ILuaContext context ) throws LuaException { - float volume = 1.0f; - float pitch = 1.0f; + String name = getString(arguments, 0); + float volume = (float) optReal( arguments, 1, 1.0 ); + float pitch = (float) optReal( arguments, 2, 1.0 ); - // Check if arguments are correct - if( arguments.length == 0 ) // Too few args - { - throw new LuaException( "Expected string, number (optional), number (optional)" ); - } - - if( !(arguments[0] instanceof String) ) // Arg wrong type - { - throw new LuaException("Expected string, number (optional), number (optional)"); - } - - if ( !SoundEvent.REGISTRY.containsKey( new ResourceLocation( "block.note." + arguments[0] ) ) ) + // Check if sound exists + if ( !SoundEvent.REGISTRY.containsKey( new ResourceLocation( "block.note." + name ) ) ) { throw new LuaException("Invalid instrument, \"" + arguments[0] + "\"!"); } - if ( arguments.length > 1 ) - { - if ( arguments[1] != null && !(arguments[1] instanceof Double) ) // Arg wrong type - { - throw new LuaException( "Expected string, number (optional), number (optional)" ); - } - volume = arguments[1] != null ? ((Double) arguments[1]).floatValue() : 1f; - } - - if( arguments.length > 2 ) - { - if( arguments[2] != null && !(arguments[2] instanceof Double) ) // Arg wrong type - { - throw new LuaException("Expected string, number (optional), number (optional)"); - } - pitch = arguments[2] != null ? ((Double) arguments[2]).floatValue() : 1f; - } - // If the resource location for note block notes changes, this method call will need to be updated Object[] returnValue = playSound( new Object[] { - "block.note." + arguments[0], + "block.note." + name, (double)Math.min( volume, 3f ), Math.pow( 2.0f, ( pitch - 12.0f ) / 12.0f) }, context, true @@ -184,42 +161,11 @@ public class SpeakerPeripheral implements IPeripheral { @Nonnull private synchronized Object[] playSound( Object[] arguments, ILuaContext context, boolean isNote ) throws LuaException { + String name = getString(arguments, 0); + float volume = (float) optReal( arguments, 1, 1.0 ); + float pitch = (float) optReal( arguments, 2, 1.0 ); - float volume = 1.0f; - float pitch = 1.0f; - - // Check if arguments are correct - if( arguments.length == 0 ) // Too few args - { - throw new LuaException( "Expected string, number (optional), number (optional)" ); - } - - if( !(arguments[0] instanceof String) ) // Arg wrong type - { - throw new LuaException( "Expected string, number (optional), number (optional)" ); - } - - if( arguments.length > 1 ) - { - if( arguments[1] != null && !(arguments[1] instanceof Double) ) // Arg wrong type - { - throw new LuaException( "Expected string, number (optional), number (optional)" ); - } - - volume = arguments[1] != null ? ((Double) arguments[1]).floatValue() : 1f; - - } - - if( arguments.length > 2 ) - { - if( arguments[2] != null && !(arguments[2] instanceof Double) ) // Arg wrong type - { - throw new LuaException( "Expected string, number (optional), number (optional)" ); - } - pitch = arguments[2] != null ? ((Double) arguments[2]).floatValue() : 1f; - } - - ResourceLocation resourceName = new ResourceLocation( (String) arguments[0] ); + ResourceLocation resourceName = new ResourceLocation( name ); if( m_clock - m_lastPlayTime >= TileSpeaker.MIN_TICKS_BETWEEN_SOUNDS || ( ( m_clock - m_lastPlayTime == 0 ) && ( m_notesThisTick < ComputerCraft.maxNotesPerTick ) && isNote ) ) { diff --git a/src/main/java/dan200/computercraft/shared/turtle/apis/TurtleAPI.java b/src/main/java/dan200/computercraft/shared/turtle/apis/TurtleAPI.java index 70b7aefd4..20376791c 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/apis/TurtleAPI.java +++ b/src/main/java/dan200/computercraft/shared/turtle/apis/TurtleAPI.java @@ -22,6 +22,8 @@ import javax.annotation.Nonnull; import java.util.HashMap; import java.util.Map; +import static dan200.computercraft.core.apis.ArgumentHelper.*; + public class TurtleAPI implements ILuaAPI { private IAPIEnvironment m_environment; @@ -115,38 +117,23 @@ public class TurtleAPI implements ILuaAPI private int parseSlotNumber( Object[] arguments, int index ) throws LuaException { - int slot = parseOptionalSlotNumber( arguments, index, 99 ); - if( slot == 99 ) - { - throw new LuaException( "Expected number" ); - } - return slot; + int slot = getInt( arguments, index ); + if( slot < 1 || slot > 16 ) throw new LuaException( "Slot number " + slot + " out of range" ); + return slot - 1; } private int parseOptionalSlotNumber( Object[] arguments, int index, int fallback ) throws LuaException { - if( arguments.length <= index || !(arguments[index] instanceof Number) ) - { - return fallback; - } - int slot = ((Number)arguments[index]).intValue(); - if( slot >= 1 && slot <= 16 ) - { - return slot - 1; - } - else - { - throw new LuaException( "Slot number " + slot + " out of range" ); - } + if( index >= arguments.length || arguments[ index ] == null ) return fallback; + + int slot = getInt( arguments, index ); + if( slot < 1 || slot > 16 ) throw new LuaException( "Slot number " + slot + " out of range" ); + return slot - 1; } private int parseCount( Object[] arguments, int index ) throws LuaException { - if( arguments.length <= index || !(arguments[index] instanceof Number) ) - { - throw new LuaException( "Expected number" ); - } - int count = ((Number)arguments[index]).intValue(); + int count = optInt( arguments, index, 64 ); if( count >= 0 && count <= 64 ) { return count; @@ -159,19 +146,16 @@ public class TurtleAPI implements ILuaAPI private Optional parseSide( Object[] arguments, int index ) throws LuaException { - if( arguments.length <= index || arguments[index] == null ) + String side = optString( arguments, index, null ); + if( side == null ) { return Optional.absent(); } - if( !(arguments[ index ] instanceof String) ) - { - throw new LuaException( "Expected string" ); - } - if( arguments[ index ].equals( "left" ) ) + else if( side.equalsIgnoreCase( "left" ) ) { return Optional.of( TurtleSide.Left ); } - else if( arguments[ index ].equals( "right" ) ) + else if( side.equalsIgnoreCase( "right" ) ) { return Optional.of( TurtleSide.Right ); } @@ -252,11 +236,7 @@ public class TurtleAPI implements ILuaAPI case 12: { // drop - int count = 64; - if( args.length > 0 ) - { - count = parseCount( args, 0 ); - } + int count = parseCount( args, 0 ); return tryCommand( context, new TurtleDropCommand( InteractDirection.Forward, count ) ); } case 13: @@ -343,51 +323,31 @@ public class TurtleAPI implements ILuaAPI case 25: { // dropUp - int count = 64; - if( args.length > 0 ) - { - count = parseCount( args, 0 ); - } + int count = parseCount( args, 0 ); return tryCommand( context, new TurtleDropCommand( InteractDirection.Up, count ) ); } case 26: { // dropDown - int count = 64; - if( args.length > 0 ) - { - count = parseCount( args, 0 ); - } + int count = parseCount( args, 0 ); return tryCommand( context, new TurtleDropCommand( InteractDirection.Down, count ) ); } case 27: { // suck - int count = 64; - if( args.length > 0 ) - { - count = parseCount( args, 0 ); - } + int count = parseCount( args, 0 ); return tryCommand( context, new TurtleSuckCommand( InteractDirection.Forward, count ) ); } case 28: { // suckUp - int count = 64; - if( args.length > 0 ) - { - count = parseCount( args, 0 ); - } + int count = parseCount( args, 0 ); return tryCommand( context, new TurtleSuckCommand( InteractDirection.Up, count ) ); } case 29: { // suckDown - int count = 64; - if( args.length > 0 ) - { - count = parseCount( args, 0 ); - } + int count = parseCount( args, 0 ); return tryCommand( context, new TurtleSuckCommand( InteractDirection.Down, count ) ); } case 30: @@ -405,11 +365,7 @@ public class TurtleAPI implements ILuaAPI case 31: { // refuel - int count = 64; - if( args.length > 0 ) - { - count = parseCount( args, 0 ); - } + int count = parseCount( args, 0 ); return tryCommand( context, new TurtleRefuelCommand( count ) ); } case 32: @@ -422,11 +378,7 @@ public class TurtleAPI implements ILuaAPI { // transferTo int slot = parseSlotNumber( args, 0 ); - int count = 64; - if( args.length > 1 ) - { - count = parseCount( args, 1 ); - } + int count = parseCount( args, 1 ); return tryCommand( context, new TurtleTransferToCommand( slot, count ) ); } case 34: diff --git a/src/main/java/dan200/computercraft/shared/turtle/upgrades/CraftingTablePeripheral.java b/src/main/java/dan200/computercraft/shared/turtle/upgrades/CraftingTablePeripheral.java index 6ef5dbb9b..3379f8c01 100644 --- a/src/main/java/dan200/computercraft/shared/turtle/upgrades/CraftingTablePeripheral.java +++ b/src/main/java/dan200/computercraft/shared/turtle/upgrades/CraftingTablePeripheral.java @@ -15,6 +15,8 @@ import dan200.computercraft.shared.turtle.core.TurtleCraftCommand; import javax.annotation.Nonnull; +import static dan200.computercraft.core.apis.ArgumentHelper.optInt; + public class CraftingTablePeripheral implements IPeripheral { @@ -45,16 +47,7 @@ public class CraftingTablePeripheral private int parseCount( Object[] arguments ) throws LuaException { - if( arguments.length < 1 ) - { - return 64; - } - - if( !(arguments[0] instanceof Number) ) - { - throw new LuaException( "Expected number" ); - } - int count = ((Number)arguments[0]).intValue(); + int count = optInt( arguments, 0, 64 ); if( count < 0 || count > 64 ) { throw new LuaException( "Crafting count " + count + " out of range" ); From fac625173adc795a7b0b485ac13df289a99c4826 Mon Sep 17 00:00:00 2001 From: SquidDev Date: Mon, 12 Jun 2017 10:54:44 +0100 Subject: [PATCH 2/3] Use Lua style error messages in the rom files This makes it mostly consistent with the Java APIs, and makes debugging significantly easier. --- .../computercraft/lua/rom/apis/colors.lua | 2 +- .../computercraft/lua/rom/apis/paintutils.lua | 44 +++++----- .../computercraft/lua/rom/apis/parallel.lua | 23 +++-- .../computercraft/lua/rom/apis/peripheral.lua | 24 +++-- .../computercraft/lua/rom/apis/settings.lua | 18 ++-- .../computercraft/lua/rom/apis/window.lua | 87 ++++++++----------- 6 files changed, 99 insertions(+), 99 deletions(-) diff --git a/src/main/resources/assets/computercraft/lua/rom/apis/colors.lua b/src/main/resources/assets/computercraft/lua/rom/apis/colors.lua index f1d5d2b0b..fea975d16 100644 --- a/src/main/resources/assets/computercraft/lua/rom/apis/colors.lua +++ b/src/main/resources/assets/computercraft/lua/rom/apis/colors.lua @@ -45,6 +45,6 @@ function rgb8( r, g, b ) bit32.lshift( bit32.band(g * 255, 0xFF), 8 ) + bit32.band(b * 255, 0xFF) else - error( "Expected 1 or 3 numbers" ) + error( "Expected 1 or 3 numbers", 2 ) end end diff --git a/src/main/resources/assets/computercraft/lua/rom/apis/paintutils.lua b/src/main/resources/assets/computercraft/lua/rom/apis/paintutils.lua index 544ce3568..8445a71be 100644 --- a/src/main/resources/assets/computercraft/lua/rom/apis/paintutils.lua +++ b/src/main/resources/assets/computercraft/lua/rom/apis/paintutils.lua @@ -11,7 +11,7 @@ end function loadImage( sPath ) if type( sPath ) ~= "string" then - error( "Expected path", 2 ) + error( "bad argument #1 (expected string, got " .. type( sPath ) .. ")", 2 ) end local tImage = {} @@ -33,9 +33,9 @@ function loadImage( sPath ) end function drawPixel( xPos, yPos, nColour ) - if type( xPos ) ~= "number" or type( yPos ) ~= "number" or (nColour ~= nil and type( nColour ) ~= "number") then - error( "Expected x, y, colour", 2 ) - end + if type( xPos ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( xPos ) .. ")", 2 ) end + if type( yPos ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( yPos ) .. ")", 2 ) end + if nColour ~= nil and type( nColour ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( nColour ) .. ")", 2 ) end if nColour then term.setBackgroundColor( nColour ) end @@ -43,11 +43,11 @@ function drawPixel( xPos, yPos, nColour ) end function drawLine( startX, startY, endX, endY, nColour ) - if type( startX ) ~= "number" or type( startX ) ~= "number" or - type( endX ) ~= "number" or type( endY ) ~= "number" or - (nColour ~= nil and type( nColour ) ~= "number") then - error( "Expected startX, startY, endX, endY, colour", 2 ) - end + if type( startX ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( startX ) .. ")", 2 ) end + if type( startY ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( startY ) .. ")", 2 ) end + if type( endX ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( endX ) .. ")", 2 ) end + if type( endY ) ~= "number" then error( "bad argument #4 (expected number, got " .. type( endY ) .. ")", 2 ) end + if nColour ~= nil and type( nColour ) ~= "string" then error( "bad argument #5 (expected number, got " .. type( nColour ) .. ")", 2 ) end startX = math.floor(startX) startY = math.floor(startY) @@ -103,11 +103,11 @@ function drawLine( startX, startY, endX, endY, nColour ) end function drawBox( startX, startY, endX, endY, nColour ) - if type( startX ) ~= "number" or type( startX ) ~= "number" or - type( endX ) ~= "number" or type( endY ) ~= "number" or - (nColour ~= nil and type( nColour ) ~= "number") then - error( "Expected startX, startY, endX, endY, colour", 2 ) - end + if type( startX ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( startX ) .. ")", 2 ) end + if type( startY ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( startY ) .. ")", 2 ) end + if type( endX ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( endX ) .. ")", 2 ) end + if type( endY ) ~= "number" then error( "bad argument #4 (expected number, got " .. type( endY ) .. ")", 2 ) end + if nColour ~= nil and type( nColour ) ~= "string" then error( "bad argument #5 (expected number, got " .. type( nColour ) .. ")", 2 ) end startX = math.floor(startX) startY = math.floor(startY) @@ -147,11 +147,11 @@ function drawBox( startX, startY, endX, endY, nColour ) end function drawFilledBox( startX, startY, endX, endY, nColour ) - if type( startX ) ~= "number" or type( startX ) ~= "number" or - type( endX ) ~= "number" or type( endY ) ~= "number" or - (nColour ~= nil and type( nColour ) ~= "number") then - error( "Expected startX, startY, endX, endY, colour", 2 ) - end + if type( startX ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( startX ) .. ")", 2 ) end + if type( startY ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( startY ) .. ")", 2 ) end + if type( endX ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( endX ) .. ")", 2 ) end + if type( endY ) ~= "number" then error( "bad argument #4 (expected number, got " .. type( endY ) .. ")", 2 ) end + if nColour ~= nil and type( nColour ) ~= "string" then error( "bad argument #5 (expected number, got " .. type( nColour ) .. ")", 2 ) end startX = math.floor(startX) startY = math.floor(startY) @@ -185,9 +185,9 @@ function drawFilledBox( startX, startY, endX, endY, nColour ) end function drawImage( tImage, xPos, yPos ) - if type( tImage ) ~= "table" or type( xPos ) ~= "number" or type( yPos ) ~= "number" then - error( "Expected image, x, y", 2 ) - end + if type( tImage ) ~= "table" then error( "bad argument #1 (expected number, got " .. type( tImage ) .. ")", 2 ) end + if type( xPos ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( xPos ) .. ")", 2 ) end + if type( yPos ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( yPos ) .. ")", 2 ) end for y=1,#tImage do local tLine = tImage[y] for x=1,#tLine do diff --git a/src/main/resources/assets/computercraft/lua/rom/apis/parallel.lua b/src/main/resources/assets/computercraft/lua/rom/apis/parallel.lua index 5c2d06faf..3c3bbb489 100644 --- a/src/main/resources/assets/computercraft/lua/rom/apis/parallel.lua +++ b/src/main/resources/assets/computercraft/lua/rom/apis/parallel.lua @@ -1,12 +1,17 @@ -local function create( first, ... ) - if first ~= nil then - if type( first ) ~= "function" then - error( "Expected function, got "..type( first ), 3 ) - end - return coroutine.create(first), create( ... ) +local function create( ... ) + local tFns = table.pack(...) + local tCos = {} + for i = 1, tFns.n, 1 do + local fn = tFns[i] + if type( fn ) ~= "function" then + error( "bad argument #" .. i .. " (expected function, got " .. type( fn ) .. ")", 3 ) + end + + tCos[i] = coroutine.create(fn) end - return nil + + return tCos end local function runUntilLimit( _routines, _limit ) @@ -51,11 +56,11 @@ local function runUntilLimit( _routines, _limit ) end function waitForAny( ... ) - local routines = { create( ... ) } + local routines = create( ... ) return runUntilLimit( routines, #routines - 1 ) end function waitForAll( ... ) - local routines = { create( ... ) } + local routines = create( ... ) runUntilLimit( routines, 0 ) end diff --git a/src/main/resources/assets/computercraft/lua/rom/apis/peripheral.lua b/src/main/resources/assets/computercraft/lua/rom/apis/peripheral.lua index bbb59afed..9ab5b6fa9 100644 --- a/src/main/resources/assets/computercraft/lua/rom/apis/peripheral.lua +++ b/src/main/resources/assets/computercraft/lua/rom/apis/peripheral.lua @@ -18,7 +18,7 @@ end function isPresent( _sSide ) if type( _sSide ) ~= "string" then - error( "Expected string", 2 ) + error( "bad argument #1 (expected string, got " .. type( _sSide ) .. ")", 2 ) end if native.isPresent( _sSide ) then return true @@ -35,7 +35,7 @@ end function getType( _sSide ) if type( _sSide ) ~= "string" then - error( "Expected string", 2 ) + error( "bad argument #1 (expected string, got " .. type( _sSide ) .. ")", 2 ) end if native.isPresent( _sSide ) then return native.getType( _sSide ) @@ -52,7 +52,7 @@ end function getMethods( _sSide ) if type( _sSide ) ~= "string" then - error( "Expected string", 2 ) + error( "bad argument #1 (expected string, got " .. type( _sSide ) .. ")", 2 ) end if native.isPresent( _sSide ) then return native.getMethods( _sSide ) @@ -68,8 +68,11 @@ function getMethods( _sSide ) end function call( _sSide, _sMethod, ... ) - if type( _sSide ) ~= "string" or type( _sMethod ) ~= "string" then - error( "Expected string, string", 2 ) + if type( _sSide ) ~= "string" then + error( "bad argument #1 (expected string, got " .. type( _sSide ) .. ")", 2 ) + end + if type( _sSide ) ~= "string" then + error( "bad argument #2 (expected string, got " .. type( _sMethod ) .. ")", 2 ) end if native.isPresent( _sSide ) then return native.call( _sSide, _sMethod, ... ) @@ -85,8 +88,8 @@ function call( _sSide, _sMethod, ... ) end function wrap( _sSide ) - if type( _sSide ) ~= "string" then - error( "Expected string", 2 ) + if type( _sSide ) ~= "string" then + error( "bad argument #1 (expected string, got " .. type( _sSide ) .. ")", 2 ) end if peripheral.isPresent( _sSide ) then local tMethods = peripheral.getMethods( _sSide ) @@ -102,8 +105,11 @@ function wrap( _sSide ) end function find( sType, fnFilter ) - if type( sType ) ~= "string" or (fnFilter ~= nil and type( fnFilter ) ~= "function") then - error( "Expected string, [function]", 2 ) + if type( _sSide ) ~= "string" then + error( "bad argument #1 (expected string, got " .. type( _sSide ) .. ")", 2 ) + end + if fnFilter ~= nil and type( fnFilter ) ~= "string" then + error( "bad argument #2 (expected function, got " .. type( fnFilter ) .. ")", 2 ) end local tResults = {} for n,sName in ipairs( peripheral.getNames() ) do diff --git a/src/main/resources/assets/computercraft/lua/rom/apis/settings.lua b/src/main/resources/assets/computercraft/lua/rom/apis/settings.lua index 6f2286766..fe20745f8 100644 --- a/src/main/resources/assets/computercraft/lua/rom/apis/settings.lua +++ b/src/main/resources/assets/computercraft/lua/rom/apis/settings.lua @@ -2,11 +2,13 @@ local tSettings = {} function set( sName, value ) - if type(sName) ~= "string" or - (type(value) ~= "string" and type(value) ~= "number" and type(value) ~= "boolean" and type(value) ~= "table") then - error( "Expected string, value", 2 ) + if type( sName ) ~= "string" then error( "bad argument #1 (expected string, got " .. type( sName ) .. ")", 2 ) end + + local sValueTy = type(value) + if sValueTy ~= "number" and sValueTy ~= "string" and sValueTy ~= "boolean" and sValueTy ~= "table" then + error( "bad argument #2 (expected value, got " .. sValueTy .. ")", 2 ) end - if type(value) == "table" then + if sValueTy == "table" then -- Ensure value is serializeable value = textutils.unserialize( textutils.serialize(value) ) end @@ -28,7 +30,7 @@ end function get( sName, default ) if type(sName) ~= "string" then - error( "Expected string", 2 ) + error( "bad argument #1 (expected string, got " .. type( sName ) .. ")", 2 ) end local result = tSettings[ sName ] if result ~= nil then @@ -40,7 +42,7 @@ end function unset( sName ) if type(sName) ~= "string" then - error( "Expected string", 2 ) + error( "bad argument #1 (expected string, got " .. type( sName ) .. ")", 2 ) end tSettings[ sName ] = nil end @@ -59,7 +61,7 @@ end function load( sPath ) if type(sPath) ~= "string" then - error( "Expected string", 2 ) + error( "bad argument #1 (expected string, got " .. type( sPath ) .. ")", 2 ) end local file = fs.open( sPath, "r" ) if not file then @@ -86,7 +88,7 @@ end function save( sPath ) if type(sPath) ~= "string" then - error( "Expected string", 2 ) + error( "bad argument #1 (expected string, got " .. type( sPath ) .. ")", 2 ) end local file = fs.open( sPath, "w" ) if not file then diff --git a/src/main/resources/assets/computercraft/lua/rom/apis/window.lua b/src/main/resources/assets/computercraft/lua/rom/apis/window.lua index df44fd0ec..eaac77eae 100644 --- a/src/main/resources/assets/computercraft/lua/rom/apis/window.lua +++ b/src/main/resources/assets/computercraft/lua/rom/apis/window.lua @@ -18,20 +18,18 @@ local tHex = { [ colors.black ] = "f", } +local type = type local string_rep = string.rep local string_sub = string.sub local table_unpack = table.unpack function create( parent, nX, nY, nWidth, nHeight, bStartVisible ) - - if type( parent ) ~= "table" or - type( nX ) ~= "number" or - type( nY ) ~= "number" or - type( nWidth ) ~= "number" or - type( nHeight ) ~= "number" or - (bStartVisible ~= nil and type( bStartVisible ) ~= "boolean") then - error( "Expected object, number, number, number, number, [boolean]", 2 ) - end + if type( parent ) ~= "table" then error( "bad argument #1 (expected table, got " .. type( parent ) .. ")", 2 ) end + if type( nX ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( nX ) .. ")", 2 ) end + if type( nY ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( nY ) .. ")", 2 ) end + if type( nWidth ) ~= "number" then error( "bad argument #4 (expected number, got " .. type( nWidth ) .. ")", 2 ) end + if type( nHeight ) ~= "number" then error( "bad argument #5 (expected number, got " .. type( nHeight ) .. ")", 2 ) end + if bStartVisible ~= nil and type( bStartVisible ) ~= "boolean" then error( "bad argument #6 (expected boolean, got " .. type( bStartVisible ) .. ")", 2 ) end if parent == term then error( "term is not a recommended window parent, try term.current() instead", 2 ) @@ -193,9 +191,9 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible ) end function window.blit( sText, sTextColor, sBackgroundColor ) - if type(sText) ~= "string" or type(sTextColor) ~= "string" or type(sBackgroundColor) ~= "string" then - error( "Expected string, string, string", 2 ) - end + if type( sText ) ~= "string" then error( "bad argument #1 (expected string, got " .. type( sText ) .. ")", 2 ) end + if type( sTextColor ) ~= "string" then error( "bad argument #2 (expected string, got " .. type( sTextColor ) .. ")", 2 ) end + if type( sBackgroundColor ) ~= "string" then error( "bad argument #3 (expected string, got " .. type( sBackgroundColor ) .. ")", 2 ) end if #sTextColor ~= #sText or #sBackgroundColor ~= #sText then error( "Arguments must be the same length", 2 ) end @@ -243,9 +241,8 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible ) end function window.setCursorPos( x, y ) - if type( x ) ~= "number" or type( y ) ~= "number" then - error( "Expected number, number", 2 ) - end + if type( x ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( x ) .. ")", 2 ) end + if type( y ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( y ) .. ")", 2 ) end nCursorX = math.floor( x ) nCursorY = math.floor( y ) if bVisible then @@ -254,9 +251,7 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible ) end function window.setCursorBlink( blink ) - if type( blink ) ~= "boolean" then - error( "Expected boolean", 2 ) - end + if type( blink ) ~= "boolean" then error( "bad argument #1 (expected boolean, got " .. type( blink ) .. ")", 2 ) end bCursorBlink = blink if bVisible then updateCursorBlink() @@ -276,10 +271,10 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible ) end local function setTextColor( color ) - if type(color) ~= "number" then - error( "Expected number", 3 ) + if type( color ) ~= "number" then + error( "bad argument #1 (expected number, got " .. type( color ) .. ")", 2 ) elseif tHex[color] == nil then - error( "Invalid color", 3 ) + error( "Invalid color", 2 ) end nTextColor = color if bVisible then @@ -287,26 +282,25 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible ) end end - function window.setTextColor( color ) - setTextColor( color ) - end - - function window.setTextColour( color ) - setTextColor( color ) - end + window.setTextColor = setTextColor + window.setTextColour = setTextColor function window.setPaletteColour( colour, r, g, b ) + if type( colour ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( colour ) .. ")", 2 ) end + local tCol - if type(colour) == "number" and type(r) == "number" and g == nil and b == nil then + if type(r) == "number" and g == nil and b == nil then tCol = { colours.rgb8( r ) } tPalette[ colour ] = tCol - elseif type(colour) == "number" and type(r) == "number" and type(g) == "number" and type(b) == "number" then + else + if type( r ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( r ) .. ")", 2 ) end + if type( g ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( g ) .. ")", 2 ) end + if type( b ) ~= "number" then error( "bad argument #4 (expected number, got " .. type( b ) .. ")", 2 ) end + tCol = tPalette[ colour ] tCol[1] = r tCol[2] = g tCol[3] = b - else - error( "Expected number, number, number, number", 2 ) end if bVisible then @@ -324,30 +318,23 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible ) window.getPaletteColor = window.getPaletteColour local function setBackgroundColor( color ) - if type(color) ~= "number" then - error( "Expected number", 3 ) + if type( color ) ~= "number" then + error( "bad argument #1 (expected number, got " .. type( color ) .. ")", 2 ) elseif tHex[color] == nil then error( "Invalid color", 3 ) end nBackgroundColor = color end - function window.setBackgroundColor( color ) - setBackgroundColor( color ) - end - - function window.setBackgroundColour( color ) - setBackgroundColor( color ) - end + window.setBackgroundColor = setBackgroundColor + window.setBackgroundColour = setBackgroundColor function window.getSize() return nWidth, nHeight end function window.scroll( n ) - if type( n ) ~= "number" then - error( "Expected number", 2 ) - end + if type( n ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( n ) .. ")", 2 ) end if n ~= 0 then local tNewLines = {} local sEmptyText = sEmptySpaceLine @@ -392,9 +379,7 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible ) -- Other functions function window.setVisible( bVis ) - if type( bVis) ~= "boolean" then - error( "Expected boolean", 2 ) - end + if type( bVis ) ~= "boolean" then error( "bad argument #1 (expected boolean, got " .. type( bVis ) .. ")", 2 ) end if bVisible ~= bVis then bVisible = bVis if bVisible then @@ -426,9 +411,11 @@ function create( parent, nX, nY, nWidth, nHeight, bStartVisible ) end function window.reposition( nNewX, nNewY, nNewWidth, nNewHeight ) - if type( nNewX ) ~= "number" or type( nNewY ) ~= "number" or type( nNewWidth ) ~= "number" or type( nNewWidth ) ~= "number" then - error( "Expected number, number, number, number", 2 ) - end + if type( nNewX ) ~= "number" then error( "bad argument #1 (expected number, got " .. type( nNewX ) .. ")", 2 ) end + if type( nNewY ) ~= "number" then error( "bad argument #2 (expected number, got " .. type( nNewY ) .. ")", 2 ) end + if type( nNewWidth ) ~= "number" then error( "bad argument #3 (expected number, got " .. type( nNewWidth ) .. ")", 2 ) end + if type( nNewHeight ) ~= "number" then error( "bad argument #4 (expected number, got " .. type( nNewHeight ) .. ")", 2 ) end + nX = nNewX nY = nNewY if nNewWidth and nNewHeight then From eb628e9b623ec360658119b4d664a731228691ed Mon Sep 17 00:00:00 2001 From: SquidDev Date: Tue, 13 Jun 2017 19:33:42 +0100 Subject: [PATCH 3/3] Make error messages more consistent --- .../dan200/computercraft/core/filesystem/FileSystem.java | 8 ++++---- .../computercraft/lua/rom/programs/fun/advanced/paint.lua | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java b/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java index b6a6d870b..cab9abdac 100644 --- a/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java +++ b/src/main/java/dan200/computercraft/core/filesystem/FileSystem.java @@ -172,7 +172,7 @@ public class FileSystem { if( m_writableMount == null ) { - throw new FileSystemException( "Access Denied" ); + throw new FileSystemException( "Access denied" ); } try { @@ -199,7 +199,7 @@ public class FileSystem { if( m_writableMount == null ) { - throw new FileSystemException( "Access Denied" ); + throw new FileSystemException( "Access denied" ); } try { @@ -219,7 +219,7 @@ public class FileSystem { if( m_writableMount == null ) { - throw new FileSystemException( "Access Denied" ); + throw new FileSystemException( "Access denied" ); } try { @@ -251,7 +251,7 @@ public class FileSystem { if( m_writableMount == null ) { - throw new FileSystemException( "Access Denied" ); + throw new FileSystemException( "Access denied" ); } try { diff --git a/src/main/resources/assets/computercraft/lua/rom/programs/fun/advanced/paint.lua b/src/main/resources/assets/computercraft/lua/rom/programs/fun/advanced/paint.lua index bba2f67a3..59089054d 100644 --- a/src/main/resources/assets/computercraft/lua/rom/programs/fun/advanced/paint.lua +++ b/src/main/resources/assets/computercraft/lua/rom/programs/fun/advanced/paint.lua @@ -310,7 +310,7 @@ local function accessMenu() -- Select an option if mChoices[selection]=="Save" then if bReadOnly then - fMessage = "Access Denied" + fMessage = "Access denied" return false end local success = save(sPath)