2020-09-30 17:12:29 +02:00

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