// scans the Input into a symbol list bool opScanner::Scan(FileReadStream& ifs, ScanMode mode, opNode* root) { Tokens.Clear(); ScanError = false; CurrentLine = 1; ScanComplete = false; scanMode = mode; Root = root; inputtype Input; ifs.ReadToContainer(Input); FixNewlines(Input); int it = 0; ScanTokens(Input); if (opError::HasErrors()) return false; // post scanning stuff Preprocessor(); FixStrings(); Keyword(); if (scanMode != SM_DialectMode) { BasicType(); UserDefined(); } ContinueLines(); Decimals(); WideStrings(); FixNumbers(); if (scanMode == SM_NormalMode) CPlusPlus(); ScanComplete = true; return true; }
bool Preprocessor::HandleInclude(size_t line_no, Tokenizer & tok){ bool issection = false; if (tok.next_token() == "section"){ issection = true; tok.next_token(); } if (tok.get_type() != Tokenizer::Type::String){ throw Exception::Error("Include name must be quoted string; got `" + tok.get_string() + "`."); } MappedFile mfile; std::string section = ""; if (issection){ section = tok.get_string(); trim_ends(section); mfile = filedata; } else{ std::string file = tok; trim_ends(file); size_t pos = file.find_first_of("?"); if (pos != std::string::npos){ section = file.substr(pos + 1); file.erase(file.begin() + pos, file.end()); } else{ if (tok.next_token()){ if (tok == "section"){ if (tok.next_token().get_type() == Tokenizer::Type::String){ section = tok.get_string(); trim_ends(section); } else{ throw Exception::Error("String expected after `section`; got `" + tok.get_string() + "`."); } } else{ throw Exception::Error("Unknown include specifier `" + tok.get_string() + "`. Did you mean to use `section`?"); } } } mfile = MappedFile(file, include_paths); } size_t file_number;// = push_file(filenames, mfile.name()); std::string test_name = "___ONCE_INCLUDE " + section + "?" + mfile.name(); if (Defined(section, test_name)){ currentData.push_back('\n'); return true; } //currentData += "#line 1 " + std::to_string(file_number) + "\n"; defines.push_back(§ions[currentSection].defines); Preprocessor p = Preprocessor(mfile, include_paths, defines, filenames, section); auto newSections = p.Preprocess(); auto& back = *defines.back(); defines.pop_back(); for (auto & def : back){ Define(def.first, def.second); } file_number = push_file(filenames, filedata.name()); currentData += newSections.at(section).data; currentData.push_back('\n'); currentData += "#line " + std::to_string(line_no) + " " + std::to_string(file_number) + "\n"; return true; }