Fixes some build issues on Solaris 11.
[platform/upstream/freerdp.git] / winpr / libwinpr / crt / string.c
1 /**
2  * WinPR: Windows Portable Runtime
3  * String Manipulation (CRT)
4  *
5  * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <errno.h>
25 #include <wctype.h>
26
27 #include <winpr/crt.h>
28
29 /* String Manipulation (CRT): http://msdn.microsoft.com/en-us/library/f0151s4x.aspx */
30
31 #ifndef _WIN32
32
33 #include "casing.c"
34
35 #include "../log.h"
36 #define TAG WINPR_TAG("crt")
37
38 char* _strdup(const char* strSource)
39 {
40         char* strDestination;
41
42         if (strSource == NULL)
43                 return NULL;
44
45         strDestination = strdup(strSource);
46
47         if (strDestination == NULL)
48                 WLog_ERR(TAG,"strdup");
49
50         return strDestination;
51 }
52
53 WCHAR* _wcsdup(const WCHAR* strSource)
54 {
55         WCHAR* strDestination;
56
57         if (strSource == NULL)
58                 return NULL;
59
60 #if defined(__APPLE__) && defined(__MACH__) || defined(ANDROID) || defined(sun)
61         strDestination = malloc(wcslen((wchar_t*)strSource));
62
63         if (strDestination != NULL)
64                 wcscpy((wchar_t*)strDestination, (const wchar_t*)strSource);
65
66 #else
67         strDestination = (WCHAR*) wcsdup((wchar_t*) strSource);
68 #endif
69
70         if (strDestination == NULL)
71                 WLog_ERR(TAG,"wcsdup");
72
73         return strDestination;
74 }
75
76 int _stricmp(const char* string1, const char* string2)
77 {
78         return strcasecmp(string1, string2);
79 }
80
81 int _strnicmp(const char* string1, const char* string2, size_t count)
82 {
83         return strncasecmp(string1, string2, count);
84 }
85
86 /* _wcscmp -> wcscmp */
87
88 int _wcscmp(const WCHAR* string1, const WCHAR* string2)
89 {
90         while (*string1 && (*string1 == *string2))
91         {
92                 string1++;
93                 string2++;
94         }
95
96         return *string1 - *string2;
97 }
98
99 /* _wcslen -> wcslen */
100
101 size_t _wcslen(const WCHAR* str)
102 {
103         WCHAR* p = (WCHAR*) str;
104
105         if (!p)
106                 return 0;
107
108         while (*p)
109                 p++;
110
111         return (p - str);
112 }
113
114 /* _wcschr -> wcschr */
115
116 WCHAR* _wcschr(const WCHAR* str, WCHAR c)
117 {
118         WCHAR* p = (WCHAR*) str;
119
120         while (*p && (*p != c))
121                 p++;
122
123         return ((*p == c) ? p : NULL);
124 }
125
126 char* strtok_s(char* strToken, const char* strDelimit, char** context)
127 {
128         return strtok_r(strToken, strDelimit, context);
129 }
130
131 WCHAR* wcstok_s(WCHAR* strToken, const WCHAR* strDelimit, WCHAR** context)
132 {
133         WCHAR* nextToken;
134
135         if (!strToken)
136                 strToken = *context;
137
138         while (*strToken && _wcschr(strDelimit, *strToken))
139                 strToken++;
140
141         if (!*strToken)
142                 return NULL;
143
144         nextToken = strToken++;
145
146         while (*strToken && !(_wcschr(strDelimit, *strToken)))
147                 strToken++;
148
149         if (*strToken)
150                 *strToken++ = 0;
151
152         *context = strToken;
153         return nextToken;
154 }
155
156 /* Windows API Sets - api-ms-win-core-string-l2-1-0.dll
157  * http://msdn.microsoft.com/en-us/library/hh802935/
158  */
159
160 LPSTR CharUpperA(LPSTR lpsz)
161 {
162         int i;
163         int length;
164
165         if (!lpsz)
166                 return NULL;
167
168         length = strlen(lpsz);
169
170         if (length < 1)
171                 return (LPSTR) NULL;
172
173         if (length == 1)
174         {
175                 char c = *lpsz;
176
177                 if ((c >= 'a') && (c <= 'z'))
178                         c = c - 32;
179
180                 *lpsz = c;
181                 return lpsz;
182         }
183
184         for (i = 0; i < length; i++)
185         {
186                 if ((lpsz[i] >= 'a') && (lpsz[i] <= 'z'))
187                         lpsz[i] = lpsz[i] - 32;
188         }
189
190         return lpsz;
191 }
192
193 LPWSTR CharUpperW(LPWSTR lpsz)
194 {
195         WLog_ERR(TAG, "CharUpperW unimplemented!");
196         return (LPWSTR) NULL;
197 }
198
199 DWORD CharUpperBuffA(LPSTR lpsz, DWORD cchLength)
200 {
201         int i;
202
203         if (cchLength < 1)
204                 return 0;
205
206         for (i = 0; i < cchLength; i++)
207         {
208                 if ((lpsz[i] >= 'a') && (lpsz[i] <= 'z'))
209                         lpsz[i] = lpsz[i] - 32;
210         }
211
212         return cchLength;
213 }
214
215 DWORD CharUpperBuffW(LPWSTR lpsz, DWORD cchLength)
216 {
217         DWORD i;
218
219         for (i = 0; i < cchLength; i++)
220         {
221                 lpsz[i] = WINPR_TOUPPERW(lpsz[i]);
222         }
223
224         return cchLength;
225 }
226
227 LPSTR CharLowerA(LPSTR lpsz)
228 {
229         int i;
230         int length;
231
232         if (!lpsz)
233                 return (LPSTR) NULL;
234
235         length = strlen(lpsz);
236
237         if (length < 1)
238                 return (LPSTR) NULL;
239
240         if (length == 1)
241         {
242                 char c = *lpsz;
243
244                 if ((c >= 'A') && (c <= 'Z'))
245                         c = c + 32;
246
247                 *lpsz = c;
248                 return lpsz;
249         }
250
251         for (i = 0; i < length; i++)
252         {
253                 if ((lpsz[i] >= 'A') && (lpsz[i] <= 'Z'))
254                         lpsz[i] = lpsz[i] + 32;
255         }
256
257         return lpsz;
258 }
259
260 LPWSTR CharLowerW(LPWSTR lpsz)
261 {
262         WLog_ERR(TAG, "CharLowerW unimplemented!");
263         return (LPWSTR) NULL;
264 }
265
266 DWORD CharLowerBuffA(LPSTR lpsz, DWORD cchLength)
267 {
268         int i;
269
270         if (cchLength < 1)
271                 return 0;
272
273         for (i = 0; i < cchLength; i++)
274         {
275                 if ((lpsz[i] >= 'A') && (lpsz[i] <= 'Z'))
276                         lpsz[i] = lpsz[i] + 32;
277         }
278
279         return cchLength;
280 }
281
282 DWORD CharLowerBuffW(LPWSTR lpsz, DWORD cchLength)
283 {
284         DWORD i;
285
286         for (i = 0; i < cchLength; i++)
287         {
288                 lpsz[i] = WINPR_TOLOWERW(lpsz[i]);
289         }
290
291         return cchLength;
292 }
293
294 BOOL IsCharAlphaA(CHAR ch)
295 {
296         if (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')))
297                 return 1;
298         else
299                 return 0;
300 }
301
302 BOOL IsCharAlphaW(WCHAR ch)
303 {
304         WLog_ERR(TAG, "IsCharAlphaW unimplemented!");
305         return 0;
306 }
307
308 BOOL IsCharAlphaNumericA(CHAR ch)
309 {
310         if (((ch >= 'a') && (ch <= 'z')) || ((ch >= 'A') && (ch <= 'Z')) ||
311                         ((ch >= '0') && (ch <= '9')))
312                 return 1;
313         else
314                 return 0;
315 }
316
317 BOOL IsCharAlphaNumericW(WCHAR ch)
318 {
319         WLog_ERR(TAG, "IsCharAlphaNumericW unimplemented!");
320         return 0;
321 }
322
323 BOOL IsCharUpperA(CHAR ch)
324 {
325         if ((ch >= 'A') && (ch <= 'Z'))
326                 return 1;
327         else
328                 return 0;
329 }
330
331 BOOL IsCharUpperW(WCHAR ch)
332 {
333         WLog_ERR(TAG, "IsCharUpperW unimplemented!");
334         return 0;
335 }
336
337 BOOL IsCharLowerA(CHAR ch)
338 {
339         if ((ch >= 'a') && (ch <= 'z'))
340                 return 1;
341         else
342                 return 0;
343 }
344
345 BOOL IsCharLowerW(WCHAR ch)
346 {
347         WLog_ERR(TAG, "IsCharLowerW unimplemented!");
348         return 0;
349 }
350
351 int lstrlenA(LPCSTR lpString)
352 {
353         return strlen(lpString);
354 }
355
356 int lstrlenW(LPCWSTR lpString)
357 {
358         LPWSTR p;
359
360         if (!lpString)
361                 return 0;
362
363         p = (LPWSTR) lpString;
364
365         while (*p)
366                 p++;
367
368         return p - lpString;
369 }
370
371 int lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
372 {
373         return strcmp(lpString1, lpString2);
374 }
375
376 int lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
377 {
378         while (*lpString1 && (*lpString1 == *lpString2))
379         {
380                 lpString1++;
381                 lpString2++;
382         }
383
384         return *lpString1 - *lpString2;
385 }
386
387 #endif
388
389 int ConvertLineEndingToLF(char* str, int size)
390 {
391         int status;
392         char* end;
393         char* pInput;
394         char* pOutput;
395
396         end = &str[size];
397         pInput = pOutput = str;
398
399         while (pInput < end)
400         {
401                 if ((pInput[0] == '\r') && (pInput[1] == '\n'))
402                 {
403                         *pOutput++ = '\n';
404                         pInput += 2;
405                 }
406                 else
407                 {
408                         *pOutput++ = *pInput++;
409                 }
410         }
411
412         status = pOutput - str;
413
414         return status;
415 }
416
417 char* ConvertLineEndingToCRLF(const char* str, int* size)
418 {
419         int count;
420         char* newStr;
421         char* pOutput;
422         const char* end;
423         const char* pInput;
424
425         end = &str[*size];
426
427         count = 0;
428         pInput = str;
429
430         while (pInput < end)
431         {
432                 if (*pInput == '\n')
433                         count++;
434
435                 pInput++;
436         }
437
438         newStr = (char*) malloc(*size + (count * 2) + 1);
439
440         if (!newStr)
441                 return NULL;
442
443         pInput = str;
444         pOutput = newStr;
445
446         while (pInput < end)
447         {
448                 if ((*pInput == '\n') && ((pInput > str) && (pInput[-1] != '\r')))
449                 {
450                         *pOutput++ = '\r';
451                         *pOutput++ = '\n';
452                 }
453                 else
454                 {
455                         *pOutput++ = *pInput;
456                 }
457
458                 pInput++;
459         }
460
461         *size = pOutput - newStr;
462
463         return newStr;
464 }
465