void V3PreProcImp::openFile(FileLine* fl, V3InFilter* filterp, const string& filename) { // Open a new file, possibly overriding the current one which is active. V3File::addSrcDepend(filename); // Read a list<string> with the whole file. StrList wholefile; bool ok = filterp->readWholefile(filename, wholefile/*ref*/); if (!ok) { error("File not found: "+filename+"\n"); return; } if (!m_preprocp->isEof()) { // IE not the first file. // We allow the same include file twice, because occasionally it pops // up, with guards preventing a real recursion. if (m_lexp->m_streampStack.size()>V3PreProc::INCLUDE_DEPTH_MAX) { error("Recursive inclusion of file: "+filename); return; } // There's already a file active. Push it to work on the new one. addLineComment(0); } // Create new stream structure m_lexp->scanNewFile(m_preprocp->fileline()->create(filename, 1)); addLineComment(1); // Enter // Filter all DOS CR's en-mass. This avoids bugs with lexing CRs in the wrong places. // This will also strip them from strings, but strings aren't supposed to be multi-line without a "\" for (StrList::iterator it=wholefile.begin(); it!=wholefile.end(); ++it) { // We don't end-loop at \0 as we allow and strip mid-string '\0's (for now). bool strip = false; const char* sp = it->data(); const char* ep = sp + it->length(); // Only process if needed, as saves extra string allocations for (const char* cp=sp; cp<ep; cp++) { if (VL_UNLIKELY(*cp == '\r' || *cp == '\0')) { strip = true; break; } } if (strip) { string out; out.reserve(it->length()); for (const char* cp=sp; cp<ep; cp++) { if (!(*cp == '\r' || *cp == '\0')) { out += *cp; } } *it = out; } // Push the data to an internal buffer. m_lexp->scanBytesBack(*it); // Reclaim memory; the push saved the string contents for us *it = ""; } }
bool preproc (FileLine* fl, const string& modname, V3InFilter* filterp, V3ParseImp* parsep, const string& errmsg) { // "" for no error debug(true); // Recheck if debug on - first check was before command line passed // Preprocess the given module, putting output in vppFilename UINFONL(1," Preprocessing "<<modname<<endl); // Preprocess s_filterp = filterp; bool ok = preprocOpen(fl, s_filterp, modname, errmsg); if (!ok) return false; while (!s_preprocp->isEof()) { string line = s_preprocp->getline(); V3Parse::ppPushText(parsep, line); } return true; }