- Fix ctype(), make is* functions binary compatible
[wine] / dlls / crtdll / string.c
1 /*
2  * CRTDLL string functions
3  * 
4  * Copyright 1996,1998 Marcus Meissner
5  * Copyright 1996 Jukka Iivonen
6  * Copyright 1997,2000 Uwe Bonnes
7  * Copyright 2000 Jon Griffiths
8  *
9  * Implementation Notes:
10  * MT Safe.
11  */
12
13 #include "crtdll.h"
14
15
16 DEFAULT_DEBUG_CHANNEL(crtdll);
17
18 /* INTERNAL: CRTDLL_malloc() based strndup */
19 LPSTR __CRTDLL__strndup(LPSTR buf, INT size);
20 LPSTR __CRTDLL__strndup(LPSTR buf, INT size)
21 {
22   char* ret;
23   int len = strlen(buf);
24   int max_len;
25
26   max_len = size <= len? size : len + 1;
27
28   ret = CRTDLL_malloc(max_len);
29   if (ret)
30   {
31     memcpy(ret,buf,max_len);
32     ret[max_len] = 0;
33   }
34   return ret;
35 }
36
37
38 /*********************************************************************
39  *                  _strdec           (CRTDLL.282)
40  *
41  * Return the byte before str2 while it is >= to str1. 
42  *
43  * PARAMS
44  *   str1 [in]  Terminating string
45  *
46  *   sre2 [in]  string to start searching from
47  *
48  * RETURNS
49  *   The byte before str2, or str1, whichever is greater
50  *
51  * NOTES
52  * This function is implemented as tested with windows, which means
53  * it does not have a terminating condition. It always returns
54  * the byte before str2. Use with extreme caution!
55  */
56 LPSTR __cdecl CRTDLL__strdec(LPSTR str1, LPSTR str2)
57 {
58   /* Hmm. While the docs suggest that the following should work... */
59   /*  return (str2<=str1?0:str2-1); */
60   /* ...Version 2.50.4170 (NT) from win98 constantly decrements! */
61   str1 = str1; /* remove warning */
62   return str2-1;
63 }
64
65
66 /*********************************************************************
67  *                  _strdup          (CRTDLL.285)
68  *
69  * Duplicate a string.
70  */
71 LPSTR __cdecl CRTDLL__strdup(LPCSTR ptr)
72 {
73     LPSTR ret = CRTDLL_malloc(strlen(ptr)+1);
74     if (ret) strcpy( ret, ptr );
75     return ret;
76 }
77
78
79 /*********************************************************************
80  *                  _strinc           (CRTDLL.287)
81  *
82  * Return a pointer to the next character in a string
83  */
84 LPSTR __cdecl CRTDLL__strinc(LPSTR str)
85 {
86   return str+1;
87 }
88
89
90 /*********************************************************************
91  *                   _strnextc         (CRTDLL.290)
92  *
93  * Return an unsigned int from a string.
94  */
95 UINT __cdecl CRTDLL__strnextc(LPCSTR str)
96 {
97   return (UINT)*str;
98 }
99
100
101 /*********************************************************************
102  *                  _strninc           (CRTDLL.292)
103  *
104  * Return a pointer to the 'n'th character in a string
105  */
106 LPSTR __cdecl CRTDLL__strninc(LPSTR str, INT n)
107 {
108   return str+n;
109 }
110
111
112 /*********************************************************************
113  *                  _strnset           (CRTDLL.293)
114  *
115  * Fill a string with a character up to a certain length
116  */
117 LPSTR __cdecl CRTDLL__strnset(LPSTR str, INT c, INT len)
118 {
119   if (len > 0 && str)
120     while (*str && len--)
121       *str++ = c;
122   return str;
123 }
124
125
126 /*********************************************************************
127  *                  _strrev              (CRTDLL.294)
128  *
129  * Reverse a string in place
130  */
131 LPSTR __cdecl CRTDLL__strrev (LPSTR str)
132 {
133   LPSTR p1;
134   LPSTR p2;
135  
136   if (str && *str)
137     for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
138     {
139       *p1 ^= *p2;
140       *p2 ^= *p1;
141       *p1 ^= *p2;
142     }
143
144   return str;
145 }
146
147 /*********************************************************************
148  *                  _strset          (CRTDLL.295)
149  *
150  * Fill a string with a value.
151  */
152 LPSTR  __cdecl CRTDLL__strset (LPSTR str, INT set)
153 {
154   char *ptr = str;
155
156   while (*ptr)
157     *ptr++ = set;
158
159   return str;
160 }
161
162
163 /*********************************************************************
164  *                  _strncnt           (CRTDLL.289)
165  *
166  * Return the length of a string or the maximum given length.
167  */
168 LONG __cdecl CRTDLL__strncnt(LPSTR str, LONG max)
169 {
170   LONG len = strlen(str);
171   return (len > max? max : len);
172 }
173
174
175 /*********************************************************************
176  *                  _strspnp           (CRTDLL.296)
177  *
178  */
179 LPSTR __cdecl CRTDLL__strspnp(LPSTR str1, LPSTR str2)
180 {
181   str1 += strspn(str1,str2);
182   return *str1? str1 : 0;
183 }
184
185
186 /*********************************************************************
187  *                  _swab           (CRTDLL.299)
188  *
189  * Copy from source to dest alternating bytes (i.e 16 bit big-to-little
190  * endian or vice versa).
191  */
192 void __cdecl CRTDLL__swab(LPSTR src, LPSTR dst, INT len)
193 {
194   if (len > 1)
195   {
196     len = (unsigned)len >> 1;
197
198     while (len--) {
199       *dst++ = src[1];
200       *dst++ = *src++;
201       src++;
202     }
203   }
204 }