diff options
author | Johnny Willemsen <jwillemsen@remedy.nl> | 2009-06-07 17:57:11 +0000 |
---|---|---|
committer | Johnny Willemsen <jwillemsen@remedy.nl> | 2009-06-07 17:57:11 +0000 |
commit | 3f77faa12016ad52e39e5e6e640bd544424dce2e (patch) | |
tree | bb38bfa2a9e8ca6da5a6ec7f728ee3d0389a4b69 | |
parent | d6cdbfdeff139917c0241654091116dda8303111 (diff) | |
download | ATCD-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/ChangeLog | 26 | ||||
-rw-r--r-- | ACE/ace/Configuration.cpp | 1 | ||||
-rw-r--r-- | ACE/ace/Makefile.am | 2 | ||||
-rw-r--r-- | ACE/ace/OS_NS_Thread.cpp | 2 | ||||
-rw-r--r-- | ACE/ace/OS_NS_Thread.h | 2 | ||||
-rw-r--r-- | ACE/ace/OS_NS_Thread.inl | 4 | ||||
-rw-r--r-- | ACE/ace/Process.cpp | 1 | ||||
-rw-r--r-- | ACE/ace/SString.cpp | 206 | ||||
-rw-r--r-- | ACE/ace/SString.h | 202 | ||||
-rw-r--r-- | ACE/ace/Tokenizer_T.cpp | 230 | ||||
-rw-r--r-- | ACE/ace/Tokenizer_T.h | 241 | ||||
-rw-r--r-- | ACE/ace/ace.mpc | 1 | ||||
-rw-r--r-- | ACE/ace/ace_for_tao.mpc | 1 | ||||
-rw-r--r-- | ACE/examples/OS/Process/process.cpp | 1 |
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$") |