Error Return (was Re: (char *)(-1))

gregg.g.wonderly gregg at cbnewsc.ATT.COM
Mon Aug 7 08:38:46 AEST 1989


>From article <8314 at boring.cwi.nl>, by siebren at piring.cwi.nl (Siebren van der Zee):
> iiitsh at cybaswan.UUCP (Steve Hosgood) writes:
>>[errval(foo())]
> Ok, and now the hard part: what should the code from the
> CALLED function look like?

I have always liked the idea of having the types of information that VMS
provides in condition codes.  Given the ability to return a relatively
large integer, or structure, it is simple enough to have something like

	struct errcode {
		int pad:3;			/*  Additional information.  */
		int fac_id:11;		/*  2048 possible facility codes.  */
		int error:14;		/*  16384 possible errors per facility.  */
		int sever:4;		/*  Severity bits.  */
	};

The sever field is the best part.  It contains one of the following values.

	1	==	success
	3	==	warning
	4	==	error
	5	==	informational
	8	==	fatal

This leaves you with an easy check for errors.  Is bit 0 set?  The VAX
instruction, blbs (branch low bit set), is used all through VMS for this
purpose.

I have written a program to generate error message declarations in C given
a simple input format of the string, a mnemonic and the severity of the
message (along with the facility id).  The VMS file format is simply

	.facility	<nnn>,SS$_

	.success
	mnemonic	<string inside less-than/greater-than brackets>
	mnemonic	<string inside less-than/greater-than brackets>
	mnemonic	<string inside less-than/greater-than brackets>
	.fatal
	...			...

	.informational
	...			...

	.warning
	...			...

	.error
	...			...

The result is that a variable by the name of SS$_mnemonic is generated that
contains the value that would be generated if the above structure was actually
a single 4-byte integer.

Now for the tough part.  The VMS linker understands named sections in
the object file and sections can have attributes, such as appended.
The magic here is that all message sections have the same name and the
attribute append.  The error message formatter, sys$errmsg(), knows how
to get to this section of the program and how to look through the
generated tables of messages.  So, if you pass it an integer, it starts
at the front of the table and looks for the table associated with the
facility-id.  If then indexs into the table based on the error message
number field and gets the text.  The severity is just used to generate
the appropriate severity character in the message.  The mnemonic is generated
in the message so that you can actually search the source for the use of
a message to aid in finding the messages origin when necessary.

The result is something like

	%SYSTEM-F-BADPARAM, insufficient parameters to system call

In my particular implementation, the corresponding unix format message
would be

	system: fatal, BADPARAM, insufficent parameters to system call

Like VMS provides the SET MESSAGE command to alter the format of the
message, I made use of the ERRMSK environment variable to allow the 4
different fields to be selected by bits in the mask.  By default, a
unix format message (you can select VMS style too) has the mask value
of 9, so the above message would look like

	system: insufficient parameters to system call.

The formatting routine uses varargs so that parameters can be provided.


-- 
-----
gregg.g.wonderly at att.com   (AT&T bell laboratories)



More information about the Comp.std.c mailing list