Merge pull request #1891 from wtgodbe/failingPinvokes
[platform/upstream/coreclr.git] / tests / src / Common / Platform / platformdefines.cpp
1 // Copyright (c) Microsoft. All rights reserved.
2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 //
4
5
6 #include "platformdefines.h"
7
8 LPWSTR HackyConvertToWSTR(char* pszInput)
9 {
10         size_t cchInput;
11         LPWSTR pwszOutput;
12         char*  pStr;
13
14         if (NULL == pszInput) return NULL;
15
16         // poor mans strlen
17         pStr     = pszInput;
18         cchInput = 0;
19         while('\0' != *pStr) {cchInput++; pStr++;}
20         pwszOutput = new WCHAR[ cchInput + 1];
21
22         for(size_t i=0; i<=cchInput; i++)
23         {
24                 pwszOutput[i] = (WCHAR)pszInput[i];
25         }
26
27         return pwszOutput;
28 }
29
30 LPSTR HackyConvertToSTR(LPWSTR pwszInput)
31 {
32         size_t cchInput;
33         LPSTR  pszOutput;
34         LPWSTR pStr;
35
36         if (NULL == pwszInput) return NULL;
37
38         cchInput = wcslen(pwszInput);
39         pszOutput = new char[ cchInput + 1];
40
41         for(size_t i=0; i<=cchInput; i++)
42         {
43                 // ugly down cast
44                 pszOutput[i] = (char)pwszInput[i];
45         }
46
47         return pszOutput;
48 }
49
50 error_t TP_scpy_s(LPWSTR strDestination, size_t sizeInWords, LPCWSTR strSource)
51 {
52         int cnt;
53         // copy sizeInBytes bytes of strSource into strDestination
54
55         if (NULL == strDestination || NULL == strSource) return 1;
56
57         cnt = 0;
58         while(cnt < sizeInWords && '\0' != strSource[cnt])
59         {
60                 strDestination[cnt] = strSource[cnt];
61                 cnt++;
62         }
63         strDestination[cnt] = '\0';
64
65         return 0;
66 }
67
68 error_t TP_scat_s(LPWSTR strDestination, size_t sizeInWords, LPCWSTR strSource)
69 {
70         LPWSTR strEnd;
71         // locate the end (ie. '\0') and TP_scpy_s the string
72
73         if (NULL == strDestination || NULL == strSource) return 1;
74
75         strEnd = strDestination;
76         while('\0' != *strEnd) strEnd++;
77
78         return TP_scpy_s(strEnd, sizeInWords - ((strEnd - strDestination) / sizeof(WCHAR)), strSource);
79 }
80
81 int TP_slen(LPWSTR str)
82 {
83         int len;
84
85         if (NULL == str) return 0;
86
87         len = 0;
88         while('\0' != *(str+len)) len++;
89
90         return len;
91 }
92
93 int TP_scmp_s(LPSTR str1, LPSTR str2)
94 {
95         // < 0 str1 less than str2
96         // 0  str1 identical to str2
97         // > 0 str1 greater than str2
98
99         if (NULL == str1 && NULL != str2) return -1;
100         if (NULL != str1 && NULL == str2) return 1;
101         if (NULL == str1 && NULL == str2) return 0;
102
103         while (*str1 == *str2 && '\0' != *str1 && '\0' != *str2)
104         {
105                 str1++;
106                 str2++;
107         }
108
109         if ('\0' == *str1 && '\0' == *str2) return 0;
110
111         if ('\0' != *str1) return -1;
112         if ('\0' != *str2) return 1;
113
114         return (*str1 > *str2) ? 1 : -1;
115 }
116
117 int TP_wcmp_s(LPWSTR str1, LPWSTR str2)
118 {
119         // < 0 str1 less than str2
120         // 0  str1 identical to str2
121         // > 0 str1 greater than str2
122
123         if (NULL == str1 && NULL != str2) return -1;
124         if (NULL != str1 && NULL == str2) return 1;
125         if (NULL == str1 && NULL == str2) return 0;
126
127         while (*str1 == *str2 && '\0' != *str1 && '\0' != *str2)
128         {
129                 str1++;
130                 str2++;
131         }
132
133         if ('\0' == *str1 && '\0' == *str2) return 0;
134
135         if ('\0' != *str1) return -1;
136         if ('\0' != *str2) return 1;
137
138         return (*str1 > *str2) ? 1 : -1;
139 }
140
141 error_t TP_getenv_s(size_t* pReturnValue, LPWSTR buffer, size_t sizeInWords, LPCWSTR varname)
142 {
143         if (NULL == pReturnValue || NULL == varname) return 1;
144
145 #ifdef WINDOWS
146         
147          size_t  returnValue;
148      WCHAR   buf[100];
149      if( 0 != _wgetenv_s(&returnValue, buf, 100, varname) || returnValue<=0 )
150                 return 2;
151         
152         
153         TP_scpy_s(buffer, sizeInWords, (LPWSTR)buf);
154 #else
155         LPSTR pRet;
156         pRet = getenv( HackyConvertToSTR((LPWSTR)varname) );
157         if (NULL == pRet) return 2;
158         TP_scpy_s(buffer, sizeInWords, HackyConvertToWSTR(pRet));
159 #endif
160         return 0;
161 }
162
163 error_t TP_putenv_s(LPTSTR name, LPTSTR value)
164 {
165         if (NULL == name || NULL == value) return 1;
166
167 #ifdef WINDOWS
168         if( 0 != _putenv_s(name, value))
169                 return 2;
170         else
171                 return 0;
172 #else
173         int retVal = 0;
174         char *assignment = (char*) malloc(sizeof(char) * (strlen(name) + strlen(value) + 1));
175         sprintf(assignment, "%s=%s", name, value);
176
177         if (0 != putenv(assignment))
178                 retVal = 2;
179         free(assignment);
180         return retVal;
181 #endif
182 }
183
184 void TP_ZeroMemory(LPVOID buffer, size_t sizeInBytes)
185 {
186         BYTE* bBuf;
187
188         // clear out the memory with 0's
189         if (NULL == buffer) return;
190
191         bBuf = (BYTE*)buffer;
192         for(int i=0; i<sizeInBytes; i++)
193         {
194                 bBuf[i] = 0;
195         }
196 }
197
198 error_t TP_itow_s(int num, LPWSTR buffer, size_t sizeInCharacters, int radix)
199 {
200         int len;
201         int tmpNum;
202
203         // only support radix == 10 and only positive numbers
204         if (10 != radix) return 1;
205         if (0 > num) return 2;
206         if (NULL == buffer) return 3;
207         if (2 > sizeInCharacters) return 4;
208
209         // take care of the trivial case
210         if (0 == num)
211         {
212                 buffer[0] = '\0';
213                 buffer[1] = '\0';
214         }
215
216         // get length of final string (dumb implementation)
217         len = 0;
218         tmpNum = num;
219         while (0 < tmpNum)
220         {
221                 tmpNum /= 10;
222                 len++;
223         }
224
225         if (len >= sizeInCharacters) return 5;
226
227         // convert num into a string (backwards)
228         buffer[len] = '\0';
229         len--;
230         while(0 < num && 0 <= len)
231         {
232                 buffer[len] = (WCHAR)((num % 10) + '0');
233                 len--;
234                 num /= 10;
235         }
236
237         return 0;
238 }
239
240 LPWSTR TP_sstr(LPWSTR str, LPWSTR searchStr)
241 {
242         LPWSTR start;
243         LPWSTR current;
244         LPWSTR searchCurrent;
245
246         if (NULL == str || NULL == searchStr) return NULL;
247
248         // return a pointer to where searchStr
249         //  exists in str
250         current = str;
251         start   = NULL;
252         searchCurrent = searchStr;
253         while('\0' != *current)
254         {
255                 if (NULL != start && '\0' == *searchCurrent)
256                 {
257                         break;
258                 }
259
260                 if (*current == *searchCurrent)
261                 {
262                         searchCurrent++;
263                         if (NULL == start) start = current;
264                 }
265                 else
266                 {
267                         searchCurrent = searchStr;
268                         start = NULL;
269                 }
270                 current++;
271         }
272
273         return start;
274 }
275
276 DWORD TP_GetFullPathName(LPWSTR fileName, DWORD nBufferLength, LPWSTR lpBuffer)
277 {
278 #ifdef WINDOWS
279         return GetFullPathNameW(fileName, nBufferLength, lpBuffer, NULL);
280 #else
281         char nativeFullPath[MAX_PATH];
282         realpath(HackyConvertToSTR(fileName), nativeFullPath);
283         LPWSTR fullPathForCLR = HackyConvertToWSTR(nativeFullPath);
284         wcscpy_s(lpBuffer, MAX_PATH, fullPathForCLR);
285         return wcslen(lpBuffer);
286 #endif
287 }
288 DWORD TP_CreateThread(THREAD_ID* tThread, LPTHREAD_START_ROUTINE worker,  LPVOID lpParameter)
289 {
290 #ifdef WINDOWS
291         DWORD ret;
292         *tThread = CreateThread(
293                 NULL,
294                 0,
295                 worker,
296                 lpParameter,
297                 0,
298                 &ret);
299         return ret;
300 #else
301         pthread_create(
302                 tThread,
303                 NULL,
304                 (MacWorker)worker,
305                 lpParameter);
306 #ifdef MAC64
307         // This is a major kludge...64 bit posix threads just can't be cast into a DWORD and there just isn't
308         // a great way to get what we're using for the ID. The fact that we're casting this at all is kind of
309         // silly since we're returing the actual thread handle and everything being done to manipulate the thread
310         // is done with that. Anyhow, the only thing done with the dword returned from this method is a printf
311         // which is good since this DWORD really shouldn't be reliably used. Just in case it is though, return
312         // a value that can be traced back to here.
313         return 42;
314 #else
315         return (DWORD)*tThread;
316 #endif
317 #endif
318 }
319
320 void TP_JoinThread(THREAD_ID tThread)
321 {
322 #ifdef WINDOWS
323         WaitForSingleObject(tThread, INFINITE);
324 #else
325         pthread_join(tThread, NULL);
326 #endif
327 }
328
329 #ifndef WINDOWS
330 void TP_DebugBreak()
331 {
332 #ifdef _PPC_
333         __asm__ __volatile__("trap");
334 #elif defined(_ARM_)
335     __asm__ __volatile__("bkpt");
336 #else
337         __asm__ __volatile__("int $3");
338 #endif  
339 }
340 #endif