diff options
author | Peter Harris <pharris@opentext.com> | 2011-01-12 17:44:09 -0500 |
---|---|---|
committer | Peter Harris <pharris@opentext.com> | 2011-01-12 17:44:09 -0500 |
commit | c7e5086931ff4138b7f346404c5778cc30ec72b8 (patch) | |
tree | 3d80e3c12fe934c2174704c8a2b532b8af8da30e | |
parent | ca0ff5ab223bafac68e53c5d20f7b312ccba3653 (diff) |
Quote command (like the C xlsclients)
-rw-r--r-- | xlsclients.go | 78 |
1 files changed, 75 insertions, 3 deletions
diff --git a/xlsclients.go b/xlsclients.go index a67e171..a3af291 100644 --- a/xlsclients.go +++ b/xlsclients.go @@ -5,6 +5,7 @@ import ( "flag" "fmt" "strings" + "unicode" "xgob" "xgob/util/atom" "xgob/xproto" @@ -53,6 +54,79 @@ func formatTextField(c *xgob.Connection, s string, t *xproto.GetPropertyReply) s return rv } +func quotedWord(buf *bytes.Buffer, word []byte, maxlen uint) uint { + quote := '\'' + otherQuote := '"' + var printed uint + + /* + * walk down seeing whether or not we need to quote + */ + needQuote := false + for _, c := range word { + if !(c < 0x80 && (unicode.IsLetter(int(c)) || unicode.IsDigit(int(c))) || + (c == '-' || c == '_' || c == '.' || c == '+' || + c == '/' || c == '=' || c == ':' || c == ',')) { + needQuote = true + break + } + } + + /* + * write out the string: if we hit a quote, then close any previous quote, + * emit the other quote, swap quotes and continue on. + */ + inQuote := needQuote + if needQuote { + buf.WriteRune(quote) + printed++ + } + for _, c := range word { + if int(c) == quote { + if inQuote { + buf.WriteRune(quote) + printed++ + } + buf.WriteRune(otherQuote) + printed++ + tmp := otherQuote + otherQuote = quote + quote = tmp + inQuote = true + } + buf.WriteRune(int(c)) + printed++ + if printed >= maxlen { break } + } + + /* close the quote if we opened one and if we printed the whole string */ + if inQuote && printed < maxlen { + buf.WriteRune(quote) + printed++ + } + + return printed +} + +func quotedWords(prop []byte) string { + buf := bytes.NewBufferString("") + + charsleft := *maxcmdlen + words := bytes.Split(prop, []byte{0}, -1) + for i, word := range words { + charsleft -= quotedWord(buf, word, charsleft) + if i < len(words)-1 { + if charsleft > 0 { + buf.WriteRune(' ') + } else { + break + } + } + } + + return buf.String() +} + func clientProperties(c *xgob.Connection, win xproto.Window, result chan string) { machineCookie := xproto.GetProperty(c, false, win, atom.Atom(c, "WM_CLIENT_MACHINE"), xproto.Atom(0), 0, 1000000) commandCookie := xproto.GetProperty(c, false, win, atom.Atom(c, "WM_COMMAND"), xproto.Atom(0), 0, 1000000) @@ -103,9 +177,7 @@ func clientProperties(c *xgob.Connection, win xproto.Window, result chan string) commandHeader = " Command: " } list = append(list, commandHeader) - - // TODO print_quoted_word - list = append(list, string(command.Value)) + list = append(list, quotedWords(command.Value)) list = append(list, "\n") // Trailer |