// Read the next token from a macro token stream. int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken) { if (atEnd()) return EndOfInput; int atom = stream[currentPos++].get(*ppToken); ppToken->loc = parseContext.getCurrentLoc(); // Check for ##, unless the current # is the last character if (atom == '#') { if (peekToken('#')) { parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); currentPos++; atom = PpAtomPaste; } } return atom; }
// Read the next token from a token stream. // (Not the source stream, but a stream used to hold a tokenized macro). int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken *ppToken) { int len; int ch; int subtoken = getSubtoken(); ppToken->loc = parseContext.getCurrentLoc(); switch (subtoken) { case '#': // Check for ##, unless the current # is the last character if (current < data.size()) { if (getSubtoken() == '#') { parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); subtoken = PpAtomPaste; } else ungetSubtoken(); } break; case PpAtomConstString: case PpAtomIdentifier: case PpAtomConstFloat: case PpAtomConstDouble: #ifdef AMD_EXTENSIONS case PpAtomConstFloat16: #endif case PpAtomConstInt: case PpAtomConstUint: case PpAtomConstInt64: case PpAtomConstUint64: len = 0; ch = getSubtoken(); while (ch != 0 && ch != EndOfInput) { if (len < MaxTokenLength) { ppToken->name[len] = (char)ch; len++; ch = getSubtoken(); } else { parseContext.error(ppToken->loc, "token too long", "", ""); break; } } ppToken->name[len] = 0; switch (subtoken) { case PpAtomIdentifier: break; case PpAtomConstString: break; case PpAtomConstFloat: case PpAtomConstDouble: #ifdef AMD_EXTENSIONS case PpAtomConstFloat16: #endif ppToken->dval = atof(ppToken->name); break; case PpAtomConstInt: if (len > 0 && ppToken->name[0] == '0') { if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) ppToken->ival = (int)strtol(ppToken->name, 0, 16); else ppToken->ival = (int)strtol(ppToken->name, 0, 8); } else ppToken->ival = atoi(ppToken->name); break; case PpAtomConstUint: if (len > 0 && ppToken->name[0] == '0') { if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) ppToken->ival = (int)strtoul(ppToken->name, 0, 16); else ppToken->ival = (int)strtoul(ppToken->name, 0, 8); } else ppToken->ival = (int)strtoul(ppToken->name, 0, 10); break; case PpAtomConstInt64: if (len > 0 && ppToken->name[0] == '0') { if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) ppToken->i64val = strtoll(ppToken->name, nullptr, 16); else ppToken->i64val = strtoll(ppToken->name, nullptr, 8); } else ppToken->i64val = atoll(ppToken->name); break; case PpAtomConstUint64: if (len > 0 && ppToken->name[0] == '0') { if (len > 1 && (ppToken->name[1] == 'x' || ppToken->name[1] == 'X')) ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 16); else ppToken->i64val = (long long)strtoull(ppToken->name, nullptr, 8); } else ppToken->i64val = (long long)strtoull(ppToken->name, 0, 10); break; } } return subtoken; }