convert_trigraphs.hpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /*=============================================================================
  2. Boost.Wave: A Standard compliant C++ preprocessor library
  3. Grammar for universal character validation (see C++ standard: Annex E)
  4. http://www.boost.org/
  5. Copyright (c) 2001-2012 Hartmut Kaiser. Distributed under the Boost
  6. Software License, Version 1.0. (See accompanying file
  7. LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. =============================================================================*/
  9. #if !defined(BOOST_CONVERT_TRIGRAPHS_HK050403_INCLUDED)
  10. #define BOOST_CONVERT_TRIGRAPHS_HK050403_INCLUDED
  11. #include <boost/wave/wave_config.hpp>
  12. #include <boost/wave/cpplexer/cpplexer_exceptions.hpp>
  13. // this must occur after all of the includes and before any code appears
  14. #ifdef BOOST_HAS_ABI_HEADERS
  15. #include BOOST_ABI_PREFIX
  16. #endif
  17. ///////////////////////////////////////////////////////////////////////////////
  18. namespace boost {
  19. namespace wave {
  20. namespace cpplexer {
  21. namespace impl {
  22. ///////////////////////////////////////////////////////////////////////////////
  23. //
  24. // Test, whether the given string represents a valid trigraph sequence
  25. //
  26. ///////////////////////////////////////////////////////////////////////////////
  27. template <typename StringT>
  28. inline bool
  29. is_trigraph(StringT const& trigraph)
  30. {
  31. if (trigraph.size() < 3 || '?' != trigraph[0] || '?' != trigraph[1])
  32. return false;
  33. switch (trigraph[2]) {
  34. case '\'': case '=': case '/': case '(':
  35. case ')': case '<': case '>': case '!':
  36. case '-':
  37. break;
  38. default:
  39. return false;
  40. }
  41. return true;
  42. }
  43. ///////////////////////////////////////////////////////////////////////////////
  44. //
  45. // convert_trigraph
  46. //
  47. // The function convert_trigraph() converts a single trigraph character
  48. // sequence into the corresponding character.
  49. //
  50. // If the given character sequence doesn't form a valid trigraph sequence
  51. // no conversion is performed.
  52. //
  53. ///////////////////////////////////////////////////////////////////////////////
  54. template <typename StringT>
  55. inline StringT
  56. convert_trigraph(StringT const &trigraph)
  57. {
  58. StringT result (trigraph);
  59. if (is_trigraph(trigraph)) {
  60. switch (trigraph[2]) {
  61. case '\'': result = "^"; break;
  62. case '=': result = "#"; break;
  63. case '/': result = "\\"; break;
  64. case '(': result = "["; break;
  65. case ')': result = "]"; break;
  66. case '<': result = "{"; break;
  67. case '>': result = "}"; break;
  68. case '!': result = "|"; break;
  69. case '-': result = "~"; break;
  70. }
  71. }
  72. return result;
  73. }
  74. ///////////////////////////////////////////////////////////////////////////////
  75. //
  76. // convert_trigraphs
  77. //
  78. // The function convert_trigraph() converts all trigraphs in the given
  79. // string into the corresponding characters.
  80. //
  81. // If one of the given character sequences doesn't form a valid trigraph
  82. // sequence no conversion is performed.
  83. //
  84. ///////////////////////////////////////////////////////////////////////////////
  85. template <typename StringT>
  86. inline StringT
  87. convert_trigraphs(StringT const &value)
  88. {
  89. StringT result;
  90. typename StringT::size_type pos = 0;
  91. typename StringT::size_type pos1 = value.find_first_of ("?", 0);
  92. if (StringT::npos != pos1) {
  93. do {
  94. result += value.substr(pos, pos1-pos);
  95. StringT trigraph (value.substr(pos1));
  96. if (is_trigraph(trigraph)) {
  97. result += convert_trigraph(trigraph);
  98. pos1 = value.find_first_of ("?", pos = pos1+3);
  99. }
  100. else {
  101. result += value[pos1];
  102. pos1 = value.find_first_of ("?", pos = pos1+1);
  103. }
  104. } while (StringT::npos != pos1);
  105. result += value.substr(pos);
  106. }
  107. else {
  108. result = value;
  109. }
  110. return result;
  111. }
  112. ///////////////////////////////////////////////////////////////////////////////
  113. } // namespace impl
  114. } // namespace cpplexer
  115. } // namespace wave
  116. } // namespace boost
  117. // the suffix header occurs after all of the code
  118. #ifdef BOOST_HAS_ABI_HEADERS
  119. #include BOOST_ABI_SUFFIX
  120. #endif
  121. #endif // !defined(BOOST_CONVERT_TRIGRAPHS_HK050403_INCLUDED)