~launchpad-results/launchpad-results/trunk

« back to all changes in this revision

Viewing changes to lib/lpresults/xunit/parsers/ansi.py

  • Committer: Marc Tardif
  • Date: 2012-03-21 22:32:04 UTC
  • Revision ID: marc.tardif@canonical.com-20120321223204-8g7mvzzwmh8ifbrt
Added support for getting systems from a person (LP #899361)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2010-2011 Canonical Ltd.  This software is licensed under the
 
2
# GNU Affero General Public License version 3 (see the file LICENSE).
 
3
 
 
4
__metaclass__ = type
 
5
 
 
6
__all__ = [
 
7
    "AnsiParser",
 
8
    ]
 
9
 
 
10
 
 
11
# BS, HT, LF, CR, FF, ESC
 
12
VALID_ANSI_PATTERN = r"\x08\x09\x0A\x0C\x0D\x1B"
 
13
 
 
14
 
 
15
class AnsiResult:
 
16
 
 
17
    text = None
 
18
 
 
19
    def setText(self, text):
 
20
        self.text = text
 
21
 
 
22
 
 
23
class AnsiParser:
 
24
    """Parser for ansi text."""
 
25
 
 
26
    def __init__(self, stream):
 
27
        self.stream = stream
 
28
 
 
29
    def __str__(self):
 
30
        result = AnsiResult()
 
31
        self.run(result)
 
32
        return result.text
 
33
 
 
34
    def run(self, result):
 
35
        text = [""]
 
36
        row = -1
 
37
        col = 0
 
38
        escape = ""
 
39
        saved = [0, 0]
 
40
 
 
41
        ansi = self.stream.read()
 
42
        for ch in ansi:
 
43
            if ord(ch) == 0x1B or len(escape) > 0:
 
44
                # On ESC
 
45
                if chr(0x1B) in [escape, ch]:
 
46
                    escape = ""
 
47
                    if ch == "c":
 
48
                        text = [""]
 
49
                        row = -1
 
50
                        col = 0
 
51
                        saved = [0, 0]
 
52
                    elif ch == "D":
 
53
                        row += 1
 
54
                        if row == 0:
 
55
                            row = -1
 
56
                            text.append("")
 
57
                    elif ch == "M":
 
58
                        row -= 1
 
59
                        if row < -len(text):
 
60
                            text = [""] + text
 
61
                    elif ch == "7":
 
62
                        saved = [row + len(text), col]
 
63
                    elif ch == "8":
 
64
                        [row, col] = saved
 
65
                        row -= len(text)
 
66
                    elif ord(ch) in [0x1B, 0x5B]:
 
67
                        escape = ch
 
68
                    continue
 
69
                # Just after hitting the extended ESC marker
 
70
                elif escape == "[":
 
71
                    escape = ""
 
72
 
 
73
                if ch in "0123456789;":
 
74
                    escape += ch
 
75
                    continue
 
76
                elif ch in "Hf":
 
77
                    opts = escape.split(";") + ["", ""]
 
78
                    row = -len(text) + max(0, int("0" + opts[0]) - 1)
 
79
                    col = max(0, int("0" + opts[1]) - 1)
 
80
                elif ch in "s":
 
81
                    saved = [row + len(text), col]
 
82
                elif ch in "u":
 
83
                    [row, col] = saved
 
84
                    row -= len(text)
 
85
                elif ch in "K":
 
86
                    if escape == "1":
 
87
                        text[row] = " " * (col + 1) + text[row][col + 1:]
 
88
                    elif escape == "2":
 
89
                        text[row] = ""
 
90
                    else:
 
91
                        text[row] = text[row][:col]
 
92
                elif ch in "J":
 
93
                    if len(escape) == 0:
 
94
                        text = text[:row] + [""]
 
95
                    else:
 
96
                        for i in range(row + len(text) + 1):
 
97
                            text[i] = ""
 
98
                elif ch in "A":
 
99
                    row -= max(1, int("0" + escape.split(";")[0]))
 
100
                    if row <= len(text):
 
101
                        row = -len(text)
 
102
                elif ch in "B":
 
103
                    row += max(1, int("0" + escape.split(";")[0]))
 
104
                    while row >= 0:
 
105
                        text.append("")
 
106
                        row -= 1
 
107
                elif ch in "C":
 
108
                    col += max(1, int("0" + escape.split(";")[0]))
 
109
                elif ch in "D":
 
110
                    col = max(0, col - max(1, int("0" + escape.split(";")[0])))
 
111
 
 
112
                escape = ""
 
113
                continue
 
114
 
 
115
            # Control char
 
116
            if ch in "\r\n\f\t\b":
 
117
                if ch == "\r":
 
118
                    col = 0
 
119
                elif ch in "\n\f":
 
120
                    row += 1
 
121
                    if row == 0:
 
122
                        row = -1
 
123
                        text.append("")
 
124
                    col = 0
 
125
                elif ch == "\t":
 
126
                    col = (col + 8) & ~7
 
127
                elif ch == "\b":
 
128
                    col = max(0, col - 1)
 
129
                continue
 
130
 
 
131
            if len(text[row]) < col:
 
132
                text[row] += " " * (col - len(text[row]))
 
133
            text[row] = text[row][:col] + ch + text[row][col + 1:]
 
134
            col += 1
 
135
 
 
136
        result.setText("\n".join(text))
 
137
        return result