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
|
/*
* MiniBox.cpp
*
* DESCRIPTION:
*
* The minimal set of functions necessary to support SCREEN style error messages, help and
* argument list parsing. Originally copied from David Brainard and Denis Pelli's
* Psychtoolbox project, with some modification.
* It has since evolved into a miscellaneous category.
*
* HISTORY:
*
* 08/22/01 awi Windows
* 11/15/01 awi Mac OS 9
* 08/20/01 awi Created file.
* 08/20/01 awi Replaced fancy memory allocation in PrintfExit with static array.
* 11/26/01 awi Replaced references to ActiveWireTable in PsychMatch with ProjectTable
* This is so we can share the MiniBox file between ActiveWire and
* Joystick projects.
* 12/17/01 awi Commented out include "joystick.h" and included stdafx.h for GetChar project.
* 12/17/01 awi All of the grief with ordering the header inclusion and porbability was
* caused by PsychMatch using the project table to read the case-sensitive
* character comparision flag from the psych table. That's a pretty useless
* feature anyway, so I just commented that out to make GetChar compile.
* 1/20/04 awi Cosmetic.
* 3/19/10 mk Cosmetic and make 64-bit clean.
*
*/
#include "Psych.h"
#include <ctype.h>
// The handle of the masterthread - The Matlab/Octave/Python/PTB main interpreter thread:
static psych_threadid masterthread = (psych_threadid) 0;
#define MAX_PRINTFEXIT_LEN 2000
static psych_bool isPsychMatchCaseSensitive = FALSE;
/* PrintfExit used some fancy stuff to allocate the memory
* which holds the the error message string passed to
* mexErrMsgTxt. I just used a static array here. -awi
*/
int PrintfExit(const char *format,...)
{
char s[MAX_PRINTFEXIT_LEN];
va_list args;
int i;
va_start(args,format);
// Octave build of Screen.mex on Windows with MSVC GStreamer?
#if (PSYCH_SYSTEM == PSYCH_WINDOWS) && defined(PTBOCTAVE3MEX)&& defined(PTB_USE_GSTREAMER)
// Yes: Hack around incompatibilities relating to vsnprintf() in MinGW + GStreamer MSVC SDK:
i = vsprintf(s, format, args);
#else
// No: All good.
i = vsnprintf(s, MAX_PRINTFEXIT_LEN - 1, format, args);
#endif
va_end(args);
if(i + 1 > MAX_PRINTFEXIT_LEN)
printf("PTB-ERROR: Buffer overrun in PrintfExit\n");
PsychErrMsgTxt(s);
return 0;
}
char *BreakLines(char *string,long lineLength)
{
long i,leftMargin,rightMargin,length;
int here;
leftMargin=0;
length = (long) strlen(string);
while(1){
rightMargin=leftMargin+lineLength;
if(rightMargin>=length)return string; /* successful completion */
here=0;
if(!here)for(i=leftMargin;i<rightMargin;i++)if(string[i]=='\n'){
here=1;
break;
}
if(!here)for(;i>=leftMargin;i--)if(string[i]==' ' || string[i]=='\n'){
here=1;
break;
}
if(!here)for(i=leftMargin;i<length;i++)if(string[i]==' ' || string[i]=='\n'){
here=1;
break;
}
if(!here)return string;
string[i]='\n';
leftMargin=i+1;
}
}
psych_bool PsychIsPsychMatchCaseSensitive(void)
{
return(isPsychMatchCaseSensitive);
}
void PsychSetPsychMatchCaseSenstive(psych_bool arg)
{
isPsychMatchCaseSensitive=arg;
}
// Compare two strings for equality. Ignore case if Psychtoolbox preferences ignore case is set.
psych_bool PsychMatch(char *s1,char *s2)
{
char a;
if(!isPsychMatchCaseSensitive){
do{
a=*s1++;
if(tolower(a)!=tolower(*s2++))return 0;
}while(a!='\0');
return 1;
}else
return strcmp(s1,s2)==0;
}
char *int2str(psych_int64 num)
{
static char numStr[256];
#if PSYCH_SYSTEM != PSYCH_WINDOWS
sprintf(numStr, "%lld", (long long int) num);
#else
// TODO FIXME AUDIT 64BIT : Figure out a way to handle psych_int64 printing on Windows:
sprintf(numStr, "%d", (int) num);
#endif
return(numStr);
}
size_t PsychIndexElementFrom2DArray(size_t mDim/*|Y|*/, size_t nDim/*|X|*/, size_t m/*y*/, size_t n/*x*/)
{
(void) nDim;
return(n*mDim + m);
}
size_t PsychIndexElementFrom3DArray(size_t mDim/*|Y|*/, size_t nDim/*|X|*/, size_t pDim/*|Z|*/, size_t m/*y*/, size_t n/*x*/, size_t p/*z*/)
{
(void) pDim;
return(p*mDim*nDim + n*mDim + m); //planeindex * planesize + columnindex * columsize + rowindex
}
size_t PsychIndexPlaneFrom3DArray(size_t mDim, size_t nDim, size_t pDim, size_t planeIndex)
{
(void) pDim;
return(planeIndex*mDim*nDim);
}
psych_int64 maxInt(psych_int64 a, psych_int64 b)
{
if(a>b)
return(a);
return(b);
}
/*
* PsychIsIntegerInDouble(double *value)
*
* If the value stored in the specified double does not have a fractional part an the value is within
* the bounds of the signed/unsigned integer type then return TRUE.
* We allow to store 32-Bit unsigned int values inside 32-Bit signed int's for this validation,
* so uint32's can be passed, e.g., via PsychCopyInIntegerArg(). They would wrap to negative in
* the returned int32 if they exceed +INT_MAX, but allowing to cast forward and backward between
* uint32 and int32 has value for access to some hardware api's, e.g., forum message #17256.
*/
psych_bool PsychIsIntegerInDouble(double *value)
{
return((*value >= INT_MIN) && (*value <= (double) 0xffffffff) && (floor(*value) == *value));
}
/* Check if it is a 64 bit integer (psych_int64) packed into a double:
* This check will already fail for any integer greater than about 2^52
* as double can't represent them accurately anymore.
*/
psych_bool PsychIsInteger64InDouble(double *value)
{
return((*value >= -9.22337203685478e+18) && (*value <= 9.22337203685478e+18) && (floor(*value) == *value));
}
void PsychInitMasterThreadId(void)
{
// Assign unique id of this thread (the Matlab/Octave/Python main interpreter thread)
// as masterthread. This masterthread is the only one allowed to execute certain code
// that may only be safe for execution on the main thread, e.g., stuff that interacts
// with the interpreter / host runtime api.
masterthread = PsychGetThreadId();
}
psych_threadid PsychGetMasterThreadId(void)
{
return(masterthread);
}
psych_bool PsychIsMasterThread(void)
{
return(PsychIsCurrentThreadEqualToId(masterthread));
}
|