1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
|
/*
PsychError.h
AUTHORS:
Allen.Ingling@nyu.edu awi
mario.kleiner.de@gmail.com mk
HISTORY:
08/18/02 awi Wrote it.
11/16/04 awi Added PsychErorr_argumentValueOutOfRange
DESCRIPTION:
TO DO:
The present system for reporting errors works pretty well, here was an early ambitious scheme to improve it:
Errors should be pointers to structures which hold information about
the error. Errors of each type should be generated by error-generator
functions which dynamically allocate a variant structure for storing
error-specific information. For example:
theError = GenError_invalidArg(); //
theError = GenError_none(); //returns null
or perhaps the constructors could accept more info:
theError = GenError_missingArg(Input, 1);
theError = GetError_none();
An acceptable alternative would be to have one generator function and
pass it an enumerated type identifying the error class, for example:
theError = GenError(PsychError_missingArg, Input, 1);
theError = Generror(PsychError_none);
Currrently, errors are variables which hold an enumerated
type classifying the error. Additional information about the error
is stashed in static variables within Psychtoolbox library files but
1) It is not attached to the error and there is no organizing
principle to suggest where it might be found. 2) It has no state,
so subsequent errors will overwrite or invalidate the information
held within the static state variables. This is particularly a
problem with PsychErrorExitMsg(), which must now be called immediatlty
after the error or else the error information is lost.
If error are pointers to structures then this adds two complications:
1- We need to dynamically allocate memory to hold the error structure
and clean it up on exit. For prototyping purposes, we could
statically allocate an array of variant structures and limit the
maximum number of concurrent errors to the length of the array. 2-
Testing for the error type can no longer be done directly with the
equals operator unless it were overloaded. A comparison function
which dereferenced the error and examined the type would have to be
supplied. Something like:
if(ErrorEqual(error1, error2)) ....
or
if(GetErrorType(error1) == GetErrorType(error2))....
*/
//begin include once
#ifndef PSYCH_IS_INCLUDED_PsychError
#define PSYCH_IS_INCLUDED_PsychError
//define the PsychErrorExitMsg Macro
#define PsychErrorExitMsg(pse1, pse2) PsychErrorExitC(pse1, pse2, __LINE__, __func__, __FILE__)
#define PsychErrorExit(pse1) PsychErrorExitC(pse1, NULL, __LINE__, __func__, __FILE__)
#include "Psych.h"
//types of error.
typedef enum
{
PsychError_none = 0,
// These four constants describe different ways the user can give an invalid argument. They are treated specially by PsychErrorExitC
// (called by macros PsychErrorExit and PsychErrorExitMsg) which gives an extra verbose report for these errors, relying on
// cached argument descriptors to make its report.
PsychError_invalidArg_absent,
PsychError_invalidArg_extra,
PsychError_invalidArg_type,
PsychError_invalidArg_size,
// These three four contants are used for the cap an limit calls at the head of module sufunctions. They don't cause the special behavior in
// PsychErrorExit.
PsychError_extraInputArg,
PsychError_missingInputArg,
PsychError_extraOutputArg,
PsychError_missingOutputArg,
PsychError_toomanyWin,
PsychError_outofMemory,
PsychError_scumberNotWindex,
PsychError_windexNotScumber,
PsychError_invalidIntegerArg,
PsychError_invalidWindex,
PsychError_invalidScumber,
PsychError_invalidNumdex,
PsychError_invalidColorArg,
PsychError_invalidDepthArg,
PsychError_invalidRectArg,
PsychError_invalidNumberBuffersArg, //invalid number of video buffers specified to SCREEN OpenWindow
PsychError_nullWinRecPntr,
PsychError_registerLimit,
PsychError_registered,
PsychError_longString,
PsychError_longStringPassed,
PsychError_unimplemented, //unimplemented feature
PsychError_internal, //catch-all category for INTERNAL PSYCHTOOLBOX ERRORS.
PsychError_system, //errors reported by system calls
PsychError_invalidArgRef,
PsychError_OpenGL,
PsychError_SDL,
PsychError_SurfaceLockFailed,
PsychError_SurfaceAlreadyLocked,
PsychError_InvalidWindowRecord,
PsychError_unsupportedVideoMode,
PsychError_user, //catch-all category for USER ERRORS.
PsychError_unrecognizedPreferenceName,
PsychError_unsupportedOS9Preference,
PsychError_inputMatrixIllegalDimensionSize,
PsychError_stringOverrun,
PsychErorr_argumentValueOutOfRange,
PsychError_last
} PsychError;
//This should be "PsychErrorType", not "PsychError"
/*
Enumerated types and structures used to describe arguments passed from the scripting environment. The ScriptingGlue functions which
retrieve arguments can push a description of the desired arguments and push a description of the found
arguments and then return an error if there is a discrepancy. PsychErrorExitMsg can then pop the descriptions
if the error type is PsychError_invalidInArgType or PsychError_invalidArgs to generate an error message
telling the user why the argument passed was bogus.
*/
typedef enum
{
#define PsychArgType_MIN PsychArgType_unspecified
PsychArgType_none = 0,
PsychArgType_unspecified = 1,
PsychArgType_unclassified = 2,
PsychArgType_char = 4,
PsychArgType_uint8 = 8,
PsychArgType_uint16 = 16,
PsychArgType_uint32 = 32,
PsychArgType_int8 = 64,
PsychArgType_int16 = 128,
PsychArgType_int32 = 256,
PsychArgType_double = 512,
PsychArgType_boolean = 1024,
PsychArgType_structArray = 2048,
PsychArgType_cellArray = 4096,
PsychArgType_single = 8192,
PsychArgType_uint64 = 16384,
PsychArgType_int64 = 32768,
PsychArgType_default = 65536,
#define PsychArgType_MAX PsychArgType_default
#define PsychArgType_NUMTYPES 17 //this does not include the PsychArgType_none
} PsychArgFormatType; //change this to PsychArgType for brevity
typedef enum
{
PsychArgIn, //change to PsychArg_in for consistant style
PsychArgOut
} PsychArgDirectionType;
typedef enum
{
kPsychArgAbsent = 0,
kPsychArgPresent = 1,
kPsychArgFixed = 2 //Arguments which are always present, the first return argument in MATLAB.
} PsychArgPresenceType;
typedef enum
{
kPsychArgOptional = 0, //Argument may be either absent or present and of the specified type
kPsychArgRequired = 1, //Argument must be present and of the specified type
kPsychArgAnything = 2 //Argument may be present with specified type, absent, or of a different type.
} PsychArgRequirementType;
typedef struct
{
int position;
PsychArgDirectionType direction;
PsychArgPresenceType isThere;
PsychArgRequirementType isRequired;
PsychArgFormatType type;
int numDims; // used only to set the received descriptor, to catch > 3 dims.
psych_int64 mDimMin; // 1 is lowest
psych_int64 mDimMax; // kPsychUnboundedArraySize = -1 is infinity
psych_int64 nDimMin; // 1 is lowest
psych_int64 nDimMax; // kPsychUnboundedArraySize = -1 is infinity
psych_int64 pDimMin; // 0 is lowest. (this should be changed to make 1 the lowest, so it agrees with n)
psych_int64 pDimMax; // kPsychUnboundedArraySize = -1 is infinity. Set p min and max to zero to forbid
} PsychArgDescriptorType;
#define kPsychUnboundedArraySize (psych_int64) -1
#define kPsychUnusedArrayDimension (psych_int64) -2
//function prototypes
PsychError InitPsychError(void);
void PsychErrorExitC(PsychError error,
const char *extraErrorString,
int lineNum,
const char *funcName,
const char *fileName);
PsychError PsychStoreArgDescriptor(PsychArgDescriptorType *specified,
PsychArgDescriptorType *provided);
PsychError PsychGetArgDescriptor(PsychArgDescriptorType **specified,
PsychArgDescriptorType **provided);
int PsychDecomposeArgFormat(PsychArgFormatType argType, const char **names);
void PsychDumpArgDescriptors(void);
//This is dumb, but we define the PsychFunctionPtr type inside of PsychError.
typedef PsychError (*PsychFunctionPtr)(void);
//end include once
#endif
|