Chromium Code Reviews| Index: src/gpu/gl/GrGLPrettyPrintSL.cpp |
| diff --git a/src/gpu/gl/GrGLPrettyPrintSL.cpp b/src/gpu/gl/GrGLPrettyPrintSL.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..db715e440eff55ff54be9f27a56d2c8a5cd1606e |
| --- /dev/null |
| +++ b/src/gpu/gl/GrGLPrettyPrintSL.cpp |
| @@ -0,0 +1,121 @@ |
| +#include "GrGLPrettyPrintSL.h" |
|
bsalomon
2014/08/01 13:37:06
Copyright
|
| +// This code is terrible. I'm sorry. It has to be fast in addition to being correct. |
| +// Please do not abuse this class. All it can do is dumbly format simple glsl. It also can |
| +// optionally add line numbers. I'm sure this will get confused with any really complex glsl stuff |
| + |
| +// rules: puts each '{' on its own line, indented properly, and matches the '}'. It expects |
| +// '//' comments and '#' to end with '\n', just as the glsl spec does. It can also accept /**/ |
| +// style comments. It knows about for loops also, that is the extent of its intellect. It ignores |
| +// tabs and newlines aside from the aformentioned cases, so its best to avoid 'cute' formatting |
| +// (ie, trying to align matrix parameters). Instead, make the glsl code look nice in Skia. |
| + |
| +// I toyed with the idea of making a true token based parser which would build an AST and could |
| +// more agressively format output, but this is all just a stop gap measure. |
| + |
| +// TODO in the longterm, completely revamp how we write shaders. We shouldn't be embedding strings |
| +// in source code, but instead should build a language into C++ using classes and overloaded |
| +// operators which would allow us to express gpu algorithms in C++ directly. |
| + |
| +namespace GrGLPrettyPrintSL { |
| + |
| +static void tab_skstring(SkString& s, int tabs) { |
| + for (int t = 0; t < tabs; t++) { |
| + s.append("\t"); |
| + } |
| +} |
| + |
| +size_t copy_to_newline(const SkString& input, const size_t length, size_t i, SkString& pretty) { |
| + while (length > i) { |
| + if ('\n' == input[i]) { |
| + break; |
| + } |
| + pretty.appendf("%c", input[i]); |
| + i++; |
| + } |
| + return i; |
| +} |
| + |
| +void line_numbering(SkString& pretty, bool countlines, int linecount, int tabs) { |
| + if (linecount != 1) { |
| + pretty.append("\n"); |
| + } |
| + if (countlines) { |
| + pretty.appendf("%4d\t", linecount); |
| + } |
| + tab_skstring(pretty, tabs); |
| +} |
| + |
| +SkString pretty_print_sl(const SkString& input, bool countlines) { |
| + SkString pretty; |
| + int linecount = 1; |
| + bool newline = false; |
| + // for loops mess us up, so don't touch semicolons in for loops |
| + int parensDepth = 0; |
| + int tabs = 0; |
| + size_t i = 0; |
| + const size_t length = input.size(); |
| + while (length > i) { |
| + // '//' comment or '#' |
| + if ('#' == input[i] || |
| + ('/' == input[i] && length > i + 1 && '/' == input[i + 1])) { |
| + line_numbering(pretty, countlines, linecount++, tabs); |
| + i = copy_to_newline(input, length, i, pretty); |
| + newline = true; |
| + } |
| + |
| + // /**/ comment |
| + if ('/' == input[i] && length > i + 1 && '*' == input[i + 1]) { |
| + line_numbering(pretty, countlines, linecount++, tabs); |
| + while (length > i) { |
| + pretty.appendf("%c", input[i]); |
| + if ('*' == input[i] && length > i + 1 && '/' == input[i + 1]) { |
| + // eat the slash |
| + i++; |
| + pretty.appendf("%c", input[i]); |
| + break; |
| + } |
| + i++; |
| + } |
| + newline = true; |
| + } |
| + |
| + if (length <= i) { |
| + break; |
| + } |
| + |
| + // ignore any pre-existing punctuation |
| + if ((newline && (' ' == input[i] || '\t' == input[i] || '\n' == input[i])) |
| + ||'\n' == input[i] || '\t' == input[i]) { |
| + i++; |
| + continue; |
| + } else if ('{' == input[i]) { |
| + line_numbering(pretty, countlines, linecount++, tabs); |
| + pretty.append("{"); |
| + tabs++; |
| + newline = true; |
| + } else if ('}' == input[i]) { |
| + tabs--; |
| + line_numbering(pretty, countlines, linecount++, tabs); |
| + pretty.append("}"); |
| + newline = true; |
| + } else if (!parensDepth && ';' == input[i]) { |
| + pretty.append(";"); |
| + newline = true; |
| + } else { |
| + if (newline) { |
| + line_numbering(pretty, countlines, linecount++, tabs); |
| + newline = false; |
| + } |
| + if ('(' == input[i]) { |
| + parensDepth++; |
| + } else if (')' == input[i]) { |
| + parensDepth--; |
| + } |
| + pretty.appendf("%c", input[i]); |
| + } |
| + i++; |
| + } |
| + return pretty; |
| +} |
| + |
| +} // end namespace |