Error reporting for JS Vector and Entity methods.
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@911 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
parent
67138687af
commit
ca593a0a1e
@ -215,6 +215,7 @@ script.javaScript.call.badSelector = $scriptError;
|
||||
script.javaScript.error = $scriptError;
|
||||
script.javaScript.exception = $scriptError;
|
||||
script.javaScript.warning = $scriptError;
|
||||
script.javaScript.badParameter = $scriptError;
|
||||
|
||||
script.load = no;
|
||||
script.load.badName = $scriptError;
|
||||
|
@ -272,6 +272,8 @@
|
||||
<string>inherit</string>
|
||||
<key>script.debug.testCondition.testValues</key>
|
||||
<string>inherit</string>
|
||||
<key>script.javaScript.badParameter</key>
|
||||
<string>$scriptError</string>
|
||||
<key>script.javaScript.call.badSelector</key>
|
||||
<string>$scriptError</string>
|
||||
<key>script.javaScript.error</key>
|
||||
|
@ -41,6 +41,8 @@ static JSBool EntityEquality(JSContext *context, JSObject *this, jsval value, JS
|
||||
|
||||
// Methods
|
||||
static JSBool EntitySetPosition(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
|
||||
// static JSBool EntitySetOrientation(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
|
||||
static JSBool EntityValid(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult);
|
||||
|
||||
|
||||
static JSExtendedClass sEntityClass =
|
||||
@ -108,6 +110,7 @@ static JSFunctionSpec sEntityMethods[] =
|
||||
// JS name Function min args
|
||||
{ "setPosition", EntitySetPosition, 1, },
|
||||
// { "setOrientation", EntitySetOrientation, 1, },
|
||||
{ "valid", EntityValid, 0, },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@ -279,8 +282,14 @@ static JSBool EntityConvert(JSContext *context, JSObject *this, JSType type, jsv
|
||||
case JSTYPE_VOID: // Used for string concatenation.
|
||||
case JSTYPE_STRING:
|
||||
// Return description of vector
|
||||
if (!JSEntityGetEntity(context, this, &entity)) return NO;
|
||||
*outValue = [[entity description] javaScriptValueInContext:context];
|
||||
if (JSEntityGetEntity(context, this, &entity))
|
||||
{
|
||||
*outValue = [[entity description] javaScriptValueInContext:context];
|
||||
}
|
||||
else
|
||||
{
|
||||
*outValue = STRING_TO_JSVAL(JS_InternString(context, "[stale Entity]"));
|
||||
}
|
||||
return YES;
|
||||
|
||||
default:
|
||||
@ -300,11 +309,11 @@ static JSBool EntityEquality(JSContext *context, JSObject *this, jsval value, JS
|
||||
{
|
||||
Entity *thisEnt, *thatEnt;
|
||||
|
||||
if (!JSVAL_IS_OBJECT(value)) return NO;
|
||||
if (!JSEntityGetEntity(context, this, &thisEnt)) return NO;
|
||||
if (!JSEntityGetEntity(context, JSVAL_TO_OBJECT(value), &thatEnt)) return NO;
|
||||
// No failures or diagnostic messages.
|
||||
JSEntityGetEntity(context, this, &thisEnt);
|
||||
JSEntityGetEntity(context, JSVAL_TO_OBJECT(value), &thatEnt);
|
||||
|
||||
*outEqual = [thisEnt isEqual:thatEnt];
|
||||
*outEqual = [thisEnt isEqual:thatEnt]; // Note ![nil isEqual:nil], so two stale entity refs will not be equal.
|
||||
return YES;
|
||||
}
|
||||
|
||||
@ -314,9 +323,22 @@ static JSBool EntitySetPosition(JSContext *context, JSObject *this, uintN argc,
|
||||
Entity *thisEnt;
|
||||
Vector vector;
|
||||
|
||||
if (!JSEntityGetEntity(context, this, &thisEnt)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &vector, NULL)) return NO;
|
||||
if (!JSEntityGetEntity(context, this, &thisEnt)) return YES; // stale reference, no-op.
|
||||
if (!VectorFromArgumentList(context, argc, argv, &vector, NULL))
|
||||
{
|
||||
ReportVectorParamConversionFailure(context, @"Entity", @"setPosition", argc, argv);
|
||||
return YES;
|
||||
}
|
||||
|
||||
[thisEnt setPosition:vector];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
static JSBool EntityValid(JSContext *context, JSObject *this, uintN argc, jsval *argv, jsval *outResult)
|
||||
{
|
||||
Entity *thisEnt;
|
||||
|
||||
*outResult = BOOLEAN_TO_JSVAL(JSEntityGetEntity(context, this, &thisEnt));
|
||||
return YES;
|
||||
}
|
||||
|
@ -46,3 +46,7 @@ BOOL JSVectorSetVector(JSContext *context, JSObject *vectorObj, Vector vector);
|
||||
|
||||
// Construct a vector from an argument list which is either a (JS) vector, a (JS) entity, or three things that can be considered numbers. The optional outConsumed argument can be used to find out how many parameters were used (currently, this will be 0 on failure, otherwise 1 or 3). If it fails (and returns NO) the vector will be unaltered.
|
||||
BOOL VectorFromArgumentList(JSContext *context, uintN argc, jsval *argv, Vector *outVector, uintN *outConsumed);
|
||||
|
||||
|
||||
// Standard error reporter for VectorFromArgumentList() failure.
|
||||
void ReportVectorParamConversionFailure(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv);
|
||||
|
@ -247,6 +247,12 @@ BOOL VectorFromArgumentList(JSContext *context, uintN argc, jsval *argv, Vector
|
||||
}
|
||||
|
||||
|
||||
void ReportVectorParamConversionFailure(JSContext *context, NSString *scriptClass, NSString *function, uintN argc, jsval *argv)
|
||||
{
|
||||
OOReportJavaScriptWarning(context, @"%@.%@(): could not construct vector from parameters %@.", scriptClass, function, [NSString stringWithJavaScriptParameters:argv count:argc inContext:context]);
|
||||
}
|
||||
|
||||
|
||||
static JSBool VectorGetProperty(JSContext *context, JSObject *this, jsval name, jsval *outValue)
|
||||
{
|
||||
Vector vector;
|
||||
@ -269,7 +275,7 @@ static JSBool VectorGetProperty(JSContext *context, JSObject *this, jsval name,
|
||||
break;
|
||||
|
||||
default:
|
||||
return NO;
|
||||
return YES;
|
||||
}
|
||||
|
||||
return YES;
|
||||
@ -300,7 +306,7 @@ static JSBool VectorSetProperty(JSContext *context, JSObject *this, jsval name,
|
||||
break;
|
||||
|
||||
default:
|
||||
return NO;
|
||||
return YES;
|
||||
}
|
||||
|
||||
return JSVectorSetVector(context, this, vector);
|
||||
@ -372,9 +378,10 @@ static JSBool VectorEquality(JSContext *context, JSObject *this, jsval value, JS
|
||||
{
|
||||
Vector thisv, thatv;
|
||||
|
||||
if (!JSVAL_IS_OBJECT(value)) return NO;
|
||||
*outEqual = NO;
|
||||
if (!JSVectorGetVector(context, this, &thisv)) return NO;
|
||||
if (!JSVectorGetVector(context, JSVAL_TO_OBJECT(value), &thatv)) return NO;
|
||||
if (!JSVAL_IS_OBJECT(value)) return YES;
|
||||
if (!JSVectorGetVector(context, JSVAL_TO_OBJECT(value), &thatv)) return YES;
|
||||
|
||||
*outEqual = vector_equal(thisv, thatv);
|
||||
return YES;
|
||||
@ -386,7 +393,11 @@ static JSBool VectorAdd(JSContext *context, JSObject *this, uintN argc, jsval *a
|
||||
Vector thisv, thatv, result;
|
||||
|
||||
if (!JSVectorGetVector(context, this, &thisv)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL))
|
||||
{
|
||||
ReportVectorParamConversionFailure(context, @"Vector", @"add", argc, argv);
|
||||
return YES;
|
||||
}
|
||||
|
||||
result = vector_add(thisv, thatv);
|
||||
|
||||
@ -399,7 +410,11 @@ static JSBool VectorSubtract(JSContext *context, JSObject *this, uintN argc, jsv
|
||||
Vector thisv, thatv, result;
|
||||
|
||||
if (!JSVectorGetVector(context, this, &thisv)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL))
|
||||
{
|
||||
ReportVectorParamConversionFailure(context, @"Vector", @"subtract", argc, argv);
|
||||
return YES;
|
||||
}
|
||||
|
||||
result = vector_subtract(thisv, thatv);
|
||||
|
||||
@ -413,7 +428,11 @@ static JSBool VectorDistanceTo(JSContext *context, JSObject *this, uintN argc, j
|
||||
GLfloat result;
|
||||
|
||||
if (!JSVectorGetVector(context, this, &thisv)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL))
|
||||
{
|
||||
ReportVectorParamConversionFailure(context, @"Vector", @"distanceTo", argc, argv);
|
||||
return YES;
|
||||
}
|
||||
|
||||
result = distance(thisv, thatv);
|
||||
|
||||
@ -427,7 +446,11 @@ static JSBool VectorSquaredDistanceTo(JSContext *context, JSObject *this, uintN
|
||||
GLfloat result;
|
||||
|
||||
if (!JSVectorGetVector(context, this, &thisv)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL))
|
||||
{
|
||||
ReportVectorParamConversionFailure(context, @"Vector", @"squaredDistanceTo", argc, argv);
|
||||
return YES;
|
||||
}
|
||||
|
||||
result = distance2(thisv, thatv);
|
||||
|
||||
@ -441,7 +464,11 @@ static JSBool VectorMultiply(JSContext *context, JSObject *this, uintN argc, jsv
|
||||
double scalar;
|
||||
|
||||
if (!JSVectorGetVector(context, this, &thisv)) return NO;
|
||||
if (!JS_ValueToNumber(context, argv[0], &scalar)) return NO;
|
||||
if (!JS_ValueToNumber(context, argv[0], &scalar))
|
||||
{
|
||||
OOLog(@"script.javaScript.badParameter.vector.multiply", @"--- JavaScript: Vector.multiply(): expected number, got %@.", [NSString stringWithJavaScriptValue:argv[0] inContext:context]);
|
||||
return YES;
|
||||
}
|
||||
|
||||
result = vector_multiply_scalar(thisv, scalar);
|
||||
|
||||
@ -455,7 +482,11 @@ static JSBool VectorDot(JSContext *context, JSObject *this, uintN argc, jsval *a
|
||||
GLfloat result;
|
||||
|
||||
if (!JSVectorGetVector(context, this, &thisv)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL))
|
||||
{
|
||||
ReportVectorParamConversionFailure(context, @"Vector", @"dot", argc, argv);
|
||||
return YES;
|
||||
}
|
||||
|
||||
result = dot_product(thisv, thatv);
|
||||
|
||||
@ -469,7 +500,11 @@ static JSBool VectorAngleTo(JSContext *context, JSObject *this, uintN argc, jsva
|
||||
GLfloat result;
|
||||
|
||||
if (!JSVectorGetVector(context, this, &thisv)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL))
|
||||
{
|
||||
ReportVectorParamConversionFailure(context, @"Vector", @"angleTo", argc, argv);
|
||||
return YES;
|
||||
}
|
||||
|
||||
result = acosf(dot_product(vector_normal(thisv), vector_normal(thatv)));
|
||||
|
||||
@ -482,7 +517,11 @@ static JSBool VectorCross(JSContext *context, JSObject *this, uintN argc, jsval
|
||||
Vector thisv, thatv, result;
|
||||
|
||||
if (!JSVectorGetVector(context, this, &thisv)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, NULL))
|
||||
{
|
||||
ReportVectorParamConversionFailure(context, @"Vector", @"cross", argc, argv);
|
||||
return YES;
|
||||
}
|
||||
|
||||
result = true_cross_product(thisv, thatv);
|
||||
|
||||
@ -497,8 +536,16 @@ static JSBool VectorTripleProduct(JSContext *context, JSObject *this, uintN argc
|
||||
uintN consumed;
|
||||
|
||||
if (!JSVectorGetVector(context, this, &thisv)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, &consumed)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc + consumed, argv, &theotherv, NULL)) return NO;
|
||||
if (!VectorFromArgumentList(context, argc, argv, &thatv, &consumed))
|
||||
{
|
||||
ReportVectorParamConversionFailure(context, @"Vector", @"tripleProduct", argc, argv);
|
||||
return YES;
|
||||
}
|
||||
if (!VectorFromArgumentList(context, argc + consumed, argv + consumed, &theotherv, NULL))
|
||||
{
|
||||
ReportVectorParamConversionFailure(context, @"Vector", @"tripleProduct", argc + consumed, argv + consumed);
|
||||
return YES;
|
||||
}
|
||||
|
||||
result = triple_product(thisv, thatv, theotherv);
|
||||
|
||||
|
@ -44,6 +44,12 @@ MA 02110-1301, USA.
|
||||
@end
|
||||
|
||||
|
||||
void OOReportJavaScriptError(JSContext *context, NSString *format, ...);
|
||||
void OOReportJavaScriptErrorWithArguments(JSContext *context, NSString *format, va_list args);
|
||||
void OOReportJavaScriptWarning(JSContext *context, NSString *format, ...);
|
||||
void OOReportJavaScriptWarningWithArguments(JSContext *context, NSString *format, va_list args);
|
||||
|
||||
|
||||
@protocol OOJavaScriptConversion <NSObject>
|
||||
|
||||
- (jsval)javaScriptValueInContext:(JSContext *)context;
|
||||
@ -59,6 +65,9 @@ MA 02110-1301, USA.
|
||||
// Convert an arbitrary JS object to an NSString, using JS_ValueToString.
|
||||
+ (id)stringWithJavaScriptValue:(jsval)value inContext:(JSContext *)context;
|
||||
|
||||
// For diagnostic messages; produces things like @"(42, true, "a string", an object description)".
|
||||
+ (id)stringWithJavaScriptParameters:(jsval *)params count:(uintN)count inContext:(JSContext *)context;
|
||||
|
||||
// Concatenate sequence of arbitrary JS objects into string.
|
||||
+ (id)concatenationOfStringsFromJavaScriptValues:(jsval *)values count:(size_t)count separator:(NSString *)separator inContext:(JSContext *)context;
|
||||
|
||||
|
@ -1175,14 +1175,19 @@ static void ReportJSError(JSContext *cx, const char *message, JSErrorReport *rep
|
||||
NSString *messageText = nil;
|
||||
NSString *lineBuf = nil;
|
||||
NSString *messageClass = nil;
|
||||
NSString *highlight = @"*****";
|
||||
|
||||
// Type of problem: error, warning or exception? (Strict flag wilfully ignored.)
|
||||
if (report->flags & JSREPORT_EXCEPTION) severity = @"exception";
|
||||
else if (report->flags & JSREPORT_WARNING) severity = @"warning";
|
||||
else if (report->flags & JSREPORT_WARNING)
|
||||
{
|
||||
severity = @"warning";
|
||||
highlight = @"-----";
|
||||
}
|
||||
else severity = @"error";
|
||||
|
||||
// The error message itself
|
||||
messageText = [NSString stringWithUTF16String:report->ucmessage];
|
||||
messageText = [NSString stringWithUTF8String:message];
|
||||
|
||||
// Get offending line, if present, and trim trailing line breaks
|
||||
lineBuf = [NSString stringWithUTF16String:report->uclinebuf];
|
||||
@ -1192,7 +1197,7 @@ static void ReportJSError(JSContext *cx, const char *message, JSErrorReport *rep
|
||||
messageClass = [NSString stringWithFormat:@"script.javaScript.%@.%u", severity, report->errorNumber];
|
||||
|
||||
// First line: problem description
|
||||
OOLog(messageClass, @"***** JavaScript %@: %@", severity, messageText);
|
||||
OOLog(messageClass, @"%@ JavaScript %@: %@", highlight, severity, messageText);
|
||||
|
||||
// Second line: where error occured, and line if provided. (The line is only provided for compile-time errors, not run-time errors.)
|
||||
if ([lineBuf length] != 0)
|
||||
@ -1242,6 +1247,7 @@ static void ReportJSError(JSContext *cx, const char *message, JSErrorReport *rep
|
||||
|
||||
/* create a context and associate it with the JS run time */
|
||||
cx = JS_NewContext(rt, 8192);
|
||||
JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_STRICT | JSOPTION_NATIVE_BRANCH_CALLBACK);
|
||||
|
||||
/* if cx does not have a value, end the program here */
|
||||
if (!cx)
|
||||
@ -1302,6 +1308,46 @@ static void ReportJSError(JSContext *cx, const char *message, JSErrorReport *rep
|
||||
@end
|
||||
|
||||
|
||||
void OOReportJavaScriptError(JSContext *context, NSString *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
OOReportJavaScriptErrorWithArguments(context, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
void OOReportJavaScriptErrorWithArguments(JSContext *context, NSString *format, va_list args)
|
||||
{
|
||||
NSString *msg = nil;
|
||||
|
||||
msg = [[NSString alloc] initWithFormat:format arguments:args];
|
||||
JS_ReportWarning(context, "%s", [msg UTF8String]);
|
||||
[msg release];
|
||||
}
|
||||
|
||||
|
||||
void OOReportJavaScriptWarning(JSContext *context, NSString *format, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, format);
|
||||
OOReportJavaScriptWarningWithArguments(context, format, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
void OOReportJavaScriptWarningWithArguments(JSContext *context, NSString *format, va_list args)
|
||||
{
|
||||
NSString *msg = nil;
|
||||
|
||||
msg = [[NSString alloc] initWithFormat:format arguments:args];
|
||||
JS_ReportWarning(context, "%s", [msg UTF8String]);
|
||||
[msg release];
|
||||
}
|
||||
|
||||
|
||||
@implementation NSString (OOJavaScriptExtensions)
|
||||
|
||||
// Convert a JSString to an NSString.
|
||||
@ -1326,6 +1372,37 @@ static void ReportJSError(JSContext *cx, const char *message, JSErrorReport *rep
|
||||
}
|
||||
|
||||
|
||||
+ (id)stringWithJavaScriptParameters:(jsval *)params count:(uintN)count inContext:(JSContext *)context
|
||||
{
|
||||
if (params == nil && count != 0) return nil;
|
||||
|
||||
uintN i;
|
||||
jsval val;
|
||||
NSMutableString *result = [NSMutableString string];
|
||||
NSString *valString = nil;
|
||||
|
||||
for (i = 0; i != count; ++i)
|
||||
{
|
||||
if (i != 0) [result appendString:@", "];
|
||||
else [result appendString:@"("];
|
||||
|
||||
val = params[i];
|
||||
valString = [self stringWithJavaScriptValue:val inContext:context];
|
||||
if (JSVAL_IS_STRING(val))
|
||||
{
|
||||
[result appendFormat:@"\"%@\"", valString];
|
||||
}
|
||||
else
|
||||
{
|
||||
[result appendString:valString];
|
||||
}
|
||||
}
|
||||
|
||||
[result appendString:@")"];
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (jsval)javaScriptValueInContext:(JSContext *)context
|
||||
{
|
||||
size_t length;
|
||||
|
Loading…
x
Reference in New Issue
Block a user