108 lines
5.0 KiB
Plaintext
108 lines
5.0 KiB
Plaintext
CV 3.50 Expression Evaluator Error Handling
|
|
|
|
Most expression evaluator functions return an error code.
|
|
This note explains how that code should normally be handled.
|
|
|
|
There are only four possible error return codes:
|
|
|
|
EENOERROR
|
|
The code EENOERROR is documented as having the value 0 so you
|
|
can check for no error with "if(error)" rather than
|
|
"if(error == EENOERROR)" if you wish. You may also call CVExprErr
|
|
with this code. It will return with no action.
|
|
|
|
EENOMEMORY
|
|
You may be in a position to do something about this. If not,
|
|
you can call CVExprErr (see under EEGENERAL) and an out of
|
|
memory condition (NOROOM) will be reported.
|
|
|
|
EECATASTROPHIC
|
|
If you don't see how this error could occur in a particular
|
|
application you should probably (debug) assert when it does.
|
|
Remember you still need to handle it in the non debug case.
|
|
If someone runs a flakey expression evaluator with non debug
|
|
CodeView it is better to report a catastrophic EE error than
|
|
to GP fault. If you call CVExprErr (see under EEGENERAL) that
|
|
is what will be reported (CATASTROPHICTM).
|
|
|
|
EEGENERAL
|
|
If you get an EE error the only clue to the type of error is
|
|
the purpose of the function which returned it. You have to
|
|
decide on that basis whether to report the error. If you decide
|
|
to report the error you should call CVExprErr:
|
|
|
|
void pascal CVExprErr(EESTATUS Err,MSGWHERE msgwhere,PHTM phTM,char far * szErr)
|
|
|
|
Set the arguments as follows:
|
|
|
|
Err The error status you got (EEGENERAL in this case).
|
|
|
|
msgwhere This specifies how the message will be displayed. It is
|
|
the same as for CVMessage. The possibilities are:
|
|
CMDWINDOW - Print a string in the command window. You
|
|
cannot always do this. If the edit manager
|
|
has already been called (e.g. you are in
|
|
a cbGetLineBuf procedure) this will not
|
|
work.
|
|
MSGBOX Display the error in a message box. I know
|
|
of no circumstances except out of memory in
|
|
which this will not work. The present CodeView
|
|
convention however is that commands initiated
|
|
from the command line have errors reported to
|
|
the command window. Also we wish to avoid the
|
|
user having to dismiss a plethora of message
|
|
boxes.
|
|
STATLINE, I cannot imagine a case for using this.
|
|
MSGSTRING Use this value and supply a character buffer
|
|
in szErr to get the text of the error message.
|
|
This is useful in the globals window to display
|
|
an error message instead of the value of an
|
|
expression. The length of the buffer should be
|
|
at least MAXERRMSG (currently 256).
|
|
MSGGERRSTR I expect this one to be used in cases where one
|
|
would normally have set errno or some local
|
|
analogue of errno and returned to the caller,
|
|
leaving him free to handle the error or modify
|
|
errno as he wishes. What it does is save the
|
|
error message until CVMessage is called with
|
|
an error code of GEXPRERR. Then the error is
|
|
retrieved and displayed. Once you hve done this
|
|
you should set errno or your local analogue to
|
|
GEXPRERR. You are then free to clean up the TM.
|
|
|
|
phTM Point to the TM the function used. You should never get
|
|
an EEGENERAL status from a function which does not use
|
|
a TM. If Err is anything other than EEGENERAL it is O.K.
|
|
to use NULL for this argument. I shall put an assert
|
|
in CVExprErr to check this.
|
|
|
|
szErr This is only used in the case msgwhere == MSGSTRING. In that
|
|
case it must point to a buffer MAXERRMSG in size.
|
|
|
|
The way CV 3.0 works is that errno is checked after each command. If it
|
|
is nonzero, then CVMessage is called to display the error. The method
|
|
of display depending on the origin of the last command. I expect we
|
|
shall use the MSGGERRSTR/GEXPRERR technique to emulate this. There will
|
|
be exceptions. For example you may get an error outside of a command or
|
|
you may have a compelling reason to display multiple error messages. If
|
|
so take care. I have pointed out the pitfalls I know of. If you set errno
|
|
and you do not get your error message, someone is probably clearing
|
|
errno after you set it. They may have a good reason to do that or they may
|
|
not.
|
|
|
|
I have modified the text manager so that he checks errno on exit
|
|
from all textwindow procs and displays any error in a popup. This
|
|
covers cases like the user typing a bad expression into the watch
|
|
window (the error is detected at cbGetLineBuf time but the faulting
|
|
routine just sets errno as usual and then the error is reported in a
|
|
popup by the text manager when the window proc returns).
|
|
|
|
The use of errno was seriously impeded by the fact that getb and putb
|
|
corrupt errno (even if they do not error). Practically everyone should
|
|
be calling DHGet/PutDebugeeBytes to go to get/putb. I have modified
|
|
these routines to save and restore errno (they report an error in the
|
|
return value). Anyone who is calling get/putb direct should consider
|
|
how to treat errno.
|
|
|
|
Arthur
|