bash - format_print.go
1 package bash
2
3 import "io"
4
5 func (a ArithmeticExpansion) printSource(w io.Writer, v bool) {
6 io.WriteString(w, "$((")
7
8 if len(a.WordsAndOperators) > 0 {
9 if v {
10 io.WriteString(w, " ")
11 }
12
13 a.WordsAndOperators[0].printSource(w, v)
14
15 for _, wo := range a.WordsAndOperators[1:] {
16 if v {
17 io.WriteString(w, " ")
18 }
19
20 wo.printSource(w, v)
21 }
22
23 if v {
24 io.WriteString(w, " ")
25 }
26 }
27
28 io.WriteString(w, "))")
29 }
30
31 func (a Assignment) printSource(w io.Writer, v bool) {
32 if a.Assignment != AssignmentAssign && a.Assignment != AssignmentAppend {
33 return
34 }
35
36 a.Identifier.printSource(w, v)
37 a.Assignment.printSource(w, v)
38 a.Value.printSource(w, v)
39 }
40
41 func (c CaseCompound) printSource(w io.Writer, v bool) {}
42
43 func (c Command) printSource(w io.Writer, v bool) {
44 if len(c.Vars) > 0 {
45 c.Vars[0].printSource(w, v)
46
47 for _, vr := range c.Vars[1:] {
48 io.WriteString(w, " ")
49 vr.printSource(w, v)
50 }
51 }
52
53 if len(c.Words) > 0 {
54 if len(c.Vars) > 0 {
55 io.WriteString(w, " ")
56 }
57
58 c.Words[0].printSource(w, v)
59
60 for _, wd := range c.Words[1:] {
61 io.WriteString(w, " ")
62 wd.printSource(w, v)
63 }
64 }
65
66 if len(c.Redirections) > 0 {
67 if len(c.Vars) > 0 || len(c.Words) > 0 {
68 io.WriteString(w, " ")
69 }
70
71 c.Redirections[0].printSource(w, v)
72
73 for _, r := range c.Redirections[1:] {
74 r.printSource(w, v)
75 }
76 }
77 }
78
79 func (c Command) printHeredoc(w io.Writer, v bool) {
80 for _, r := range c.Redirections {
81 r.printHeredoc(w, v)
82 }
83 }
84
85 func (c CommandOrCompound) printSource(w io.Writer, v bool) {}
86
87 func (c CommandOrCompound) printHeredoc(w io.Writer, v bool) {
88 if c.Command != nil {
89 c.Command.printHeredoc(w, v)
90 } else if c.Compound != nil {
91 c.Compound.printHeredoc(w, v)
92 }
93 }
94
95 func (c CommandSubstitution) printSource(w io.Writer, v bool) {
96 io.WriteString(w, "$(")
97 c.Command.printSource(w, v)
98 io.WriteString(w, ")")
99 }
100
101 func (c Compound) printSource(w io.Writer, v bool) {}
102
103 func (c Compound) printHeredoc(w io.Writer, v bool) {}
104
105 func (f File) printSource(w io.Writer, v bool) {
106 if len(f.Lines) > 0 {
107 f.Lines[0].printSource(w, v)
108
109 for _, l := range f.Lines[1:] {
110 io.WriteString(w, "\n")
111 l.printSource(w, v)
112 }
113 }
114 }
115
116 func (f ForCompound) printSource(w io.Writer, v bool) {}
117
118 func (g GroupingCompound) printSource(w io.Writer, v bool) {}
119
120 func (h Heredoc) printSource(w io.Writer, v bool) {
121 for _, p := range h.HeredocPartsOrWords {
122 p.printSource(w, v)
123 }
124 }
125
126 func (h HeredocPartOrWord) printSource(w io.Writer, v bool) {
127 if h.HeredocPart != nil {
128 io.WriteString(w, h.HeredocPart.Data)
129 } else if h.Word != nil {
130 h.Word.printSource(w, v)
131 }
132 }
133
134 func (i IfCompound) printSource(w io.Writer, v bool) {
135 io.WriteString(w, "if ")
136 i.If.printSource(w, v)
137
138 for _, e := range i.ElIf {
139 io.WriteString(w, "\nelif ")
140 e.printSource(w, v)
141 }
142
143 if i.Else != nil {
144 ip := indentPrinter{Writer: w}
145
146 io.WriteString(w, "\nelse")
147 io.WriteString(&ip, "\n")
148 i.Else.printSource(&ip, v)
149 }
150
151 io.WriteString(w, "fi")
152 }
153
154 func (l Line) printSource(w io.Writer, v bool) {
155 if len(l.Statements) > 0 {
156 l.Statements[0].printSource(w, v)
157
158 for _, s := range l.Statements[1:] {
159 io.WriteString(w, " ")
160 s.printSource(w, v)
161 }
162
163 for _, s := range l.Statements {
164 s.printHeredoc(w, v)
165 }
166 }
167 }
168
169 func (l LoopCompound) printSource(w io.Writer, v bool) {}
170
171 func (p ParameterAssign) printSource(w io.Writer, v bool) {
172 if p.Identifier != nil {
173 io.WriteString(w, p.Identifier.Data)
174
175 if p.Subscript != nil {
176 io.WriteString(w, "[")
177 p.Subscript.printSource(w, v)
178 io.WriteString(w, "]")
179 }
180 }
181 }
182
183 func (p ParameterExpansion) printSource(w io.Writer, v bool) {
184 io.WriteString(w, "${")
185
186 if p.Indirect {
187 io.WriteString(w, "!")
188 } else if p.Type == ParameterLength {
189 io.WriteString(w, "#")
190 }
191
192 p.Parameter.printSource(w, v)
193
194 if p.Word != nil {
195 switch p.Type {
196 case ParameterSubstitution:
197 io.WriteString(w, ":=")
198 p.Word.printSource(w, v)
199 case ParameterAssignment:
200 io.WriteString(w, ":?")
201 p.Word.printSource(w, v)
202 case ParameterMessage:
203 io.WriteString(w, ":+")
204 p.Word.printSource(w, v)
205 case ParameterSetAssign:
206 io.WriteString(w, ":-")
207 p.Word.printSource(w, v)
208 case ParameterRemoveStartShortest:
209 io.WriteString(w, "#")
210 p.Word.printSource(w, v)
211 case ParameterRemoveStartLongest:
212 io.WriteString(w, "##")
213 p.Word.printSource(w, v)
214 case ParameterRemoveEndShortest:
215 io.WriteString(w, "%")
216 p.Word.printSource(w, v)
217 case ParameterRemoveEndLongest:
218 io.WriteString(w, "%%")
219 p.Word.printSource(w, v)
220 }
221 } else if p.Pattern != nil {
222 isReplacement := false
223
224 switch p.Type {
225 case ParameterReplace:
226 isReplacement = true
227
228 io.WriteString(w, "/")
229 io.WriteString(w, p.Pattern.Data)
230 case ParameterReplaceAll:
231 isReplacement = true
232
233 io.WriteString(w, "//")
234 io.WriteString(w, p.Pattern.Data)
235 case ParameterReplaceStart:
236 isReplacement = true
237
238 io.WriteString(w, "/#")
239 io.WriteString(w, p.Pattern.Data)
240 case ParameterReplaceEnd:
241 isReplacement = true
242
243 io.WriteString(w, "/%")
244 io.WriteString(w, p.Pattern.Data)
245 case ParameterLowercaseFirstMatch:
246 io.WriteString(w, "^")
247 io.WriteString(w, p.Pattern.Data)
248 case ParameterLowercaseAllMatches:
249 io.WriteString(w, "^^")
250 io.WriteString(w, p.Pattern.Data)
251 case ParameterUppercaseFirstMatch:
252 io.WriteString(w, ",")
253 io.WriteString(w, p.Pattern.Data)
254 case ParameterUppercaseAllMatches:
255 io.WriteString(w, ",,")
256 io.WriteString(w, p.Pattern.Data)
257 }
258
259 if isReplacement && p.String != nil {
260 io.WriteString(w, "/")
261 p.String.printSource(w, v)
262 }
263 } else if !p.Indirect {
264 switch p.Type {
265 case ParameterPrefix:
266 io.WriteString(w, "*")
267 case ParameterPrefixSeperate:
268 io.WriteString(w, "@")
269 }
270 } else {
271 switch p.Type {
272 case ParameterSubstring:
273 if p.SubstringStart != nil {
274 io.WriteString(w, ":")
275 io.WriteString(w, p.SubstringStart.Data)
276
277 if p.SubstringEnd != nil {
278 io.WriteString(w, ":")
279 io.WriteString(w, p.SubstringEnd.Data)
280 }
281 }
282 case ParameterUppercase:
283 io.WriteString(w, "@U")
284 case ParameterUppercaseFirst:
285 io.WriteString(w, "@u")
286 case ParameterLowercase:
287 io.WriteString(w, "@L")
288 case ParameterQuoted:
289 io.WriteString(w, "@Q")
290 case ParameterEscaped:
291 io.WriteString(w, "@E")
292 case ParameterPrompt:
293 io.WriteString(w, "@P")
294 case ParameterDeclare:
295 io.WriteString(w, "@A")
296 case ParameterQuotedArrays:
297 io.WriteString(w, "@K")
298 case ParameterQuotedArraysSeperate:
299 io.WriteString(w, "@a")
300 case ParameterAttributes:
301 io.WriteString(w, "@k")
302 }
303 }
304
305 io.WriteString(w, "}")
306 }
307
308 func (p Parameter) printSource(w io.Writer, v bool) {
309 if p.Parameter != nil {
310 io.WriteString(w, p.Parameter.Data)
311
312 if p.Array != nil {
313 io.WriteString(w, "[")
314 p.Array.printSource(w, v)
315 io.WriteString(w, "]")
316 }
317 }
318 }
319
320 func (p Pattern) printSource(w io.Writer, v bool) {}
321
322 func (p PatternLines) printSource(w io.Writer, v bool) {}
323
324 func (p Pipeline) printSource(w io.Writer, v bool) {
325 p.PipelineTime.printSource(w, v)
326
327 if p.Not {
328 io.WriteString(w, "! ")
329 }
330
331 p.CommandOrCompound.printSource(w, v)
332
333 if p.Pipeline != nil {
334 io.WriteString(w, " | ")
335 p.Pipeline.printSource(w, v)
336 }
337 }
338
339 func (p Pipeline) printHeredoc(w io.Writer, v bool) {
340 p.CommandOrCompound.printHeredoc(w, v)
341
342 if p.Pipeline != nil {
343 p.printHeredoc(w, v)
344 }
345 }
346
347 func (r Redirection) printSource(w io.Writer, v bool) {
348 if r.Redirector == nil {
349 return
350 }
351
352 if r.Input != nil {
353 io.WriteString(w, r.Input.Data)
354 }
355
356 io.WriteString(w, r.Redirector.Data)
357 r.Output.printSource(w, v)
358 }
359
360 func (r Redirection) printHeredoc(w io.Writer, v bool) {
361 if r.Redirector != nil && r.Heredoc != nil && (r.Redirector.Data == "<<" || r.Redirector.Data == "<<-") {
362 if r.Redirector.Data == "<<" {
363 w = unwrapIndentPrinter(w)
364 }
365
366 r.Heredoc.printSource(w, v)
367 r.Output.printSource(w, v)
368 }
369 }
370
371 func (s SelectCompound) printSource(w io.Writer, v bool) {}
372
373 func (s Statement) printSource(w io.Writer, v bool) {
374 s.Pipeline.printSource(w, v)
375
376 if (s.LogicalOperator == LogicalOperatorAnd || s.LogicalOperator == LogicalOperatorOr) && s.Statement != nil {
377 s.LogicalOperator.printSource(w, v)
378 s.Statement.printSource(w, v)
379 }
380
381 if s.JobControl == JobControlBackground {
382 if v {
383 io.WriteString(w, " &")
384 } else {
385 io.WriteString(w, "&")
386 }
387 } else {
388 io.WriteString(w, ";")
389 }
390 }
391
392 func (s Statement) printHeredoc(w io.Writer, v bool) {
393 s.Pipeline.printHeredoc(w, v)
394
395 if s.Statement != nil {
396 s.Statement.printHeredoc(w, v)
397 }
398 }
399
400 func (s String) printSource(w io.Writer, v bool) {
401 for _, p := range s.WordsOrTokens {
402 p.printSource(w, v)
403 }
404 }
405
406 func (t TestCompound) printSource(w io.Writer, v bool) {}
407
408 func (t TestConsequence) printSource(w io.Writer, v bool) {
409 t.Test.printSource(w, v)
410 io.WriteString(w, " then\n")
411
412 ip := indentPrinter{Writer: w}
413
414 t.Consequence.printSource(&ip, v)
415 }
416
417 func (ve Value) printSource(w io.Writer, v bool) {
418 if ve.Word != nil {
419 ve.printSource(w, v)
420 } else if ve.Array != nil {
421 if len(ve.Array) == 0 {
422 io.WriteString(w, "()")
423 } else {
424
425 if v {
426 io.WriteString(w, "( ")
427 } else {
428 io.WriteString(w, "(")
429 }
430
431 ve.Array[0].printSource(w, v)
432
433 for _, word := range ve.Array[1:] {
434 io.WriteString(w, " ")
435 word.printSource(w, v)
436 }
437
438 if v {
439 io.WriteString(w, " )")
440 } else {
441 io.WriteString(w, ")")
442 }
443 }
444 }
445 }
446
447 func (wo WordOrOperator) printSource(w io.Writer, v bool) {
448 if wo.Operator != nil {
449 io.WriteString(w, wo.Operator.Data)
450 } else if wo.Word != nil {
451 wo.Word.printSource(w, v)
452 }
453 }
454
455 func (wt WordOrToken) printSource(w io.Writer, v bool) {
456 if wt.Word != nil {
457 wt.Word.printSource(w, v)
458 } else if wt.Token != nil {
459 io.WriteString(w, wt.Token.Data)
460 }
461 }
462
463 func (wp WordPart) printSource(w io.Writer, v bool) {
464 if wp.Part != nil {
465 io.WriteString(w, wp.Part.Data)
466 } else if wp.ArithmeticExpansion != nil {
467 wp.ArithmeticExpansion.printSource(w, v)
468 } else if wp.CommandSubstitution != nil {
469 wp.CommandSubstitution.printSource(w, v)
470 } else if wp.ParameterExpansion != nil {
471 wp.ParameterExpansion.printSource(w, v)
472 }
473 }
474
475 func (wd Word) printSource(w io.Writer, v bool) {
476 for _, word := range wd.Parts {
477 word.printSource(w, v)
478 }
479 }
480