PpTokens.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. //
  2. // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
  3. // Copyright (C) 2013 LunarG, Inc.
  4. // Copyright (C) 2015-2018 Google, Inc.
  5. //
  6. // All rights reserved.
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions
  10. // are met:
  11. //
  12. // Redistributions of source code must retain the above copyright
  13. // notice, this list of conditions and the following disclaimer.
  14. //
  15. // Redistributions in binary form must reproduce the above
  16. // copyright notice, this list of conditions and the following
  17. // disclaimer in the documentation and/or other materials provided
  18. // with the distribution.
  19. //
  20. // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
  21. // contributors may be used to endorse or promote products derived
  22. // from this software without specific prior written permission.
  23. //
  24. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  27. // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  28. // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  29. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  30. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31. // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  32. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  34. // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  35. // POSSIBILITY OF SUCH DAMAGE.
  36. //
  37. /****************************************************************************\
  38. Copyright (c) 2002, NVIDIA Corporation.
  39. NVIDIA Corporation("NVIDIA") supplies this software to you in
  40. consideration of your agreement to the following terms, and your use,
  41. installation, modification or redistribution of this NVIDIA software
  42. constitutes acceptance of these terms. If you do not agree with these
  43. terms, please do not use, install, modify or redistribute this NVIDIA
  44. software.
  45. In consideration of your agreement to abide by the following terms, and
  46. subject to these terms, NVIDIA grants you a personal, non-exclusive
  47. license, under NVIDIA's copyrights in this original NVIDIA software (the
  48. "NVIDIA Software"), to use, reproduce, modify and redistribute the
  49. NVIDIA Software, with or without modifications, in source and/or binary
  50. forms; provided that if you redistribute the NVIDIA Software, you must
  51. retain the copyright notice of NVIDIA, this notice and the following
  52. text and disclaimers in all such redistributions of the NVIDIA Software.
  53. Neither the name, trademarks, service marks nor logos of NVIDIA
  54. Corporation may be used to endorse or promote products derived from the
  55. NVIDIA Software without specific prior written permission from NVIDIA.
  56. Except as expressly stated in this notice, no other rights or licenses
  57. express or implied, are granted by NVIDIA herein, including but not
  58. limited to any patent rights that may be infringed by your derivative
  59. works or by other works in which the NVIDIA Software may be
  60. incorporated. No hardware is licensed hereunder.
  61. THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
  62. WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  63. INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
  64. NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
  65. ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
  66. PRODUCTS.
  67. IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
  68. INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  69. TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  70. USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
  71. OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
  72. NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
  73. TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
  74. NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  75. \****************************************************************************/
  76. //
  77. // For recording and playing back the stream of tokens in a macro definition.
  78. //
  79. #ifndef _CRT_SECURE_NO_WARNINGS
  80. #define _CRT_SECURE_NO_WARNINGS
  81. #endif
  82. #if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/)
  83. #define snprintf sprintf_s
  84. #endif
  85. #include <cassert>
  86. #include <cstdlib>
  87. #include <cstring>
  88. #include <cctype>
  89. #include "PpContext.h"
  90. #include "PpTokens.h"
  91. namespace glslang {
  92. // Add a token (including backing string) to the end of a macro
  93. // token stream, for later playback.
  94. void TPpContext::TokenStream::putToken(int atom, TPpToken* ppToken)
  95. {
  96. TokenStream::Token streamToken(atom, *ppToken);
  97. stream.push_back(streamToken);
  98. }
  99. // Read the next token from a macro token stream.
  100. int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken)
  101. {
  102. if (atEnd())
  103. return EndOfInput;
  104. int atom = stream[currentPos++].get(*ppToken);
  105. ppToken->loc = parseContext.getCurrentLoc();
  106. #ifndef GLSLANG_WEB
  107. // Check for ##, unless the current # is the last character
  108. if (atom == '#') {
  109. if (peekToken('#')) {
  110. parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)");
  111. parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)");
  112. currentPos++;
  113. atom = PpAtomPaste;
  114. }
  115. }
  116. #endif
  117. return atom;
  118. }
  119. // We are pasting if
  120. // 1. we are preceding a pasting operator within this stream
  121. // or
  122. // 2. the entire macro is preceding a pasting operator (lastTokenPastes)
  123. // and we are also on the last token
  124. bool TPpContext::TokenStream::peekTokenizedPasting(bool lastTokenPastes)
  125. {
  126. // 1. preceding ##?
  127. size_t savePos = currentPos;
  128. // skip white space
  129. while (peekToken(' '))
  130. ++currentPos;
  131. if (peekToken(PpAtomPaste)) {
  132. currentPos = savePos;
  133. return true;
  134. }
  135. // 2. last token and we've been told after this there will be a ##
  136. if (! lastTokenPastes)
  137. return false;
  138. // Getting here means the last token will be pasted, after this
  139. // Are we at the last non-whitespace token?
  140. savePos = currentPos;
  141. bool moreTokens = false;
  142. do {
  143. if (atEnd())
  144. break;
  145. if (!peekToken(' ')) {
  146. moreTokens = true;
  147. break;
  148. }
  149. ++currentPos;
  150. } while (true);
  151. currentPos = savePos;
  152. return !moreTokens;
  153. }
  154. // See if the next non-white-space tokens are two consecutive #
  155. bool TPpContext::TokenStream::peekUntokenizedPasting()
  156. {
  157. // don't return early, have to restore this
  158. size_t savePos = currentPos;
  159. // skip white-space
  160. while (peekToken(' '))
  161. ++currentPos;
  162. // check for ##
  163. bool pasting = false;
  164. if (peekToken('#')) {
  165. ++currentPos;
  166. if (peekToken('#'))
  167. pasting = true;
  168. }
  169. currentPos = savePos;
  170. return pasting;
  171. }
  172. void TPpContext::pushTokenStreamInput(TokenStream& ts, bool prepasting)
  173. {
  174. pushInput(new tTokenInput(this, &ts, prepasting));
  175. ts.reset();
  176. }
  177. int TPpContext::tUngotTokenInput::scan(TPpToken* ppToken)
  178. {
  179. if (done)
  180. return EndOfInput;
  181. int ret = token;
  182. *ppToken = lval;
  183. done = true;
  184. return ret;
  185. }
  186. void TPpContext::UngetToken(int token, TPpToken* ppToken)
  187. {
  188. pushInput(new tUngotTokenInput(this, token, ppToken));
  189. }
  190. } // end namespace glslang