File: MiniBox.c

package info (click to toggle)
psychtoolbox-3 3.0.19.14.dfsg1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 86,796 kB
  • sloc: ansic: 176,245; cpp: 20,103; objc: 5,393; sh: 2,753; python: 1,397; php: 384; makefile: 193; java: 113
file content (199 lines) | stat: -rw-r--r-- 6,583 bytes parent folder | download | duplicates (3)
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));
}