Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!wasatch!cs.utexas.edu!sun-barr!ames!pacbell!att!cbnewsc!gregg From: gregg@cbnewsc.ATT.COM (gregg.g.wonderly) Newsgroups: comp.std.c Subject: Re: Error Return (was Re: (char *)(-1)) Message-ID: <2265@cbnewsc.ATT.COM> Date: 6 Aug 89 22:38:46 GMT References: <8314@boring.cwi.nl> Organization: AT&T Bell Laboratories Lines: 91 From article <8314@boring.cwi.nl>, by siebren@piring.cwi.nl (Siebren van der Zee): > iiitsh@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 ,SS$_ .success mnemonic mnemonic mnemonic .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@att.com (AT&T bell laboratories)