summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohnny Willemsen <jwillemsen@remedy.nl>2009-06-07 17:57:11 +0000
committerJohnny Willemsen <jwillemsen@remedy.nl>2009-06-07 17:57:11 +0000
commit3f77faa12016ad52e39e5e6e640bd544424dce2e (patch)
treebb38bfa2a9e8ca6da5a6ec7f728ee3d0389a4b69
parentd6cdbfdeff139917c0241654091116dda8303111 (diff)
downloadATCD-3f77faa12016ad52e39e5e6e640bd544424dce2e.tar.gz
Sun Jun 7 17:53:05 2009 Johnny Willemsen <jwillemsen@remedy.nl>
* ace/Tokenizer_T.cpp * ace/Tokenizer_T.h * ace/SString.cpp * ace/SString.h Moved ACE_Tokenizer to its own file and reworked it to the C++ template ACE_Tokenizer_T. ACE_Tokenizer is then a typedef of ACE_Tokenizer_T<ACE_TCHAR>. This makes it possible to use a char tokenizer in a wchar build * ace/ace.mpc: * ace/ace_for_tao.mpc: * ace/Makefile.am: Added new files * ace/Configuration.cpp: * ace/Process.cpp: * examples/OS/Process/process.cpp: Added include of Tokenizer_T.h * ace/OS_NS_Thread.cpp * ace/OS_NS_Thread.h * ace/OS_NS_Thread.inl Changed important_writer_ to bool
-rw-r--r--ACE/ChangeLog26
-rw-r--r--ACE/ace/Configuration.cpp1
-rw-r--r--ACE/ace/Makefile.am2
-rw-r--r--ACE/ace/OS_NS_Thread.cpp2
-rw-r--r--ACE/ace/OS_NS_Thread.h2
-rw-r--r--ACE/ace/OS_NS_Thread.inl4
-rw-r--r--ACE/ace/Process.cpp1
-rw-r--r--ACE/ace/SString.cpp206
-rw-r--r--ACE/ace/SString.h202
-rw-r--r--ACE/ace/Tokenizer_T.cpp230
-rw-r--r--ACE/ace/Tokenizer_T.h241
-rw-r--r--ACE/ace/ace.mpc1
-rw-r--r--ACE/ace/ace_for_tao.mpc1
-rw-r--r--ACE/examples/OS/Process/process.cpp1
14 files changed, 508 insertions, 412 deletions
diff --git a/ACE/ChangeLog b/ACE/ChangeLog
index b44fc2d2ee3..a50b45b7e2a 100644
--- a/ACE/ChangeLog
+++ b/ACE/ChangeLog
@@ -1,3 +1,29 @@
+Sun Jun 7 17:53:05 2009 Johnny Willemsen <jwillemsen@remedy.nl>
+
+ * ace/Tokenizer_T.cpp
+ * ace/Tokenizer_T.h
+ * ace/SString.cpp
+ * ace/SString.h
+ Moved ACE_Tokenizer to its own file and reworked it to
+ the C++ template ACE_Tokenizer_T. ACE_Tokenizer is then a
+ typedef of ACE_Tokenizer_T<ACE_TCHAR>. This makes it
+ possible to use a char tokenizer in a wchar build
+
+ * ace/ace.mpc:
+ * ace/ace_for_tao.mpc:
+ * ace/Makefile.am:
+ Added new files
+
+ * ace/Configuration.cpp:
+ * ace/Process.cpp:
+ * examples/OS/Process/process.cpp:
+ Added include of Tokenizer_T.h
+
+ * ace/OS_NS_Thread.cpp
+ * ace/OS_NS_Thread.h
+ * ace/OS_NS_Thread.inl
+ Changed important_writer_ to bool
+
Fri Jun 5 18:20:05 2009 Johnny Willemsen <jwillemsen@remedy.nl>
* ace/SString.h:
diff --git a/ACE/ace/Configuration.cpp b/ACE/ace/Configuration.cpp
index 6efc3fc5564..68df0fdbbfe 100644
--- a/ACE/ace/Configuration.cpp
+++ b/ACE/ace/Configuration.cpp
@@ -4,6 +4,7 @@
#include "ace/SString.h"
#include "ace/OS_NS_string.h"
#include "ace/OS_NS_strings.h"
+#include "ace/Tokenizer_T.h"
// Can remove this when import_config and export_config are removed from
// ACE_Configuration. They're deprecated at ACE 5.2.
diff --git a/ACE/ace/Makefile.am b/ACE/ace/Makefile.am
index f8f092dec5b..8a21c9da631 100644
--- a/ACE/ace/Makefile.am
+++ b/ACE/ace/Makefile.am
@@ -1075,6 +1075,8 @@ nobase_include_HEADERS += \
Timer_Queuefwd.h \
Timer_Wheel_T.cpp \
Timer_Wheel_T.h \
+ Tokenizer_T.cpp \
+ Tokenizer_T.h \
Timer_Hash.h \
Timer_Heap.h \
Timer_List.h \
diff --git a/ACE/ace/OS_NS_Thread.cpp b/ACE/ace/OS_NS_Thread.cpp
index a7914d4e28a..9315613c74b 100644
--- a/ACE/ace/OS_NS_Thread.cpp
+++ b/ACE/ace/OS_NS_Thread.cpp
@@ -3421,7 +3421,7 @@ ACE_OS::rwlock_init (ACE_rwlock_t *rw,
rw->ref_count_ = 0;
rw->num_waiting_writers_ = 0;
rw->num_waiting_readers_ = 0;
- rw->important_writer_ = 0;
+ rw->important_writer_ = false;
result = 0;
}
ACE_OS::condattr_destroy (attributes);
diff --git a/ACE/ace/OS_NS_Thread.h b/ACE/ace/OS_NS_Thread.h
index 82573039b34..70d8d730b34 100644
--- a/ACE/ace/OS_NS_Thread.h
+++ b/ACE/ace/OS_NS_Thread.h
@@ -433,7 +433,7 @@ public:
int ref_count_;
/// Indicate that a reader is trying to upgrade
- int important_writer_;
+ bool important_writer_;
/// Condition for the upgrading reader
ACE_cond_t waiting_important_writer_;
diff --git a/ACE/ace/OS_NS_Thread.inl b/ACE/ace/OS_NS_Thread.inl
index 70b9707b104..bddcd067859 100644
--- a/ACE/ace/OS_NS_Thread.inl
+++ b/ACE/ace/OS_NS_Thread.inl
@@ -1089,7 +1089,7 @@ ACE_OS::rw_trywrlock_upgrade (ACE_rwlock_t *rw)
while (rw->ref_count_ > 1) // wait until only I am left
{
rw->num_waiting_writers_++; // prohibit any more readers
- rw->important_writer_ = 1;
+ rw->important_writer_ = true;
if (ACE_OS::cond_wait (&rw->waiting_important_writer_, &rw->lock_) == -1)
{
@@ -1097,7 +1097,7 @@ ACE_OS::rw_trywrlock_upgrade (ACE_rwlock_t *rw)
// we know that we have the lock again, we have this guarantee,
// but something went wrong
}
- rw->important_writer_ = 0;
+ rw->important_writer_ = false;
rw->num_waiting_writers_--;
}
if (result == 0)
diff --git a/ACE/ace/Process.cpp b/ACE/ace/Process.cpp
index 7fff4c8c44b..b4121ad0c1a 100644
--- a/ACE/ace/Process.cpp
+++ b/ACE/ace/Process.cpp
@@ -22,6 +22,7 @@
#include "ace/Countdown_Time.h"
#include "ace/Truncate.h"
#include "ace/Vector_T.h"
+#include "ace/Tokenizer_T.h"
#if defined (ACE_VXWORKS) && (ACE_VXWORKS > 0x600) && defined (__RTP__)
# include <rtpLib.h>
diff --git a/ACE/ace/SString.cpp b/ACE/ace/SString.cpp
index 5ba108655aa..c95e4279dc5 100644
--- a/ACE/ace/SString.cpp
+++ b/ACE/ace/SString.cpp
@@ -333,212 +333,6 @@ ACE_SString::substring (size_type offset,
// ************************************************************
-ACE_Tokenizer::ACE_Tokenizer (ACE_TCHAR *buffer)
- : buffer_ (buffer),
- index_ (0),
- preserves_index_ (0),
- delimiter_index_ (0)
-{
-}
-
-int
-ACE_Tokenizer::delimiter (ACE_TCHAR d)
-{
- if (delimiter_index_ == MAX_DELIMITERS)
- return -1;
-
- delimiters_[delimiter_index_].delimiter_ = d;
- delimiters_[delimiter_index_].replace_ = 0;
- delimiter_index_++;
- return 0;
-}
-
-int
-ACE_Tokenizer::delimiter_replace (ACE_TCHAR d,
- ACE_TCHAR replacement)
-{
- // Make it possible to replace delimiters on-the-fly, e.g., parse
- // string until certain token count and then copy rest of the
- // original string.
- for (int i = 0; i < delimiter_index_; i++)
- if (delimiters_[i].delimiter_ == d)
- {
- delimiters_[i].replacement_ = replacement;
- delimiters_[i].replace_ = 1;
- return 0;
- }
-
- if (delimiter_index_ >= MAX_DELIMITERS)
- return -1;
-
- delimiters_[delimiter_index_].delimiter_ = d;
- delimiters_[delimiter_index_].replacement_ = replacement;
- delimiters_[delimiter_index_].replace_ = 1;
- delimiter_index_++;
- return 0;
-}
-
-int
-ACE_Tokenizer::preserve_designators (ACE_TCHAR start,
- ACE_TCHAR stop,
- int strip)
-{
- if (preserves_index_ == MAX_PRESERVES)
- return -1;
-
- preserves_[preserves_index_].start_ = start;
- preserves_[preserves_index_].stop_ = stop;
- preserves_[preserves_index_].strip_ = strip;
- preserves_index_++;
- return 0;
-}
-
-int
-ACE_Tokenizer::is_delimiter (ACE_TCHAR d,
- int &replace,
- ACE_TCHAR &r)
-{
- replace = 0;
-
- for (int x = 0; x < delimiter_index_; x++)
- if (delimiters_[x].delimiter_ == d)
- {
- if (delimiters_[x].replace_)
- {
- r = delimiters_[x].replacement_;
- replace = 1;
- }
- return 1;
- }
-
- return 0;
-}
-
-int
-ACE_Tokenizer::is_preserve_designator (ACE_TCHAR start,
- ACE_TCHAR &stop,
- int &strip)
-{
- for (int x = 0; x < preserves_index_; x++)
- if (preserves_[x].start_ == start)
- {
- stop = preserves_[x].stop_;
- strip = preserves_[x].strip_;
- return 1;
- }
-
- return 0;
-}
-
-ACE_TCHAR *
-ACE_Tokenizer::next (void)
-{
- // Check if the previous pass was the last one in the buffer.
- if (index_ == -1)
- {
- index_ = 0;
- return 0;
- }
-
- ACE_TCHAR replacement = 0;
- int replace;
- ACE_TCHAR *next_token;
-
- // Skip all leading delimiters.
- for (;;)
- {
- // Check for end of string.
- if (buffer_[index_] == '\0')
- {
- // If we hit EOS at the start, return 0.
- index_ = 0;
- return 0;
- }
-
- if (this->is_delimiter (buffer_[index_],
- replace,
- replacement))
- index_++;
- else
- break;
- }
-
- // When we reach this point, buffer_[index_] is a non-delimiter and
- // not EOS - the start of our next_token.
- next_token = buffer_ + index_;
-
- // A preserved region is it's own token.
- ACE_TCHAR stop;
- int strip;
- if (this->is_preserve_designator (buffer_[index_],
- stop,
- strip))
- {
- while (++index_)
- {
- if (buffer_[index_] == '\0')
- {
- index_ = -1;
- goto EXIT_LABEL;
- }
-
- if (buffer_[index_] == stop)
- break;
- }
-
- if (strip)
- {
- // Skip start preserve designator.
- next_token += 1;
- // Zap the stop preserve designator.
- buffer_[index_] = '\0';
- // Increment to the next token.
- index_++;
- }
-
- goto EXIT_LABEL;
- }
-
- // Step through finding the next delimiter or EOS.
- for (;;)
- {
- // Advance pointer.
- index_++;
-
- // Check for delimiter.
- if (this->is_delimiter (buffer_[index_],
- replace,
- replacement))
- {
- // Replace the delimiter.
- if (replace != 0)
- buffer_[index_] = replacement;
-
- // Move the pointer up and return.
- index_++;
- goto EXIT_LABEL;
- }
-
- // A preserve designator signifies the end of this token.
- if (this->is_preserve_designator (buffer_[index_],
- stop,
- strip))
- goto EXIT_LABEL;
-
- // Check for end of string.
- if (buffer_[index_] == '\0')
- {
- index_ = -1;
- goto EXIT_LABEL;
- }
- }
-
-EXIT_LABEL:
- return next_token;
-}
-
-// *************************************************************
-
#if defined (ACE_HAS_EXPLICIT_STATIC_TEMPLATE_MEMBER_INSTANTIATION)
template char ACE_String_Base<char>::NULL_String_;
template ACE_WSTRING_TYPE ACE_String_Base<ACE_WSTRING_TYPE>::NULL_String_;
diff --git a/ACE/ace/SString.h b/ACE/ace/SString.h
index 5d1f88cc8cf..fcaa89a3f3e 100644
--- a/ACE/ace/SString.h
+++ b/ACE/ace/SString.h
@@ -256,208 +256,6 @@ typedef ACE_WString ACE_TString;
typedef ACE_CString ACE_TString;
#endif /* ACE_USES_WCHAR */
-
-// ************************************************************
-
-/**
- * @class ACE_Tokenizer
- *
- * @brief Tokenizer
- *
- * Tokenizes a buffer. Allows application to set delimiters and
- * preserve designators. Does not allow special characters, yet
- * (e.g., printf ("\"like a quoted string\"")).
- */
-class ACE_Export ACE_Tokenizer
-{
-public:
- /**
- * \a buffer will be parsed. Notice that ACE_Tokenizer will modify
- * \a buffer if you use <code> delimiter_replace </code> or <code>
- * preserve_designators </code> to do character substitution.
- * @note You should NOT pass a constant string or string literal
- * to this constructor, since ACE_Tokenizer will try to modify
- * the string.
- * \sa preserve_designators
- * \sa preserve_designators
- */
- ACE_Tokenizer (ACE_TCHAR *buffer);
-
- /**
- * \a d is a delimiter.
- * \return Returns 0 on success, -1 if there is no memory left.
- *
- * <B>Example:</B>
- * \verbatim
- char buf[30];
- ACE_OS::strcpy(buf, "William/Joseph/Hagins");
-
- ACE_Tokenizer tok (buf);
- tok.delimiter ('/');
- for (char *p = tok.next (); p; p = tok.next ())
- cout << p << endl;
- \endverbatim
- *
- * This will print out:
- * \verbatim
- William/Joseph/Hagins
- Joseph/Hagins
- Hagins \endverbatim
- */
- int delimiter (ACE_TCHAR d);
-
- /**
- * \a d is a delimiter and, when found, will be replaced by
- * \a replacement.
- * \return 0 on success, -1 if there is no memory left.
- *
- * <B>Example:</B>
- * \verbatim
- char buf[30];
- ACE_OS::strcpy(buf, "William/Joseph/Hagins");
-
- ACE_Tokenizer tok (buf);
- tok.delimiter_replace ('/', 0);
- for (char *p = tok.next (); p; p = tok.next ())
- cout << p << endl;
- \endverbatim
- *
- * This will print out:
- * \verbatim
- William
- Joseph
- Hagins \endverbatim
- */
- int delimiter_replace (ACE_TCHAR d, ACE_TCHAR replacement);
-
- /**
- * Extract string between a pair of designator characters.
- * For instance, quotes, or '(' and ')'.
- * \a start specifies the begin designator.
- * \a stop specifies the end designator.
- * \a strip If \a strip == 1, then the preserve
- * designators will be stripped from the tokens returned by next.
- * \return 0 on success, -1 if there is no memory left.
- *
- * <B>Example with strip = 0:</B>
- * \verbatim
- char buf[30];
- ACE_OS::strcpy(buf, "William(Joseph)Hagins");
-
- ACE_Tokenizer tok (buf);
- tok.preserve_designators ('(', ')', 0);
- for (char *p = tok.next (); p; p = tok.next ())
- cout << p << endl;
- \endverbatim
- *
- * This will print out:
- * \verbatim
- William(Joseph)Hagins
- (Joseph)Hagins
- )Hagins \endverbatim
- *
- * <B>Example with strip = 1:</B>
- * \verbatim
- char buf[30];
- ACE_OS::strcpy(buf, "William(Joseph)Hagins");
-
- ACE_Tokenizer tok (buf);
- tok.preserve_designators ('(', ')', 1);
- for (char *p = tok.next (); p; p = tok.next ())
- cout << p << endl;
- \endverbatim
- *
- * This will print out:
- * \verbatim
- William
- Joseph
- Hagins \endverbatim
- */
- int preserve_designators (ACE_TCHAR start, ACE_TCHAR stop, int strip=1);
-
- /// Returns the next token.
- ACE_TCHAR *next (void);
-
- enum {
- MAX_DELIMITERS=16,
- MAX_PRESERVES=16
- };
-
-protected:
- /// Returns 1 if @a d is a delimiter, 0 otherwise. If @a d should be
- /// replaced with @a r, @a replace is set to 1, otherwise 0.
- int is_delimiter (ACE_TCHAR d, int &replace, ACE_TCHAR &r);
-
- /**
- * If @a start is a start preserve designator, returns 1 and sets
- * @a stop to the stop designator. Returns 0 if @a start is not a
- * preserve designator.
- */
- int is_preserve_designator (ACE_TCHAR start, ACE_TCHAR &stop, int &strip);
-
- ACE_TCHAR *buffer_;
- int index_;
-
- /**
- * @class Preserve_Entry
- *
- * @brief Preserve Entry
- *
- * Defines a set of characters that designate an area that
- * should not be parsed, but should be treated as a complete
- * token. For instance, in: (this is a preserve region), start
- * would be a left paren -(- and stop would be a right paren
- * -)-. The strip determines whether the designators should be
- * removed from the token.
- */
- class Preserve_Entry
- {
- public:
- /**
- * E.g., "(".
- * E.g., ")".
- * Whether the designators should be removed from the token.
- */
- ACE_TCHAR start_;
- ACE_TCHAR stop_;
- int strip_;
- };
-
- /// The application can specify MAX_PRESERVES preserve designators.
- Preserve_Entry preserves_[MAX_PRESERVES];
-
- /// Pointer to the next free spot in preserves_.
- int preserves_index_;
-
- /**
- * @class Delimiter_Entry
- *
- * @brief Delimiter Entry
- *
- * Describes a delimiter for the tokenizer.
- */
- class Delimiter_Entry
- {
- public:
- /**
- * Most commonly a space ' '.
- * What occurrences of delimiter_ should be replaced with.
- * Whether replacement_ should be used. This should be replaced
- * with a technique that sets replacement_ = delimiter by
- * default. I'll do that next iteration.
- */
- ACE_TCHAR delimiter_;
- ACE_TCHAR replacement_;
- int replace_;
- };
-
- /// The tokenizer allows MAX_DELIMITERS number of delimiters.
- Delimiter_Entry delimiters_[MAX_DELIMITERS];
-
- /// Pointer to the next free space in delimiters_.
- int delimiter_index_;
-};
-
// ****************************************************************
/**
diff --git a/ACE/ace/Tokenizer_T.cpp b/ACE/ace/Tokenizer_T.cpp
new file mode 100644
index 00000000000..f9ce33a7fc9
--- /dev/null
+++ b/ACE/ace/Tokenizer_T.cpp
@@ -0,0 +1,230 @@
+// $Id$
+
+#ifndef ACE_TOKENIZER_T_CPP
+#define ACE_TOKENIZER_T_CPP
+
+#include "ace/ACE.h"
+#include "ace/Malloc_Base.h"
+#include "ace/String_Base.h"
+#include "ace/Auto_Ptr.h"
+#include "ace/OS_NS_string.h"
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+template <class CHAR>
+ACE_Tokenizer_T<CHAR>::ACE_Tokenizer_T (CHAR *buffer)
+ : buffer_ (buffer),
+ index_ (0),
+ preserves_index_ (0),
+ delimiter_index_ (0)
+{
+}
+
+template <class CHAR>
+int
+ACE_Tokenizer_T<CHAR>::delimiter (CHAR d)
+{
+ if (delimiter_index_ == MAX_DELIMITERS)
+ return -1;
+
+ delimiters_[delimiter_index_].delimiter_ = d;
+ delimiters_[delimiter_index_].replace_ = 0;
+ ++delimiter_index_;
+ return 0;
+}
+
+template <class CHAR>
+int
+ACE_Tokenizer_T<CHAR>::delimiter_replace (CHAR d,
+ CHAR replacement)
+{
+ // Make it possible to replace delimiters on-the-fly, e.g., parse
+ // string until certain token count and then copy rest of the
+ // original string.
+ for (int i = 0; i < delimiter_index_; i++)
+ if (delimiters_[i].delimiter_ == d)
+ {
+ delimiters_[i].replacement_ = replacement;
+ delimiters_[i].replace_ = 1;
+ return 0;
+ }
+
+ if (delimiter_index_ >= MAX_DELIMITERS)
+ return -1;
+
+ delimiters_[delimiter_index_].delimiter_ = d;
+ delimiters_[delimiter_index_].replacement_ = replacement;
+ delimiters_[delimiter_index_].replace_ = 1;
+ ++delimiter_index_;
+ return 0;
+}
+
+template <class CHAR>
+int
+ACE_Tokenizer_T<CHAR>::preserve_designators (CHAR start,
+ CHAR stop,
+ int strip)
+{
+ if (preserves_index_ == MAX_PRESERVES)
+ return -1;
+
+ preserves_[preserves_index_].start_ = start;
+ preserves_[preserves_index_].stop_ = stop;
+ preserves_[preserves_index_].strip_ = strip;
+ ++preserves_index_;
+ return 0;
+}
+
+template <class CHAR>
+int
+ACE_Tokenizer_T<CHAR>::is_delimiter (CHAR d,
+ int &replace,
+ CHAR &r)
+{
+ replace = 0;
+
+ for (int x = 0; x < delimiter_index_; x++)
+ if (delimiters_[x].delimiter_ == d)
+ {
+ if (delimiters_[x].replace_)
+ {
+ r = delimiters_[x].replacement_;
+ replace = 1;
+ }
+ return 1;
+ }
+
+ return 0;
+}
+
+template <class CHAR>
+int
+ACE_Tokenizer_T<CHAR>::is_preserve_designator (CHAR start,
+ CHAR &stop,
+ int &strip)
+{
+ for (int x = 0; x < preserves_index_; x++)
+ if (preserves_[x].start_ == start)
+ {
+ stop = preserves_[x].stop_;
+ strip = preserves_[x].strip_;
+ return 1;
+ }
+
+ return 0;
+}
+
+template <class CHAR>
+CHAR *
+ACE_Tokenizer_T<CHAR>::next (void)
+{
+ // Check if the previous pass was the last one in the buffer.
+ if (index_ == -1)
+ {
+ index_ = 0;
+ return 0;
+ }
+
+ CHAR replacement = 0;
+ int replace;
+ CHAR *next_token = 0;
+
+ // Skip all leading delimiters.
+ for (;;)
+ {
+ // Check for end of string.
+ if (buffer_[index_] == '\0')
+ {
+ // If we hit EOS at the start, return 0.
+ index_ = 0;
+ return 0;
+ }
+
+ if (this->is_delimiter (buffer_[index_],
+ replace,
+ replacement))
+ ++index_;
+ else
+ break;
+ }
+
+ // When we reach this point, buffer_[index_] is a non-delimiter and
+ // not EOS - the start of our next_token.
+ next_token = buffer_ + index_;
+
+ // A preserved region is it's own token.
+ CHAR stop;
+ int strip;
+ if (this->is_preserve_designator (buffer_[index_],
+ stop,
+ strip))
+ {
+ while (++index_)
+ {
+ if (buffer_[index_] == '\0')
+ {
+ index_ = -1;
+ goto EXIT_LABEL;
+ }
+
+ if (buffer_[index_] == stop)
+ break;
+ }
+
+ if (strip)
+ {
+ // Skip start preserve designator.
+ next_token += 1;
+ // Zap the stop preserve designator.
+ buffer_[index_] = '\0';
+ // Increment to the next token.
+ ++index_;
+ }
+
+ goto EXIT_LABEL;
+ }
+
+ // Step through finding the next delimiter or EOS.
+ for (;;)
+ {
+ // Advance pointer.
+ ++index_;
+
+ // Check for delimiter.
+ if (this->is_delimiter (buffer_[index_],
+ replace,
+ replacement))
+ {
+ // Replace the delimiter.
+ if (replace != 0)
+ buffer_[index_] = replacement;
+
+ // Move the pointer up and return.
+ ++index_;
+ goto EXIT_LABEL;
+ }
+
+ // A preserve designator signifies the end of this token.
+ if (this->is_preserve_designator (buffer_[index_],
+ stop,
+ strip))
+ goto EXIT_LABEL;
+
+ // Check for end of string.
+ if (buffer_[index_] == '\0')
+ {
+ index_ = -1;
+ goto EXIT_LABEL;
+ }
+ }
+
+EXIT_LABEL:
+ return next_token;
+}
+
+// *************************************************************
+
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#endif /* ACE_TOKENIZER_T_CPP */
diff --git a/ACE/ace/Tokenizer_T.h b/ACE/ace/Tokenizer_T.h
new file mode 100644
index 00000000000..d862e4153fa
--- /dev/null
+++ b/ACE/ace/Tokenizer_T.h
@@ -0,0 +1,241 @@
+// -*- C++ -*-
+
+//=============================================================================
+/**
+ * @file Tokenizer.h
+ *
+ * $Id$
+ *
+ * @author Douglas C. Schmidt (schmidt@cs.wustl.edu)
+ * @author Nanbor Wang <nanbor@cs.wustl.edu>
+ */
+//=============================================================================
+
+#ifndef ACE_TOKENIZER_T_H
+#define ACE_TOKENIZER_T_H
+
+#include /**/ "ace/pre.h"
+
+#include "ace/Global_Macros.h"
+
+#if !defined (ACE_LACKS_PRAGMA_ONCE)
+# pragma once
+#endif /* ACE_LACKS_PRAGMA_ONCE */
+
+ACE_BEGIN_VERSIONED_NAMESPACE_DECL
+
+/**
+ * @class ACE_Tokenizer_T
+ *
+ * @brief Tokenizer
+ *
+ * Tokenizes a buffer. Allows application to set delimiters and
+ * preserve designators. Does not allow special characters, yet
+ * (e.g., printf ("\"like a quoted string\"")).
+ */
+template <class CHAR>
+class ACE_Tokenizer_T
+{
+public:
+ /**
+ * \a buffer will be parsed. Notice that ACE_Tokenizer_T will modify
+ * \a buffer if you use <code> delimiter_replace </code> or <code>
+ * preserve_designators </code> to do character substitution.
+ * @note You should NOT pass a constant string or string literal
+ * to this constructor, since ACE_Tokenizer_T will try to modify
+ * the string.
+ * \sa preserve_designators
+ * \sa preserve_designators
+ */
+ ACE_Tokenizer_T (CHAR *buffer);
+
+ /**
+ * \a d is a delimiter.
+ * \return Returns 0 on success, -1 if there is no memory left.
+ *
+ * <B>Example:</B>
+ * \verbatim
+ char buf[30];
+ ACE_OS::strcpy(buf, "William/Joseph/Hagins");
+
+ ACE_Tokenizer_T tok (buf);
+ tok.delimiter ('/');
+ for (char *p = tok.next (); p; p = tok.next ())
+ cout << p << endl;
+ \endverbatim
+ *
+ * This will print out:
+ * \verbatim
+ William/Joseph/Hagins
+ Joseph/Hagins
+ Hagins \endverbatim
+ */
+ int delimiter (CHAR d);
+
+ /**
+ * \a d is a delimiter and, when found, will be replaced by
+ * \a replacement.
+ * \return 0 on success, -1 if there is no memory left.
+ *
+ * <B>Example:</B>
+ * \verbatim
+ char buf[30];
+ ACE_OS::strcpy(buf, "William/Joseph/Hagins");
+
+ ACE_Tokenizer tok (buf);
+ tok.delimiter_replace ('/', 0);
+ for (char *p = tok.next (); p; p = tok.next ())
+ cout << p << endl;
+ \endverbatim
+ *
+ * This will print out:
+ * \verbatim
+ William
+ Joseph
+ Hagins \endverbatim
+ */
+ int delimiter_replace (CHAR d, CHAR replacement);
+
+ /**
+ * Extract string between a pair of designator characters.
+ * For instance, quotes, or '(' and ')'.
+ * \a start specifies the begin designator.
+ * \a stop specifies the end designator.
+ * \a strip If \a strip == 1, then the preserve
+ * designators will be stripped from the tokens returned by next.
+ * \return 0 on success, -1 if there is no memory left.
+ *
+ * <B>Example with strip = 0:</B>
+ * \verbatim
+ char buf[30];
+ ACE_OS::strcpy(buf, "William(Joseph)Hagins");
+
+ ACE_Tokenizer tok (buf);
+ tok.preserve_designators ('(', ')', 0);
+ for (char *p = tok.next (); p; p = tok.next ())
+ cout << p << endl;
+ \endverbatim
+ *
+ * This will print out:
+ * \verbatim
+ William(Joseph)Hagins
+ (Joseph)Hagins
+ )Hagins \endverbatim
+ *
+ * <B>Example with strip = 1:</B>
+ * \verbatim
+ char buf[30];
+ ACE_OS::strcpy(buf, "William(Joseph)Hagins");
+
+ ACE_Tokenizer tok (buf);
+ tok.preserve_designators ('(', ')', 1);
+ for (char *p = tok.next (); p; p = tok.next ())
+ cout << p << endl;
+ \endverbatim
+ *
+ * This will print out:
+ * \verbatim
+ William
+ Joseph
+ Hagins \endverbatim
+ */
+ int preserve_designators (CHAR start, CHAR stop, int strip=1);
+
+ /// Returns the next token.
+ CHAR *next (void);
+
+ enum {
+ MAX_DELIMITERS=16,
+ MAX_PRESERVES=16
+ };
+
+protected:
+ /// Returns 1 if @a d is a delimiter, 0 otherwise. If @a d should be
+ /// replaced with @a r, @a replace is set to 1, otherwise 0.
+ int is_delimiter (CHAR d, int &replace, CHAR &r);
+
+ /**
+ * If @a start is a start preserve designator, returns 1 and sets
+ * @a stop to the stop designator. Returns 0 if @a start is not a
+ * preserve designator.
+ */
+ int is_preserve_designator (CHAR start, CHAR &stop, int &strip);
+
+ CHAR *buffer_;
+ int index_;
+
+ /**
+ * @class Preserve_Entry
+ *
+ * @brief Preserve Entry
+ *
+ * Defines a set of characters that designate an area that
+ * should not be parsed, but should be treated as a complete
+ * token. For instance, in: (this is a preserve region), start
+ * would be a left paren -(- and stop would be a right paren
+ * -)-. The strip determines whether the designators should be
+ * removed from the token.
+ */
+ class Preserve_Entry
+ {
+ public:
+ /**
+ * E.g., "(".
+ * E.g., ")".
+ * Whether the designators should be removed from the token.
+ */
+ CHAR start_;
+ CHAR stop_;
+ int strip_;
+ };
+
+ /// The application can specify MAX_PRESERVES preserve designators.
+ Preserve_Entry preserves_[MAX_PRESERVES];
+
+ /// Pointer to the next free spot in preserves_.
+ int preserves_index_;
+
+ /**
+ * @class Delimiter_Entry
+ *
+ * @brief Delimiter Entry
+ *
+ * Describes a delimiter for the tokenizer.
+ */
+ class Delimiter_Entry
+ {
+ public:
+ /**
+ * Most commonly a space ' '.
+ * What occurrences of delimiter_ should be replaced with.
+ * Whether replacement_ should be used. This should be replaced
+ * with a technique that sets replacement_ = delimiter by
+ * default. I'll do that next iteration.
+ */
+ CHAR delimiter_;
+ CHAR replacement_;
+ int replace_;
+ };
+
+ /// The tokenizer allows MAX_DELIMITERS number of delimiters.
+ Delimiter_Entry delimiters_[MAX_DELIMITERS];
+
+ /// Pointer to the next free space in delimiters_.
+ int delimiter_index_;
+};
+
+typedef ACE_Tokenizer_T <char> ACE_Tokenizer;
+
+ACE_END_VERSIONED_NAMESPACE_DECL
+
+#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
+#include "ace/Tokenizer_T.cpp"
+#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
+
+#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
+#pragma implementation ("Tokenizer_T.cpp")
+#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
+
+#include /**/ "ace/post.h"
+
+#endif /* ACE_TOKENIZER_T_H */
diff --git a/ACE/ace/ace.mpc b/ACE/ace/ace.mpc
index 5dfcba00478..fbc2424a2ed 100644
--- a/ACE/ace/ace.mpc
+++ b/ACE/ace/ace.mpc
@@ -360,6 +360,7 @@ project(ACE) : ace_output, acedefaults, install, other, codecs, token, svcconf,
Timer_Queue_Adapters.cpp
Timer_Queue_T.cpp
Timer_Wheel_T.cpp
+ Tokenizer_T.cpp
Typed_SV_Message.cpp
Typed_SV_Message_Queue.cpp
Unbounded_Queue.cpp
diff --git a/ACE/ace/ace_for_tao.mpc b/ACE/ace/ace_for_tao.mpc
index c4625e51f6a..85778635617 100644
--- a/ACE/ace/ace_for_tao.mpc
+++ b/ACE/ace/ace_for_tao.mpc
@@ -271,6 +271,7 @@ project(ACE_FOR_TAO) : acedefaults, install, svcconf, uuid, versioned_namespace,
Timer_Queue_Adapters.cpp
Timer_Queue_T.cpp
Timer_Wheel_T.cpp
+ Tokenizer_T.cpp
Typed_SV_Message.cpp
Typed_SV_Message_Queue.cpp
Unbounded_Queue.cpp
diff --git a/ACE/examples/OS/Process/process.cpp b/ACE/examples/OS/Process/process.cpp
index 89d32881243..7187338dd5d 100644
--- a/ACE/examples/OS/Process/process.cpp
+++ b/ACE/examples/OS/Process/process.cpp
@@ -29,6 +29,7 @@
#include "ace/Time_Value.h"
#include "ace/SString.h"
#include "ace/Truncate.h"
+#include "ace/Tokenizer_T.h"
ACE_RCSID(Process, process, "$Id$")