Parse a single IRC protocol line per RFC 1459 grammar. Returns (prefix, command, params) or None on malformed input.
(line: str)
| 109 | |
| 110 | |
| 111 | def parse_irc_line(line: str) -> Optional[Tuple[str, str, List[str]]]: |
| 112 | """Parse a single IRC protocol line per RFC 1459 grammar. |
| 113 | |
| 114 | Returns (prefix, command, params) or None on malformed input. |
| 115 | """ |
| 116 | if not line: |
| 117 | return None |
| 118 | s = line.strip('\r\n') |
| 119 | if not s: |
| 120 | return None |
| 121 | prefix = '' |
| 122 | if s.startswith(':'): |
| 123 | space = s.find(' ') |
| 124 | if space < 0: |
| 125 | return None |
| 126 | prefix = s[1:space] |
| 127 | s = s[space + 1:] |
| 128 | # Trailing parameter starts at ' :' and grabs the rest verbatim. |
| 129 | trailing = None |
| 130 | if ' :' in s: |
| 131 | head, trailing = s.split(' :', 1) |
| 132 | else: |
| 133 | head = s |
| 134 | tokens = head.split() |
| 135 | if not tokens: |
| 136 | return None |
| 137 | command = tokens[0].upper() |
| 138 | params = tokens[1:] |
| 139 | if trailing is not None: |
| 140 | params.append(trailing) |
| 141 | return prefix, command, params |
| 142 | |
| 143 | |
| 144 | class IRCDPIParser: |