refactor: unify into one file per program - ploot - simple plotting tools
(HTM) git clone git://bitreich.org/ploot git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/ploot
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
(DIR) LICENSE
---
(DIR) commit ecbd21a496446ea895412dc2c98c803173828520
(DIR) parent c385adf172be43bfa1d8e0d2e5fcd6bc8ea2477d
(HTM) Author: Josuah Demangeon <mail@josuah.net>
Date: Tue, 12 Jun 2018 02:24:39 +0200
refactor: unify into one file per program
rename programs ploot* into ploot-* to build a toolset reading the
same format with eventually a REPL driver called "ploot".
Diffstat:
M .gitignore | 4 ++--
M Makefile | 41 ++++++++++++++++---------------
M README | 120 ++++++++++++++++----------------
D config.h | 8 --------
D ffdraw.c | 164 -------------------------------
D ffplot.c | 316 -------------------------------
M font.h | 1723 ++++++++++++++++++++++++++++++-
D font_14x7.c | 1639 ------------------------------
D font_14x7.h | 1 -
A ploot-feed.c | 236 +++++++++++++++++++++++++++++++
A ploot-ff.c | 640 +++++++++++++++++++++++++++++++
D ploot.1 | 94 -------------------------------
D ploot.c | 154 -------------------------------
D ploot.h | 49 -------------------------------
D plootxt.c | 247 -------------------------------
M util.c | 35 ++++++++++++++++++++++++++++++-
M util.h | 10 ++++++----
17 files changed, 2676 insertions(+), 2805 deletions(-)
---
(DIR) diff --git a/.gitignore b/.gitignore
@@ -1,4 +1,4 @@
*.o
*.core
-ploot
-plootxt
+ploot-ff
+ploot-feed
(DIR) diff --git a/Makefile b/Makefile
@@ -1,32 +1,33 @@
-CFLAGS = -Wall -Wextra -Werror -std=c89 -pedantic -fPIC \
- -D_POSIX_C_SOURCE=200809L
-LDFLAGS = -static
+CFLAGS = -Wall -Wextra -Werror -std=c89 -pedantic -fPIC \
+ -D_POSIX_C_SOURCE=200809L
+LDFLAGS = -static
+BIN = ploot-ff ploot-feed
+LIB = -lm
-PLOOT_SRC = ploot.c ffplot.c ffdraw.c font_14x7.c util.c
-PLOOT_OBJ = $(PLOOT_SRC:.c=.o)
+SRC_PLOOT_FF = util.c ploot-ff.c
+HDR_PLOOT_FF = arg.h util.h font.h
+OBJ_PLOOT_FF = $(SRC_PLOOT_FF:.c=.o)
-PLOOTXT_SRC = plootxt.c util.c
-PLOOTXT_OBJ = $(PLOOTXT_SRC:.c=.o)
+SRC_PLOOT_FEED = util.c ploot-feed.c
+HDR_PLOOT_FEED = arg.h util.h
+OBJ_PLOOT_FEED = $(SRC_PLOOT_FEED:.c=.o)
+all: $(BIN)
-LIB = -lm
+ploot-ff: $(OBJ_PLOOT_FF)
+ ${CC} $(LDFLAGS) -o $@ $(OBJ_PLOOT_FF) $(LIB)
-all:V ploot plootxt
+ploot-feed: $(OBJ_PLOOT_FEED)
+ ${CC} $(LDFLAGS) -o $@ $(OBJ_PLOOT_FEED) $(LIB)
-ploot: $(PLOOT_OBJ)
- ${CC} $(LDFLAGS) -o $@ $(PLOOT_OBJ) $(LIB)
-
-plootxt: $(PLOOTXT_OBJ)
- ${CC} $(LDFLAGS) -o $@ $(PLOOTXT_OBJ) $(LIB)
-
-install:V ploot plootxt
+install: $(BIN)
mkdir -p ${PREFIX}/bin
cp ploot plootxt ${PREFIX}/bin
-clean:V
+clean:
rm -f *.o
-V: # :V acts like .PHONY:
+.PHONY: all install clean
-$(PLOOT_SRC) $(PLOOTXT_SRC): \
-arg.h ploot.h util.h font.h font_14x7.h
+$(SRC_PLOOT_FF): $(HDR_PLOOT_FF)
+$(SRC_PLOOT_FEED): $(HDR_PLOOT_FEED)
(DIR) diff --git a/README b/README
@@ -1,60 +1,60 @@
-PLOOT(1) General Commands Manual PLOOT(1)
-
-NAME
- ploot – plain text plotting tool
-
-SYNOPSIS
- ploot [-h height] [-o offset] [-t title]
-
-DESCRIPTION
- The ploot utility reads decimal values from stdin and print a plain text
- graph of the values to stdout. The values are separated by blanks or
- newlines, and can be either a plain list or a time serie (if the -o flag
- is set)
-
- -h height
- Sets the height of the plot in characters.
-
- -o offset
- Read data as time series: the input alternates UNIX epoch and
- value to be plotted. The time stamps are assumed to be at an
- interval of offset.
-
- -t title
- Print title centered at the bottom of the graph.
-
-EXIT STATUS
- The ploot utility exits 0 on success, and >0 if an error occurs.
-
-EXAMPLES
- % awk 'BEGIN { for (i=0; i<60; i++) print sin(i/3)+1 }' | ploot -h 10 -t List
-
- | .... .... ....
- 1.5963 -| ::::::. ::::::. .:::::: .:
- |.::::::::. .::::::::. .::::::::. .::
- 0.7982 -|::::::::::: .::::::::::. .::::::::::. ::::
- |::::::::::::. ::::::::::::::. .:::::::::::::: .:::::
- 0 -+------------------------------------------------------------
- List
-
- % ploot -h 8 -o 200 -t 'Time series'
- 1518780448 12 1518780643 13 1518780848 31 1518781028 19 1518781291 23
- 1518781423 20 1518781687 10 1518781819 13 1518782215 22 1518782412 11
- 1518782632 18 1518782822 11 1518783039 16 1518783235 21 1518783499 21
- 1518786629 30 1518786812 28 1518787012 11 1518787202 11 1518787433 11
- 1518787629 10 1518788042 16 1518788333 29 1518788494 26 1518788633 12
- 1518788821 28 1518789072 11 1518789201 11 1518789421 11 1518789630 11
-
- 31.000 -| : .. . .
- | : .. . .. :: :: :
- 15.500 -|..:::: . : : ::: :: :::.:
- |:::::::: ::::::: :::::: :::::::::
- 0 -+--------x-------xxxxxxxxxxxxxxx------x---------
- 12:27 12:50 13:14 13:37 14:00 14:24 14:47
- 2018/02/16 2018/02/16
- Time series
-
- The ‘x’ symbols on the horizontal axis represent a lack of data for that
- interval.
-
-Void Linux February 15, 2018 Void Linux
+ploot
+================================================================================
+
+
+ploot-ff
+--------------------------------------------------------------------------------
+
+*ploot-ff* reads collectd-style comma separated values (CSV) and produces a plot
+in the farbfeld [1] image format (pipe it to ff2png). It is an alternative to
+RRDtool [2].
+
+It is targetting at generating monitoring graph, and it always read unix
+timestamp as first column on standard input. The first line determines the
+name of the curves.
+
+[1]: https://tools.suckless.org/farbfeld/
+[2]: https://oss.oetiker.ch/rrdtool/
+
+
+ploot-feed
+--------------------------------------------------------------------------------
+
+*ploot-feed* also reads collectd-style comma separated values (CSV) but produces
+a plain text continuous waterfall chart for live monitoring in the terminal. it
+is an alternative to grafana [1].
+
+ % plootxt 1 1 1 <load-average.csv
+
+ │shortterm │midterm │longterm │
+ 17:34:00 _│⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣯⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 18/05/01 │⣟⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ │⣛⣂⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 20:34:00 _│⣧⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣧⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 18/05/01 │⣧⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣇⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ │⣟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⡃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 23:34:00 _│⣿⡒⠒⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣷⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 18/05/01 │⡧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡷⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ │⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 05:44:41 _│⣿⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⡉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⡉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 18/05/02 │⣛⣁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣟⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ │⣷⠶⠶⠶⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⡷⠶⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⣷⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 08:44:41 _│⡗⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡟⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 18/05/02 │⡯⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ │⠗⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 11:44:41 _│⠗⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 18/05/02 │⡿⠶⠒⠒⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣷⠖⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣷⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ │⠖⠒⠒⠒⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣷⠒⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 14:44:41 _│⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣟⡁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 18/05/02 │⣿⠟⠓⠒⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⠓⠒⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⠒⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ │⣿⠤⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡿⠆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 17:44:41 _│⡟⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⠒⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣷⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 18/05/02 │⣭⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ │⠄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⠇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 20:51:38 _│⣶⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣷⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣶⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 18/05/02 │⣿⣷⣶⣶⣶⣶⣶⠖⠒⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⣶⣶⣶⣶⣶⣶⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⣶⣶⣶⣦⣤⣄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ │shortterm │midterm │longterm │
+ 22:51:38 _│⣿⣿⣿⣟⣛⡋⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⣿⣿⣟⣛⠛⠛⠉⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⣿⣿⣿⡟⠛⠛⠋⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+ 18/05/02 │⣿⡿⠍⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⡿⠟⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│⣿⣿⠟⠛⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀│
+
+[1]: https://grafana.com/
(DIR) diff --git a/config.h b/config.h
@@ -1,8 +0,0 @@
-ColorList colorlist[] = {
- { "red", { 0xffff, 0x4444, 0x4444, 0xffff } },
- { "orange", { 0xffff, 0x9999, 0x4444, 0xffff } },
- { "yellow", { 0xffff, 0xffff, 0x4444, 0xffff } },
- { "green", { 0x1111, 0xffff, 0x5555, 0xffff } },
- { "cyan", { 0x0000, 0xffff, 0xdddd, 0xffff } },
- { NULL, { 0, 0, 0, 0 } }
-};
(DIR) diff --git a/ffdraw.c b/ffdraw.c
@@ -1,164 +0,0 @@
-/*
- * Render bitmapped font as a farbfeld image
- *
- * The convention used: y
- * - (0,0) is at the lower left corner of the canvas. |
- * - (0,1) is above it. +--x
- */
-
-#include <arpa/inet.h>
-
-#include <stdint.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "util.h"
-#include "ploot.h"
-
-/*
- * Convert (x,y) coordinates to (row,col) for printing into the buffer.
- * The buffer only contain one number, so the coordinate is a single integer:
- * width * x + y.
- * The coordinates are shifted by offx and offy to permit relative coordinates.
- */
-void
-ffdraw_pixel(Canvas *can, Color *col,
- int x, int y)
-{
- x += can->x;
- y += can->y;
- if (x < 0 || x >= can->h || y < 0 || y >= can->w)
- return;
- memcpy(can->b + can->w * (can->h - 1 - x) + y, col, sizeof(*can->b));
-}
-
-void
-ffdraw_rectangle(Canvas *can, Color *col,
- int x1, int y1,
- int x2, int y2)
-{
- int x, y, xmin, ymin, xmax, ymax;
-
- xmin = MIN(x1, x2); xmax = MAX(x1, x2);
- ymin = MIN(y1, y2); ymax = MAX(y1, y2);
-
- for (x = xmin; x <= xmax; x++)
- for (y = ymin; y <= ymax; y++)
- ffdraw_pixel(can, col, x, y);
-}
-
-/*
- * From Bresenham's line algorithm and dcat's tplot.
- */
-void
-ffdraw_line(Canvas *can, Color *col,
- int x0, int y0,
- int x1, int y1)
-{
- int dx, dy, sx, sy, err, e;
-
- sx = x0 < x1 ? 1 : -1;
- sy = y0 < y1 ? 1 : -1;
- dx = abs(x1 - x0);
- dy = abs(y1 - y0);
- err = (dx > dy ? dx : -dy) / 2;
-
- for (;;) {
- ffdraw_pixel(can, col, x0, y0);
-
- if (x0 == x1 && y0 == y1)
- break;
-
- e = err;
- if (e > -dx) {
- x0 += sx;
- err -= dy;
- }
- if (e < dy) {
- y0 += sy;
- err += dx;
- }
- }
-}
-
-/*
- * Draw a coloured glyph from font f centered on x.
- */
-void
-ffdraw_char(Canvas *can, Color *col, char c, Font *f,
- int x, int y)
-{
- int xf, yf;
-
- if (c & 0x80)
- c = '\0';
-
- x -= f->h / 2;
-
- for (xf = 0; xf < f->h; xf++)
- for (yf = 0; yf < f->w; yf++)
- if (f->b[(int)c][f->w * (f->h - xf - 1) + yf] > 0)
- ffdraw_pixel(can, col, x + xf, y + yf);
-}
-
-/*
- * Draw a left aligned string without wrapping it.
- */
-void
-ffdraw_str_left(Canvas *can, Color *col, char *s, Font *f,
- int x, int y)
-{
- for (; *s != '\0'; y += f->w, s++)
- ffdraw_char(can, col, *s, f, x, y);
-}
-
-/*
- * Draw a center aligned string without wrapping it.
- */
-void
-ffdraw_str_center(Canvas *can, Color *col, char *s, Font *f,
- int x, int y)
-{
- y -= f->w * strlen(s) / 2;
- ffdraw_str_left(can, col, s, f, x, y);
-}
-
-/*
- * Draw a right aligned string without wrapping it.
- */
-void
-ffdraw_str_right(Canvas *can, Color *col, char *s, Font *f,
- int x, int y)
-{
- y -= f->w * strlen(s);
- ffdraw_str_left(can, col, s, f, x, y);
-}
-
-void
-ffdraw_fill(Canvas *can, Color *col)
-{
- int x, y;
-
- x = can->x; can->x = 0;
- y = can->y; can->y = 0;
-
- ffdraw_rectangle(can, col, 0, 0, can->h - 1, can->w - 1);
-
- can->x = x;
- can->y = y;
-}
-
-void
-ffdraw_print(Canvas *can)
-{
- uint32_t w, h;
-
- w = htonl(can->w);
- h = htonl(can->h);
-
- fputs("farbfeld", stdout);
- fwrite(&w, sizeof(w), 1, stdout);
- fwrite(&h, sizeof(h), 1, stdout);
- fwrite(can->b, can->w * can->h, sizeof(*can->b), stdout);
-}
(DIR) diff --git a/ffplot.c b/ffplot.c
@@ -1,316 +0,0 @@
-/*
- * Draw a plot
- *
- * Title (units)
- * y ^ Legend
- * label |- + - + - + - + -
- * here |- + - + - + - + -
- * +--+---+---+---+-->
- * x label here
- */
-
-#include <math.h>
-#include <string.h>
-#include <stdio.h>
-#include <time.h>
-
-#include "ploot.h" /* placed before for Font type declaration */
-#include "font_14x7.h"
-
-#define ABS(x) ((x) < 0 ? -(x) : (x))
-#define LEN(x) (sizeof(x) / sizeof(*x))
-
-#define MARGIN 4
-
-#define XDENSITY 7 /* how many values to be displayed on x axis */
-#define YDENSITY 7 /* how many values to be displayed on y axis */
-
-#define FONT_H 14
-#define FONT_W 7
-
-#define TITLE_X (IMAGE_H - TITLE_H)
-#define TITLE_Y (XLABEL_W)
-#define TITLE_H (FONT_H * 2)
-#define TITLE_W (PLOT_W)
-
-#define XLABEL_X (PLOT_X)
-#define XLABEL_Y (0)
-#define XLABEL_H (PLOT_H)
-#define XLABEL_W (FONT_W * 9 + MARGIN)
-
-#define YLABEL_X (0)
-#define YLABEL_Y (PLOT_Y)
-#define YLABEL_H (FONT_H * 2)
-#define YLABEL_W (PLOT_W)
-
-#define PLOT_X (YLABEL_H)
-#define PLOT_Y (XLABEL_W)
-#define PLOT_W 700
-#define PLOT_H 160
-
-#define LEGEND_X (YLABEL_H)
-#define LEGEND_Y (IMAGE_W - LEGEND_W)
-#define LEGEND_W (FONT_W + 150 + FONT_W)
-#define LEGEND_H (PLOT_H)
-
-#define IMAGE_H (TITLE_H + PLOT_H + YLABEL_H)
-#define IMAGE_W (XLABEL_W + PLOT_W + LEGEND_W)
-
-Color buffer[IMAGE_W * IMAGE_H];
-
-Color c_axis = { 0xffff, 0xffff, 0xffff, 0xfff };
-Font *font = &font_14x7;
-
-static int
-t2y(time_t t, time_t tmin, time_t tmax)
-{
- return (t - tmin) * PLOT_W / (tmax - tmin);
-}
-
-static int
-v2x(double v, double vmin, double vmax)
-{
- return (v - vmin) * PLOT_H / (vmax - vmin);
-}
-
-/*
- * Set 'str' to a human-readable form of 'num' with always a width of 8 (+ 1
- * the '\0' terminator). Buffer overflow is ensured not to happen due to the
- * max size of a double. Return the exponent.
- */
-static int
-humanize(char *str, double val)
-{
- int exp, precision;
- char label[] = { '\0', 'M', 'G', 'T', 'E' };
-
- for (exp = 0; ABS(val) > 1000; exp++)
- val /= 1000;
-
- precision = (ABS(val) < 10) ? 2 : (ABS(val) < 100) ? 1 : 0;
- precision += (exp == 0);
-
- snprintf(str, 9, "%+.*f %c", precision, val, label[exp]);
- str[8] = '\0';
- if (val >= 0)
- str[0] = ' ';
-
- return exp * 3;
-}
-
-static void
-xaxis(Canvas *can, Color *label, Color *grid,
- double vmin, double vmax, double vstep)
-{
- double v;
- int x;
- char str[8 + 1];
-
- for (v = vmax - fmod(vmax, vstep); v >= vmin; v -= vstep) {
- x = v2x(v, vmin, vmax);
-
- ffdraw_line(can, grid,
- x, XLABEL_W,
- x, XLABEL_W + PLOT_W);
-
- humanize(str, v);
- ffdraw_str_right(can, label, str, font,
- x, XLABEL_W - MARGIN);
- }
-}
-
-static void
-yaxis(Canvas *can, Color *label, Color *grid,
- time_t tmin, time_t tmax, time_t tstep)
-{
- time_t t;
- int y;
- char str[sizeof("MM/DD HH/MM")], *fmt;
-
- if (tstep < 3600 * 12)
- fmt = "%H:%M:%S";
- else if (tstep < 3600 * 24)
- fmt = "%m/%d %H:%M";
- else
- fmt = "%Y/%m/%d";
-
- for (t = tmax - tmax % tstep; t >= tmin; t -= tstep) {
- y = t2y(t, tmin, tmax);
-
- ffdraw_line(can, grid,
- YLABEL_H, y,
- YLABEL_H + PLOT_H, y);
-
- strftime(str, sizeof(str), fmt, localtime(&t));
- ffdraw_str_center(can, label, str, font,
- YLABEL_H / 2, y);
- }
-}
-
-static void
-title(Canvas *can,
- Color *ct, char *title,
- Color *cu, char *unit)
-{
- ffdraw_str_left(can, ct, title, font,
- TITLE_H / 2, 0);
- ffdraw_str_right(can, cu, unit, font,
- TITLE_H / 2, TITLE_W);
-}
-
-static void
-graph(Canvas *can, Vlist *v,
- double vmin, double vmax,
- time_t tmin, time_t tmax)
-{
- time_t *tp;
- double *vp;
- int x, y, n, xlast, ylast, first;
-
- first = 1;
- for (tp = v->t, vp = v->v, n = v->n; n > 0; n--, vp++, tp++) {
- x = v2x(*vp, vmin, vmax);
- y = t2y(*tp, tmin, tmax);
-
- if (!first)
- ffdraw_line(can, &v->col, xlast, ylast, x, y);
-
- xlast = x;
- ylast = y;
- first = 0;
- }
-}
-
-static void
-plot(Canvas *can, Vlist *v, int n,
- double vmin, double vmax,
- time_t tmin, time_t tmax)
-{
- for (; n > 0; n--, v++)
- graph(can, v, vmin, vmax, tmin, tmax);
-}
-
-static void
-legend(Canvas *can, Color *label_fg, Vlist *v, int n)
-{
- int i, x, y;
-
- for (i = 0; i < n; i++, v++) {
- x = LEGEND_H - i * (FONT_H + MARGIN) - FONT_H / 2;
-
- y = MARGIN + FONT_W;
- ffdraw_str_left(can, &v->col, "\1", font, x, y);
-
- y += FONT_W * 2;
- ffdraw_str_left(can, label_fg, v->label, font, x, y);
- }
-}
-
-void
-find_scales(Vlist *v, int n,
- double *vmin, double *vmax, double *vstep,
- time_t *tmin, time_t *tmax, time_t *tstep)
-{
- double dv, *vs, vscale[] = { 1, 2, 3, 5 };
- time_t dt, *ts, tscale[] = {
- 1, 5, 2, 10, 20, 30, 60, 60*2, 60*5, 60*10, 60*20, 60*30, 3600,
- 3600*2, 3600*5, 3600*10, 3600*18, 3600*24, 3600*24*2,
- 3600*24*5, 3600*24*10, 3600*24*20, 3600*24*30, 3600*24*50,
- 3600*24*100, 3600*24*365
- };
- int i;
-
- *vmin = *vmax = 0;
- *tmin = *tmax = *v->t;
-
- for (; n-- > 0; v++) {
- for (i = 0; i < v->n; i++) {
- if (v->v[i] < *vmin)
- *vmin = v->v[i];
- if (v->v[i] > *vmax)
- *vmax = v->v[i];
- if (v->t[i] < *tmin)
- *tmin = v->t[i];
- if (v->t[i] > *tmax)
- *tmax = v->t[i];
- }
- }
-
- dv = *vmax - *vmin;
- dt = *tmax - *tmin;
-
- for (ts = tscale; ts < tscale + LEN(tscale); ts++)
- if (dt < *ts * YDENSITY) {
- *tstep = *ts;
- break;
- }
-
- if (dv > 1) {
- for (i = 1; i != 0; i *= 10) {
- for (vs = vscale; vs < vscale + LEN(vscale); vs++) {
- if (dv < *vs * i * XDENSITY) {
- *vstep = *vs * i;
- return;
- }
- }
- }
- } else {
- for (i = 1; i != 0; i *= 10) {
- for (vs = vscale + LEN(vscale) - 1; vs >= vscale; vs--) {
- if (dv > *vs / i * XDENSITY / 2) {
- *vstep = *vs / i;
- return;
- }
- }
- }
- }
-}
-
-/*
- * Plot the 'n' values list of the 'v' array with title 'name' and
- * 'units' label.
- */
-void
-ffplot(Vlist *v, int n, char *name, char *units)
-{
- Canvas can = { IMAGE_W, IMAGE_H, buffer, 0, 0 };
- Color plot_bg = { 0x2222, 0x2222, 0x2222, 0xffff };
- Color grid_bg = { 0x2929, 0x2929, 0x2929, 0xffff };
- Color grid_fg = { 0x3737, 0x3737, 0x3737, 0xffff };
- Color label_fg = { 0x8888, 0x8888, 0x8888, 0xffff };
- Color title_fg = { 0xdddd, 0xdddd, 0xdddd, 0xffff };
- double vmin, vmax, vstep = 30;
- time_t tmin, tmax, tstep = 30;
-
- find_scales(v, n, &vmin, &vmax, &vstep, &tmin, &tmax, &tstep);
-
- can.x = 0;
- can.y = 0;
- ffdraw_fill(&can, &plot_bg);
-
- can.x = PLOT_X;
- can.y = PLOT_Y;
- ffdraw_rectangle(&can, &grid_bg, 0, 0, PLOT_H, PLOT_W);
-
- can.x = YLABEL_X;
- can.y = YLABEL_Y;
- yaxis(&can, &label_fg, &grid_fg, tmin, tmax, tstep);
-
- can.x = XLABEL_X;
- can.y = XLABEL_Y;
- xaxis(&can, &label_fg, &grid_fg, vmin, vmax, vstep);
-
- can.x = TITLE_X;
- can.y = TITLE_Y;
- title(&can, &title_fg, name, &label_fg, units);
-
- can.x = PLOT_X;
- can.y = PLOT_Y;
- plot(&can, v, n, vmin, vmax, tmin, tmax);
-
- can.x = LEGEND_X;
- can.y = LEGEND_Y;
- legend(&can, &label_fg, v, n);
-
- ffdraw_print(&can);
-}
(DIR) diff --git a/font.h b/font.h
@@ -1,46 +1,1677 @@
-#include <stddef.h>
-#include <stdint.h>
-
-#include "ploot.h"
-
-/*
- * Macros to make the fonts header file more readable.
- */
-#define _ 0
-#define X 1
-#define C(x) static char glyph_ ## x[FONT_WIDTH * FONT_HEIGHT]
-
-#define FONT(x) Font x = { FONT_WIDTH, FONT_HEIGHT, { \
- glyph_error, glyph_error, glyph_error, glyph_error, \
- glyph_error, glyph_error, glyph_error, glyph_error, \
- glyph_error, glyph_error, glyph_error, glyph_error, \
- glyph_error, glyph_error, glyph_error, glyph_error, \
- glyph_error, glyph_error, glyph_error, glyph_error, \
- glyph_error, glyph_error, glyph_error, glyph_error, \
- glyph_error, glyph_error, glyph_error, glyph_error, \
- glyph_error, glyph_error, glyph_error, glyph_error, \
- glyph_space, glyph_bang, glyph_double, glyph_hash, \
- glyph_dollar, glyph_percent, glyph_ampersand, glyph_single, \
- glyph_l_round, glyph_r_round, glyph_asterisk, glyph_plus, \
- glyph_coma, glyph_minus, glyph_dot, glyph_slash, \
- glyph_0, glyph_1, glyph_2, glyph_3, \
- glyph_4, glyph_5, glyph_6, glyph_7, \
- glyph_8, glyph_9, glyph_column, glyph_semicolumn, \
- glyph_l_angle, glyph_equal, glyph_r_angle, glyph_question, \
- glyph_at, glyph_A, glyph_B, glyph_C, \
- glyph_D, glyph_E, glyph_F, glyph_G, \
- glyph_H, glyph_I, glyph_J, glyph_K, \
- glyph_L, glyph_M, glyph_N, glyph_O, \
- glyph_P, glyph_Q, glyph_R, glyph_S, \
- glyph_T, glyph_U, glyph_V, glyph_W, \
- glyph_X, glyph_Y, glyph_Z, glyph_l_square, \
- glyph_backslash, glyph_r_square, glyph_hat, glyph_underscore, \
- glyph_backtilt, glyph_a, glyph_b, glyph_c, \
- glyph_d, glyph_e, glyph_f, glyph_g, \
- glyph_h, glyph_i, glyph_j, glyph_k, \
- glyph_l, glyph_m, glyph_n, glyph_o, \
- glyph_p, glyph_q, glyph_r, glyph_s, \
- glyph_t, glyph_u, glyph_v, glyph_w, \
- glyph_x, glyph_y, glyph_z, glyph_l_curly, \
- glyph_pipe, glyph_r_curly, glyph_tilde, glyph_error \
-} }
+#define FONT_W 7
+#define FONT_H 14
+
+#define C(x) static char glyph_ ## x[FONT_W * FONT_H]
+#define _ 0
+#define X 1
+
+C(error) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,X,X,X,_,_,
+ _,_,X,X,X,_,_,
+ _,_,X,X,X,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(space) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(bang) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(double) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(hash) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,X,X,X,X,X,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,X,X,X,X,X,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(dollar) = {
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,_,_,
+ _,X,_,X,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,X,_,X,_,
+ _,_,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(percent) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,_,_,X,_,
+ _,X,X,_,_,X,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,X,_,_,X,X,_,
+ _,X,_,_,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(ampersand) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,X,_,X,_,
+ _,X,_,_,X,_,_,
+ _,X,_,_,X,_,_,
+ _,X,_,_,X,_,_,
+ _,_,X,X,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(single) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(l_round) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(r_round) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(asterisk) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,X,_,X,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,X,_,X,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(plus) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,X,X,X,X,X,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(coma) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(minus) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(dot) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(slash) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(0) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(1) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(2) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(3) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(4) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,X,X,_,
+ _,_,_,X,_,X,_,
+ _,_,X,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,X,X,X,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(5) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(6) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(7) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(8) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(9) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(column) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(semicolumn) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(l_angle) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(equal) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(r_angle) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(question) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(at) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,X,X,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,X,X,_,
+ _,X,_,_,_,_,_,
+ _,_,X,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(A) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,X,X,X,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(B) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(C) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(D) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(E) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(F) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(G) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,X,X,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(H) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,X,X,X,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(I) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(J) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,X,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,X,_,_,X,_,_,
+ _,_,X,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(K) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,X,_,_,
+ _,X,_,X,_,_,_,
+ _,X,X,_,_,_,_,
+ _,X,_,X,_,_,_,
+ _,X,_,_,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(L) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(M) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,X,_,X,X,_,
+ _,X,X,_,X,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(N) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,X,_,_,X,_,
+ _,X,X,_,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,_,X,X,_,
+ _,X,_,_,X,X,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(O) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(P) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(Q) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,X,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(R) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,X,X,X,_,_,
+ _,X,_,X,_,_,_,
+ _,X,_,_,X,_,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(S) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(T) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(U) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(V) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(W) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,X,_,X,X,_,
+ _,X,X,_,X,X,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(X) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(Y) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(Z) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(l_square) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(backslash) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(r_square) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(hat) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,X,_,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(underscore) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+X ,X,X,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(backtilt) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(a) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,_,X,X,X,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(b) = {
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(c) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(d) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,_,X,X,X,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(e) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,X,X,X,X,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(f) = {
+ _,_,_,_,_,_,_,
+ _,_,_,X,X,X,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(g) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,X,_,
+ _,_,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_
+};
+
+C(h) = {
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(i) = {
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(j) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,X,_,_,X,_,_,
+ _,_,X,X,_,_,_
+};
+
+C(k) = {
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,X,_,_,
+ _,X,_,X,_,_,_,
+ _,X,X,_,_,_,_,
+ _,X,_,X,_,_,_,
+ _,X,_,_,X,_,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(l) = {
+ _,_,_,_,_,_,_,
+ _,_,X,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(m) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(n) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(o) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(p) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,X,X,X,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_
+};
+
+C(q) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X
+};
+
+C(r) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,X,X,X,X,
+ _,X,X,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(s) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,X,X,_,
+ _,X,_,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,_,X,X,X,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,_,X,_,
+ _,X,X,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(t) = {
+ _,_,_,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,X,X,X,X,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,_,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(u) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(v) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,_,X,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(w) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,X,_,X,_,
+ _,_,X,_,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(x) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,X,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(y) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,X,_,
+ _,_,_,_,_,X,_,
+ _,X,_,_,_,X,_,
+ _,_,X,X,X,_,_
+};
+
+C(z) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,X,_,_,
+ _,_,_,X,_,_,_,
+ _,_,X,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,X,X,X,X,X,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(l_curly) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,X,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,X,_,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,X,_,_,_,_,
+ _,_,_,X,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(pipe) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(r_curly) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,X,_,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,_,X,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,_,_,X,_,_,
+ _,_,X,X,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+C(tilde) = {
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,X,_,_,X,_,
+ _,X,_,X,_,X,_,
+ _,X,_,_,X,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_,
+ _,_,_,_,_,_,_
+};
+
+#undef C
+#undef _
+#undef X
+
+char *glyph[128] = {
+ glyph_error, glyph_error, glyph_error, glyph_error,
+ glyph_error, glyph_error, glyph_error, glyph_error,
+ glyph_error, glyph_error, glyph_error, glyph_error,
+ glyph_error, glyph_error, glyph_error, glyph_error,
+ glyph_error, glyph_error, glyph_error, glyph_error,
+ glyph_error, glyph_error, glyph_error, glyph_error,
+ glyph_error, glyph_error, glyph_error, glyph_error,
+ glyph_error, glyph_error, glyph_error, glyph_error,
+ glyph_space, glyph_bang, glyph_double, glyph_hash,
+ glyph_dollar, glyph_percent, glyph_ampersand, glyph_single,
+ glyph_l_round, glyph_r_round, glyph_asterisk, glyph_plus,
+ glyph_coma, glyph_minus, glyph_dot, glyph_slash,
+ glyph_0, glyph_1, glyph_2, glyph_3,
+ glyph_4, glyph_5, glyph_6, glyph_7,
+ glyph_8, glyph_9, glyph_column, glyph_semicolumn,
+ glyph_l_angle, glyph_equal, glyph_r_angle, glyph_question,
+ glyph_at, glyph_A, glyph_B, glyph_C,
+ glyph_D, glyph_E, glyph_F, glyph_G,
+ glyph_H, glyph_I, glyph_J, glyph_K,
+ glyph_L, glyph_M, glyph_N, glyph_O,
+ glyph_P, glyph_Q, glyph_R, glyph_S,
+ glyph_T, glyph_U, glyph_V, glyph_W,
+ glyph_X, glyph_Y, glyph_Z, glyph_l_square,
+ glyph_backslash, glyph_r_square, glyph_hat, glyph_underscore,
+ glyph_backtilt, glyph_a, glyph_b, glyph_c,
+ glyph_d, glyph_e, glyph_f, glyph_g,
+ glyph_h, glyph_i, glyph_j, glyph_k,
+ glyph_l, glyph_m, glyph_n, glyph_o,
+ glyph_p, glyph_q, glyph_r, glyph_s,
+ glyph_t, glyph_u, glyph_v, glyph_w,
+ glyph_x, glyph_y, glyph_z, glyph_l_curly,
+ glyph_pipe, glyph_r_curly, glyph_tilde, glyph_error
+};
(DIR) diff --git a/font_14x7.c b/font_14x7.c
@@ -1,1639 +0,0 @@
-#include "font.h"
-#include "font_14x7.h"
-
-#define FONT_HEIGHT 14
-#define FONT_WIDTH 7
-
-C(error) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,_,X,X,X,_,_,
- _,_,X,X,X,_,_,
- _,_,X,X,X,_,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(space) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(bang) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(double) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(hash) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,X,X,X,X,X,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,X,X,X,X,X,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(dollar) = {
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,_,_,
- _,X,_,X,_,_,_,
- _,_,X,X,X,_,_,
- _,_,_,X,_,X,_,
- _,_,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(percent) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,_,_,X,_,
- _,X,X,_,_,X,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,X,_,_,X,X,_,
- _,X,_,_,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(ampersand) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,X,X,_,X,_,
- _,X,_,_,X,_,_,
- _,X,_,_,X,_,_,
- _,X,_,_,X,_,_,
- _,_,X,X,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(single) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(l_round) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(r_round) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(asterisk) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,X,_,X,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,X,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,X,_,X,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(plus) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,X,X,X,X,X,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(coma) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(minus) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(dot) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(slash) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(0) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(1) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,X,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(2) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(3) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(4) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,X,X,_,
- _,_,_,X,_,X,_,
- _,_,X,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,X,X,X,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(5) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,X,X,X,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(6) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(7) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(8) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(9) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(column) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(semicolumn) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(l_angle) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,_,_,_,
- _,X,_,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(equal) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(r_angle) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,_,_,_,
- _,X,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(question) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(at) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,X,X,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,X,X,_,
- _,X,_,_,_,_,_,
- _,_,X,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(A) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,X,X,X,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(B) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(C) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(D) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(E) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(F) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(G) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,X,X,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(H) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,X,X,X,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(I) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(J) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,X,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,X,_,_,X,_,_,
- _,_,X,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(K) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,X,_,_,
- _,X,_,X,_,_,_,
- _,X,X,_,_,_,_,
- _,X,_,X,_,_,_,
- _,X,_,_,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(L) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(M) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,X,_,X,X,_,
- _,X,X,_,X,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(N) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,X,_,_,X,_,
- _,X,X,_,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,_,X,X,_,
- _,X,_,_,X,X,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(O) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(P) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(Q) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,X,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(R) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,X,X,X,_,_,
- _,X,_,X,_,_,_,
- _,X,_,_,X,_,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(S) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(T) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(U) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(V) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(W) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,X,X,_,X,X,_,
- _,X,X,_,X,X,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(X) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(Y) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(Z) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(l_square) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(backslash) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(r_square) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(hat) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,X,_,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(underscore) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
-X ,X,X,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(backtilt) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(a) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,_,X,X,X,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(b) = {
- _,_,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(c) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(d) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,_,X,X,X,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(e) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,X,X,X,X,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(f) = {
- _,_,_,_,_,_,_,
- _,_,_,X,X,X,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,X,X,X,X,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(g) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,X,_,
- _,_,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_
-};
-
-C(h) = {
- _,_,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(i) = {
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(j) = {
- _,_,_,_,_,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,X,_,_,X,_,_,
- _,_,X,X,_,_,_
-};
-
-C(k) = {
- _,_,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,X,_,_,
- _,X,_,X,_,_,_,
- _,X,X,_,_,_,_,
- _,X,_,X,_,_,_,
- _,X,_,_,X,_,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(l) = {
- _,_,_,_,_,_,_,
- _,_,X,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(m) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,_,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(n) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(o) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(p) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,X,X,X,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_
-};
-
-C(q) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X
-};
-
-C(r) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,X,X,X,X,
- _,X,X,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(s) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,X,X,_,
- _,X,_,_,_,_,_,
- _,X,_,_,_,_,_,
- _,_,X,X,X,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,_,X,_,
- _,X,X,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(t) = {
- _,_,_,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,X,X,X,X,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,_,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(u) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(v) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,_,X,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(w) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,X,_,X,_,
- _,_,X,_,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(x) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,X,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(y) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,X,_,
- _,_,_,_,_,X,_,
- _,X,_,_,_,X,_,
- _,_,X,X,X,_,_
-};
-
-C(z) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,_,_,_,_,X,_,
- _,_,_,_,X,_,_,
- _,_,_,X,_,_,_,
- _,_,X,_,_,_,_,
- _,X,_,_,_,_,_,
- _,X,X,X,X,X,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(l_curly) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,X,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,X,_,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,X,_,_,_,_,
- _,_,_,X,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(pipe) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(r_curly) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,X,_,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,_,X,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,_,_,X,_,_,
- _,_,X,X,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-C(tilde) = {
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,X,_,_,X,_,
- _,X,_,X,_,X,_,
- _,X,_,_,X,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_,
- _,_,_,_,_,_,_
-};
-
-FONT(font_14x7);
(DIR) diff --git a/font_14x7.h b/font_14x7.h
@@ -1 +0,0 @@
-extern Font font_14x7;
(DIR) diff --git a/ploot-feed.c b/ploot-feed.c
@@ -0,0 +1,236 @@
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "arg.h"
+#include "util.h"
+
+#define WIDTH_MAX 1024
+#define BRAILLE_START 10240
+
+int wflag = 80;
+int width;
+char *argv0;
+
+/*
+ * Turn the bit at position (row, col) on in the .
+ */
+static void
+plot_dot(long *out, int row, int col)
+{
+ long flags[4][2] = {
+ { 0x01, 0x08 },
+ { 0x02, 0x10 },
+ { 0x04, 0x20 },
+ { 0x40, 0x80 },
+ };
+
+ *out |= flags[row][col];;
+}
+
+static void
+plot_val(long *out, double val, double max, int row)
+{
+ int col, c;
+
+ val = MIN(max, val);
+ col = (int)(val * (double)(width - 1) / max * 2);
+ for (c = 0; c < col; c++)
+ plot_dot(out + c / 2, row, c % 2);
+}
+
+/*
+ * Change the braille characters on a whole row, this for all the
+ * values line.
+ */
+static time_t
+plot_row(long *out, char *line, double *max, int nrow, int ncol)
+{
+ time_t epoch;
+ double val;
+ int n;
+ char *tok;
+
+ if ((tok = strsep(&line, ",")) == NULL)
+ fputs("*** missing epoch value\n", stderr), exit(1);
+ epoch = eatol(tok);
+
+ for (n = 0; (tok = strsep(&line, ",")) != NULL; n++) {
+ if (n >= ncol)
+ fputs("too many values\n", stderr), exit(1);
+ val = atof(tok);
+ plot_val(out + n * width, val, max[n], nrow);
+ }
+ if (n < ncol)
+ fputs("not enough values\n", stderr), exit(1);
+
+ return epoch;
+}
+
+/*
+ * Read enough input in order to print one line and plot it into 'out'.
+ */
+static time_t
+plot_line(long *out, double *max, int ncol)
+{
+ time_t epoch;
+ int n, nrow;
+ long *o, rune;
+ char line[LINE_MAX];
+
+ for (rune = BRAILLE_START, o = out, n = ncol * width; n > 0; o++, n--)
+ memcpy(o, &rune, sizeof(rune));
+ *o = '\0';
+ for (rune = 0x2502, o = out, n = 0; n < ncol; o += width, n++)
+ memcpy(o, &rune, sizeof(rune));
+ out++;
+
+ for (nrow = 0; nrow < 4; nrow++) {
+ if ((esfgets(line, LINE_MAX, stdin)) == NULL)
+ exit(0);
+ epoch = plot_row(out, line, max, nrow, ncol);
+ }
+
+ return epoch;
+}
+
+static void
+put_time(time_t epoch, time_t last, int nline)
+{
+ char *out, buf[sizeof("XXxXXxXX ")];
+
+ switch (nline % 3) {
+ case 0:
+ strftime(buf, sizeof(buf), "%H:%M:%S _", localtime(&epoch));
+ out = buf;
+ break;
+ case 1:
+ strftime(buf, sizeof(buf), "%y/%m/%d ", localtime(&last));
+ out = buf;
+ break;
+ case 2:
+ out = " ";
+ break;
+ }
+
+ fputs(out, stdout);
+}
+
+static void
+put_line(long *out)
+{
+ for (; *out != '\0'; out++)
+ put3utf(*out);
+ puts("│");
+}
+
+static void
+plot(char labels[LINE_MAX], double *max, int ncol)
+{
+ time_t epoch, last_epoch;
+ long out[WIDTH_MAX + 1];
+ int n;
+
+ last_epoch = epoch = 0;
+
+ for (n = 0;; n = n == 25 ? 0 : n + 1) {
+ if (n == 0)
+ put_time(0, 0, 2), fputs(labels, stdout), puts("│");
+
+ epoch = plot_line(out, max, ncol);
+ put_time(epoch, last_epoch, n);
+ last_epoch = epoch;
+ put_line(out);
+
+ fflush(stdout);
+ }
+}
+
+/*
+ * Label must be able to store all pointers to token buf has to
+ * offer: sizeof(*buf / 2).
+ */
+static int
+read_labels(char *labv[LINE_MAX])
+{
+ int ncol;
+ char *l, line[LINE_MAX], *tok;
+
+ if ((l = esfgets(line, LINE_MAX, stdin)) == NULL)
+ fputs("missing label line\n", stderr), exit(1);
+
+ if (strcmp(strsep(&l, ","), "epoch") != 0)
+ fputs("first label must be \"epoch\"\n", stderr), exit(1);
+
+ for (ncol = 0; (tok = strsep(&l, ",")) != NULL; ncol++, labv++)
+ *labv = tok;
+ *labv = NULL;
+
+ if (ncol < 1)
+ fputs("no label found\n", stderr), exit(1);
+
+ return ncol;
+}
+
+static void
+fmt_labels(char out[LINE_MAX], int ncol, char *labels[LINE_MAX / 2])
+{
+ int i, n;
+
+ for (i = 0; i < ncol; labels++, i++) {
+ n = LINE_MAX - (width + sizeof("│")) * i;
+ out += snprintf(out, n, "│%-*s", width - 1, *labels);
+ }
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s [-w width] maxval... <csv\n", argv0);
+ exit(1);
+}
+
+static int
+parse_args(int argc, char **argv, double *max)
+{
+ int n;
+
+ ARGBEGIN {
+ case 'w':
+ wflag = atoi(EARGF(usage()));
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if (argc == 0)
+ usage();
+
+ for (n = argc; n > 0; n--, argv++, max++)
+ *max = eatof(*argv);
+
+ return argc;
+}
+
+int
+main(int argc, char **argv)
+{
+ double max[LINE_MAX / 2];
+ int ncol, nmax;
+ char *labv[LINE_MAX / 2], labels[LINE_MAX];
+
+ setvbuf(stdin, NULL, _IOLBF, 0);
+ nmax = parse_args(argc, argv, max);
+ ncol = read_labels(labv);
+ width = (wflag - sizeof("XXxXXxXX _")) / ncol - sizeof("|");
+ fmt_labels(labels, ncol, labv);
+ if (ncol != nmax)
+ fputs("not as many labels and arguments\n", stderr), exit(1);
+ plot(labels, max, ncol);
+
+ return 0;
+}
(DIR) diff --git a/ploot-ff.c b/ploot-ff.c
@@ -0,0 +1,640 @@
+#include <arpa/inet.h>
+
+#include <math.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include <stdint.h>
+
+#include "arg.h"
+#include "util.h"
+#include "font.h"
+
+#define MARGIN 4
+
+#define XDENSITY 7 /* nb of values on x axis */
+#define YDENSITY 7 /* nb of values on y axis */
+
+#define TITLE_X (IMAGE_H - TITLE_H)
+#define TITLE_Y (XLABEL_W)
+#define TITLE_H (FONT_H * 2)
+#define TITLE_W (PLOT_W)
+
+#define XLABEL_X (PLOT_X)
+#define XLABEL_Y (0)
+#define XLABEL_H (PLOT_H)
+#define XLABEL_W (FONT_W * 9 + MARGIN)
+
+#define YLABEL_X (0)
+#define YLABEL_Y (PLOT_Y)
+#define YLABEL_H (FONT_H * 2)
+#define YLABEL_W (PLOT_W)
+
+#define PLOT_X (YLABEL_H)
+#define PLOT_Y (XLABEL_W)
+#define PLOT_W 700
+#define PLOT_H 160
+
+#define LEGEND_X (YLABEL_H)
+#define LEGEND_Y (IMAGE_W - LEGEND_W)
+#define LEGEND_W (FONT_W + 150 + FONT_W)
+#define LEGEND_H (PLOT_H)
+
+#define IMAGE_H (TITLE_H + PLOT_H + YLABEL_H)
+#define IMAGE_W (XLABEL_W + PLOT_W + LEGEND_W)
+
+typedef uint16_t Color[4];
+typedef struct clist Clist;
+typedef struct vlist Vlist;
+typedef struct canvas Canvas;
+typedef struct font Font;
+
+struct vlist {
+ Color col; /* color to use to draw the line */
+ time_t *t; /* array of timestamps */
+ double *v; /* array of values */
+ int n; /* number of values */
+ char *label; /* for the legend */
+};
+
+struct canvas {
+ int w; /* width */
+ int h; /* height */
+ int x; /* x offset */
+ int y; /* x offset */
+ Color b[IMAGE_W * IMAGE_H];
+};
+
+struct font {
+ int w; /* width */
+ int h; /* height */
+ char **b; /* buffer */
+};
+
+struct clist {
+ char *name;
+ Color col;
+};
+
+char *argv0;
+char *tflag = "";
+char *uflag = "";
+
+Clist clist[] = {
+ /* name red green blue alpha */
+ { "red", { 0xffff, 0x4444, 0x4444, 0xffff } },
+ { "orange", { 0xffff, 0x9999, 0x4444, 0xffff } },
+ { "yellow", { 0xffff, 0xffff, 0x4444, 0xffff } },
+ { "green", { 0x2222, 0xffff, 0x5555, 0xffff } },
+ { "cyan", { 0x0000, 0xffff, 0xdddd, 0xffff } },
+ { "blue", { 0x2222, 0x9999, 0xffff, 0xffff } },
+ { NULL, { 0, 0, 0, 0 } }
+};
+
+Font font = { FONT_W, FONT_H, glyph };
+
+static int
+color(Color *col, char *name)
+{
+ Clist *c;
+
+ for (c = clist; c->name != NULL; c++) {
+ if (strcmp(name, c->name) == 0) {
+ memcpy(col, c->col, sizeof(*col));
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+static void
+scale_minmax(Vlist *v, int n,
+ double *vmin, double *vmax,
+ time_t *tmin, time_t *tmax)
+{
+ int i;
+
+ *vmin = *vmax = 0;
+ *tmin = *tmax = *v->t;
+
+ for (; n-- > 0; v++) {
+ for (i = 0; i < v->n; i++) {
+ if (v->v[i] < *vmin)
+ *vmin = v->v[i];
+ if (v->v[i] > *vmax)
+ *vmax = v->v[i];
+ if (v->t[i] < *tmin)
+ *tmin = v->t[i];
+ if (v->t[i] > *tmax)
+ *tmax = v->t[i];
+ }
+ }
+}
+
+static void
+scale_tstep(time_t *step, int density, time_t min, time_t max)
+{
+ time_t dt, *s, scale[] = {
+ 1, 5, 2, 10, 20, 30, 60, 60*2, 60*5, 60*10, 60*20, 60*30, 3600,
+ 3600*2, 3600*5, 3600*10, 3600*18, 3600*24, 3600*24*2,
+ 3600*24*5, 3600*24*10, 3600*24*20, 3600*24*30, 3600*24*50,
+ 3600*24*100, 3600*24*365
+ };
+
+ dt = max - min;
+
+ for (s = scale; s < scale + LEN(scale); s++) {
+ if (dt < *s * density) {
+ *step = *s;
+ break;
+ }
+ }
+}
+
+static void
+scale_vstep(double *step, int density, double min, double max)
+{
+ double dv, *s, scale[] = { 1, 2, 3, 5 };
+ int i;
+
+ dv = max - min;
+
+ if (dv > 1) {
+ for (i = 1; i != 0; i *= 10) {
+ for (s = scale; s < scale + LEN(scale); s++) {
+ if (dv < *s * i * density) {
+ *step = *s * i;
+ return;
+ }
+ }
+ }
+ } else {
+ for (i = 1; i != 0; i *= 10) {
+ for (s = scale + LEN(scale) - 1; s >= scale; s--) {
+ if (dv > *s / i * density / 2) {
+ *step = *s / i;
+ return;
+ }
+ }
+ }
+ }
+}
+
+static void
+scale(Vlist *v, int n,
+ double *vmin, double *vmax, double *vstep,
+ time_t *tmin, time_t *tmax, time_t *tstep)
+{
+ scale_minmax(v, n, vmin, vmax, tmin, tmax);
+ scale_tstep(tstep, YDENSITY, *tmin, *tmax);
+ scale_vstep(vstep, XDENSITY, *vmin, *vmax);
+}
+
+/*
+ * Convert (x,y) coordinates to (row,col) for printing into the buffer.
+ * The buffer only contain one number, so the coordinate is a single integer:
+ * width * x + y.
+ * The coordinates are shifted by offx and offy to permit relative coordinates.
+ *
+ * The convention used: y
+ * - (0,0) is at the lower left corner of the canvas. |
+ * - (0,1) is above it. +--x
+ */
+static void
+ff_pixel(Canvas *can, Color *col,
+ int x, int y)
+{
+ x += can->x;
+ y += can->y;
+ if (x < 0 || x >= can->h || y < 0 || y >= can->w)
+ return;
+ memcpy(can->b + can->w * (can->h - 1 - x) + y, col, sizeof(*can->b));
+}
+
+static void
+ff_rectangle(Canvas *can, Color *col,
+ int x1, int y1,
+ int x2, int y2)
+{
+ int x, y, xmin, ymin, xmax, ymax;
+
+ xmin = MIN(x1, x2); xmax = MAX(x1, x2);
+ ymin = MIN(y1, y2); ymax = MAX(y1, y2);
+
+ for (x = xmin; x <= xmax; x++)
+ for (y = ymin; y <= ymax; y++)
+ ff_pixel(can, col, x, y);
+}
+
+/*
+ * From Bresenham's line algorithm and dcat's tplot.
+ */
+static void
+ff_line(Canvas *can, Color *col,
+ int x0, int y0,
+ int x1, int y1)
+{
+ int dx, dy, sx, sy, err, e;
+
+ sx = x0 < x1 ? 1 : -1;
+ sy = y0 < y1 ? 1 : -1;
+ dx = abs(x1 - x0);
+ dy = abs(y1 - y0);
+ err = (dx > dy ? dx : -dy) / 2;
+
+ for (;;) {
+ ff_pixel(can, col, x0, y0);
+
+ if (x0 == x1 && y0 == y1)
+ break;
+
+ e = err;
+ if (e > -dx) {
+ x0 += sx;
+ err -= dy;
+ }
+ if (e < dy) {
+ y0 += sy;
+ err += dx;
+ }
+ }
+}
+
+/*
+ * Draw a coloured glyph from font f centered on x.
+ */
+static void
+ff_char(Canvas *can, Color *col, char c, Font *f,
+ int x, int y)
+{
+ int xf, yf;
+
+ if (c & 0x80)
+ c = '\0';
+
+
+ x -= f->h / 2;
+
+ for (xf = 0; xf < f->h; xf++)
+ for (yf = 0; yf < f->w; yf++)
+ if (f->b[(int)c][f->w * (f->h - xf) + yf] == 1)
+ ff_pixel(can, col, x + xf, y + yf);
+}
+
+/*
+ * Draw a left aligned string without wrapping it.
+ */
+static void
+ff_str_left(Canvas *can, Color *col, char *s, Font *f,
+ int x, int y)
+{
+ for (; *s != '\0'; y += f->w, s++)
+ ff_char(can, col, *s, f, x, y);
+}
+
+/*
+ * Draw a center aligned string without wrapping it.
+ */
+static void
+ff_str_center(Canvas *can, Color *col, char *s, Font *f,
+ int x, int y)
+{
+ y -= f->w * strlen(s) / 2;
+ ff_str_left(can, col, s, f, x, y);
+}
+
+/*
+ * Draw a right aligned string without wrapping it.
+ */
+static void
+ff_str_right(Canvas *can, Color *col, char *s, Font *f,
+ int x, int y)
+{
+ y -= f->w * strlen(s);
+ ff_str_left(can, col, s, f, x, y);
+}
+
+static void
+ff_print(Canvas *can)
+{
+ uint32_t w, h;
+
+ w = htonl(can->w);
+ h = htonl(can->h);
+
+ fputs("farbfeld", stdout);
+ fwrite(&w, sizeof(w), 1, stdout);
+ fwrite(&h, sizeof(h), 1, stdout);
+ fwrite(can->b, can->w * can->h, sizeof(*can->b), stdout);
+}
+
+static int
+ff_t2y(time_t t, time_t tmin, time_t tmax)
+{
+ return (t - tmin) * PLOT_W / (tmax - tmin);
+}
+
+static int
+ff_v2x(double v, double vmin, double vmax)
+{
+ return (v - vmin) * PLOT_H / (vmax - vmin);
+}
+
+static void
+ff_xaxis(Canvas *can, Color *label, Color *grid,
+ double vmin, double vmax, double vstep)
+{
+ double v;
+ int x;
+ char str[8 + 1];
+
+ for (v = vmax - fmod(vmax, vstep); v >= vmin; v -= vstep) {
+ x = ff_v2x(v, vmin, vmax);
+
+ ff_line(can, grid,
+ x, XLABEL_W,
+ x, XLABEL_W + PLOT_W);
+
+ humanize(str, v);
+ ff_str_right(can, label, str, &font,
+ x, XLABEL_W - MARGIN);
+ }
+}
+
+static void
+ff_yaxis(Canvas *can, Color *label, Color *grid,
+ time_t tmin, time_t tmax, time_t tstep)
+{
+ time_t t;
+ int y;
+ char str[sizeof("MM/DD HH/MM")], *fmt;
+
+ if (tstep < 3600 * 12)
+ fmt = "%H:%M:%S";
+ else if (tstep < 3600 * 24)
+ fmt = "%m/%d %H:%M";
+ else
+ fmt = "%Y/%m/%d";
+
+ for (t = tmax - tmax % tstep; t >= tmin; t -= tstep) {
+ y = ff_t2y(t, tmin, tmax);
+
+ ff_line(can, grid,
+ YLABEL_H, y,
+ YLABEL_H + PLOT_H, y);
+
+ strftime(str, sizeof(str), fmt, localtime(&t));
+ ff_str_center(can, label, str, &font,
+ YLABEL_H / 2, y);
+ }
+}
+
+static void
+ff_title(Canvas *can,
+ Color *ct, char *title,
+ Color *cu, char *unit)
+{
+ ff_str_left(can, ct, title, &font,
+ TITLE_H / 2, 0);
+ ff_str_right(can, cu, unit, &font,
+ TITLE_H / 2, TITLE_W);
+}
+
+static void
+ff_plot(Canvas *can, Vlist *v,
+ double vmin, double vmax,
+ time_t tmin, time_t tmax)
+{
+ time_t *tp;
+ double *vp;
+ int x, y, n, xlast, ylast, first;
+
+ first = 1;
+ for (tp = v->t, vp = v->v, n = v->n; n > 0; n--, vp++, tp++) {
+ x = ff_v2x(*vp, vmin, vmax);
+ y = ff_t2y(*tp, tmin, tmax);
+
+ if (!first)
+ ff_line(can, &v->col, xlast, ylast, x, y);
+
+ xlast = x;
+ ylast = y;
+ first = 0;
+ }
+}
+
+static void
+ff_values(Canvas *can, Vlist *v, int n,
+ double vmin, double vmax,
+ time_t tmin, time_t tmax)
+{
+ for (; n > 0; n--, v++)
+ ff_plot(can, v, vmin, vmax, tmin, tmax);
+}
+
+static void
+ff_legend(Canvas *can, Color *label_fg, Vlist *v, int n)
+{
+ int i, x, y;
+
+ for (i = 0; i < n; i++, v++) {
+ x = LEGEND_H - i * (FONT_H + MARGIN) - FONT_H / 2;
+
+ y = MARGIN + FONT_W;
+ ff_str_left(can, &v->col, "\1", &font, x, y);
+
+ y += FONT_W * 2;
+ ff_str_left(can, label_fg, v->label, &font, x, y);
+ }
+}
+
+/*
+ * Plot the 'n' values list of the 'v' array with title 'name' and
+ * 'units' label.
+ *
+ * Title (units)
+ * y ^ Legend
+ * label |- + - + - + - + - ....
+ * here |- + - + - + - + - ....
+ * +--+---+---+---+-->
+ * x label here
+ */
+static void
+ff(Vlist *v, int n, char *name, char *units)
+{
+ Canvas can = { IMAGE_W, IMAGE_H, 0, 0, { { 0 }, { 0 } } };
+ Color plot_bg = { 0x2222, 0x2222, 0x2222, 0xffff };
+ Color grid_bg = { 0x2929, 0x2929, 0x2929, 0xffff };
+ Color grid_fg = { 0x3737, 0x3737, 0x3737, 0xffff };
+ Color label_fg = { 0x8888, 0x8888, 0x8888, 0xffff };
+ Color title_fg = { 0xdddd, 0xdddd, 0xdddd, 0xffff };
+ double vmin, vmax, vstep;
+ time_t tmin, tmax, tstep;
+
+ scale(v, n, &vmin, &vmax, &vstep, &tmin, &tmax, &tstep);
+
+ can.x = 0;
+ can.y = 0;
+ ff_rectangle(&can, &plot_bg, 0, 0, IMAGE_H - 1, IMAGE_W - 1);
+
+ can.x = PLOT_X;
+ can.y = PLOT_Y;
+ ff_rectangle(&can, &grid_bg, 0, 0, PLOT_H, PLOT_W);
+
+ can.x = YLABEL_X;
+ can.y = YLABEL_Y;
+ ff_yaxis(&can, &label_fg, &grid_fg, tmin, tmax, tstep);
+
+ can.x = XLABEL_X;
+ can.y = XLABEL_Y;
+ ff_xaxis(&can, &label_fg, &grid_fg, vmin, vmax, vstep);
+
+ can.x = TITLE_X;
+ can.y = TITLE_Y;
+ ff_title(&can, &title_fg, name, &label_fg, units);
+
+ can.x = PLOT_X;
+ can.y = PLOT_Y;
+ ff_values(&can, v, n, vmin, vmax, tmin, tmax);
+
+ can.x = LEGEND_X;
+ can.y = LEGEND_Y;
+ ff_legend(&can, &label_fg, v, n);
+
+ ff_print(&can);
+}
+
+static void
+csv_labels(Vlist *v, char **argv, char *buf)
+{
+ if (esfgets(buf, LINE_MAX, stdin) == NULL)
+ fputs("missing label line\n", stderr), exit(1);
+
+ if (strcmp(strsep(&buf, ","), "epoch") != 0)
+ fputs("first label must be \"epoch\"\n", stderr), exit(1);
+
+ for (; *argv != NULL; v++, argv++) {
+ if ((v->label = strsep(&buf, ",")) == NULL)
+ fputs("more arguments than columns\n", stderr), exit(1);
+ else if (color(&v->col, *argv) == -1)
+ fprintf(stderr, "unknown color: %s\n", *argv), exit(1);
+ }
+
+ if (strsep(&buf, ",") != NULL)
+ fputs("more columns than arguments\n", stderr), exit(1);
+}
+
+static int
+csv_addval(Vlist *v, int bufsize, int nval, double field, time_t epoch)
+{
+ if (nval >= bufsize) {
+ bufsize = bufsize * 2 + 1;
+ if ((v->v = realloc(v->v, bufsize * sizeof(*v->v))) == NULL)
+ perror("reallocating values buffer"), exit(1);
+ if ((v->t = realloc(v->t, bufsize * sizeof(*v->t))) == NULL)
+ perror("reallocating values buffer"), exit(1);
+ }
+ v->v[nval] = field;
+ v->t[nval] = epoch;
+ v->n = nval + 1;
+
+ return bufsize;
+}
+
+/*
+ * Add to each column the value on the current row.
+ */
+static int
+csv_addrow(Vlist *v, int bufsize, int ncol, int nval, char *line)
+{
+ time_t epoch;
+ int bs;
+ char *field, *dot;
+
+ if ((field = strsep(&line, ",")) == NULL)
+ fprintf(stderr, "%d: missing epoch\n", nval), exit(1);
+
+ if ((dot = strchr(field, '.')) != NULL)
+ *dot = '\0';
+ epoch = eatol(field);
+ for (; (field = strsep(&line, ",")) != NULL; ncol--, v++) {
+ if (ncol <= 0)
+ fprintf(stderr, "%d: too many fields\n", nval), exit(1);
+ bs = csv_addval(v, bufsize, nval, eatof(field), epoch);
+ }
+ if (ncol > 0)
+ fprintf(stderr, "%d: too few fields\n", nval), exit(1);
+
+ return bs;
+}
+
+/*
+ * < ncol >
+ * epoch,a1,b1,c1 ^
+ * epoch,a2,b2,c2 nval
+ * epoch,a3,b3,c3 v
+ */
+static void
+csv_values(Vlist *v, int ncol)
+{
+ int nval, bufsize;
+ char line[LINE_MAX];
+
+ bufsize = 0;
+ for (nval = 0; esfgets(line, sizeof(line), stdin) != NULL; nval++)
+ bufsize = csv_addrow(v, bufsize, ncol, nval, line);
+ if (nval == 0)
+ fputs("no value could be read\n", stderr), exit(1);
+}
+
+static void
+usage(void)
+{
+ Clist *c;
+
+ fprintf(stderr, "usage: %s [-t title] [-u unit] {", argv0);
+ fputs(clist->name, stderr);
+ for (c = clist + 1; c->name != NULL; c++)
+ fprintf(stderr, ",%s", c->name);
+ fputs("}...\n", stderr);
+ exit(1);
+}
+
+int
+main(int argc, char **argv)
+{
+ Vlist *v;
+ char labels[LINE_MAX];
+
+ ARGBEGIN {
+ case 't':
+ tflag = EARGF(usage());
+ break;
+ case 'u':
+ uflag = EARGF(usage());
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if ((v = calloc(argc, sizeof(*v))) == NULL)
+ perror("calloc value list"), exit(1);
+
+ csv_labels(v, argv, labels);
+ csv_values(v, argc);
+
+ ff(v, argc, tflag, uflag);
+
+ return 0;
+}
(DIR) diff --git a/ploot.1 b/ploot.1
@@ -1,94 +0,0 @@
-.Dd $Mdocdate: February 15 2018$
-.Dt PLOOT 1
-.Os
-.
-.
-.Sh NAME
-.
-.Nm ploot
-.Nd plain text plotting tool
-.
-.
-.Sh SYNOPSIS
-.
-.Nm
-.Op Fl h Ar height
-.Op Fl o Ar offset
-.Op Fl t Ar title
-.
-.
-.Sh DESCRIPTION
-.
-The
-.Nm
-utility reads decimal values from stdin and print a plain text graph
-of the values to stdout.
-The values are separated by blanks or newlines, and can be either a plain
-list or a time serie
-.Po
-if the
-.Fl o
-flag is set
-.Pc
-.
-.Bl -tag -width 6n
-.
-.It Fl h Ar height
-Sets the height of the plot in characters.
-.
-.It Fl o Ar offset
-Read data as time series: the input alternates UNIX epoch and value
-to be plotted.
-The time stamps are assumed to be at an interval of
-.Ar offset .
-.
-.It Fl t Ar title
-Print
-.Ar title
-centered at the bottom of the graph.
-.
-.El
-.
-.
-.Sh EXIT STATUS
-.
-.Ex -std
-.
-.
-.Sh EXAMPLES
-.
-.Bd -literal
-% awk 'BEGIN { for (i=0; i<60; i++) print sin(i/3)+1 }' | ploot -h 10 -t List
-
- | .... .... ....
- 1.5963 -| ::::::. ::::::. .:::::: .:
- |.::::::::. .::::::::. .::::::::. .::
- 0.7982 -|::::::::::: .::::::::::. .::::::::::. ::::
- |::::::::::::. ::::::::::::::. .:::::::::::::: .:::::
- 0 -+------------------------------------------------------------
- List
-.Ed
-.
-.Bd -literal
-% ploot -h 8 -o 200 -t 'Time series'
-1518780448 12 1518780643 13 1518780848 31 1518781028 19 1518781291 23
-1518781423 20 1518781687 10 1518781819 13 1518782215 22 1518782412 11
-1518782632 18 1518782822 11 1518783039 16 1518783235 21 1518783499 21
-1518786629 30 1518786812 28 1518787012 11 1518787202 11 1518787433 11
-1518787629 10 1518788042 16 1518788333 29 1518788494 26 1518788633 12
-1518788821 28 1518789072 11 1518789201 11 1518789421 11 1518789630 11
-
- 31.000 -| : .. . .
- | : .. . .. :: :: :
- 15.500 -|..:::: . : : ::: :: :::.:
- |:::::::: ::::::: :::::: :::::::::
- 0 -+--------x-------xxxxxxxxxxxxxxx------x---------
- 12:27 12:50 13:14 13:37 14:00 14:24 14:47
- 2018/02/16 2018/02/16
- Time series
-.Ed
-.
-.Pp
-The
-.Sq x
-symbols on the horizontal axis represent a lack of data for that interval.
(DIR) diff --git a/ploot.c b/ploot.c
@@ -1,154 +0,0 @@
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "arg.h"
-#include "ploot.h"
-#include "util.h"
-#include "config.h" /* after ploot.h for type definitions */
-
-char *argv0;
-char *tflag = "";
-char *uflag = "";
-
-static int
-color(Color *col, char *name)
-{
- ColorList *c;
-
- for (c = colorlist; c->name != NULL; c++) {
- if (strcmp(name, c->name) == 0) {
- memcpy(col, &c->col, sizeof(*col));
- return 0;
- }
- }
-
- return -1;
-}
-
-static void
-read_labels(Vlist *v, char **argv, char *buf)
-{
- if (esfgets(buf, LINE_MAX, stdin) == NULL)
- fputs("missing label line\n", stderr), exit(1);
-
- if (strcmp(strsep(&buf, ","), "epoch") != 0)
- fputs("first label must be \"epoch\"\n", stderr), exit(1);
-
- for (; *argv != NULL; v++, argv++)
- if ((v->label = strsep(&buf, ",")) == NULL)
- fputs("more arguments than columns\n", stderr), exit(1);
- else if (color(&v->col, *argv) == -1)
- fprintf(stderr, "unknown color: %s\n", *argv), exit(1);
-
- if (strsep(&buf, ",") != NULL)
- fputs("more columns than arguments\n", stderr), exit(1);
-}
-
-static int
-add_val(Vlist *v, int bufsize, int nval, double field, time_t epoch)
-{
- if (nval >= bufsize) {
- bufsize = bufsize * 2 + 1;
- if ((v->v = realloc(v->v, bufsize * sizeof(*v->v))) == NULL)
- perror("reallocating values buffer"), exit(1);
- if ((v->t = realloc(v->t, bufsize * sizeof(*v->t))) == NULL)
- perror("reallocating values buffer"), exit(1);
- }
- v->v[nval] = field;
- v->t[nval] = epoch;
- v->n = nval + 1;
-
- return bufsize;
-}
-
-/*
- * Add to each column the value on the current row.
- */
-static int
-add_row(Vlist *v, int bufsize, int ncol, int nval, char *line)
-{
- time_t epoch;
- int bs;
- char *field, *dot;
-
- if ((field = strsep(&line, ",")) == NULL)
- fprintf(stderr, "%d: missing epoch\n", nval), exit(1);
-
- if ((dot = strchr(field, '.')) != NULL)
- *dot = '\0';
- epoch = eatol(field);
- for (; (field = strsep(&line, ",")) != NULL; ncol--, v++) {
- if (ncol <= 0)
- fprintf(stderr, "%d: too many fields\n", nval), exit(1);
- bs = add_val(v, bufsize, nval, eatof(field), epoch);
- }
- if (ncol > 0)
- fprintf(stderr, "%d: too few fields\n", nval), exit(1);
-
- return bs;
-}
-
-/*
- * < ncol >
- * epoch,a1,b1,c1 ^
- * epoch,a2,b2,c2 nval
- * epoch,a3,b3,c3 v
- */
-static void
-read_values(Vlist *v, int ncol)
-{
- int nval, bufsize;
- char line[LINE_MAX];
-
- bufsize = 0;
- for (nval = 0; esfgets(line, sizeof(line), stdin) != NULL; nval++)
- bufsize = add_row(v, bufsize, ncol, nval, line);
- if (nval == 0)
- fputs("no value could be read\n", stderr), exit(1);
-}
-
-static void
-usage(void)
-{
- ColorList *c;
-
- fprintf(stderr, "usage: %s [-t title] [-u unit] {", argv0);
- fputs(colorlist->name, stderr);
- for (c = colorlist + 1; c->name != NULL; c++)
- fprintf(stderr, ",%s", c->name);
- fputs("}...\n", stderr);
- exit(1);
-}
-
-int
-main(int argc, char **argv)
-{
- Vlist *v;
- char labels[LINE_MAX];
-
- ARGBEGIN {
- case 't':
- tflag = EARGF(usage());
- break;
- case 'u':
- uflag = EARGF(usage());
- break;
- default:
- usage();
- } ARGEND;
-
- if ((v = calloc(argc, sizeof(*v))) == NULL)
- perror("calloc value list"), exit(1);
-
- read_labels(v, argv, labels);
- read_values(v, argc);
-
- ffplot(v, argc, tflag, uflag);
-
- return 0;
-}
(DIR) diff --git a/ploot.h b/ploot.h
@@ -1,49 +0,0 @@
-#include <time.h>
-#include <stdint.h>
-
-typedef uint16_t Color[4];
-
-typedef struct {
- int w; /* width */
- int h; /* height */
- Color *b; /* buffer */
- int x; /* x offset */
- int y; /* x offset */
-} Canvas;
-
-typedef struct {
- int w; /* width */
- int h; /* height */
- char *b[128]; /* buffer */
-} Font;
-
-typedef struct {
- Color col; /* for drawing the curve and the legend */
- time_t *t; /* array of timestamps */
- double *v; /* array of values */
- int n; /* number of values */
- char *label; /* for the legend */
-} Vlist;
-
-typedef struct {
- char *name;
- Color col;
-} ColorList;
-
-/* ffdraw.c */
-void ffdraw_pixel (Canvas *, Color *, int, int);
-void ffdraw_rectangle(Canvas *, Color *, int, int, int, int);
-void ffdraw_line (Canvas *, Color *, int, int, int, int);
-void ffdraw_char (Canvas *, Color *, char, Font *, int, int);
-void ffdraw_str_left(Canvas *, Color *, char *, Font *, int, int);
-void ffdraw_str_center(Canvas *, Color *, char *, Font *, int, int);
-void ffdraw_str_right(Canvas *, Color *, char *, Font *, int, int);
-void ffdraw_fill (Canvas *, Color *);
-void ffdraw_print (Canvas *);
-
-/* ffplot.c */
-void ffplot (Vlist *, int, char *, char *);
-
-/* util.c */
-char *strsep (char **, const char *);
-
(DIR) diff --git a/plootxt.c b/plootxt.c
@@ -1,247 +0,0 @@
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <string.h>
-#include <ctype.h>
-
-#include "arg.h"
-#include "util.h"
-
-#define LEN(x) (sizeof(x) / sizeof(*x))
-
-#define WIDTH_MAX 1024
-#define BRAILLE_START 10240
-
-int wflag = 80;
-int width;
-
-char *argv0;
-
-/*
- * Turn the bit at position (row, col) on in the .
- */
-static void
-plot_dot(long *out, int row, int col)
-{
- long flags[4][2] = {
- { 0x01, 0x08 },
- { 0x02, 0x10 },
- { 0x04, 0x20 },
- { 0x40, 0x80 },
- };
-
- *out |= flags[row][col];;
-}
-
-static void
-plot_val(long *out, double val, double max, int row)
-{
- int col, c;
-
- val = MIN(max, val);
- col = (int)(val * (double)(width - 1) / max * 2);
- for (c = 0; c < col; c++)
- plot_dot(out + c / 2, row, c % 2);
-}
-
-/*
- * Change the braille characters on a whole row, this for all the
- * values line.
- */
-static time_t
-plot_row(long *out, char *line, double *max, int nrow, int ncol)
-{
- time_t epoch;
- double val;
- int n;
- char *tok;
-
- if ((tok = strsep(&line, ",")) == NULL)
- fputs("*** missing epoch value\n", stderr), exit(1);
- epoch = eatol(tok);
-
- for (n = 0; (tok = strsep(&line, ",")) != NULL; n++) {
- if (n >= ncol)
- fputs("too many values\n", stderr), exit(1);
- val = atof(tok);
- plot_val(out + n * width, val, max[n], nrow);
- }
- if (n < ncol)
- fputs("not enough values\n", stderr), exit(1);
-
- return epoch;
-}
-
-/*
- * Read enough input in order to print one line and plot it into 'out'.
- */
-static time_t
-plot_line(long *out, double *max, int ncol)
-{
- time_t epoch;
- int n, nrow;
- long *o, rune;
- char line[LINE_MAX];
-
- for (rune = BRAILLE_START, o = out, n = ncol * width; n > 0; o++, n--)
- memcpy(o, &rune, sizeof(rune));
- *o = '\0';
- for (rune = 0x2502, o = out, n = 0; n < ncol; o += width, n++)
- memcpy(o, &rune, sizeof(rune));
- out++;
-
- for (nrow = 0; nrow < 4; nrow++) {
- if ((esfgets(line, LINE_MAX, stdin)) == NULL)
- exit(0);
- epoch = plot_row(out, line, max, nrow, ncol);
- }
-
- return epoch;
-}
-
-static void
-put_time(time_t epoch, time_t last, int nline)
-{
- char *out, buf[sizeof("XXxXXxXX ")];
-
- switch (nline % 3) {
- case 0:
- strftime(buf, sizeof(buf), "%H:%M:%S _", localtime(&epoch));
- out = buf;
- break;
- case 1:
- strftime(buf, sizeof(buf), "%y/%m/%d ", localtime(&last));
- out = buf;
- break;
- case 2:
- out = " ";
- break;
- }
-
- fputs(out, stdout);
-}
-
-static void
-print_utf8_3bytes(long rune)
-{
- putchar((char)(0xe0 | (0x0f & (rune >> 12)))); /* 1110xxxx */
- putchar((char)(0x80 | (0x3f & (rune >> 6)))); /* 10xxxxxx */
- putchar((char)(0x80 | (0x3f & (rune)))); /* 10xxxxxx */
-}
-
-static void
-put_line(long *out)
-{
- for (; *out != '\0'; out++)
- print_utf8_3bytes(*out);
- puts("│");
-}
-
-static void
-plot(char labels[LINE_MAX], double *max, int ncol)
-{
- time_t epoch, last_epoch;
- long out[WIDTH_MAX + 1];
- int n;
-
- last_epoch = epoch = 0;
-
- for (n = 0;; n = n == 25 ? 0 : n + 1) {
- if (n == 0)
- put_time(0, 0, 2), fputs(labels, stdout), puts("│");
-
- epoch = plot_line(out, max, ncol);
- put_time(epoch, last_epoch, n);
- last_epoch = epoch;
- put_line(out);
-
- fflush(stdout);
- }
-}
-
-/*
- * Label must be able to store all pointers to token buf has to
- * offer: sizeof(*buf / 2).
- */
-static int
-read_labels(char *labv[LINE_MAX])
-{
- int ncol;
- char *l, line[LINE_MAX], *tok;
-
- if ((l = esfgets(line, LINE_MAX, stdin)) == NULL)
- fputs("missing label line\n", stderr), exit(1);
-
- if (strcmp(strsep(&l, ","), "epoch") != 0)
- fputs("first label must be \"epoch\"\n", stderr), exit(1);
-
- for (ncol = 0; (tok = strsep(&l, ",")) != NULL; ncol++, labv++)
- *labv = tok;
- *labv = NULL;
-
- if (ncol < 1)
- fputs("no label found\n", stderr), exit(1);
-
- return ncol;
-}
-
-static void
-fmt_labels(char out[LINE_MAX], int ncol, char *labels[LINE_MAX / 2])
-{
- int i, n;
-
- for (i = 0; i < ncol; labels++, i++) {
- n = LINE_MAX - (width + sizeof("│")) * i;
- out += snprintf(out, n, "│%-*s", width - 1, *labels);
- }
-}
-
-static void
-usage(void)
-{
- fprintf(stderr, "usage: %s [-w width] maxval... <csv\n", argv0);
- exit(1);
-}
-
-static int
-parse_args(int argc, char **argv, double *max)
-{
- int n;
-
- ARGBEGIN {
- case 'w':
- wflag = atoi(EARGF(usage()));
- break;
- default:
- usage();
- } ARGEND;
-
- if (argc == 0)
- usage();
-
- for (n = argc; n > 0; n--, argv++, max++)
- *max = eatof(*argv);
-
- return argc;
-}
-
-int
-main(int argc, char **argv)
-{
- double max[LINE_MAX / 2];
- int ncol, nmax;
- char *labv[LINE_MAX / 2], labels[LINE_MAX];
-
- setvbuf(stdin, NULL, _IOLBF, 0);
- nmax = parse_args(argc, argv, max);
- ncol = read_labels(labv);
- width = (wflag - sizeof("XXxXXxXX _")) / ncol - sizeof("|");
- fmt_labels(labels, ncol, labv);
- if (ncol != nmax)
- fputs("not as many labels and arguments\n", stderr), exit(1);
- plot(labels, max, ncol);
-
- return 0;
-}
(DIR) diff --git a/util.c b/util.c
@@ -5,7 +5,15 @@
#include <stdlib.h>
#include <ctype.h>
-#include "ploot.h"
+#include "util.h"
+
+void
+put3utf(long rune)
+{
+ putchar((char)(0xe0 | (0x0f & (rune >> 12)))); /* 1110xxxx */
+ putchar((char)(0x80 | (0x3f & (rune >> 6)))); /* 10xxxxxx */
+ putchar((char)(0x80 | (0x3f & (rune)))); /* 10xxxxxx */
+}
char *
strsep(char **strp, const char *sep)
@@ -69,3 +77,28 @@ esfgets(char *buf, size_t n, FILE *file)
estriplf(buf);
return buf;
}
+
+/*
+ * Set 'str' to a human-readable form of 'num' with always a width of 8 (+ 1
+ * the '\0' terminator). Buffer overflow is ensured not to happen due to the
+ * max size of a double. Return the exponent.
+ */
+int
+humanize(char *str, double val)
+{
+ int exp, precision;
+ char label[] = { '\0', 'M', 'G', 'T', 'E' };
+
+ for (exp = 0; ABS(val) > 1000; exp++)
+ val /= 1000;
+
+ precision = (ABS(val) < 10) ? 2 : (ABS(val) < 100) ? 1 : 0;
+ precision += (exp == 0);
+
+ snprintf(str, 9, "%+.*f %c", precision, val, label[exp]);
+ str[8] = '\0';
+ if (val >= 0)
+ str[0] = ' ';
+
+ return exp * 3;
+}
(DIR) diff --git a/util.h b/util.h
@@ -1,10 +1,12 @@
-#define MIN(x, y) ((x) < (y) ? (x) : (y))
-#define MAX(x, y) ((x) > (y) ? (x) : (y))
-#define LEN(x) (sizeof(x) / sizeof(*x))
+#define LEN(x) (sizeof(x) / sizeof(*x))
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+#define ABS(x) ((x) < 0 ? -(x) : (x))
-/* util.c */
+void put3utf (long);
char *strsep (char **, const char *);
void estriplf (char *);
double eatof (char *);
long eatol (char *);
char *esfgets (char *, size_t, FILE *);
+int humanize (char *, double);