1 // 2 //Copyright (C) 2002-2005 3Dlabs Inc. Ltd. 3 //Copyright (C) 2013 LunarG, Inc. 4 //All rights reserved. 5 // 6 //Redistribution and use in source and binary forms, with or without 7 //modification, are permitted provided that the following conditions 8 //are met: 9 // 10 // Redistributions of source code must retain the above copyright 11 // notice, this list of conditions and the following disclaimer. 12 // 13 // Redistributions in binary form must reproduce the above 14 // copyright notice, this list of conditions and the following 15 // disclaimer in the documentation and/or other materials provided 16 // with the distribution. 17 // 18 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its 19 // contributors may be used to endorse or promote products derived 20 // from this software without specific prior written permission. 21 // 22 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 23 //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 24 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 25 //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 26 //COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 27 //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 28 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 29 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 30 //CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32 //ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33 //POSSIBILITY OF SUCH DAMAGE. 34 // 35 /****************************************************************************\ 36 Copyright (c) 2002, NVIDIA Corporation. 37 38 NVIDIA Corporation("NVIDIA") supplies this software to you in 39 consideration of your agreement to the following terms, and your use, 40 installation, modification or redistribution of this NVIDIA software 41 constitutes acceptance of these terms. If you do not agree with these 42 terms, please do not use, install, modify or redistribute this NVIDIA 43 software. 44 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 62 THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT 63 WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, 64 INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE, 65 NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 66 ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER 67 PRODUCTS. 68 69 IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT, 70 INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 71 TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 72 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY 73 OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE 74 NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, 75 TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF 76 NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 77 \****************************************************************************/ 78 79 // 80 // For recording and playing back the stream of tokens in a macro definition. 81 // 82 83 #if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) 84 #define _CRT_SECURE_NO_WARNINGS 85 #define snprintf sprintf_s 86 #endif 87 88 #include <assert.h> 89 #include <stdlib.h> 90 #include <stdio.h> 91 #include <string.h> 92 #include <ctype.h> 93 94 #include "PpContext.h" 95 #include "PpTokens.h" 96 97 namespace glslang { 98 99 void TPpContext::lAddByte(TokenStream *fTok, unsigned char fVal) 100 { 101 fTok->data.push_back(fVal); 102 } 103 104 /* 105 * Get the next byte from a stream. 106 */ 107 int TPpContext::lReadByte(TokenStream *pTok) 108 { 109 if (pTok->current < pTok->data.size()) 110 return pTok->data[pTok->current++]; 111 else 112 return EndOfInput; 113 } 114 115 void TPpContext::lUnreadByte(TokenStream *pTok) 116 { 117 if (pTok->current > 0) 118 --pTok->current; 119 } 120 121 /* 122 * Add a token to the end of a list for later playback. 123 */ 124 void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken* ppToken) 125 { 126 const char* s; 127 char* str = NULL; 128 129 if (token > PpAtomMaxSingle) 130 lAddByte(pTok, (unsigned char)((token & 0x7f) + 0x80)); 131 else 132 lAddByte(pTok, (unsigned char)(token & 0x7f)); 133 134 switch (token) { 135 case PpAtomIdentifier: 136 case PpAtomConstString: 137 s = ppToken->name; 138 while (*s) 139 lAddByte(pTok, (unsigned char) *s++); 140 lAddByte(pTok, 0); 141 break; 142 case PpAtomConstInt: 143 case PpAtomConstUint: 144 case PpAtomConstInt64: 145 case PpAtomConstUint64: 146 case PpAtomConstFloat: 147 case PpAtomConstDouble: 148 str = ppToken->name; 149 while (*str) { 150 lAddByte(pTok, (unsigned char) *str); 151 str++; 152 } 153 lAddByte(pTok, 0); 154 break; 155 default: 156 break; 157 } 158 } 159 160 /* 161 * Reset a token stream in preperation for reading. 162 */ 163 void TPpContext::RewindTokenStream(TokenStream *pTok) 164 { 165 pTok->current = 0; 166 } 167 168 /* 169 * Read the next token from a token stream (not the source stream, but stream used to hold a tokenized macro). 170 */ 171 int TPpContext::ReadToken(TokenStream *pTok, TPpToken *ppToken) 172 { 173 char* tokenText = ppToken->name; 174 int ltoken, len; 175 int ch; 176 177 ltoken = lReadByte(pTok); 178 ppToken->loc = parseContext.getCurrentLoc(); 179 if (ltoken > 127) 180 ltoken += 128; 181 switch (ltoken) { 182 case '#': 183 if (lReadByte(pTok) == '#') { 184 parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); 185 parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); 186 parseContext.error(ppToken->loc, "token pasting not implemented (internal error)", "##", ""); 187 //return PpAtomPaste; 188 return ReadToken(pTok, ppToken); 189 } else 190 lUnreadByte(pTok); 191 break; 192 case PpAtomConstString: 193 case PpAtomIdentifier: 194 case PpAtomConstFloat: 195 case PpAtomConstDouble: 196 case PpAtomConstInt: 197 case PpAtomConstUint: 198 case PpAtomConstInt64: 199 case PpAtomConstUint64: 200 len = 0; 201 ch = lReadByte(pTok); 202 while (ch != 0 && ch != EndOfInput) { 203 if (len < MaxTokenLength) { 204 tokenText[len] = (char)ch; 205 len++; 206 ch = lReadByte(pTok); 207 } else { 208 parseContext.error(ppToken->loc, "token too long", "", ""); 209 break; 210 } 211 } 212 tokenText[len] = 0; 213 214 switch (ltoken) { 215 case PpAtomIdentifier: 216 ppToken->atom = LookUpAddString(tokenText); 217 break; 218 case PpAtomConstString: 219 break; 220 case PpAtomConstFloat: 221 case PpAtomConstDouble: 222 ppToken->dval = atof(ppToken->name); 223 break; 224 case PpAtomConstInt: 225 case PpAtomConstUint: 226 if (len > 0 && tokenText[0] == '0') { 227 if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X')) 228 ppToken->ival = strtol(ppToken->name, 0, 16); 229 else 230 ppToken->ival = strtol(ppToken->name, 0, 8); 231 } else 232 ppToken->ival = atoi(ppToken->name); 233 break; 234 case PpAtomConstInt64: 235 case PpAtomConstUint64: 236 if (len > 0 && tokenText[0] == '0') { 237 if (len > 1 && (tokenText[1] == 'x' || tokenText[1] == 'X')) 238 ppToken->i64val = strtoll(ppToken->name, nullptr, 16); 239 else 240 ppToken->i64val = strtoll(ppToken->name, nullptr, 8); 241 } else 242 ppToken->i64val = atoll(ppToken->name); 243 break; 244 } 245 } 246 247 return ltoken; 248 } 249 250 int TPpContext::tTokenInput::scan(TPpToken* ppToken) 251 { 252 return pp->ReadToken(tokens, ppToken); 253 } 254 255 void TPpContext::pushTokenStreamInput(TokenStream* ts) 256 { 257 pushInput(new tTokenInput(this, ts)); 258 RewindTokenStream(ts); 259 } 260 261 int TPpContext::tUngotTokenInput::scan(TPpToken* ppToken) 262 { 263 if (done) 264 return EndOfInput; 265 266 int ret = token; 267 *ppToken = lval; 268 done = true; 269 270 return ret; 271 } 272 273 void TPpContext::UngetToken(int token, TPpToken* ppToken) 274 { 275 pushInput(new tUngotTokenInput(this, token, ppToken)); 276 } 277 278 } // end namespace glslang 279