summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Harris <pharris@opentext.com>2011-01-12 17:44:09 -0500
committerPeter Harris <pharris@opentext.com>2011-01-12 17:44:09 -0500
commitc7e5086931ff4138b7f346404c5778cc30ec72b8 (patch)
tree3d80e3c12fe934c2174704c8a2b532b8af8da30e
parentca0ff5ab223bafac68e53c5d20f7b312ccba3653 (diff)
Quote command (like the C xlsclients)
-rw-r--r--xlsclients.go78
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