Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / OS_NS_string.cpp
blob223d753589a56a1c0f4c057b03b63c86517c212e
1 #include "ace/ACE.h"
2 #include "ace/Global_Macros.h"
3 #include "ace/OS_NS_string.h"
4 #include "ace/OS_NS_stdio.h"
5 #include "ace/OS_NS_stdlib.h"
7 #if !defined (ACE_HAS_INLINED_OSCALLS)
8 # include "ace/OS_NS_string.inl"
9 #endif /* ACE_HAS_INLINED_OSCALLS */
11 #if defined (ACE_HAS_ALLOC_HOOKS)
12 # include "ace/Malloc_Base.h"
13 #endif /* ACE_HAS_ALLOC_HOOKS */
15 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
17 #if (defined (ACE_LACKS_STRDUP) && !defined (ACE_STRDUP_EQUIVALENT)) \
18 || defined (ACE_HAS_STRDUP_EMULATION)
19 char *
20 ACE_OS::strdup_emulation (const char *s)
22 #if defined (ACE_HAS_ALLOC_HOOKS)
23 char *t = (char *) ACE_Allocator::instance()->malloc (ACE_OS::strlen (s) + 1);
24 #else
25 char *t = (char *) ACE_OS::malloc (ACE_OS::strlen (s) + 1);
26 #endif /* ACE_HAS_ALLOC_HOOKS */
28 if (t == 0)
29 return 0;
31 return ACE_OS::strcpy (t, s);
33 #endif /* (ACE_LACKS_STRDUP && !ACE_STRDUP_EQUIVALENT) || ... */
35 #if defined (ACE_HAS_WCHAR)
36 #if (defined (ACE_LACKS_WCSDUP) && !defined (ACE_WCSDUP_EQUIVALENT)) \
37 || defined (ACE_HAS_WCSDUP_EMULATION)
38 wchar_t *
39 ACE_OS::strdup_emulation (const wchar_t *s)
41 wchar_t *buffer =
42 (wchar_t *) ACE_OS::malloc ((ACE_OS::strlen (s) + 1)
43 * sizeof (wchar_t));
44 if (buffer == 0)
45 return 0;
47 return ACE_OS::strcpy (buffer, s);
49 #endif /* (ACE_LACKS_WCSDUP && !ACE_WCSDUP_EQUIVALENT) || ... */
50 #endif /* ACE_HAS_WCHAR */
52 char *
53 ACE_OS::strecpy (char *s, const char *t)
55 char *dscan = s;
56 const char *sscan = t;
58 while ((*dscan++ = *sscan++) != '\0')
59 continue;
61 return dscan;
64 #if defined (ACE_HAS_WCHAR)
65 wchar_t *
66 ACE_OS::strecpy (wchar_t *s, const wchar_t *t)
68 wchar_t *dscan = s;
69 const wchar_t *sscan = t;
71 while ((*dscan++ = *sscan++) != ACE_TEXT_WIDE ('\0'))
72 continue;
74 return dscan;
76 #endif /* ACE_HAS_WCHAR */
78 char *
79 ACE_OS::strerror (int errnum)
81 static char ret_errortext[128];
83 if (ACE::is_sock_error (errnum))
85 const ACE_TCHAR *errortext = ACE::sock_error (errnum);
86 ACE_OS::strsncpy (ret_errortext,
87 ACE_TEXT_ALWAYS_CHAR (errortext),
88 sizeof (ret_errortext));
89 return ret_errortext;
91 #if defined (ACE_LACKS_STRERROR)
92 errno = EINVAL;
93 return ACE_OS::strerror_emulation (errnum);
94 #else /* ACE_LACKS_STRERROR */
95 // Adapt to the various ways that strerror() indicates a bad errnum.
96 // Most modern systems set errno to EINVAL. Some older platforms return
97 // a pointer to a NULL string. This code makes the behavior more consistent
98 // across platforms. On a bad errnum, we make a string with the error number
99 // and set errno to EINVAL.
100 ACE_Errno_Guard g (errno);
101 errno = 0;
102 char *errmsg = 0;
104 #if defined (ACE_HAS_TR24731_2005_CRT)
105 errmsg = ret_errortext;
106 ACE_SECURECRTCALL (strerror_s (ret_errortext, sizeof(ret_errortext), errnum),
107 char *, 0, errmsg);
108 if (errnum < 0 || errnum >= _sys_nerr)
109 g = EINVAL;
111 return errmsg;
112 #elif defined (ACE_WIN32)
113 if (errnum < 0 || errnum >= _sys_nerr)
114 errno = EINVAL;
115 #endif /* ACE_WIN32 */
116 errmsg = ::strerror (errnum);
118 if (errno == EINVAL || errmsg == 0 || errmsg[0] == 0)
120 ACE_OS::snprintf (ret_errortext, 128, "Unknown error %d", errnum);
121 errmsg = ret_errortext;
122 g = EINVAL;
124 return errmsg;
125 #endif /* ACE_LACKS_STRERROR */
128 #if defined (ACE_LACKS_STRERROR)
130 * Just returns "Unknown Error" all the time.
132 char *
133 ACE_OS::strerror_emulation (int)
135 return const_cast <char*> ("Unknown Error");
137 #endif /* ACE_LACKS_STRERROR */
139 char *
140 ACE_OS::strsignal (int signum)
142 static char signal_text[128];
143 #if defined (ACE_HAS_STRSIGNAL)
144 char *ret_val = 0;
146 # if defined (ACE_NEEDS_STRSIGNAL_RANGE_CHECK)
147 if (signum < 0 || signum >= ACE_NSIG)
148 ret_val = 0;
149 else
150 # endif /* (ACE_NEEDS_STRSIGNAL_RANGE_CHECK */
151 ret_val = ::strsignal (signum);
153 if (ret_val <= reinterpret_cast<char *> (0))
155 ACE_OS::snprintf (signal_text, 128, "Unknown signal: %d", signum);
156 ret_val = signal_text;
158 return ret_val;
159 #else
160 if (signum < 0 || signum >= ACE_NSIG)
162 ACE_OS::snprintf (signal_text, 128, "Unknown signal: %d", signum);
163 return signal_text;
165 # if defined (ACE_SYS_SIGLIST)
166 return ACE_SYS_SIGLIST[signum];
167 # else
168 ACE_OS::snprintf (signal_text, 128, "Signal: %d", signum);
169 return signal_text;
170 # endif /* ACE_SYS_SIGLIST */
171 #endif /* ACE_HAS_STRSIGNAL */
174 char *
175 ACE_OS::strerror_r (int errnum, char *buf, size_t buflen)
177 #ifdef ACE_HAS_STRERROR_R
178 # ifdef ACE_HAS_STRERROR_R_XSI
179 if (::strerror_r (errnum, buf, buflen) == 0)
180 return buf;
181 return const_cast <char*> ("Unknown Error");
182 # else
183 return ::strerror_r (errnum, buf, buflen);
184 # endif
185 #else
186 return ACE_OS::strncpy (buf, strerror (errnum), buflen);
187 #endif
190 const char *
191 ACE_OS::strnchr (const char *s, int c, size_t len)
193 for (size_t i = 0; i < len; ++i)
194 if (s[i] == c)
195 return s + i;
197 return 0;
200 const ACE_WCHAR_T *
201 ACE_OS::strnchr (const ACE_WCHAR_T *s, ACE_WCHAR_T c, size_t len)
203 for (size_t i = 0; i < len; ++i)
205 if (s[i] == c)
207 return s + i;
211 return 0;
214 const char *
215 ACE_OS::strnstr (const char *s1, const char *s2, size_t len2)
217 // Substring length
218 size_t const len1 = ACE_OS::strlen (s1);
220 // Check if the substring is longer than the string being searched.
221 if (len2 > len1)
222 return 0;
224 // Go upto <len>
225 size_t const len = len1 - len2;
227 for (size_t i = 0; i <= len; i++)
229 if (ACE_OS::memcmp (s1 + i, s2, len2) == 0)
231 // Found a match! Return the index.
232 return s1 + i;
236 return 0;
239 const ACE_WCHAR_T *
240 ACE_OS::strnstr (const ACE_WCHAR_T *s1, const ACE_WCHAR_T *s2, size_t len2)
242 // Substring length
243 size_t const len1 = ACE_OS::strlen (s1);
245 // Check if the substring is longer than the string being searched.
246 if (len2 > len1)
247 return 0;
249 // Go upto <len>
250 size_t const len = len1 - len2;
252 for (size_t i = 0; i <= len; i++)
254 if (ACE_OS::memcmp (s1 + i, s2, len2 * sizeof (ACE_WCHAR_T)) == 0)
256 // Found a match! Return the index.
257 return s1 + i;
261 return 0;
264 char *
265 ACE_OS::strsncpy (char *dst, const char *src, size_t maxlen)
267 char *rdst = dst;
268 const char *rsrc = src;
269 size_t rmaxlen = maxlen;
271 if (rmaxlen > 0)
273 if (rdst!=rsrc)
275 *rdst = '\0';
276 if (rsrc != 0)
278 ACE_OS::strncat (rdst, rsrc, --rmaxlen);
281 else
283 rdst += (rmaxlen - 1);
284 *rdst = '\0';
287 return dst;
290 ACE_WCHAR_T *
291 ACE_OS::strsncpy (ACE_WCHAR_T *dst, const ACE_WCHAR_T *src, size_t maxlen)
293 ACE_WCHAR_T *rdst = dst;
294 const ACE_WCHAR_T *rsrc = src;
295 size_t rmaxlen = maxlen;
297 if (rmaxlen > 0)
299 if (rdst!= rsrc)
301 *rdst = ACE_TEXT_WIDE ('\0');
302 if (rsrc != 0)
304 ACE_OS::strncat (rdst, rsrc, --rmaxlen);
307 else
309 rdst += (rmaxlen - 1);
310 *rdst = ACE_TEXT_WIDE ('\0');
313 return dst;
316 #if defined (ACE_LACKS_STRTOK_R)
317 char *
318 ACE_OS::strtok_r_emulation (char *s, const char *tokens, char **lasts)
320 if (s == 0)
321 s = *lasts;
322 else
323 *lasts = s;
324 if (*s == 0) // We have reached the end
325 return 0;
326 size_t const l_org = ACE_OS::strlen (s);
327 s = ::strtok (s, tokens);
328 if (s == 0)
329 return 0;
330 size_t const l_sub = ACE_OS::strlen (s);
331 if (s + l_sub < *lasts + l_org)
332 *lasts = s + l_sub + 1;
333 else
334 *lasts = s + l_sub;
335 return s ;
337 #endif /* ACE_LACKS_STRTOK_R */
339 # if defined (ACE_HAS_WCHAR) && defined (ACE_LACKS_WCSTOK)
340 wchar_t*
341 ACE_OS::strtok_r_emulation (ACE_WCHAR_T *s,
342 const ACE_WCHAR_T *tokens,
343 ACE_WCHAR_T **lasts)
345 ACE_WCHAR_T* sbegin = s ? s : *lasts;
346 sbegin += ACE_OS::strspn(sbegin, tokens);
347 if (*sbegin == 0)
349 static ACE_WCHAR_T empty[1] = { 0 };
350 *lasts = empty;
351 return 0;
353 ACE_WCHAR_T*send = sbegin + ACE_OS::strcspn(sbegin, tokens);
354 if (*send != 0)
355 *send++ = 0;
356 *lasts = send;
357 return sbegin;
359 # endif /* ACE_HAS_WCHAR && ACE_LACKS_WCSTOK */
361 ACE_END_VERSIONED_NAMESPACE_DECL