X-Git-Url: https://git.saurik.com/cycript.git/blobdiff_plain/2e2ed904884fa1dc0a0670364d44cdc3dc9a0775..82a02edec66cecb6ab494865736e5d75519b81db:/Highlight.cpp diff --git a/Highlight.cpp b/Highlight.cpp new file mode 100644 index 0000000..371722e --- /dev/null +++ b/Highlight.cpp @@ -0,0 +1,93 @@ +/* Cycript - Optimizing JavaScript Compiler/Runtime + * Copyright (C) 2009-2012 Jay Freeman (saurik) +*/ + +/* GNU Lesser General Public License, Version 3 {{{ */ +/* + * Cycript is free software: you can redistribute it and/or modify it under + * the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Cycript is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Cycript. If not, see . +**/ +/* }}} */ + +#include "Highlight.hpp" + +#include "Cycript.tab.hh" +#include "Parser.hpp" + +static void Skip(const char *data, size_t size, std::ostream &output, size_t &offset, cy::position ¤t, cy::position target) { + while (current.line != target.line || current.column != target.column) { + _assert(offset != size); + char next(data[offset++]); + + output.put(next); + + _assert(current.line < target.line || current.line == target.line && current.column < target.column); + if (next == '\n') + current.lines(); + else + current.columns(); + } +} + +struct CYColor { + bool bold_; + unsigned code_; + + CYColor() { + } + + CYColor(bool bold, unsigned code) : + bold_(bold), + code_(code) + { + } +}; + +void CYLexerHighlight(const char *data, size_t size, std::ostream &output) { + CYStream stream(data, data + size); + CYDriver driver(stream); + + size_t offset(0); + cy::position current; + + CYLocalPool pool; + + YYSTYPE value; + cy::location location; + + while (cylex(&value, &location, driver.scanner_) != 0) { + CYColor color; + + switch (value.highlight_) { + case hi::Comment: color = CYColor(true, 30); break; + case hi::Constant: color = CYColor(false, 31); break; + case hi::Control: color = CYColor(false, 33); break; + case hi::Escape: color = CYColor(true, 31); break; + case hi::Identifier: color = CYColor(false, 0); break; + case hi::Meta: color = CYColor(false, 32); break; + case hi::Nothing: color = CYColor(false, 0); break; + case hi::Operator: color = CYColor(false, 36); break; + case hi::Structure: color = CYColor(true, 34); break; + case hi::Type: color = CYColor(true, 34); break; + } + + Skip(data, size, output, offset, current, location.begin); + if (color.code_ != 0) + output << "\e[" << (color.bold_ ? '1' : '0') << ";" << color.code_ << "m"; + Skip(data, size, output, offset, current, location.end); + if (color.code_ != 0) + output << "\e[0m"; + } + + output.write(data + offset, size - offset); +}