Initial commit.
This commit is contained in:
commit
a5fa886a6f
18
Makefile
Normal file
18
Makefile
Normal file
@ -0,0 +1,18 @@
|
||||
CC=gcc
|
||||
PREFIX=/usr/local
|
||||
LIBS=-lncurses
|
||||
|
||||
all: build
|
||||
|
||||
clean:
|
||||
rm ascii
|
||||
|
||||
ascii: ascii.c
|
||||
$(CC) ascii.c $(LIBS) -o ascii
|
||||
|
||||
build: ascii
|
||||
|
||||
install: ascii
|
||||
install -d $(PREFIX)/bin
|
||||
install -m 755 ascii $(PREFIX)/bin
|
||||
|
228
ascii.c
Normal file
228
ascii.c
Normal file
@ -0,0 +1,228 @@
|
||||
/**
|
||||
ASCII Table Utility
|
||||
|
||||
A simple utility that uses ncurses to display the ASCII table and lets you
|
||||
manually output ASCII characters one byte at a time. Use arrow keys or
|
||||
h/j/k/l to move, 'enter' to add a character to the output, and 'q' or escape
|
||||
to quit and print the output.
|
||||
|
||||
Copyright 2018 Bruce Hill
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <curses.h>
|
||||
#include <unistd.h>
|
||||
#include <ncurses.h>
|
||||
|
||||
// The descriptive names of the ASCII characters
|
||||
const char *NAMES[128][2] = {
|
||||
{"NUL", "null"}, // 0
|
||||
{"SOH", "start of heading"}, // 1
|
||||
{"STX", "start of text"}, // 2
|
||||
{"ETX", "end of text"}, // 3
|
||||
{"EOT", "end of transmission"}, // 4
|
||||
{"ENQ", "enquiry"}, // 5
|
||||
{"ACK", "acknowledge"}, // 6
|
||||
{"BEL", "bell"}, // 7
|
||||
{"BS", "backspace"}, // 8
|
||||
{"TAB", "horizontal tab"}, // 9
|
||||
{"LF", "NL line feed, new line"}, // 10
|
||||
{"VT", "vertical tab"}, // 11
|
||||
{"FF", "NP form feed, new page"}, // 12
|
||||
{"CR", "carriage return"}, // 13
|
||||
{"SO", "shift out"}, // 14
|
||||
{"SI", "shift in"}, // 15
|
||||
{"DLE", "data link escape"}, // 16
|
||||
{"DC1", "device control 1"}, // 17
|
||||
{"DC2", "device control 2"}, // 18
|
||||
{"DC3", "device control 3"}, // 19
|
||||
{"DC4", "device control 4"}, // 20
|
||||
{"NAK", "negative acknowledge"}, // 21
|
||||
{"SYN", "synchonous idle"}, // 22
|
||||
{"ETB", "end of transmission block"}, // 23
|
||||
{"CAN", "cancel"}, // 24
|
||||
{"EM", "end of medium"}, // 25
|
||||
{"SUB", "substitute"}, // 26
|
||||
{"ESC", "escape"}, // 27
|
||||
{"FS", "file separator"}, // 28
|
||||
{"GS", "group separator"}, // 29
|
||||
{"RS", "record separator"}, // 30
|
||||
{"US", "unit separator"}, // 31
|
||||
{" ", "space"}, // 32
|
||||
[127] = {"DEL", "delete"}
|
||||
};
|
||||
|
||||
#define DECIMAL_COLOR 1
|
||||
#define HEX_COLOR 2
|
||||
#define CHAR_COLOR 3
|
||||
#define DESCRIPTION_COLOR 4
|
||||
#define OUTPUT_CHAR_COLOR 5
|
||||
#define OUTPUT_ESCAPE_COLOR 6
|
||||
|
||||
const int COL_WIDTH = 42;
|
||||
int W = 0;
|
||||
int H = 0;
|
||||
|
||||
// Draw the information for one character
|
||||
static inline void draw_char(int i)
|
||||
{
|
||||
int x = (i / (H-1)) * COL_WIDTH;
|
||||
int y = i % (H-1);
|
||||
color_set(DECIMAL_COLOR, NULL);
|
||||
mvprintw(y, x, "%3d ", i);
|
||||
x += 4;
|
||||
color_set(HEX_COLOR, NULL);
|
||||
mvprintw(y, x, " 0x%02X ", i);
|
||||
x += 6;
|
||||
color_set(CHAR_COLOR, NULL);
|
||||
if (NAMES[i][0]) {
|
||||
mvprintw(y, x, " %-3s ", NAMES[i][0]);
|
||||
} else {
|
||||
mvprintw(y, x, " %c ", i);
|
||||
}
|
||||
x += 5;
|
||||
if (NAMES[i][1]) {
|
||||
color_set(DESCRIPTION_COLOR, NULL);
|
||||
mvprintw(y, x, " %-25s", NAMES[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Redraw the parts of the ASCII table necessary for the selected item
|
||||
static void redraw(int selected)
|
||||
{
|
||||
static int last_selected = -1;
|
||||
if (selected == last_selected) return;
|
||||
if (last_selected == -1) {
|
||||
for (int i = 0; i < 128; i++) {
|
||||
if (i == selected) attr_on(A_REVERSE, NULL);
|
||||
else attr_off(A_REVERSE, NULL);
|
||||
draw_char(i);
|
||||
}
|
||||
} else {
|
||||
attr_on(A_REVERSE, NULL);
|
||||
draw_char(selected);
|
||||
attr_off(A_REVERSE, NULL);
|
||||
draw_char(last_selected);
|
||||
}
|
||||
refresh();
|
||||
last_selected = selected;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if (argc >= 2) {
|
||||
for (int i = 1; i < argc; i++) {
|
||||
putc(atoi(argv[i]), stdout);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t buf_size = 256, buf_i = 0;
|
||||
char *outbuf = calloc(buf_size, sizeof(char));
|
||||
|
||||
SCREEN *screen = newterm(NULL, stderr, stdin);
|
||||
set_term(screen);
|
||||
set_escdelay(5);
|
||||
W = getmaxx(stdscr);
|
||||
H = getmaxy(stdscr);
|
||||
noecho();
|
||||
keypad(stdscr, 1);
|
||||
curs_set(0);
|
||||
start_color();
|
||||
init_pair(DECIMAL_COLOR, COLOR_YELLOW, COLOR_BLACK);
|
||||
init_pair(HEX_COLOR, COLOR_GREEN, COLOR_BLACK);
|
||||
init_pair(CHAR_COLOR, COLOR_MAGENTA, COLOR_BLACK);
|
||||
init_pair(DESCRIPTION_COLOR, COLOR_WHITE, COLOR_BLACK);
|
||||
init_pair(OUTPUT_CHAR_COLOR, COLOR_BLACK, COLOR_WHITE);
|
||||
init_pair(OUTPUT_ESCAPE_COLOR, COLOR_RED, COLOR_WHITE);
|
||||
|
||||
// Bar at the bottom of the screen showing the output text
|
||||
attr_on(A_BOLD, NULL);
|
||||
attr_on(A_REVERSE, NULL);
|
||||
mvprintw(H-1, 0, " Output:");
|
||||
int output_x = 9;
|
||||
|
||||
int selected = 0;
|
||||
while (1) {
|
||||
redraw(selected);
|
||||
int key = getch();
|
||||
switch (key) {
|
||||
case 'j': case KEY_DOWN:
|
||||
selected++;
|
||||
break;
|
||||
|
||||
case 'J':
|
||||
selected += 10;
|
||||
break;
|
||||
|
||||
case 'k': case KEY_UP:
|
||||
selected--;
|
||||
break;
|
||||
|
||||
case 'K':
|
||||
selected -= 10;
|
||||
break;
|
||||
|
||||
case 'l': case 'L': case KEY_RIGHT: case KEY_SRIGHT:
|
||||
if (selected + H-1 < 128)
|
||||
selected += H-1;
|
||||
break;
|
||||
|
||||
case 'h': case 'H': case KEY_LEFT: case KEY_SLEFT:
|
||||
if (selected - H-1 >= 0)
|
||||
selected -= H-1;
|
||||
break;
|
||||
|
||||
case KEY_RESIZE:
|
||||
W = getmaxx(stdscr);
|
||||
H = getmaxy(stdscr);
|
||||
clear();
|
||||
break;
|
||||
|
||||
case KEY_ENTER: case '\n':
|
||||
outbuf[buf_i++] = (char)selected;
|
||||
if (buf_i >= buf_size) {
|
||||
buf_size *= 2;
|
||||
outbuf = realloc(outbuf, buf_size);
|
||||
}
|
||||
if (' ' <= selected && selected <= '~') { // printable range
|
||||
color_set(OUTPUT_CHAR_COLOR, NULL);
|
||||
mvprintw(H-1, output_x++, "%c", selected);
|
||||
} else {
|
||||
color_set(OUTPUT_ESCAPE_COLOR, NULL);
|
||||
mvprintw(H-1, output_x, "\\x%02X", selected);
|
||||
output_x += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'q': case 'Q': case KEY_CANCEL: case KEY_CLOSE: case KEY_EXIT: case 27:
|
||||
endwin();
|
||||
write(1, outbuf, buf_i);
|
||||
return 0;
|
||||
}
|
||||
if (selected < 0) selected = 0;
|
||||
if (selected >= 128) selected = 127;
|
||||
}
|
||||
|
||||
endwin();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user