⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mal_exception.mx

📁 一个内存数据库的源代码这是服务器端还有客户端
💻 MX
字号:
@' The contents of this file are subject to the MonetDB Public License@' Version 1.1 (the "License"); you may not use this file except in@' compliance with the License. You may obtain a copy of the License at@' http://monetdb.cwi.nl/Legal/MonetDBLicense-1.1.html@'@' Software distributed under the License is distributed on an "AS IS"@' basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the@' License for the specific language governing rights and limitations@' under the License.@'@' The Original Code is the MonetDB Database System.@'@' The Initial Developer of the Original Code is CWI.@' Portions created by CWI are Copyright (C) 1997-2007 CWI.@' All Rights Reserved.@f mal_exception@a F. Groffen, M. Kersten@v 1.0@+ Exception handlingMAL comes with an exception handling mechanism, similar in styleas found in modern programming languages.Exceptions are considered rare situations that alterthe flow of control to a place where they can be handled.After the exceptional case has been handled the following options exista) continue where it went wrong, b) retry the failed instruction,c) leave the block where the exception was handled,or d) pass the exception to an enclosing call.The current implementation of the MAL interpreter only supports c) and d).@- Exception controlThe exception handling keywords are: @sc{catch} and @sc{raise}The @sc{catch}  marks a point in the dataflow wherean exception raised can be dealt with. Any statement between thepoint where it is raised and the catch block is ignored.Moreover, the @sc{ catch} ... @sc{ exit} block is ignored whenno errors have occurred in the preceeding dataflow structure.Within the catch block, the exception variable can be manipulatedwithout constraints.An exception message is linked with a exception variable oftype string. If this variable is defined in the receiving block,the exception message can be delivered. Otherwise, itimplicitly raises the exception in the surrounding scope.After an exception has been dealt with the catch block can be leftat the normal @sc{exit} with the option @sc{leave} orcontinue after the failed instruction using a @sc{redo}.The latter case assumes the catched code block has been able to providean alternative for the failed instruction.Both @sc{leave} and @sc{redo} are conditional flow of control modifiers,which trigger on a non-empty string variable.An exception raised within a catch-block terminatesthe function and returns control to the enclosing environment.The argument to the catch statement is a target list,which holds the exception variables you are interested in.The snippet below illustrates how an exception raisedin the function @sc{io.read} is catched using the exception variable IOerror.After dealing with it locally, it raises a new exception @sc{ FATALerror}for the enclosing call.@example	io.write("Welcome");	...catch IOerror:str;	print("input error on reading password");raise FATALerror:= "Can't handle it";exit IOerror;@end exampleSince @sc{catch} is a flow control modifier it can be attached to anyassignment statement. This statement is executed whenever there is noexception outstanding, but will be ignored when control is movedto the block otherwise.@- Builtin exceptions The policy implemented in the MAL modules, and recognized bythe interpreter, is to return a string value by default.A NULL return value indicates succesful execution; otherwisethe string encodes information to analyse the error occurred.This string pattern is strictly formatted and easy to analyse.It starts with the name of the exception variable tobe set, followed by an indication where the exception wasraise, i.e. the function name and the program counter,and concludes with specific information needed to interpret and handle the exception.For example, the exception string @sc{ 'MALException:Admin.main[2]:address of function missing'}denotes an exception raised while typechecking a MAL program.The exceptions captured within the kernel are marked as 'GDKerror'.At that level there is no knowledge about the MAL context, whichmakes interpretation difficult for the average programmer.Exceptions in the MAL language layer are denoted by 'MALerror',and query language exceptiosn fall in their own class, e.g. 'SQLerror'.Exceptions can be cascaded to form a trail of exceptions recognizedduring the exection.@{@f mal_errors@+ Error HandlingInternationalization and consistent error reporting is helped by acentral place of all kernel error messages. They are split into @sc{fatal}, code{errors} and @sc{warnings}.The second category is the system component in which it is raised.The first attempt: grep on src/MAL module.@-@f mal_exception@h#ifndef _MAL_EXCEPTION_H#define _MAL_EXCEPTION_H#include "mal_instruction.h"/* #define _DEBUG_EXCEPTION_		trace the exception handling *//* These are the exceptions known, adding new ones here requires to also * add the "full" name to the exceptionNames array below */enum malexception {	MAL=0,	ILLARG,	OUTOFBNDS,	IO,	INVCRED,	OPTIMIZER,	STKOF,	SYNTAX,	TYPE,	LOADER,	PARSE,	ARITH,	PERMD,	SQL};#define MAL_SUCCEED ((str) 0) /* no error */#define throw \	return createException#define rethrow(FCN, TMP, PRV) \	if ((TMP = PRV) != MAL_SUCCEED) return(TMP);mal_export str	createException(enum malexception, str, str, ...);mal_export void	showException(enum malexception, str, str, ...);mal_export str	createScriptException(MalBlkPtr, int, enum malexception, str, str, ...);mal_export void	showScriptException(MalBlkPtr, int, enum malexception, str, ...);mal_export enum malexception	getExceptionType(str);mal_export str	getExceptionPlace(str);mal_export str	getExceptionMessage(str);mal_export str	exceptionToString(enum malexception);#endif /*  _MAL_EXCEPTION_H*/@-@c#include "mal_config.h"#include "mal_exception.h"static char *exceptionNames[] = {/* 0 */	"MALException",/* 1 */	"IllegalArgumentException",/* 2 */	"OutOfBoundsException",/* 3 */	"IOException",/* 4 */	"InvalidCredentialsException",/* 5 */	"OptimizerException",/* 6 */	"StackOverflowException",/* 7 */	"SyntaxException",/* 8 */	"TypeException",/* 9 */	"LoaderException",/*10 */	"ParseException",/*11 */	"ArithmeticException",/*12 */	"PermissionDeniedException",/*13 */	"SQLException",/*EOE*/	NULL};/** * Internal helper function for createException and * showException such that they share the same code, because reuse * is good. */static strcreateExceptionInternal(enum malexception type, str fcn, str format, va_list ap){	char message[GDKMAXERRLEN];	int len;#ifdef _DEBUG_EXCEPTION_	printf("exception:%s:%s\n",fcn,format);#endif	len = snprintf(message, GDKMAXERRLEN - 1, "%s:%s:",			exceptionNames[type], fcn);	len += vsnprintf(message + len, GDKMAXERRLEN - 1 - len, format, ap);	message[len] = '\0';	return(GDKstrdup(message));}/** * Returns an exception string for the given type of exception, function * and additional formatting parameters.  This function will crash the * system or return bogus when the malexception enum is not aligned with * the exceptionNames array. */strcreateException(enum malexception type, str fcn, str format, ...){	va_list ap;	str ret;	va_start(ap, format);	ret = createExceptionInternal(type, fcn, format, ap);	va_end(ap);	return(ret);}/** * Internal helper function to properly emit the given string to GDKout, * thereby abiding to all the protocol laws.  This function will bluntly * crash if the given string (pointer) is NULL. */static voiddumpToGDKout(str whatever) {	size_t i;	size_t last = 0;	size_t len = strlen(whatever);	/* yes, crash if whatever is NULL */	/* make sure each line starts with a ! */	for (i = 0; i < len; i++) {		if (whatever[i] == '\n') {			whatever[i] = '\0';			if (i - last > 0) /* skip empty lines */				stream_printf(GDKout, "!%s\n", whatever + last);			last = i + 1;		}	}	/* flush last part */	if (i - last > 0) /* skip if empty */		stream_printf(GDKout, "!%s\n", whatever + last);}/** * Dump an error message using the exception structure using the primary * console as defined by GDKout. */voidshowException(enum malexception type, str fcn, str format, ...){	va_list ap;	str msg;	va_start(ap, format);	msg = createExceptionInternal(type, fcn, format, ap);	va_end(ap);	dumpToGDKout(msg);	GDKfree(msg);}/** * Internal helper function for createScriptException and * showScriptException such that they share the same code, because reuse * is good. */static strcreateScriptExceptionInternal(MalBlkPtr mb, int pc, enum malexception type, str prev, str format, va_list ap){	char buf[GDKMAXERRLEN];	size_t i;	str s, fcn;	s = mb ? getModName(mb) : "unknown";	fcn = mb ? getFcnName(mb) : "unknown";	i = 0;	if (prev)		i += snprintf(buf + i, GDKMAXERRLEN - 1 - i, "%s\n", prev);	i += snprintf(buf + i, GDKMAXERRLEN - 1 - i, "%s:%s.%s[%d]:",			exceptionNames[type], s, fcn, pc);	i += vsnprintf(buf + i, GDKMAXERRLEN - 1 - i, format, ap);	buf[i] = '\0';	return GDKstrdup(buf);}/** * Returns an exception string for the use of MAL scripts.  These * exceptions are newline terminated, and determine module and function * from the given MalBlkPtr.  An old exception can be given, such that * this exception is chained to the previous one.  Conceptually this * creates a "stack" of exceptions. * This function will crash the system or return bogus when the * malexception enum is not aligned with the exceptionNames array. */strcreateScriptException(MalBlkPtr mb, int pc, enum malexception type, str prev, str format, ...){	va_list ap;	str ret;	va_start(ap, format);	ret = createScriptExceptionInternal(mb, pc, type, prev, format, ap);	va_end(ap);	return(ret);}/** * Sends the exception as generated by a call to * createScriptException(mb, pc, type, NULL, format, ...) to the console * defined by GDKout. */voidshowScriptException(MalBlkPtr mb, int pc, enum malexception type, str format, ...){	va_list ap;	str msg;	va_start(ap, format);	msg = createScriptExceptionInternal(mb, pc, type, NULL, format, ap);	va_end(ap);	dumpToGDKout(msg);	GDKfree(msg);}/** * Returns the malexception number for the given exception string.  If no * exception could be found in the string, MAL is returned indicating a * generic MALException. */enum malexceptiongetExceptionType(str exception){	enum malexception ret = MAL;	str s;	enum malexception i;	if ((s = strchr(exception, ':')) != NULL)		*s = '\0';	for (i = MAL; exceptionNames[i] != NULL; i++) {		if (strcmp(exceptionNames[i], exception) == 0) {			ret = i;			break;		}	}	/* restore original string */	if (s != NULL)		*s = ':';	return(ret);}/** * Returns the location the exception was raised, if known.  It depends * on the how the exception was created, what the location looks like. * The returned string is mallocced with GDKmalloc, and hence needs to * be GDKfreed. */strgetExceptionPlace(str exception){	str ret;	str s, t;	if ((s = strchr(exception, ':')) != NULL &&			(t = strchr(s + 1, ':')) != NULL)	{		*t = '\0';		ret = GDKstrdup(s + 1);		*t = ':';		return(ret);	} else {		return(GDKstrdup("(unknown)"));	}}/** * Returns the informational message of the exception given. */strgetExceptionMessage(str exception){	str s, t;	if ((s = strchr(exception, ':')) != NULL) {		/* skip the place, if there */		if ((t = strchr(s + 1, ':')) != NULL)			s = t;		return(s + 1);	} else {		return(exception);	}}/** * Returns the string representation of the given exception.  This is * the string as used when creating an exception of the same type. */strexceptionToString(enum malexception e){	return(exceptionNames[e]);}@}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -