namespace Tmate { [SingleInstance] // *INDENT-OFF* class Stdout : Object { public enum TokenType { SOCKET, ADDRESS, MATES, EMPTY, COMMENT, RESTART, INIT, TERM, UNKNOWN, ERROR; public string to_string() { return EnumClass.to_string(typeof(TokenType), this) .replace("TMATE_STDOUT_TOKEN_TYPE_", "Tmate.Stdout.TokenType."); } } public class Token { public TokenType @class {get; private set;} public string[] list {get; private set;} public Token(string[] list, TokenType @class = UNKNOWN) { this.class = @class; this.list = list; } public string to_string() { if (this.list.length == 0) return "<%s>".printf(this.@class.to_string()); else if(this.list.length == 1) return "<%s {\"%s\"}>".printf( this.@class.to_string(), this.list[0]); else return "<%s {\n\t\"%s\"\n}>".printf( this.@class.to_string(), string.joinv("\",\n\t\"", this.list)); } } private Regex r_connect = /^Connecting to (.+)\.\.\.$/; private Regex r_socket = /^To connect.+ tmate -S (.+) attach$/; private Regex r_mates = /^.+ (joined|left) \(([^()]+)\) -- (\d+) clients? .+$/; private Regex r_closed = /^Session closed$/; private Regex r_restarted = /^Session shell restarted$/; private Regex r_comment = /^(Note: |Reconnecting)/; private Regex r_dnsfail = /^(?P[^ ]+ lookup failure\.).+ \((non-recoverable )?(?P.+)\)$/; private Regex r_netfail = /^(?PError [^:]+)[:] [^:]+[:] (?P.+)$/; private Regex r_address = /^(ssh|web) \w+ ?(|read only)[:](?:|.+) ([^ ]+)$/; private MatchInfo info; public Token parse(string input) { var line = input.strip(); if(line == "") return new Token({}, EMPTY); else if(r_mates.match(line, 0, out info)) return new Token({ info.fetch(1), // joined | left info.fetch(2), // mate ip/domain info.fetch(3) // active mates }, MATES); else if(r_dnsfail.match(line, 0, out info) || r_netfail.match(line, 0, out info)) return new Token({ info.fetch_named("summery"), info.fetch_named("body"), }, ERROR); else if(r_comment.match(line)) return new Token({line}, COMMENT); else if(r_restarted.match(line)) return new Token({}, RESTART); else if(r_address.match(line, 0, out info)) return new Token({ info.fetch(1), // web | ssh info.fetch(2), // read only? info.fetch(3) // address }, ADDRESS); else if(r_socket.match(line, 0, out info)) return new Token({ info.fetch(1) }, SOCKET); else if(r_closed.match(line)) return new Token({}, TERM); else if(r_connect.match(line, 0, out info)) return new Token({ info.fetch(1) }, INIT); return new Token({line}); } } }