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 |