00001
00002
00003 #include "ace/Lib_Find.h"
00004 #include "ace/Log_Msg.h"
00005 #include "ace/OS_NS_string.h"
00006 #include "ace/OS_NS_errno.h"
00007 #include "ace/OS_NS_stdio.h"
00008 #include "ace/OS_NS_unistd.h"
00009 #include "ace/OS_NS_stdlib.h"
00010 #include "ace/OS_Memory.h"
00011 #include "ace/OS_NS_fcntl.h"
00012
00013 #if defined (ACE_WIN32)
00014 # include "ace/OS_NS_strings.h"
00015 #endif
00016
00017 #if defined (ACE_OPENVMS)
00018 #include "ace/RB_Tree.h"
00019 #include "ace/Thread_Mutex.h"
00020 #include "ace/Singleton.h"
00021
00022 #include "descrip.h"
00023 #include "chfdef.h"
00024 #include "stsdef.h"
00025 #include "libdef.h"
00026
00027 extern "C" int LIB$FIND_IMAGE_SYMBOL(...);
00028
00029 class ACE_LD_Symbol_Registry
00030 {
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 public:
00053
00054 typedef ACE_RB_Tree<const ACE_TCHAR*,
00055 void*,
00056 ACE_Less_Than<const ACE_TCHAR*>,
00057 ACE_Thread_Mutex>
00058 TREE;
00059
00060 void register_symbol (const ACE_TCHAR* symname, void* symaddr);
00061
00062 void* find_symbol (const ACE_TCHAR* symname);
00063
00064 ACE_LD_Symbol_Registry () {}
00065 private:
00066
00067 TREE symbol_registry_;
00068 };
00069
00070 void
00071 ACE_LD_Symbol_Registry::register_symbol (const ACE_TCHAR* symname,
00072 void* symaddr)
00073 {
00074 int const result = symbol_registry_.bind (symname, symaddr);
00075 if (result == 1)
00076 {
00077 ACE_DEBUG((LM_INFO, ACE_TEXT ("ACE_LD_Symbol_Registry:")
00078 ACE_TEXT (" duplicate symbol %s registered\n"),
00079 ACE_TEXT_ALWAYS_CHAR (symname)));
00080 }
00081 else if (result == -1)
00082 {
00083 ACE_ERROR((LM_ERROR, ACE_TEXT ("ACE_LD_Symbol_Registry:")
00084 ACE_TEXT (" failed to register symbol %s\n"),
00085 ACE_TEXT_ALWAYS_CHAR (symname)));
00086 }
00087 }
00088
00089 void*
00090 ACE_LD_Symbol_Registry::find_symbol (const ACE_TCHAR* symname)
00091 {
00092 void* symaddr = 0;
00093 int const result = symbol_registry_.find (symname, symaddr);
00094
00095 return (result == 0 ? symaddr : 0);
00096 }
00097
00098
00099 ACE_SINGLETON_DECLARE (ACE_Singleton,
00100 ACE_LD_Symbol_Registry,
00101 ACE_Thread_Mutex)
00102
00103 typedef ACE_Singleton<ACE_LD_Symbol_Registry, ACE_Thread_Mutex>
00104 ACE_LD_SYMBOL_REGISTRY;
00105
00106 #if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
00107 template ACE_Singleton<ACE_LD_Symbol_Registry, ACE_Thread_Mutex> *
00108 ACE_Singleton<ACE_LD_Symbol_Registry, ACE_Thread_Mutex>::singleton_;
00109 #endif
00110 #endif
00111
00112 ACE_RCSID(ace, Lib_Find, "$Id: Lib_Find.cpp 80826 2008-03-04 14:51:23Z wotte $")
00113
00114 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00115
00116 int
00117 ACE::ldfind (const ACE_TCHAR* filename,
00118 ACE_TCHAR pathname[],
00119 size_t maxpathnamelen)
00120 {
00121 ACE_TRACE ("ACE::ldfind");
00122 #if defined (ACE_OPENVMS)
00123 if (ACE_OS::strlen(filename) >= maxpathnamelen)
00124 {
00125 errno = ENOMEM;
00126 return -1;
00127 }
00128
00129 dsc$descriptor nameDsc;
00130 nameDsc.dsc$b_class = DSC$K_CLASS_S;
00131 nameDsc.dsc$b_dtype = DSC$K_DTYPE_T;
00132 nameDsc.dsc$w_length = ACE_OS::strlen(filename);
00133 nameDsc.dsc$a_pointer = (char*)filename;
00134
00135 char symbol[] = "NULL";
00136 dsc$descriptor symbolDsc;
00137 symbolDsc.dsc$b_class = DSC$K_CLASS_S;
00138 symbolDsc.dsc$b_dtype = DSC$K_DTYPE_T;
00139 symbolDsc.dsc$w_length = ACE_OS::strlen(symbol);
00140 symbolDsc.dsc$a_pointer = symbol;
00141
00142 int symbolValue;
00143 int result;
00144 try
00145 {
00146 result = LIB$FIND_IMAGE_SYMBOL(&nameDsc, &symbolDsc, &symbolValue, 0, 0);
00147 }
00148 catch (chf$signal_array& sig)
00149 {
00150 result = sig.chf$l_sig_name;
00151 }
00152
00153 int severity = result & STS$M_SEVERITY;
00154 int conditionId = result & STS$M_COND_ID;
00155 if (severity == STS$K_SUCCESS || severity == STS$K_WARNING || severity == STS$K_INFO ||
00156 (severity == STS$K_ERROR && conditionId == (LIB$_KEYNOTFOU & STS$M_COND_ID)))
00157 {
00158 ACE_OS::strcpy(pathname, filename);
00159 return 0;
00160 }
00161
00162 if (ACE_OS::strlen(filename) + ACE_OS::strlen(ACE_DLL_PREFIX) >= maxpathnamelen)
00163 {
00164 errno = ENOMEM;
00165 return -1;
00166 }
00167
00168
00169 ACE_OS::strcpy(pathname, ACE_DLL_PREFIX);
00170 ACE_OS::strcat(pathname, filename);
00171 nameDsc.dsc$w_length = ACE_OS::strlen(pathname);
00172 nameDsc.dsc$a_pointer = pathname;
00173 try
00174 {
00175 result = LIB$FIND_IMAGE_SYMBOL(&nameDsc, &symbolDsc, &symbolValue, 0, 0);
00176 }
00177 catch (chf$signal_array& sig)
00178 {
00179 result = sig.chf$l_sig_name;
00180 }
00181
00182 severity = result & STS$M_SEVERITY;
00183 conditionId = result & STS$M_COND_ID;
00184 if (severity == STS$K_SUCCESS || severity == STS$K_WARNING || severity == STS$K_INFO ||
00185 (severity == STS$K_ERROR && conditionId == (LIB$_KEYNOTFOU & STS$M_COND_ID)))
00186 {
00187 return 0;
00188 }
00189 errno = ENOENT;
00190 return -1;
00191 #endif
00192
00193 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE) && \
00194 !defined (ACE_HAS_PHARLAP)
00195 ACE_TCHAR expanded_filename[MAXPATHLEN];
00196 if (ACE_TEXT_ExpandEnvironmentStrings (filename,
00197 expanded_filename,
00198 sizeof expanded_filename
00199 / sizeof (ACE_TCHAR)))
00200 filename = expanded_filename;
00201 #endif
00202
00203 ACE_TCHAR tempcopy[MAXPATHLEN + 1];
00204 ACE_TCHAR searchpathname[MAXPATHLEN + 1];
00205 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00206 ACE_TCHAR decorator[] = ACE_LD_DECORATOR_STR;
00207 ACE_TCHAR searchfilename[MAXPATHLEN + sizeof(decorator) / sizeof (ACE_TCHAR)];
00208 #else
00209 ACE_TCHAR searchfilename[MAXPATHLEN + 1];
00210 #endif
00211
00212
00213 if (ACE_OS::strlen (filename) + 1
00214 > (sizeof tempcopy / sizeof (ACE_TCHAR)))
00215 {
00216 errno = ENOMEM;
00217 return -1;
00218 }
00219 else
00220 ACE_OS::strcpy (tempcopy, filename);
00221
00222
00223 ACE_TCHAR *separator_ptr;
00224
00225 #if (ACE_DIRECTORY_SEPARATOR_CHAR != '/')
00226
00227
00228 ACE::strrepl (tempcopy, ACE_DIRECTORY_SEPARATOR_CHAR, '/');
00229 #endif
00230
00231
00232 separator_ptr = ACE_OS::strrchr (tempcopy, '/');
00233
00234
00235 if (separator_ptr == 0)
00236 {
00237 searchpathname[0] = '\0';
00238 ACE_OS::strcpy (searchfilename, tempcopy);
00239 }
00240 else
00241 {
00242 ACE_OS::strcpy (searchfilename, separator_ptr + 1);
00243 separator_ptr[1] = '\0';
00244 ACE_OS::strcpy (searchpathname, tempcopy);
00245 }
00246
00247 bool has_suffix = false;
00248
00249
00250
00251 ACE_TCHAR *s = ACE_OS::strrchr (searchfilename, '.');
00252
00253 const ACE_TCHAR *dll_suffix = ACE_DLL_SUFFIX;
00254
00255 if (s != 0)
00256 {
00257
00258 has_suffix = true;
00259
00260
00261
00262 #if defined (ACE_WIN32)
00263
00264
00265 if (ACE_OS::strcasecmp (s, dll_suffix) != 0)
00266 #else
00267 if (ACE_OS::strcmp (s, dll_suffix) != 0)
00268 #endif
00269 {
00270 ACE_ERROR ((LM_WARNING,
00271 ACE_TEXT ("Warning: improper suffix for a ")
00272 ACE_TEXT ("shared library on this platform: %s\n"),
00273 s));
00274 }
00275 }
00276
00277
00278 if (ACE_OS::strlen (searchfilename)
00279 + ACE_OS::strlen (ACE_DLL_PREFIX)
00280 + (has_suffix ? 0 : ACE_OS::strlen (dll_suffix))
00281 >= (sizeof searchfilename / sizeof (ACE_TCHAR)))
00282 {
00283 errno = ENOMEM;
00284 return -1;
00285 }
00286
00287 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00288 size_t len_searchfilename = ACE_OS::strlen (searchfilename);
00289 if (! has_suffix)
00290 ACE_OS::strcpy (searchfilename + len_searchfilename,
00291 decorator);
00292
00293 for (int tag = 1; tag >= 0; tag --)
00294 {
00295 if (tag == 0)
00296 searchfilename [len_searchfilename] = 0;
00297
00298 #endif
00299
00300 if (ACE_OS::strlen (searchpathname) > 0)
00301 {
00302 if (ACE_OS::strlen (searchfilename)
00303 + ACE_OS::strlen (searchpathname) >= maxpathnamelen)
00304 {
00305 errno = ENOMEM;
00306 return -1;
00307 }
00308 else
00309 {
00310 #if (ACE_DIRECTORY_SEPARATOR_CHAR != '/')
00311
00312 ACE::strrepl (searchpathname,
00313 '/',
00314 ACE_DIRECTORY_SEPARATOR_CHAR);
00315 #endif
00316
00317
00318 ACE_OS::sprintf (pathname,
00319 ACE_TEXT ("%s%s%s"),
00320 searchpathname,
00321 searchfilename,
00322 has_suffix ? ACE_TEXT ("") : dll_suffix);
00323 if (ACE_OS::access (pathname, F_OK) == 0)
00324 return 0;
00325
00326
00327 ACE_OS::sprintf (pathname,
00328 ACE_TEXT ("%s%s%s%s"),
00329 searchpathname,
00330 ACE_DLL_PREFIX,
00331 searchfilename,
00332 has_suffix ? ACE_TEXT ("") : dll_suffix);
00333 if (ACE_OS::access (pathname, F_OK) == 0)
00334 return 0;
00335 }
00336 }
00337
00338
00339
00340 else
00341 {
00342 #if defined (ACE_WIN32) && !defined (ACE_HAS_WINCE)
00343 ACE_TCHAR *file_component = 0;
00344 DWORD pathlen =
00345 ACE_TEXT_SearchPath (0,
00346 searchfilename,
00347 dll_suffix,
00348 static_cast<DWORD> (maxpathnamelen),
00349 pathname,
00350 &file_component);
00351 if (pathlen >= maxpathnamelen)
00352 {
00353 errno = ENOMEM;
00354 return -1;
00355 }
00356 else if (pathlen > 0)
00357 return 0;
00358
00359
00360
00361 ACE_OS::strcpy (searchfilename, ACE_DLL_PREFIX);
00362 ACE_OS::strcat (searchfilename, tempcopy);
00363 pathlen =
00364 ACE_TEXT_SearchPath (0,
00365 searchfilename,
00366 dll_suffix,
00367 static_cast<DWORD> (maxpathnamelen),
00368 pathname,
00369 &file_component);
00370 if (pathlen >= maxpathnamelen)
00371 {
00372 errno = ENOMEM;
00373 return -1;
00374 }
00375 else if (pathlen > 0)
00376 return 0;
00377 #else
00378 ACE_TCHAR *ld_path;
00379 # if defined ACE_DEFAULT_LD_SEARCH_PATH
00380 ld_path = ACE_DEFAULT_LD_SEARCH_PATH;
00381 # else
00382 # if defined (ACE_WIN32) || !defined (ACE_USES_WCHAR)
00383 ld_path = ACE_OS::getenv (ACE_LD_SEARCH_PATH);
00384 # else
00385
00386
00387 ACE_Ascii_To_Wide wide_ldpath
00388 (ACE_OS::getenv (ACE_TEXT_ALWAYS_CHAR (ACE_LD_SEARCH_PATH)));
00389 ld_path = wide_ldpath.wchar_rep ();
00390 # endif
00391 # endif
00392
00393 #if defined (ACE_HAS_WINCE)
00394 ACE_TCHAR *ld_path_temp = 0;
00395 if (ld_path != 0)
00396 {
00397 ld_path_temp = (ACE_TCHAR *)
00398 ACE_OS::malloc ((ACE_OS::strlen (ld_path) + 2)
00399 * sizeof (ACE_TCHAR));
00400 if (ld_path_temp != 0)
00401 {
00402 ACE_OS::strcpy (ld_path_temp,
00403 ACE_LD_SEARCH_PATH_SEPARATOR_STR);
00404
00405 ACE_OS::strcat (ld_path_temp, ld_path);
00406 ld_path = ld_path_temp;
00407 }
00408 else
00409 {
00410 ACE_OS::free ((void *) ld_path_temp);
00411 ld_path = ld_path_temp = 0;
00412 }
00413 }
00414 #endif
00415
00416 if (ld_path != 0
00417 && (ld_path = ACE_OS::strdup (ld_path)) != 0)
00418 {
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434 ACE_TCHAR *nextholder = 0;
00435 const ACE_TCHAR *path_entry =
00436 ACE::strsplit_r (ld_path,
00437 ACE_LD_SEARCH_PATH_SEPARATOR_STR,
00438 nextholder);
00439 int result = 0;
00440
00441 for (;;)
00442 {
00443
00444 if (path_entry == 0)
00445 {
00446 errno = ENOENT;
00447 result = -1;
00448 break;
00449 }
00450 else if (ACE_OS::strlen (path_entry)
00451 + 1
00452 + ACE_OS::strlen (searchfilename)
00453 >= maxpathnamelen)
00454 {
00455 errno = ENOMEM;
00456 result = -1;
00457 break;
00458 }
00459
00460
00461
00462
00463 else if (path_entry[0] == '\0')
00464 path_entry = ACE_TEXT (".");
00465
00466
00467
00468 ACE_OS::sprintf (pathname,
00469 ACE_TEXT ("%s%c%s%s"),
00470 path_entry,
00471 ACE_DIRECTORY_SEPARATOR_CHAR,
00472 searchfilename,
00473 has_suffix ? ACE_TEXT ("") : dll_suffix);
00474 if (ACE_OS::access (pathname, F_OK) == 0)
00475 break;
00476
00477
00478
00479 ACE_OS::sprintf (pathname,
00480 ACE_TEXT ("%s%c%s%s%s"),
00481 path_entry,
00482 ACE_DIRECTORY_SEPARATOR_CHAR,
00483 ACE_DLL_PREFIX,
00484 searchfilename,
00485 has_suffix ? ACE_TEXT ("") : dll_suffix);
00486 if (ACE_OS::access (pathname, F_OK) == 0)
00487 break;
00488
00489
00490 path_entry =
00491 ACE::strsplit_r (0,
00492 ACE_LD_SEARCH_PATH_SEPARATOR_STR,
00493 nextholder);
00494 }
00495
00496 #if defined (ACE_HAS_WINCE)
00497 if (ld_path_temp != 0)
00498 ACE_OS::free (ld_path_temp);
00499 #endif
00500 ACE_OS::free ((void *) ld_path);
00501 #if defined (ACE_HAS_WINCE) && defined (ACE_LD_DECORATOR_STR) && \
00502 !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00503 if (result == 0 || tag == 0)
00504 #endif
00505 return result;
00506 }
00507 #endif
00508 }
00509 #if defined (ACE_WIN32) && defined (ACE_LD_DECORATOR_STR) && !defined (ACE_DISABLE_DEBUG_DLL_CHECK)
00510 }
00511 #endif
00512
00513 errno = ENOENT;
00514 return -1;
00515 }
00516
00517 FILE *
00518 ACE::ldopen (const ACE_TCHAR *filename,
00519 const ACE_TCHAR *type)
00520 {
00521 ACE_TRACE ("ACE::ldopen");
00522
00523 ACE_TCHAR buf[MAXPATHLEN + 1];
00524 if (ACE::ldfind (filename,
00525 buf,
00526 sizeof (buf) /sizeof (ACE_TCHAR)) == -1)
00527 return 0;
00528 else
00529 return ACE_OS::fopen (buf, type);
00530 }
00531
00532 ACE_TCHAR *
00533 ACE::ldname (const ACE_TCHAR *entry_point)
00534 {
00535 ACE_TRACE ("ACE::ldname");
00536
00537 #if defined(ACE_NEEDS_DL_UNDERSCORE)
00538 size_t size =
00539 1
00540 + ACE_OS::strlen (entry_point)
00541 + 1;
00542
00543 ACE_TCHAR *new_name;
00544 ACE_NEW_RETURN (new_name,
00545 ACE_TCHAR[size],
00546 0);
00547
00548 ACE_OS::strcpy (new_name, ACE_TEXT ("_"));
00549 ACE_OS::strcat (new_name, entry_point);
00550
00551 return new_name;
00552 #else
00553 size_t size =
00554 ACE_OS::strlen (entry_point)
00555 + 1;
00556
00557 ACE_TCHAR *new_name;
00558 ACE_NEW_RETURN (new_name,
00559 ACE_TCHAR[size],
00560 0);
00561
00562 ACE_OS::strcpy (new_name, entry_point);
00563 return new_name;
00564 #endif
00565 }
00566
00567 #if defined (ACE_OPENVMS)
00568 void
00569 ACE::ldregister (const ACE_TCHAR *entry_point,
00570 void* entry_addr)
00571 {
00572 ACE_LD_SYMBOL_REGISTRY::instance ()->register_symbol (entry_point,
00573 entry_addr);
00574 }
00575
00576 void *
00577 ACE::ldsymbol (ACE_SHLIB_HANDLE sh, const ACE_TCHAR *entry_point)
00578 {
00579 void* symaddr = ACE_OS::dlsym (sh, entry_point);
00580
00581 if (symaddr == 0)
00582 symaddr = ACE_LD_SYMBOL_REGISTRY::instance ()->find_symbol (entry_point);
00583
00584 return symaddr;
00585 }
00586 #endif
00587
00588 int
00589 ACE::get_temp_dir (ACE_TCHAR *buffer, size_t buffer_len)
00590 {
00591 int result;
00592 #if defined (ACE_WIN32)
00593 result = ACE_TEXT_GetTempPath (static_cast<DWORD> (buffer_len),
00594 buffer);
00595
00596
00597 if (result == 0 && ::GetLastError () != ERROR_SUCCESS
00598 || result > static_cast<int> (buffer_len))
00599 result = -1;
00600
00601 #else
00602
00603
00604
00605
00606
00607
00608
00609 const char *tmpdir = ACE_OS::getenv ("TMPDIR");
00610
00611 if (tmpdir == 0)
00612 tmpdir = "/tmp";
00613
00614 size_t len = ACE_OS::strlen (tmpdir);
00615
00616
00617
00618 if ((len + 2) > buffer_len)
00619 {
00620 result = -1;
00621 }
00622 else
00623 {
00624 ACE_OS::strcpy (buffer, ACE_TEXT_CHAR_TO_TCHAR (tmpdir));
00625
00626
00627
00628 buffer[len] = ACE_TEXT ('/');
00629 buffer[len + 1] = 0;
00630 result = 0;
00631 }
00632 #endif
00633 return result;
00634 }
00635
00636 ACE_HANDLE
00637 ACE::open_temp_file (const ACE_TCHAR *name, int mode, int perm)
00638 {
00639 #if defined (ACE_WIN32)
00640 ACE_UNUSED_ARG (perm);
00641 ACE_HANDLE handle = ACE_OS::open (name,
00642 mode,
00643 FILE_SHARE_READ
00644 | FILE_SHARE_WRITE
00645 | FILE_SHARE_DELETE);
00646 #else
00647
00648 ACE_HANDLE handle = ACE_OS::open (name, mode, perm);
00649 #endif
00650
00651 if (handle == ACE_INVALID_HANDLE)
00652 return ACE_INVALID_HANDLE;
00653
00654
00655
00656 if (ACE_OS::unlink (name) == -1)
00657 return ACE_INVALID_HANDLE;
00658 else
00659
00660 return handle;
00661 }
00662
00663 size_t
00664 ACE::strrepl (char *s, char search, char replace)
00665 {
00666 ACE_TRACE ("ACE::strrepl");
00667
00668 size_t replaced = 0;
00669
00670 for (size_t i = 0; s[i] != '\0'; i++)
00671 if (s[i] == search)
00672 {
00673 s[i] = replace;
00674 ++replaced;
00675 }
00676
00677 return replaced;
00678 }
00679
00680
00681
00682
00683
00684 char *
00685 ACE::strsplit_r (char *str,
00686 const char *token,
00687 char *&next_start)
00688 {
00689 char *result = 0;
00690
00691 if (str != 0)
00692 next_start = str;
00693
00694 if (next_start != 0)
00695 {
00696 char *tok_loc = ACE_OS::strstr (next_start, token);
00697
00698 if (tok_loc != 0)
00699 {
00700
00701 result = next_start;
00702
00703
00704 *tok_loc = '\0';
00705 next_start = tok_loc + ACE_OS::strlen (token);
00706 }
00707 else
00708 {
00709 result = next_start;
00710 next_start = (char *) 0;
00711 }
00712 }
00713
00714 return result;
00715 }
00716
00717 #if defined (ACE_HAS_WCHAR)
00718 wchar_t *
00719 ACE::strsplit_r (wchar_t *str,
00720 const wchar_t *token,
00721 wchar_t *&next_start)
00722 {
00723 wchar_t *result = 0;
00724
00725 if (str != 0)
00726 next_start = str;
00727
00728 if (next_start != 0)
00729 {
00730 wchar_t *tok_loc = ACE_OS::strstr (next_start, token);
00731
00732 if (tok_loc != 0)
00733 {
00734
00735 result = next_start;
00736
00737
00738 *tok_loc = '\0';
00739 next_start = tok_loc + ACE_OS::strlen (token);
00740 }
00741 else
00742 {
00743 result = next_start;
00744 next_start = (wchar_t *) 0;
00745 }
00746 }
00747
00748 return result;
00749 }
00750
00751 size_t
00752 ACE::strrepl (wchar_t *s, wchar_t search, wchar_t replace)
00753 {
00754 ACE_TRACE ("ACE::strrepl");
00755
00756 size_t replaced = 0;
00757
00758 for (size_t i = 0; s[i] != '\0'; i++)
00759 if (s[i] == search)
00760 {
00761 s[i] = replace;
00762 ++replaced;
00763 }
00764
00765 return replaced;
00766 }
00767 #endif
00768
00769 ACE_END_VERSIONED_NAMESPACE_DECL