OLD | NEW |
---|---|
(Empty) | |
1 #include "GrGLPrettyPrintSL.h" | |
bsalomon
2014/08/01 13:37:06
Copyright
| |
2 // This code is terrible. I'm sorry. It has to be fast in addition to being co rrect. | |
3 // Please do not abuse this class. All it can do is dumbly format simple glsl. It also can | |
4 // optionally add line numbers. I'm sure this will get confused with any really complex glsl stuff | |
5 | |
6 // rules: puts each '{' on its own line, indented properly, and matches the '}'. It expects | |
7 // '//' comments and '#' to end with '\n', just as the glsl spec does. It can a lso accept /**/ | |
8 // style comments. It knows about for loops also, that is the extent of its int ellect. It ignores | |
9 // tabs and newlines aside from the aformentioned cases, so its best to avoid 'c ute' formatting | |
10 // (ie, trying to align matrix parameters). Instead, make the glsl code look ni ce in Skia. | |
11 | |
12 // I toyed with the idea of making a true token based parser which would build a n AST and could | |
13 // more agressively format output, but this is all just a stop gap measure. | |
14 | |
15 // TODO in the longterm, completely revamp how we write shaders. We shouldn't b e embedding strings | |
16 // in source code, but instead should build a language into C++ using classes an d overloaded | |
17 // operators which would allow us to express gpu algorithms in C++ directly. | |
18 | |
19 namespace GrGLPrettyPrintSL { | |
20 | |
21 static void tab_skstring(SkString& s, int tabs) { | |
22 for (int t = 0; t < tabs; t++) { | |
23 s.append("\t"); | |
24 } | |
25 } | |
26 | |
27 size_t copy_to_newline(const SkString& input, const size_t length, size_t i, SkS tring& pretty) { | |
28 while (length > i) { | |
29 if ('\n' == input[i]) { | |
30 break; | |
31 } | |
32 pretty.appendf("%c", input[i]); | |
33 i++; | |
34 } | |
35 return i; | |
36 } | |
37 | |
38 void line_numbering(SkString& pretty, bool countlines, int linecount, int tabs) { | |
39 if (linecount != 1) { | |
40 pretty.append("\n"); | |
41 } | |
42 if (countlines) { | |
43 pretty.appendf("%4d\t", linecount); | |
44 } | |
45 tab_skstring(pretty, tabs); | |
46 } | |
47 | |
48 SkString pretty_print_sl(const SkString& input, bool countlines) { | |
49 SkString pretty; | |
50 int linecount = 1; | |
51 bool newline = false; | |
52 // for loops mess us up, so don't touch semicolons in for loops | |
53 int parensDepth = 0; | |
54 int tabs = 0; | |
55 size_t i = 0; | |
56 const size_t length = input.size(); | |
57 while (length > i) { | |
58 // '//' comment or '#' | |
59 if ('#' == input[i] || | |
60 ('/' == input[i] && length > i + 1 && '/' == input[i + 1])) { | |
61 line_numbering(pretty, countlines, linecount++, tabs); | |
62 i = copy_to_newline(input, length, i, pretty); | |
63 newline = true; | |
64 } | |
65 | |
66 // /**/ comment | |
67 if ('/' == input[i] && length > i + 1 && '*' == input[i + 1]) { | |
68 line_numbering(pretty, countlines, linecount++, tabs); | |
69 while (length > i) { | |
70 pretty.appendf("%c", input[i]); | |
71 if ('*' == input[i] && length > i + 1 && '/' == input[i + 1]) { | |
72 // eat the slash | |
73 i++; | |
74 pretty.appendf("%c", input[i]); | |
75 break; | |
76 } | |
77 i++; | |
78 } | |
79 newline = true; | |
80 } | |
81 | |
82 if (length <= i) { | |
83 break; | |
84 } | |
85 | |
86 // ignore any pre-existing punctuation | |
87 if ((newline && (' ' == input[i] || '\t' == input[i] || '\n' == input[i] )) | |
88 ||'\n' == input[i] || '\t' == input[i]) { | |
89 i++; | |
90 continue; | |
91 } else if ('{' == input[i]) { | |
92 line_numbering(pretty, countlines, linecount++, tabs); | |
93 pretty.append("{"); | |
94 tabs++; | |
95 newline = true; | |
96 } else if ('}' == input[i]) { | |
97 tabs--; | |
98 line_numbering(pretty, countlines, linecount++, tabs); | |
99 pretty.append("}"); | |
100 newline = true; | |
101 } else if (!parensDepth && ';' == input[i]) { | |
102 pretty.append(";"); | |
103 newline = true; | |
104 } else { | |
105 if (newline) { | |
106 line_numbering(pretty, countlines, linecount++, tabs); | |
107 newline = false; | |
108 } | |
109 if ('(' == input[i]) { | |
110 parensDepth++; | |
111 } else if (')' == input[i]) { | |
112 parensDepth--; | |
113 } | |
114 pretty.appendf("%c", input[i]); | |
115 } | |
116 i++; | |
117 } | |
118 return pretty; | |
119 } | |
120 | |
121 } // end namespace | |
OLD | NEW |