nfctool: Initial color support
authorSamuel Ortiz <sameo@linux.intel.com>
Thu, 2 May 2013 10:51:37 +0000 (12:51 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Thu, 2 May 2013 14:29:48 +0000 (16:29 +0200)
SNEP decoding is colored now, for a more readable output.

Makefile.am
tools/nfctool/display.c [new file with mode: 0644]
tools/nfctool/display.h [new file with mode: 0644]
tools/nfctool/nfctool.h
tools/nfctool/snep-decode.c

index fca5caf..67699be 100644 (file)
@@ -109,7 +109,9 @@ tools_nfctool_nfctool_SOURCES = tools/nfctool/main.c \
                                        tools/nfctool/llcp-decode.h \
                                        tools/nfctool/llcp-decode.c \
                                        tools/nfctool/snep-decode.h \
-                                       tools/nfctool/snep-decode.c
+                                       tools/nfctool/snep-decode.c \
+                                       tools/nfctool/display.h \
+                                       tools/nfctool/display.c
 
 tools_nfctool_nfctool_LDADD = @GLIB_LIBS@ @NETLINK_LIBS@
 
diff --git a/tools/nfctool/display.c b/tools/nfctool/display.c
new file mode 100644 (file)
index 0000000..773a003
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *
+ *  Near Field Communication nfctool
+ *
+ *  Copyright (C) 2011-2013  Intel Corporation
+ *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/prctl.h>
+#include <sys/ioctl.h>
+
+#include "display.h"
+
+static pid_t pager_pid = 0;
+
+bool use_color(void)
+{
+       static int cached_use_color = -1;
+
+       if (__builtin_expect(!!(cached_use_color < 0), 0))
+               cached_use_color = isatty(STDOUT_FILENO) > 0 || pager_pid > 0;
+
+       return cached_use_color;
+}
+
+int num_columns(void)
+{
+       static int cached_num_columns = -1;
+
+       if (__builtin_expect(!!(cached_num_columns < 0), 0)) {
+               struct winsize ws;
+
+               if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) < 0)
+                       return -1;
+
+               if (ws.ws_col > 0)
+                       cached_num_columns = ws.ws_col;
+       }
+
+       return cached_num_columns;
+}
diff --git a/tools/nfctool/display.h b/tools/nfctool/display.h
new file mode 100644 (file)
index 0000000..21722d8
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ *
+ *  Near Field Communication nfctool
+ *
+ *  Copyright (C) 2011-2013  Intel Corporation
+ *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <stdbool.h>
+
+bool use_color(void);
+
+#define COLOR_OFF      "\x1B[0m"
+#define COLOR_BLACK    "\x1B[0;30m"
+#define COLOR_RED      "\x1B[0;31m"
+#define COLOR_GREEN    "\x1B[0;32m"
+#define COLOR_YELLOW   "\x1B[0;33m"
+#define COLOR_BLUE     "\x1B[0;34m"
+#define COLOR_MAGENTA  "\x1B[0;35m"
+#define COLOR_CYAN     "\x1B[0;36m"
+#define COLOR_WHITE    "\x1B[0;37m"
+#define COLOR_WHITE_BG "\x1B[0;47m"
+#define COLOR_HIGHLIGHT        "\x1B[1;39m"
+
+#define COLOR_ERROR    "\x1B[1;31m"
+
+#define print_indent(indent, color, fmt, args...) \
+do { \
+       printf("%*c%s" fmt " %s\n", (indent), ' ', \
+               use_color() ? (color) : "", ## args, \
+               use_color() ? COLOR_OFF : ""); \
+} while (0)
+
+int num_columns(void);
index 1fcbbb9..1f9895b 100644 (file)
 #ifndef __NFCTOOL_H
 #define __NFCTOOL_H
 
+#include "display.h"
+
 #ifdef DEBUG
 #define DBG(fmt, ...) fprintf(stdout, "%s: " fmt "\n", __func__, ## __VA_ARGS__)
 #else
 #define DBG(fmt, ...)
 #endif
 
+#define SNEP_COLOR COLOR_YELLOW
+#define SNEP_HEADER_INDENT 4
+#define SNEP_MSG_INDENT    6
+
 #define print_error(fmt, ...) fprintf(stderr, fmt"\n", ## __VA_ARGS__)
 
 #define POLLING_MODE_INITIATOR 0x01
index 35a7d43..fbcc50e 100644 (file)
@@ -31,9 +31,6 @@
 #include "sniffer.h"
 #include "snep-decode.h"
 
-#define HEADER_INDENT  "    "
-#define MSG_INDENT     "      "
-
 #define SNEP_HEADER_LEN 6
 
 #define SNEP_REQUEST_CONTINUE  0x00
                snep_make_frag_index((p)->adapter_idx, (p)->direction, \
                                     (p)->llcp.local_sap, (p)->llcp.remote_sap)
 
-#define snep_printf(fmt, ...) printf(MSG_INDENT fmt, ## __VA_ARGS__)
+#define snep_printf_header(fmt, ...) print_indent(SNEP_HEADER_INDENT, \
+                                              SNEP_COLOR, fmt, ## __VA_ARGS__)
+
+#define snep_printf_msg(fmt, ...) print_indent(SNEP_MSG_INDENT, \
+                                              SNEP_COLOR, fmt, ## __VA_ARGS__)
 
 struct snep_frag {
        guint32 index;
@@ -107,10 +108,10 @@ static void snep_frag_rejected(struct sniffer_packet *packet)
 static int snep_frag_append(struct snep_frag *frag,
                            struct sniffer_packet *packet)
 {
-       snep_printf("Ongoing fragmented message\n");
+       snep_printf_msg("Ongoing fragmented message");
 
        if (frag->received + packet->llcp.data_len > frag->buffer_size) {
-               snep_printf("Too many bytes received\n");
+               snep_printf_msg("Too many bytes received\n");
                return -EINVAL;
        }
 
@@ -121,12 +122,12 @@ static int snep_frag_append(struct snep_frag *frag,
 
        frag->count++;
 
-       snep_printf("Received fragment #%hu of %u bytes (total %u/%u)\n",
+       snep_printf_msg("Received fragment #%hu of %u bytes (total %u/%u)\n",
                    frag->count, packet->llcp.data_len,
                    frag->received, frag->buffer_size);
 
        if (frag->received == frag->buffer_size) {
-               snep_printf("End of fragmented message\n");
+               snep_printf_msg("End of fragmented message\n");
 
                sniffer_print_hexdump(stdout, frag->buffer, frag->buffer_size,
                                      6, TRUE);
@@ -163,10 +164,10 @@ static int snep_decode_info(struct sniffer_packet *packet)
 
        frag->index = snep_get_frag_index(packet);
 
-       snep_printf("Start receiving fragmented message of %u bytes\n",
+       snep_printf_msg("Start receiving fragmented message of %u bytes\n",
                    frag->buffer_size);
 
-       snep_printf("Received fragment #%hu of %u bytes\n", frag->count,
+       snep_printf_msg("Received fragment #%hu of %u bytes\n", frag->count,
                    frag->received);
 
        DBG("Adding frag with index 0x%x", frag->index);
@@ -220,7 +221,7 @@ static int snep_decode_header(struct sniffer_packet *packet)
 
 static void snep_print_version(struct sniffer_packet *packet)
 {
-       snep_printf("Version: %d.%d\n", (packet->snep.version & 0xF0) >> 4,
+       snep_printf_msg("Version: %d.%d", (packet->snep.version & 0xF0) >> 4,
                    packet->snep.version & 0x0F);
 }
 
@@ -228,14 +229,14 @@ static void print_request(struct sniffer_packet *packet, gchar *msg)
 {
        snep_print_version(packet);
 
-       snep_printf("Request: %s\n", msg);
+       snep_printf_msg("Request: %s", msg);
 }
 
 static void snep_print_response(struct sniffer_packet *packet, gchar *msg)
 {
        snep_print_version(packet);
 
-       snep_printf("Response: %s\n", msg);
+       snep_printf_msg("Response: %s", msg);
 }
 
 int snep_print_pdu(struct sniffer_packet *packet)
@@ -244,7 +245,7 @@ int snep_print_pdu(struct sniffer_packet *packet)
        guint32 frag_index;
        struct snep_frag *frag;
 
-       printf(HEADER_INDENT "Simple NDEF Exchange Protocol (SNEP)\n");
+       snep_printf_header("Simple NDEF Exchange Protocol (SNEP)");
 
        frag_index = snep_get_frag_index(packet);
 
@@ -255,7 +256,7 @@ int snep_print_pdu(struct sniffer_packet *packet)
                err = snep_frag_append(frag, packet);
 
                if (err != 0) {
-                       snep_printf("Error receiving fragmented message\n");
+                       snep_printf_msg("Error receiving fragmented message\n");
 
                        snep_frag_delete(frag_index);
                }
@@ -265,7 +266,7 @@ int snep_print_pdu(struct sniffer_packet *packet)
 
        err = snep_decode_header(packet);
        if (err != 0) {
-               snep_printf("Error decoding message header\n");
+               snep_printf_msg("Error decoding message header\n");
 
                goto exit;
        }
@@ -283,7 +284,7 @@ int snep_print_pdu(struct sniffer_packet *packet)
                if (err != 0)
                        goto exit;
 
-               snep_printf("Acceptable length: %u\n",
+               snep_printf_msg("Acceptable length: %u\n",
                            packet->snep.acceptable_len);
 
                snep_decode_info(packet);
@@ -340,7 +341,7 @@ int snep_print_pdu(struct sniffer_packet *packet)
                break;
 
        default:
-               snep_printf("Invalid request or response code: %d\n",
+               snep_printf_msg("Invalid request or response code: %d\n",
                            packet->snep.rcode);
                break;
        }