Initial Patch of Auction House bot rev. 135
[auctionmangos.git] / dep / ACE_wrappers / ace / Lib_Find.cpp
blob913e94e941dc01e92d528acbdfefb51741a3d34f
1 // $Id: Lib_Find.cpp 80826 2008-03-04 14:51:23Z wotte $
3 #include "ace/Lib_Find.h"
4 #include "ace/Log_Msg.h"
5 #include "ace/OS_NS_string.h"
6 #include "ace/OS_NS_errno.h"
7 #include "ace/OS_NS_stdio.h"
8 #include "ace/OS_NS_unistd.h"
9 #include "ace/OS_NS_stdlib.h"
10 #include "ace/OS_Memory.h"
11 #include "ace/OS_NS_fcntl.h"
13 #if defined (ACE_WIN32)
14 # include "ace/OS_NS_strings.h"
15 #endif /* ACE_WIN32 */
17 #if defined (ACE_OPENVMS)
18 #include "ace/RB_Tree.h"
19 #include "ace/Thread_Mutex.h"
20 #include "ace/Singleton.h"
22 #include /**/ "descrip.h"
23 #include /**/ "chfdef.h"
24 #include /**/ "stsdef.h"
25 #include /**/ "libdef.h"
27 extern "C" int LIB$FIND_IMAGE_SYMBOL(...);
29 class ACE_LD_Symbol_Registry
31 // @internal
32 // = TITLE
33 // Implements a class to register symbols and addresses for use with DLL
34 // symbol retrieval.
36 // = DESCRIPTION
37 // OpenVMS restricts symbol length to 31 characters encoding any symbols
38 // longer than that. In these cases dlsym() only works with the encoded
39 // names.
40 // This creates serious problems for the service configurator framework
41 // where the factory method names often exceed 31 chars and where loading
42 // is based on retrieval of method pointers using the *full* name.
43 // For OpenVMS we therefor added this singleton class and the
44 // ACE_Dynamic_Svc_Registrar class which registers full names and function
45 // pointers with this singleton at the time the static ACE_Dynamic_Svc_Registrar
46 // object is created in a (service) DLL.
47 // By forcing the DLL to load using a common symbol ("NULL") we trigger static
48 // object creation *before* the full names are referenced.
49 // Symbol references will be resolved as follows on OpenVMS:
50 // - first try directly from DLL using the RTL dlsym() function and if that fails;
51 // - try to find symbol in singleton registry.
52 public:
54 typedef ACE_RB_Tree<const ACE_TCHAR*,
55 void*,
56 ACE_Less_Than<const ACE_TCHAR*>,
57 ACE_Thread_Mutex>
58 TREE;
60 void register_symbol (const ACE_TCHAR* symname, void* symaddr);
62 void* find_symbol (const ACE_TCHAR* symname);
64 ACE_LD_Symbol_Registry () {}
65 private:
67 TREE symbol_registry_;
70 void
71 ACE_LD_Symbol_Registry::register_symbol (const ACE_TCHAR* symname,
72 void* symaddr)
74 int const result = symbol_registry_.bind (symname, symaddr);
75 if (result == 1)
77 ACE_DEBUG((LM_INFO, ACE_TEXT ("ACE_LD_Symbol_Registry:")
78 ACE_TEXT (" duplicate symbol %s registered\n"),
79 ACE_TEXT_ALWAYS_CHAR (symname)));
81 else if (result == -1)
83 ACE_ERROR((LM_ERROR, ACE_TEXT ("ACE_LD_Symbol_Registry:")
84 ACE_TEXT (" failed to register symbol %s\n"),
85 ACE_TEXT_ALWAYS_CHAR (symname)));
89 void*
90 ACE_LD_Symbol_Registry::find_symbol (const ACE_TCHAR* symname)
92 void* symaddr = 0;
93 int const result = symbol_registry_.find (symname, symaddr);
95 return (result == 0 ? symaddr : 0);
98 /// Declare a process wide singleton
99 ACE_SINGLETON_DECLARE (ACE_Singleton,
100 ACE_LD_Symbol_Registry,
101 ACE_Thread_Mutex)
103 typedef ACE_Singleton<ACE_LD_Symbol_Registry, ACE_Thread_Mutex>
104 ACE_LD_SYMBOL_REGISTRY;
106 #if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
107 template ACE_Singleton<ACE_LD_Symbol_Registry, ACE_Thread_Mutex> *
108 ACE_Singleton<ACE_LD_Symbol_Registry, ACE_Thread_Mutex>::singleton_;
109 #endif /* ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION */
110 #endif
112 ACE_RCSID(ace, Lib_Find, "$Id: Lib_Find.cpp 80826 2008-03-04 14:51:23Z wotte $")
114 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
117 ACE::ldfind (const ACE_TCHAR* filename,
118 ACE_TCHAR pathname[],
119 size_t maxpathnamelen)
121 ACE_TRACE ("ACE::ldfind");
122 #if defined (ACE_OPENVMS)
123 if (ACE_OS::strlen(filename) >= maxpathnamelen)
125 errno = ENOMEM;
126 return -1;
129 dsc$descriptor nameDsc;
130 nameDsc.dsc$b_class = DSC$K_CLASS_S;
131 nameDsc.dsc$b_dtype = DSC$K_DTYPE_T;
132 nameDsc.dsc$w_length = ACE_OS::strlen(filename);
133 nameDsc.dsc$a_pointer = (char*)filename;
135 char symbol[] = "NULL";
136 dsc$descriptor symbolDsc;
137 symbolDsc.dsc$b_class = DSC$K_CLASS_S;
138 symbolDsc.dsc$b_dtype = DSC$K_DTYPE_T;
139 symbolDsc.dsc$w_length = ACE_OS::strlen(symbol);
140 symbolDsc.dsc$a_pointer = symbol;
142 int symbolValue;
143 int result;
146 result = LIB$FIND_IMAGE_SYMBOL(&nameDsc, &symbolDsc, &symbolValue, 0, 0);
148 catch (chf$signal_array& sig)
150 result = sig.chf$l_sig_name;
153 int severity = result & STS$M_SEVERITY;
154 int conditionId = result & STS$M_COND_ID;
155 if (severity == STS$K_SUCCESS || severity == STS$K_WARNING || severity == STS$K_INFO ||
156 (severity == STS$K_ERROR && conditionId == (LIB$_KEYNOTFOU & STS$M_COND_ID)))
158 ACE_OS::strcpy(pathname, filename);
159 return 0;
162 if (ACE_OS::strlen(filename) + ACE_OS::strlen(ACE_DLL_PREFIX) >= maxpathnamelen)
164 errno = ENOMEM;
165 return -1;
169 ACE_OS::strcpy(pathname, ACE_DLL_PREFIX);
170 ACE_OS::strcat(pathname, filename);
171 nameDsc.dsc$w_length = ACE_OS::strlen(pathname);
172 nameDsc.dsc$a_pointer = pathname;
175 result = LIB$FIND_IMAGE_SYMBOL(&nameDsc, &symbolDsc, &symbolValue, 0, 0);
177 catch (chf$signal_array& sig)
179 result = sig.chf$l_sig_name;
182 severity = result & STS$M_SEVERITY;
183 conditionId = result & STS$M_COND_ID;
184 if (severity == STS$K_SUCCESS || severity == STS$K_WARNING || severity == STS$K_INFO ||
185 (severity == STS$K_ERROR && conditionId == (LIB$_KEYNOTFOU & STS$M_COND_ID)))
187 return 0;
189 errno = ENOENT;
190 return -1;
191 #endif /* ACE_OPENVMS */
193 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) && \
194 !defined (ACE_HAS_PHARLAP)
195 ACE_TCHAR expanded_filename[MAXPATHLEN];
196 if (ACE_TEXT_ExpandEnvironmentStrings (filename,
197 expanded_filename,
198 sizeof expanded_filename
199 / sizeof (ACE_TCHAR)))
200 filename = expanded_filename;
201 #endif /* ACE_WIN32 && !ACE_HAS_WINCE && !ACE_HAS_PHARLAP */
203 ACE_TCHAR tempcopy[MAXPATHLEN + 1];
204 ACE_TCHAR searchpathname[MAXPATHLEN + 1];
205 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
206 ACE_TCHAR decorator[] = ACE_LD_DECORATOR_STR;
207 ACE_TCHAR searchfilename[MAXPATHLEN + sizeof(decorator) / sizeof (ACE_TCHAR)];
208 #else
209 ACE_TCHAR searchfilename[MAXPATHLEN + 1];
210 #endif /* ACE_WIN32 && ACE_LD_DECORATOR_STR && !ACE_DISABLE_DEBUG_DLL_CHECK */
212 // Create a copy of filename to work with.
213 if (ACE_OS::strlen (filename) + 1
214 > (sizeof tempcopy / sizeof (ACE_TCHAR)))
216 errno = ENOMEM;
217 return -1;
219 else
220 ACE_OS::strcpy (tempcopy, filename);
222 // Insert canonical directory separators.
223 ACE_TCHAR *separator_ptr;
225 #if (ACE_DIRECTORY_SEPARATOR_CHAR != '/')
226 // Make all the directory separators "canonical" to simplify
227 // subsequent code.
228 ACE::strrepl (tempcopy, ACE_DIRECTORY_SEPARATOR_CHAR, '/');
229 #endif /* ACE_DIRECTORY_SEPARATOR_CHAR */
231 // Separate filename from pathname.
232 separator_ptr = ACE_OS::strrchr (tempcopy, '/');
234 // This is a relative path.
235 if (separator_ptr == 0)
237 searchpathname[0] = '\0';
238 ACE_OS::strcpy (searchfilename, tempcopy);
240 else // This is an absolute path.
242 ACE_OS::strcpy (searchfilename, separator_ptr + 1);
243 separator_ptr[1] = '\0';
244 ACE_OS::strcpy (searchpathname, tempcopy);
247 bool has_suffix = false;
249 // Check to see if this has an appropriate DLL suffix for the OS
250 // platform.
251 ACE_TCHAR *s = ACE_OS::strrchr (searchfilename, '.');
253 const ACE_TCHAR *dll_suffix = ACE_DLL_SUFFIX;
255 if (s != 0)
257 // If we have a dot, we have a suffix
258 has_suffix = true;
260 // Check whether this matches the appropriate platform-specific
261 // suffix.
262 #if defined (ACE_WIN32)
263 // Use <ACE_OS::strcasecmp> on any platform with
264 // case-insensitive filenames.
265 if (ACE_OS::strcasecmp (s, dll_suffix) != 0)
266 #else
267 if (ACE_OS::strcmp (s, dll_suffix) != 0)
268 #endif /* ACE_WIN32 */
270 ACE_ERROR ((LM_WARNING,
271 ACE_TEXT ("Warning: improper suffix for a ")
272 ACE_TEXT ("shared library on this platform: %s\n"),
273 s));
277 // Make sure we've got enough space in searchfilename.
278 if (ACE_OS::strlen (searchfilename)
279 + ACE_OS::strlen (ACE_DLL_PREFIX)
280 + (has_suffix ? 0 : ACE_OS::strlen (dll_suffix))
281 >= (sizeof searchfilename / sizeof (ACE_TCHAR)))
283 errno = ENOMEM;
284 return -1;
287 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
288 size_t len_searchfilename = ACE_OS::strlen (searchfilename);
289 if (! has_suffix)
290 ACE_OS::strcpy (searchfilename + len_searchfilename,
291 decorator);
293 for (int tag = 1; tag >= 0; tag --)
295 if (tag == 0)
296 searchfilename [len_searchfilename] = 0;
298 #endif /* ACE_WIN32 && ACE_LD_DECORATOR_STR && !ACE_DISABLE_DEBUG_DLL_CHECK */
299 // Use absolute pathname if there is one.
300 if (ACE_OS::strlen (searchpathname) > 0)
302 if (ACE_OS::strlen (searchfilename)
303 + ACE_OS::strlen (searchpathname) >= maxpathnamelen)
305 errno = ENOMEM;
306 return -1;
308 else
310 #if (ACE_DIRECTORY_SEPARATOR_CHAR != '/')
311 // Revert to native path name separators.
312 ACE::strrepl (searchpathname,
313 '/',
314 ACE_DIRECTORY_SEPARATOR_CHAR);
315 #endif /* ACE_DIRECTORY_SEPARATOR_CHAR */
316 // First, try matching the filename *without* adding a
317 // prefix.
318 ACE_OS::sprintf (pathname,
319 ACE_TEXT ("%s%s%s"),
320 searchpathname,
321 searchfilename,
322 has_suffix ? ACE_TEXT ("") : dll_suffix);
323 if (ACE_OS::access (pathname, F_OK) == 0)
324 return 0;
326 // Second, try matching the filename *with* adding a prefix.
327 ACE_OS::sprintf (pathname,
328 ACE_TEXT ("%s%s%s%s"),
329 searchpathname,
330 ACE_DLL_PREFIX,
331 searchfilename,
332 has_suffix ? ACE_TEXT ("") : dll_suffix);
333 if (ACE_OS::access (pathname, F_OK) == 0)
334 return 0;
338 // Use relative filenames via LD_LIBRARY_PATH or PATH (depending on
339 // OS platform).
340 else
342 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
343 ACE_TCHAR *file_component = 0;
344 DWORD pathlen =
345 ACE_TEXT_SearchPath (0,
346 searchfilename,
347 dll_suffix,
348 static_cast<DWORD> (maxpathnamelen),
349 pathname,
350 &file_component);
351 if (pathlen >= maxpathnamelen)
353 errno = ENOMEM;
354 return -1;
356 else if (pathlen > 0)
357 return 0;
359 // In case not found we should try again with the ACE_DLL_PREFIX
360 // prefixed
361 ACE_OS::strcpy (searchfilename, ACE_DLL_PREFIX);
362 ACE_OS::strcat (searchfilename, tempcopy);
363 pathlen =
364 ACE_TEXT_SearchPath (0,
365 searchfilename,
366 dll_suffix,
367 static_cast<DWORD> (maxpathnamelen),
368 pathname,
369 &file_component);
370 if (pathlen >= maxpathnamelen)
372 errno = ENOMEM;
373 return -1;
375 else if (pathlen > 0)
376 return 0;
377 #else
378 ACE_TCHAR *ld_path;
379 # if defined ACE_DEFAULT_LD_SEARCH_PATH
380 ld_path = ACE_DEFAULT_LD_SEARCH_PATH;
381 # else
382 # if defined (ACE_WIN32) || !defined (ACE_USES_WCHAR)
383 ld_path = ACE_OS::getenv (ACE_LD_SEARCH_PATH);
384 # else
385 // Wide-char, non-Windows only offers char * getenv. So capture
386 // it, translate to wide-char, and continue.
387 ACE_Ascii_To_Wide wide_ldpath
388 (ACE_OS::getenv (ACE_TEXT_ALWAYS_CHAR (ACE_LD_SEARCH_PATH)));
389 ld_path = wide_ldpath.wchar_rep ();
390 # endif /* ACE_WIN32 || !ACE_USES_WCHAR */
391 # endif /* ACE_DEFAULT_LD_SEARCH_PATH */
393 #if defined (ACE_HAS_WINCE)
394 ACE_TCHAR *ld_path_temp = 0;
395 if (ld_path != 0)
397 ld_path_temp = (ACE_TCHAR *)
398 ACE_OS::malloc ((ACE_OS::strlen (ld_path) + 2)
399 * sizeof (ACE_TCHAR));
400 if (ld_path_temp != 0)
402 ACE_OS::strcpy (ld_path_temp,
403 ACE_LD_SEARCH_PATH_SEPARATOR_STR);
405 ACE_OS::strcat (ld_path_temp, ld_path);
406 ld_path = ld_path_temp;
408 else
410 ACE_OS::free ((void *) ld_path_temp);
411 ld_path = ld_path_temp = 0;
414 #endif /* ACE_HAS_WINCE */
416 if (ld_path != 0
417 && (ld_path = ACE_OS::strdup (ld_path)) != 0)
419 // strtok has the strange behavior of not separating the
420 // string ":/foo:/bar" into THREE tokens. One would expect
421 // that the first iteration the token would be an empty
422 // string, the second iteration would be "/foo", and the
423 // third iteration would be "/bar". However, this is not
424 // the case; one only gets two iterations: "/foo" followed
425 // by "/bar".
427 // This is especially a problem in parsing Unix paths
428 // because it is permissible to specify 'the current
429 // directory' as an empty entry. So, we introduce the
430 // following special code to cope with this:
432 // Look at each dynamic lib directory in the search path.
434 ACE_TCHAR *nextholder = 0;
435 const ACE_TCHAR *path_entry =
436 ACE::strsplit_r (ld_path,
437 ACE_LD_SEARCH_PATH_SEPARATOR_STR,
438 nextholder);
439 int result = 0;
441 for (;;)
443 // Check if at end of search path.
444 if (path_entry == 0)
446 errno = ENOENT;
447 result = -1;
448 break;
450 else if (ACE_OS::strlen (path_entry)
452 + ACE_OS::strlen (searchfilename)
453 >= maxpathnamelen)
455 errno = ENOMEM;
456 result = -1;
457 break;
459 // This works around the issue where a path might have
460 // an empty component indicating 'current directory'.
461 // We need to do it here rather than anywhere else so
462 // that the loop condition will still work.
463 else if (path_entry[0] == '\0')
464 path_entry = ACE_TEXT (".");
466 // First, try matching the filename *without* adding a
467 // prefix.
468 ACE_OS::sprintf (pathname,
469 ACE_TEXT ("%s%c%s%s"),
470 path_entry,
471 ACE_DIRECTORY_SEPARATOR_CHAR,
472 searchfilename,
473 has_suffix ? ACE_TEXT ("") : dll_suffix);
474 if (ACE_OS::access (pathname, F_OK) == 0)
475 break;
477 // Second, try matching the filename *with* adding a
478 // prefix.
479 ACE_OS::sprintf (pathname,
480 ACE_TEXT ("%s%c%s%s%s"),
481 path_entry,
482 ACE_DIRECTORY_SEPARATOR_CHAR,
483 ACE_DLL_PREFIX,
484 searchfilename,
485 has_suffix ? ACE_TEXT ("") : dll_suffix);
486 if (ACE_OS::access (pathname, F_OK) == 0)
487 break;
489 // Fetch the next item in the path
490 path_entry =
491 ACE::strsplit_r (0,
492 ACE_LD_SEARCH_PATH_SEPARATOR_STR,
493 nextholder);
496 #if defined (ACE_HAS_WINCE)
497 if (ld_path_temp != 0)
498 ACE_OS::free (ld_path_temp);
499 #endif /* ACE_HAS_WINCE */
500 ACE_OS::free ((void *) ld_path);
501 #if defined (ACE_HAS_WINCE) && defined (ACE_LD_DECORATOR_STR) && \
502 !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
503 if (result == 0 || tag == 0)
504 #endif /* ACE_HAS_WINCE && ACE_LD_DECORATOR_STR && !ACE_DISABLE_DEBUG_DLL_CHECK */
505 return result;
507 #endif /* ACE_WIN32 && !ACE_HAS_WINCE */
509 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
511 #endif /* ACE_WIN32 && ACE_LD_DECORATOR_STR && !ACE_DISABLE_DEBUG_DLL_CHECK */
513 errno = ENOENT;
514 return -1;
517 FILE *
518 ACE::ldopen (const ACE_TCHAR *filename,
519 const ACE_TCHAR *type)
521 ACE_TRACE ("ACE::ldopen");
523 ACE_TCHAR buf[MAXPATHLEN + 1];
524 if (ACE::ldfind (filename,
525 buf,
526 sizeof (buf) /sizeof (ACE_TCHAR)) == -1)
527 return 0;
528 else
529 return ACE_OS::fopen (buf, type);
532 ACE_TCHAR *
533 ACE::ldname (const ACE_TCHAR *entry_point)
535 ACE_TRACE ("ACE::ldname");
537 #if defined(ACE_NEEDS_DL_UNDERSCORE)
538 size_t size =
539 1 // leading '_'
540 + ACE_OS::strlen (entry_point)
541 + 1;
543 ACE_TCHAR *new_name;
544 ACE_NEW_RETURN (new_name,
545 ACE_TCHAR[size],
548 ACE_OS::strcpy (new_name, ACE_TEXT ("_"));
549 ACE_OS::strcat (new_name, entry_point);
551 return new_name;
552 #else /* ACE_NEEDS_DL_UNDERSCORE */
553 size_t size =
554 ACE_OS::strlen (entry_point)
555 + 1;
557 ACE_TCHAR *new_name;
558 ACE_NEW_RETURN (new_name,
559 ACE_TCHAR[size],
562 ACE_OS::strcpy (new_name, entry_point);
563 return new_name;
564 #endif /* ACE_NEEDS_DL_UNDERSCORE */
567 #if defined (ACE_OPENVMS)
568 void
569 ACE::ldregister (const ACE_TCHAR *entry_point,
570 void* entry_addr)
572 ACE_LD_SYMBOL_REGISTRY::instance ()->register_symbol (entry_point,
573 entry_addr);
576 void *
577 ACE::ldsymbol (ACE_SHLIB_HANDLE sh, const ACE_TCHAR *entry_point)
579 void* symaddr = ACE_OS::dlsym (sh, entry_point);
580 // if not found through dlsym() try registry
581 if (symaddr == 0)
582 symaddr = ACE_LD_SYMBOL_REGISTRY::instance ()->find_symbol (entry_point);
584 return symaddr;
586 #endif
589 ACE::get_temp_dir (ACE_TCHAR *buffer, size_t buffer_len)
591 int result;
592 #if defined (ACE_WIN32)
593 result = ACE_TEXT_GetTempPath (static_cast<DWORD> (buffer_len),
594 buffer);
596 // Make sure to return -1 if there is an error
597 if (result == 0 && ::GetLastError () != ERROR_SUCCESS
598 || result > static_cast<int> (buffer_len))
599 result = -1;
601 #else /* ACE_WIN32 */
603 // NOTE! Non-Windows platforms don't deal with wide chars for env.
604 // variables, so do this narrow-char and convert to wide for the
605 // caller if necessary.
607 // On non-win32 platforms, check to see what the TMPDIR environment
608 // variable is defined to be. If it doesn't exist, just use /tmp
609 const char *tmpdir = ACE_OS::getenv ("TMPDIR");
611 if (tmpdir == 0)
612 tmpdir = "/tmp";
614 size_t len = ACE_OS::strlen (tmpdir);
616 // Check to see if the buffer is large enough for the string,
617 // another /, and its null character (hence the + 2)
618 if ((len + 2) > buffer_len)
620 result = -1;
622 else
624 ACE_OS::strcpy (buffer, ACE_TEXT_CHAR_TO_TCHAR (tmpdir));
626 // Add a trailing slash because we cannot assume there is already one
627 // at the end. And having an extra one should not cause problems.
628 buffer[len] = ACE_TEXT ('/');
629 buffer[len + 1] = 0;
630 result = 0;
632 #endif /* ACE_WIN32 */
633 return result;
636 ACE_HANDLE
637 ACE::open_temp_file (const ACE_TCHAR *name, int mode, int perm)
639 #if defined (ACE_WIN32)
640 ACE_UNUSED_ARG (perm);
641 ACE_HANDLE handle = ACE_OS::open (name,
642 mode,
643 FILE_SHARE_READ
644 | FILE_SHARE_WRITE
645 | FILE_SHARE_DELETE);
646 #else
647 // Open it.
648 ACE_HANDLE handle = ACE_OS::open (name, mode, perm);
649 #endif /* ACE_WIN32 */
651 if (handle == ACE_INVALID_HANDLE)
652 return ACE_INVALID_HANDLE;
654 // Unlink it so that the file will be removed automatically when the
655 // process goes away.
656 if (ACE_OS::unlink (name) == -1)
657 return ACE_INVALID_HANDLE;
658 else
659 // Return the handle.
660 return handle;
663 size_t
664 ACE::strrepl (char *s, char search, char replace)
666 ACE_TRACE ("ACE::strrepl");
668 size_t replaced = 0;
670 for (size_t i = 0; s[i] != '\0'; i++)
671 if (s[i] == search)
673 s[i] = replace;
674 ++replaced;
677 return replaced;
681 // Split a string up into 'token'-delimited pieces, ala Perl's
682 // "split".
684 char *
685 ACE::strsplit_r (char *str,
686 const char *token,
687 char *&next_start)
689 char *result = 0;
691 if (str != 0)
692 next_start = str;
694 if (next_start != 0)
696 char *tok_loc = ACE_OS::strstr (next_start, token);
698 if (tok_loc != 0)
700 // Return the beginning of the string.
701 result = next_start;
703 // Insure it's terminated.
704 *tok_loc = '\0';
705 next_start = tok_loc + ACE_OS::strlen (token);
707 else
709 result = next_start;
710 next_start = (char *) 0;
714 return result;
717 #if defined (ACE_HAS_WCHAR)
718 wchar_t *
719 ACE::strsplit_r (wchar_t *str,
720 const wchar_t *token,
721 wchar_t *&next_start)
723 wchar_t *result = 0;
725 if (str != 0)
726 next_start = str;
728 if (next_start != 0)
730 wchar_t *tok_loc = ACE_OS::strstr (next_start, token);
732 if (tok_loc != 0)
734 // Return the beginning of the string.
735 result = next_start;
737 // Insure it's terminated.
738 *tok_loc = '\0';
739 next_start = tok_loc + ACE_OS::strlen (token);
741 else
743 result = next_start;
744 next_start = (wchar_t *) 0;
748 return result;
751 size_t
752 ACE::strrepl (wchar_t *s, wchar_t search, wchar_t replace)
754 ACE_TRACE ("ACE::strrepl");
756 size_t replaced = 0;
758 for (size_t i = 0; s[i] != '\0'; i++)
759 if (s[i] == search)
761 s[i] = replace;
762 ++replaced;
765 return replaced;
767 #endif /* ACE_HAS_WCHAR */
769 ACE_END_VERSIONED_NAMESPACE_DECL