1c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet/* 2c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Copyright (C) 2015 The Android Open Source Project 3c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * 4c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Licensed under the Apache License, Version 2.0 (the "License"); 5c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * you may not use this file except in compliance with the License. 6c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * You may obtain a copy of the License at 7c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * 8c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * http://www.apache.org/licenses/LICENSE-2.0 9c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * 10c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * Unless required by applicable law or agreed to in writing, software 11c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * distributed under the License is distributed on an "AS IS" BASIS, 12c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * See the License for the specific language governing permissions and 14c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet * limitations under the License. 15c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet */ 16c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 17c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <iostream> 18c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include <sstream> 19c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 20c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include "Scanner.h" 21c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include "Specification.h" 22c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet#include "Utilities.h" 23c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 24c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletusing namespace std; 25c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 26c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet// Maximum of errors we'll report before bailing out. 27c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletconst int MAX_ERRORS = 10; 28c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 29c5184e202ced435258adb2cfe2013570e7190954Jean-Luc BrouilletScanner::Scanner(const string& fileName, FILE* file) 30c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet : mFileName(fileName), mFile(file), mLineNumber(0), mTagConsumed(true), mErrorCount(0) { 31c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 32c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 33c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletbool Scanner::atEnd() { 34c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return (mTagConsumed && feof(mFile)) || mErrorCount > MAX_ERRORS; 35c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 36c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 37c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletint Scanner::getChar() { 38c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int c = fgetc(mFile); 39c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (c == '\n') { 40c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mLineNumber++; 41c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 42c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return c; 43c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 44c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 45c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid Scanner::readUpTo(char delimiter, string* segment) { 46c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (;;) { 47c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int c = getChar(); 48c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (c == EOF || c == '\n') { 49c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet break; 50c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 51c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet segment->push_back((char)c); 52c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (c == delimiter) { 53c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet break; 54c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 55c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 56c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 57c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 58c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid Scanner::readRestOfLine(string* segment) { 59c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (;;) { 60c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int c = getChar(); 61c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (c == EOF || c == '\n') { 62c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return; 63c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 64c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet segment->push_back((char)c); 65c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 66c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 67c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 68c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletbool Scanner::getNextEntry() { 69c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mTag.clear(); 70c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mValue.clear(); 71c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet for (;;) { 72c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet int c = getChar(); 73c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (c == EOF) { 74c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return false; 75c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 76c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (c == '#') { 77c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet // Skip the comment 78c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string comment; 79c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet readRestOfLine(&comment); 80c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet continue; 81c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 82c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (c == ' ') { 83c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet readRestOfLine(&mValue); 84c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet break; 85c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else if (c == '\n') { 86c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet break; 87c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 88c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mTag = c; 89c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet readUpTo(':', &mTag); 90c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet readRestOfLine(&mValue); 91c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet trimSpaces(&mValue); 92c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet break; 93c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 94c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 95c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return true; 96c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 97c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 98c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletostream& Scanner::error() { 99c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return error(mLineNumber); 100c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 101c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 102c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletostream& Scanner::error(int lineNumber) { 103c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (++mErrorCount <= MAX_ERRORS) { 104c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet cerr << mFileName << ":" << lineNumber << ": error: "; 105c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 106c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return cerr; 107c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 108c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 109c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid Scanner::skipBlankEntries() { 110c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet while (findOptionalTag("")) { 111c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!mValue.empty()) { 112c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet error() << "Unexpected: \" " << mValue << "\".\n"; 113c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 114c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 115c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 116c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 117c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletbool Scanner::findTag(const char* tag) { 118c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet bool found = findOptionalTag(tag); 119c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!found) { 120c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet error() << "Found \"" << mTag << "\" while looking for \"" << tag << "\".\n"; 121c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 122c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mTagConsumed = true; 123c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return found; 124c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 125c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 126c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletbool Scanner::findOptionalTag(const char* tag) { 127c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (mTagConsumed) { 128c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!getNextEntry()) { 129c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return false; 130c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 131c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 132c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet mTagConsumed = (mTag == tag); 133c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return mTagConsumed; 134c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 135c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 1362217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouilletvoid Scanner::skipUntilTag(const char* tag) { 1372217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet while(!findOptionalTag(tag)) { 1382217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet mTagConsumed = true; 1392217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet } 1402217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet} 1412217eb7b12e598e5b435a732207647918c171560Jean-Luc Brouillet 142c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid Scanner::checkNoValue() { 143c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!mValue.empty()) { 144c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet error() << "Did not expect \"" << mValue << "\" after \"" << mTag << "\".\n"; 145c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 146c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 147c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 148c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouilletvoid Scanner::parseDocumentation(string* s, string* documentation) { 149c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet size_t docStart = s->find(", \""); 150c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (docStart == string::npos) { 151c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet documentation->erase(); 152c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 153c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet size_t first = docStart + 3; 154c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet size_t last = s->find('\"', first); 155c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (last == string::npos) { 156c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet error() << "Missing closing double quote\n"; 157c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 158c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet *documentation = s->substr(first, last - first); 159c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet s->erase(docStart); 160c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 161c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 162c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 163c5184e202ced435258adb2cfe2013570e7190954Jean-Luc BrouilletParameterEntry* Scanner::parseArgString(bool isReturn) { 164c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet string s = mValue; 165c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet ParameterEntry* p = new ParameterEntry(); 166c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet parseDocumentation(&s, &p->documentation); 167c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 168c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet size_t optionStart = s.find(", "); 169c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (optionStart != string::npos) { 170c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet p->testOption = s.substr(optionStart + 2); 171c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet s.erase(optionStart); 172c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 173c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 174c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet trimSpaces(&s); 175c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (!isReturn) { 176c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet size_t nameStart = s.rfind(' '); 177c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (nameStart == string::npos) { 17812398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni if (s == "...") { 17912398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni p->name = s; 180fab6947a18e00964f79e6c802dc70bbaed981730Yang Ni p->type = s; 18112398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni p->lineNumber = mLineNumber; 18212398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni return p; 18312398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni } else { 18412398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni error() << "Missing variable name\n"; 18512398d81f32e5e0479d02b8608a83c75cd991bb3Yang Ni } 186c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } else { 187c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet p->name = s.substr(nameStart + 1); 188c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet s.erase(nameStart); 189c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (p->name.find('*') != string::npos) { 190c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet error() << "The '*' should be attached to the type\n"; 191c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 192c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 193c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 194c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet 195c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet if (s == "void" && !isReturn) { 196c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet error() << "void is only allowed for ret:\n"; 197c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet } 198c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet p->type = s; 199c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet p->lineNumber = mLineNumber; 200c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet return p; 201c5184e202ced435258adb2cfe2013570e7190954Jean-Luc Brouillet} 202