[mw-devel] MW3 r1114 - trunk/src

psycodom at sucs.org psycodom at sucs.org
Tue Dec 1 12:59:04 GMT 2009


Author: psycodom
Date: 2009-12-01 12:59:04 +0000 (Tue, 01 Dec 2009)
New Revision: 1114

Modified:
   trunk/src/init.c
   trunk/src/js.c
Log:
mwjs tweaks

Fixes a bug that makes mw segv if you ^C before js has started
Fixes a bug that made mw tell you it couldn't find a file a js that exists contains an error
Creates a new js_warning that means warning messages can present filename and lineno that caused the warning
Changed all builtin functions as JSPROP_READONLY|JSPROP_PERMANENT to stop people overwriting them wth their own functions/variable of the same name



Modified: trunk/src/init.c
===================================================================
--- trunk/src/init.c	2009-11-26 15:12:32 UTC (rev 1113)
+++ trunk/src/init.c	2009-12-01 12:59:04 UTC (rev 1114)
@@ -138,7 +138,7 @@
 	if ((a=strrchr(filename, '.'))!=NULL && strncasecmp(a, ".js", 3)==0) {
 		int ret = load_jsfile(file, filename);
 		fclose(file);
-		return ret;
+		return 0; // changed because if an error occured after this point the file exists, the js code has reported the error to the user and returning 1 will report to them that it doesn't exist
 	}
 
 	lineno=0;	

Modified: trunk/src/js.c
===================================================================
--- trunk/src/js.c	2009-11-26 15:12:32 UTC (rev 1113)
+++ trunk/src/js.c	2009-12-01 12:59:04 UTC (rev 1114)
@@ -14,6 +14,8 @@
 #include <readline/readline.h>
 #include <curl/curl.h>
 
+#include <jsdbgapi.h>
+
 #include "bb.h"
 #include "proto.h"
 #include "sqlite.h"
@@ -87,11 +89,32 @@
 };
 
 
+/* prints a warning */
+void js_warning(JSContext *cx, const char *warning) 
+{
+	JSStackFrame *fp = NULL;
+	JSScript *script;
+	const char *filename;
+	int lineno;
+	jsbytecode *pc;
+	
+	fp = JS_GetScriptedCaller(cx, NULL); // get the current js stack frame
+	script = JS_GetFrameScript(cx, fp); // get the current script from the stack frame
+	filename = JS_GetScriptFilename(cx, script); // get the file name of the script
+	pc = JS_GetFramePC(cx, fp); // get the current pc fro the stack frome
+	lineno = JS_PCToLineNumber(cx, script, pc); // get the actual line number from the pc
+
+	printf("JS Warning: %s\nFile: %s:%u\n", warning, filename, lineno+1);
+	
+}
+
+/* called if a script runs too long */
 void js_timeout(void *ptr)
 {
 	js_interrupted=2;
 }
 
+/* clears the timeout event when a js finishes (or the js uses input) */
 void js_clear_timeout(void)
 {
 	if(js_timeout_event != NULL)
@@ -101,6 +124,7 @@
 	}
 }
 
+/* starts a 3 second timer that will interupt js if it is exceeded */
 void js_start_timeout(void)
 {
 	js_clear_timeout();
@@ -295,7 +319,7 @@
 				}
 			}		
 		} else {
-			printf("Warning: when a parameter is specified to javascript input() command it should be a string to use as the prompt\n");
+			js_warning(cx, "When a parameter is specified to javascript input() command it should be a string to use as the prompt");
 		}
 	}
 	if( prompt == NULL )
@@ -347,10 +371,10 @@
 		beeps=JSVAL_TO_INT(argv[0]);
 		if(beeps < 1 || beeps > 5) {
 			beeps=0;
-			fprintf(stderr, "Warning: javascript beep will only do between 1 and 5 beeps.\n");
+			js_warning(cx, "beep() will only do between 1 and 5 beeps");
 		}
 	} else {
-		fprintf(stderr, "Warning: javascript beep command expects an integer.\n");
+		js_warning(cx, "beep() command expects an integer");
 	}
 	for(i=0;i<beeps;i++)
 	{
@@ -368,6 +392,10 @@
 //	int conversion_result;
 	int bind_type=-1;
 	int i=1;
+	char msg[MAXTEXTLENGTH];
+	
+	msg[MAXTEXTLENGTH-1]='\0';
+	
 	if (argc < 2) {
 		JS_ReportError(cx, "Error in javascript: bind expects at least 2 arguments");
 		return JS_FALSE;
@@ -398,76 +426,86 @@
 	switch(bind_type) {
 		case K_BIND:
 			if(bind == NULL || bind[0]=='\0') {
-				JS_ReportError(cx, "Error: Empty bind");
+				JS_ReportError(cx, "Empty bind");
 				return JS_FALSE;
 			}
 			if (AddLink(&bind_list, bind, function_name))
 			{
-				printf("Bind %s already exists. Redefined\n", bind);
+				snprintf(msg, MAXTEXTLENGTH-1, "Bind %s already exists. Redefined", bind);
+				js_warning(cx, msg);
 			}
 
 			break;
 		case K_BIND_ALIAS:
 			if(bind == NULL || bind[0]=='\0') {
-				printf("Error: Empty bind\n");
+				JS_ReportError(cx, "Empty bind");
 				return JS_FALSE;
 			}
 			if (AddLink(&alias_list, bind, function_name))
 			{
-				printf("Alias %s->%s already exists. Redefined\n", bind, function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "Alias %s->%s already exists. Redefined", bind, function_name);
+				js_warning(cx, msg);
 			}
 
 			break;
 		case K_BIND_RPC:
 			if(bind == NULL || bind[0]=='\0') {
-				printf("Error: Empty bind\n");
+				JS_ReportError(cx, "Empty bind");
 				return JS_TRUE;
 			}
 			if (AddLink(&rpc_list, bind, function_name))
 			{
-				printf("RPC %s Bind %s already exists. Redefined\n", bind, function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "RPC %s Bind %s already exists. Redefined", bind, function_name);
+				js_warning(cx, msg);
 			}
 
 			break;
 		case K_BIND_EVENT:
 			if(AddLink(&event_list, function_name, ""))
 			{
-				printf("Event bind %s already exists.\n", function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "Event bind %s already exists", function_name);
+				js_warning(cx, msg);
 			}
 			break;
 		case K_BIND_ONOFF:
 			if(AddLink(&onoff_list, function_name, ""))
 			{
-				printf("CheckOnOff bind %s already exists.\n", function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "CheckOnOff bind %s already exists", function_name);
+				js_warning(cx, msg);
 			}
 			break;
 		case K_BIND_IPC:
 			if(AddLink(&ipc_list, function_name, ""))
 			{
-				printf("IPC bind %s already exists.\n", function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "IPC bind %s already exists", function_name);
+				js_warning(cx, msg);
 			}
 			break;
 		case K_BIND_FORCE:
 			if(AddLink(&force_list, function_name, ""))
 			{
-				printf("Force bind %s already exists.\n", function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "Force bind %s already exists", function_name);
+				js_warning(cx, msg);
 			}
 			break;
 		case K_BIND_SHUTDOWN:
 			if(AddLink(&shutdown_list, function_name, ""))
 			{
-				printf("Shutdown bind %s already exists.\n", function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "Shutdown bind %s already exists", function_name);
+				js_warning(cx, msg);
 			}
 			
 			break;
 		case K_BIND_INPUT:
 			if(AddLink(&eventin_list, function_name, ""))
 			{
-				printf("Input Event bind %s already exists.\n", function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "Input Event bind %s already exists", function_name);
+				js_warning(cx, msg);
 			}
 			break;
 		default:
-			printf("Unknown bind type %d\n", bind_type);
+			snprintf(msg, MAXTEXTLENGTH-1, "Unknown bind type %d", bind_type);
+				js_warning(cx, msg);
 			break;
 	}
 	return JS_TRUE;
@@ -479,7 +517,10 @@
 	char *bind=NULL;
 	char *function_name=NULL;
 	int bind_type=-1;
+	char msg[MAXTEXTLENGTH];
 	
+	msg[MAXTEXTLENGTH-1]='\0';
+	
 	if (argc < 1) {
 		JS_ReportError(cx, "Error in javascript: unbind expects at least 1 argument");
 		return JS_FALSE;
@@ -510,71 +551,81 @@
 			}
 			if(!DestroyLink(&bind_list, bind))
 			{
-				printf("Bind %s does not exist for unbinding.\n", bind);
+				snprintf(msg, MAXTEXTLENGTH-1, "Bind %s does not exist for unbinding", bind);
+				js_warning(cx, msg);
 			}
 
 			break;
 		case K_BIND_ALIAS:
 			if(bind == NULL || bind[0]=='\0') {
-				printf("Error: Empty bind\n");
+				JS_ReportError(cx, "Empty bind");
 				return JS_TRUE;
 			}
 			if (!DestroyLink(&alias_list, bind))
 			{
-				printf("Alias %s does not exist for unbinding.\n", bind);
+				snprintf(msg, MAXTEXTLENGTH-1, "Alias %s does not exist for unbinding", bind);
+				js_warning(cx, msg);
 			}
 
 			break;
 		case K_BIND_RPC:
 			if(bind == NULL || bind[0]=='\0') {
-				printf("Error: Empty bind\n");
+				JS_ReportError(cx, "Empty bind");
 				return JS_TRUE;
 			}
 			if (!DestroyLink(&rpc_list, bind))
 			{
-				printf("RPC %s does not exist for unbinding.\n", bind);
+				snprintf(msg, MAXTEXTLENGTH-1, "RPC %s does not exist for unbinding", bind);
+				js_warning(cx, msg);
 			}
 
 			break;
 		case K_BIND_EVENT:
 			if(!DestroyLink(&event_list, function_name))
 			{
-				printf("Event bind %s does not exist for unbinding.\n", function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "Event bind %s does not exist for unbinding", function_name);
+				js_warning(cx, msg);
 			}
 			break;
 		case K_BIND_ONOFF:
 			if(!DestroyLink(&onoff_list, function_name))
 			{
-				printf("CheckOnOff bind %s does not exist for unbinding.\n", function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "CheckOnOff bind %s does not exist for unbinding", function_name);
+				js_warning(cx, msg);
 			}
 			break;
 		case K_BIND_IPC:
 			if(!DestroyLink(&ipc_list, function_name))
 			{
-				printf("IPC bind %s does not exist for unbinding.\n", function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "IPC bind %s does not exist for unbinding", function_name);
+				js_warning(cx, msg);
 			}
 			break;
 		case K_BIND_FORCE:
 			if(!DestroyLink(&force_list, function_name))
 			{
-				printf("Force bind %s does not exist for unbinding.\n", function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "Force bind %s does not exist for unbinding", function_name);
+				js_warning(cx, msg);
 			}
 			break;
 		case K_BIND_SHUTDOWN:
 			if(!DestroyLink(&shutdown_list, function_name))
 			{
-				printf("Shutdown bind %s does not exist for unbinding.\n", function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "Shutdown bind %s does not exist for unbinding", function_name);
+				js_warning(cx, msg);
 			}
 			
 			break;
 		case K_BIND_INPUT:
 			if(!DestroyLink(&eventin_list, function_name))
 			{
-				printf("Input Event bind %s does not exist for unbinding.\n", function_name);
+				snprintf(msg, MAXTEXTLENGTH-1, "Input Event bind %s does not exist for unbinding", function_name);
+				js_warning(cx, msg);
 			}
 			break;
 		default:
-			printf("Unknown unbind type %d\n", bind_type);
+			snprintf(msg, MAXTEXTLENGTH-1, "Unknown unbind type %d", bind_type);
+				js_warning(cx, msg);
 			break;
 	}
 	return JS_TRUE;
@@ -698,9 +749,12 @@
 {
 	char *url;
 	JSString *jsstr;
+	char msg[MAXTEXTLENGTH];
+	
+	msg[MAXTEXTLENGTH-1]='\0';
 
 	if (argc < 1) {
-		printf("Bad Call to js_urlget\n");
+		JS_ReportError(cx, "Bad Call to js_urlget\n");
 		return JS_FALSE;
 	}
 	
@@ -724,7 +778,8 @@
 		curl_easy_setopt(cl, CURLOPT_USERAGENT, "Milliways III v" VER_MAJ "." VER_MIN "." VER_TWK " (Dev)");
 #endif
 		if (curl_easy_perform(cl))
-				fprintf(stderr, "JavaScript urlget failed %s: %s\n", url, cerr);
+				snprintf(msg, MAXTEXTLENGTH-1, "JavaScript urlget failed %s: %s", url, cerr);
+				js_warning(cx, msg);
 		curl_easy_cleanup(cl);
 
 		jsstr = JS_NewStringCopyZ(cx, answer->p_buffer);
@@ -1046,7 +1101,7 @@
 		len--;
 	}
 	
-	printf("JS Error: %s\nFile: %s:%u\n", msg, er->filename, er->lineno);
+	printf("JS Error: %s\nFile: %s:%u\n", msg, er->filename, er->lineno+1);
 	
 	if (line[0]) {
 		printf("%s\n%s\n", line, pointer);
@@ -1153,7 +1208,11 @@
 
 int js_isrunning(void)
 {
-	return JS_IsRunning(jscx);
+	if(jscx) {
+		return JS_IsRunning(jscx);
+	} else {
+		return 0;
+	}
 }
 
 // cleans up the javascript environment
@@ -1207,22 +1266,22 @@
 	
 	/* initiate local stuff */
 
-	JS_DefineFunction(jscx, jsroot, "print", js_print, 1, 0);
-	JS_DefineFunction(jscx, jsroot, "exec", js_mwexec, 1, 0);
-	JS_DefineFunction(jscx, jsroot, "say", js_say, 1, 0);
-	JS_DefineFunction(jscx, jsroot, "wholist", js_wholist, 0, 1);
-	JS_DefineFunction(jscx, jsroot, "rpc", js_rpc, 3, 0);
-	JS_DefineFunction(jscx, jsroot, "ipc", js_ipc, 2, 0);
-	JS_DefineFunction(jscx, jsroot, "urlget", js_urlget, 1, 1);
+	JS_DefineFunction(jscx, jsroot, "print", js_print, 1, JSPROP_READONLY|JSPROP_PERMANENT);
+	JS_DefineFunction(jscx, jsroot, "exec", js_mwexec, 1, JSPROP_READONLY|JSPROP_PERMANENT);
+	JS_DefineFunction(jscx, jsroot, "say", js_say, 1, JSPROP_READONLY|JSPROP_PERMANENT);
+	JS_DefineFunction(jscx, jsroot, "wholist", js_wholist, 0, JSPROP_READONLY|JSPROP_PERMANENT);
+	JS_DefineFunction(jscx, jsroot, "rpc", js_rpc, 3, JSPROP_READONLY|JSPROP_PERMANENT);
+	JS_DefineFunction(jscx, jsroot, "ipc", js_ipc, 2, JSPROP_READONLY|JSPROP_PERMANENT);
+	JS_DefineFunction(jscx, jsroot, "urlget", js_urlget, 1, JSPROP_READONLY|JSPROP_PERMANENT);
 
 	JS_DefineProperty(jscx, jsroot, "whoami", STRING_TO_JSVAL(JS_NewStringCopyZ(jscx,user->name)), NULL, NULL, JSPROP_READONLY|JSPROP_PERMANENT);
 
-	JS_DefineFunction(jscx, jsroot, "beep", js_beep, 1, 0);
-	JS_DefineFunction(jscx, jsroot, "input", js_input, 2, 0);
-	JS_DefineFunction(jscx, jsroot, "termsize", js_termsize, 0, 0);
+	JS_DefineFunction(jscx, jsroot, "beep", js_beep, 1, JSPROP_READONLY|JSPROP_PERMANENT);
+	JS_DefineFunction(jscx, jsroot, "input", js_input, 2, JSPROP_READONLY|JSPROP_PERMANENT);
+	JS_DefineFunction(jscx, jsroot, "termsize", js_termsize, 0, JSPROP_READONLY|JSPROP_PERMANENT);
 
-	JS_DefineFunction(jscx, jsroot, "bind", js_bind, 2, 0);
-	JS_DefineFunction(jscx, jsroot, "unbind", js_unbind, 2, 0);
+	JS_DefineFunction(jscx, jsroot, "bind", js_bind, 2, JSPROP_READONLY|JSPROP_PERMANENT);
+	JS_DefineFunction(jscx, jsroot, "unbind", js_unbind, 2, JSPROP_READONLY|JSPROP_PERMANENT);
 
 	// Set the bind type constants
 	JS_DefineProperty(jscx, jsroot, "K_BIND_EVENT", INT_TO_JSVAL(K_BIND_EVENT), NULL, NULL, JSPROP_READONLY|JSPROP_PERMANENT);




More information about the mw-devel mailing list