// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // LineStream.cc -- Modified stream that inserts line directives into output. // // Author : Andrew Beach // Created On : Thr May 4 13:15:00 2017 // Last Modified By : Andrew Beach // Last Modified On : Fri May 5 14:29:00 2017 // Update Count : 0 // #include "LineStream.h" namespace CodeGen { LineStream::LineStream(std::ostream & baseStream, bool insertLines) : baseStream(baseStream), insertLines(insertLines) {} void LineStream::printLineDirective(CodeLocation const & location) { baseStream << "\n# " << location.linenumber; if (std::string("") != location.filename) { baseStream << " \"" << location.filename << '"'; } baseStream << '\n'; } bool LineStream::actualDiffersFromExpected() const { return actualLocation.isSet() && // actualLocation & expectedLocation must match at the line. (actualLocation.linenumber != expectedLocation.linenumber || actualLocation.filename != expectedLocation.filename); } void LineStream::emptyBuffer(bool addNewline) { if (actualDiffersFromExpected()) { printLineDirective(actualLocation); expectedLocation = actualLocation; } actualLocation.unset(); if (addNewLine) { expectedLocation.linenumber += 1; buffer.put('\n'); } baseStream << buffer.str() << std::flush; buffer.str(""); } void LineStream::setLoc(CodeLocation const & location) { if (insertLines) { if (expectedLocation.isUnset()) { expectedLocation = actualLocation = location; } else if (actualLocation.isUnset()) { actualLocation = location; } else if (actualLocation.filename != location.filename) { emptyBuffer(true); actualLocation = location; } else if (location.linenumber <= actualLocation.linenumber){ actualLocation.linenumber = location.linenumber; } } } LineStream & LineStream::operator<<(char const * str) { buffer << str; return *this; } LineStream & LineStream::operator<<(std::string const & str) { buffer << str; return *this; } LineStream & LineStream::operator<<(StreamFlag flag) { static StringFlag const endlCopy = std::endl; if (!insertLines) { baseStream << flag; } else if (endlCopy == flag) { emptyBuffer(true); } else { buffer << flag; } return *this; } LineStream & LineStream::flush() { if (insertLines) { emptyBuffer(false); } else { baseStream.flush(); } return *this; } } // CodeGen