Request #11
~/devel/sleek
% pp sandbox_24002_m.c
#include <daejana.h>
#include <termios.h>
#include <sys/ioctl.h>
static struct termios termios_st;
static struct termios b_termios_st;
int
main (int argc, char * argv [])
{
uint8_t u;
error_flag = false;
printf("\n");
if (!( isatty(STDIN_FILENO))) { goto L2; }
tcgetattr(STDIN_FILENO, & termios_st);
b_termios_st = termios_st;
termios_st.c_lflag &= ~(ICANON | ECHO | IEXTEN | ISIG);
termios_st.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
termios_st.c_cflag &= ~(CSIZE | PARENB);
termios_st.c_cflag |= CS8;
termios_st.c_cc[VMIN] = 1;
termios_st.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSAFLUSH, & termios_st);
while (true) {
if (fread(& u, sizeof (uint8_t), 1, stdin) < 1) { ouch(); goto L1; }
if (u == 0x04) { goto L1; }
if (u == 0x20) { printf(" "); goto L0; }
if (u == 0x0d) { printf("\n"); goto L0; }
printf(" %02hhx", u);
L0:
;
}
L1:
printf("\n");
tcsetattr(STDIN_FILENO, TCSAFLUSH, & b_termios_st);
L2:
if (error_flag) { exit(EXIT_FAILURE); }
return EXIT_SUCCESS;
}
// sandbox_24002_m.c
% gcc -c -I${HOME}/devel/proto/aej sandbox_24002_m.c && { gcc -o sandbox_24002_m ~/devel/proto/aej/daejana.o sandbox_24002_m.o && {
↪ ./sandbox_24002_m; rm sandbox_24002_m; }; rm sandbox_24002_m.o; }
1b 5b 5a 1b 5b 33 7e 1b 5b 33 3b 32 7e
1b 5b 43 1b 5b 41 1b 5b 44 1b 5b 42
1b 5b 31 3b 32 43 1b 5b 31 3b 32 44
1b 66 1b 62
c2 a0 40 0a 7f 08
% mkdir -p ~/devel/swift/Aej_c
% cd !$
% swift package init --type empty
Creating empty package: Aej_c
Creating Package.swift
% mkdir -p ~/devel/swift/Aej_c/Sources/Aej_c/include
% cd !$
% stt Aej_c.h
Aej_c.h
% cd ~/devel/swift/Aej_c/Sources/Aej_c
% stt Aej_c.c
Aej_c.c
% mkdir -p ~/devel/swift/Aej
% cd !$
% swift package init --type executable
Creating executable package: Aej
Creating Package.swift
Creating .gitignore
% mkdir -p ~/devel/swift/Aej/Sources/Resources
% cdw
~/devel/swift/Aej/Sources
% stt Daejana.swift main.swift
% stm Quickie_24001.swift
main.swift
% pp ~/devel/swift/Aej_c/Package.swift
// swift-tools-version: 5.10
import PackageDescription
let package = Package(
name: "Aej_c",
products: [
.library(name: "Aej_c", targets: ["Aej_c"])
],
targets: [
.target(name: "Aej_c")
]
)
// ~/devel/swift/Aej_c/Package.swift
% pp ~/devel/swift/Aej_c/Sources/Aej_c/Aej_c.c
#include <Aej_c.h>
#include <termios.h>
#include <sys/ioctl.h>
struct termios termios_st;
struct termios b_termios_st;
struct winsize winsize_st;
void
switch_terminal_mode_immediate_on (int_t * w, int_t * h)
{
if (!( isatty(STDIN_FILENO))) { return; }
tcgetattr(STDIN_FILENO, & termios_st);
b_termios_st = termios_st;
termios_st.c_lflag &= ~(ICANON | ECHO | IEXTEN | ISIG);
termios_st.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
termios_st.c_cflag &= ~(CSIZE | PARENB);
termios_st.c_cflag |= CS8;
termios_st.c_cc[VMIN] = 1;
termios_st.c_cc[VTIME] = 0;
tcsetattr(STDIN_FILENO, TCSAFLUSH, & termios_st);
ioctl(1, TIOCGWINSZ, & winsize_st);
* w = int_c( winsize_st.ws_col);
* h = int_c( winsize_st.ws_row);
return;
}
void
switch_terminal_mode_immediate_off (void)
{
if (!( isatty(STDIN_FILENO))) { return; }
tcsetattr(STDIN_FILENO, TCSAFLUSH, & b_termios_st);
return;
}
uint64_t
getk (void)
{
uint8_t k [sizeof (uint64_t) * sizeof (uint8_t)];
uint8_t u;
int_t j;
int_t n;
if (fread(& u, sizeof (uint8_t), 1, stdin) < 1) { * (uint64_t *) k = 0x000000000000001b; goto Ll; }
* (uint64_t *) k = 0x0000000000000000;
if (u < 0x80) {
k[0] = u;
if (u == 0x1b) {
j = 0;
if (fread(& u, sizeof (uint8_t), 1, stdin) < 1) { * (uint64_t *) k = 0x000000000000001b; goto Ll; }
j += 1;
switch (u) {
case 0x5b:
k[j] = u;
if (fread(& u, sizeof (uint8_t), 1, stdin) < 1) { * (uint64_t *) k = 0x000000000000001b; goto Ll; }
j += 1;
switch (u) {
case 0x31:
k[j] = u;
if (fread(& u, sizeof (uint8_t), 1, stdin) < 1) { * (uint64_t *) k = 0x000000000000001b; goto Ll; }
j += 1;
if (u == 0x3b) {
k[j] = u;
if (fread(& u, sizeof (uint8_t), 1, stdin) < 1) { * (uint64_t *) k = 0x000000000000001b; goto Ll; }
j += 1;
if (u == 0x32) {
k[j] = u;
if (fread(& u, sizeof (uint8_t), 1, stdin) < 1) { * (uint64_t *) k = 0x000000000000001b; goto Ll; }
j += 1;
if (u == 0x43) { // right_shift ← 0x000043323b315b1b
k[j] = u;
goto Ll;
}
else if (u == 0x44) { // left_shift ← 0x000044323b315b1b
k[j] = u;
goto Ll;
}
}
}
* (uint64_t *) k = 0x000000000000001b; goto Ll;
case 0x33:
k[j] = u;
if (fread(& u, sizeof (uint8_t), 1, stdin) < 1) { * (uint64_t *) k = 0x000000000000001b; goto Ll; }
j += 1;
switch (u) {
case 0x3b:
k[j] = u;
if (fread(& u, sizeof (uint8_t), 1, stdin) < 1) { * (uint64_t *) k = 0x000000000000001b; goto Ll; }
j += 1;
if (u == 0x32) {
k[j] = u;
if (fread(& u, sizeof (uint8_t), 1, stdin) < 1) { * (uint64_t *) k = 0x000000000000001b; goto Ll; }
j += 1;
if (u == 0x7e) { // delete_shift ← 0x00007e323b335b1b
k[j] = u;
goto Ll;
}
}
* (uint64_t *) k = 0x000000000000001b; goto Ll;
case 0x7e: // delete ← 0x000000007e335b1b
k[j] = u;
goto Ll;
default:
* (uint64_t *) k = 0x000000000000001b; goto Ll;
}
case 0x41: // up ← 0x0000000000415b1b
case 0x42: // down ← 0x0000000000425b1b
case 0x43: // right ← 0x0000000000435b1b
case 0x44: // left ← 0x0000000000445b1b
case 0x5a: // tab_shift ← 0x00000000005a5b1b
k[j] = u;
goto Ll;
default:
* (uint64_t *) k = 0x000000000000001b; goto Ll;
}
case 0x62: // left_option ← 0x000000000000621b
case 0x66: // right_option ← 0x000000000000661b
k[j] = u;
goto Ll;
default:
* (uint64_t *) k = 0x000000000000001b; goto Ll;
}
}
goto Ll; // nonescape_7bit
}
else if (u < 0xc0) {
n = 0; // control_8bit
}
else if ((u & 0xe0) == 0xc0) {
// 110xxxxx u
// 11100000 e0
// 11000000 c0
n = 1; // utf8 (2 byte)
}
else if ((u & 0xf0) == 0xe0) {
// 1110xxxx u
// 11110000 f0
// 11100000 e0
n = 2; // utf8 (3 byte)
}
else {
// (u & 0xf8) == 0xf0
// 11110xxx u
// 11111000 f8
// 11110000 f0
// 0xef < u
// 11101111 ef
n = 3; // utf8 (4 byte)
}
k[0] = u;
j = 0;
while (0 < n) {
if (fread(& u, sizeof (uint8_t), 1, stdin) < 1) { * (uint64_t *) k = 0x000000000000001b; goto Ll; }
j += 1;
if ((u & 0xc0) == 0x80) {
// 10xxxxxx u
// 11000000 c0
// 10000000 80
k[j] = u;
}
else {
* (uint64_t *) k = 0x000000000000001b; goto Ll;
}
n -= 1;
}
Ll:
return * (uint64_t *) k;
}
// Aej_c.c
% pp ~/devel/swift/Aej_c/Sources/Aej_c/include/Aej_c.h
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
typedef int64_t int_t;
typedef uint64_t uint_t;
typedef double flt_t;
typedef bool bool_t;
#define int_c(Q) ((int_t)(Q))
#define uint_c(Q) ((uint_t)(Q))
void switch_terminal_mode_immediate_on (int_t *, int_t *);
void switch_terminal_mode_immediate_off (void);
uint64_t getk (void);
// Aej_c.h
% cd ~/devel/swift/Aej
% pp Package.swift
// swift-tools-version: 5.10
import PackageDescription
let package = Package(
name: "Aej",
dependencies: [
.package(path: "../Aej_c"),
],
targets: [
.executableTarget(
name: "Aej",
dependencies: [
.product(name: "Aej_c", package: "Aej_c"),
],
path: "Sources",
resources: [
.process("Resources/sample_01.log"),
.process("Resources/sample_02.log"),
.process("Resources/sample_03.log"),
.process("Resources/sample_04.log"),
]
),
]
)
// ~/devel/swift/Aej/Package.swift
% cdw
~/devel/swift/Aej/Sources
% pp main.swift
private let a = [
"Quickie_24001" : Quickie_24001.main,
]
if 1 < CommandLine.arguments.count {
if let c = a[CommandLine.arguments[1]] {
c(Array(CommandLine.arguments[2...]))
print()
precondition(!error_flag)
}
}
// ~/devel/swift/Aej/Sources/main.swift
% pp Daejana.swift
var error_flag = false
func ouch (_ t: String...) -> Void
{
error_flag = true
print(t.reduce("Ouch! \u{2620}", { x, y in x + "\u{20}" + y }))
return
}
// Daejana.swift
% pp Quickie_24001.swift
import Aej_c
enum Quickie_24001 {
static let main = { (_ t : [String]) -> Void in
print(t.reduce("Quickie_24001", { x, y in x + "\u{20}" + y }) + " \u{2026}")
print()
defer { switch_terminal_mode_immediate_off() }; var screen_width : Int64 = 0, screen_height : Int64 = 0;
↪ switch_terminal_mode_immediate_on(&screen_width, &screen_height)
Ll: while true {
let k = getk()
print(String(format: "0x%016lx", k), terminator: " ")
let h = UInt8( k % 256)
if h == 0x1b {
switch (k) {
case 0x00000000005a5b1b: print("→ tab_shift")
case 0x000000007e335b1b: print("→ delete")
case 0x00007e323b335b1b: print("→ delete_shift")
case 0x0000000000435b1b: print("→ right")
case 0x0000000000415b1b: print("→ up")
case 0x0000000000445b1b: print("→ left")
case 0x0000000000425b1b: print("→ down")
case 0x000043323b315b1b: print("→ right_shift")
case 0x000044323b315b1b: print("→ left_shift")
case 0x000000000000661b: print("→ right_option")
case 0x000000000000621b: print("→ left_option")
default: ouch()
}
}
else if h < 0x80 {
if (32..<127).contains(h) {
if 0x20 < h {
print("→ nonspace_printable_7bit")
}
else {
print("→ space")
}
}
else {
print("→ nonescape_control_7bit")
if h == 0x04 {
break Ll;
}
}
}
else if h < 0xc0 {
print("→ control_8bit")
}
else {
print("→ printable_utf8", terminator: " ")
var a : [UInt8]
if h & 0xe0 == 0xc0 {
a = [UInt8( k % 256), UInt8( (k / 0x00000100) % 256)]
}
else if h & 0xf0 == 0xe0 {
a = [UInt8( k % 256), UInt8( (k / 0x00000100) % 256), UInt8( (k / 0x00010000) % 256)]
}
else { // 0xef < h, h & 0xf8 == 0xf0
a = [UInt8( k % 256), UInt8( (k / 0x00000100) % 256), UInt8( (k / 0x00010000) % 256), UInt8( (k / 0x01000000) % 256)]
}
if let s = String(bytes: a, encoding: .utf8) { print("\"", terminator: ""); print(s, terminator: ""); print("\""); }
}
}
return
}
}
// Quickie_24001.swift
% swb Quickie_24001
Building for debugging...
[8/8] Applying Aej
Build complete! (0.47s)
Quickie_24001 …
0x00000000005a5b1b → tab_shift
0x000000007e335b1b → delete
0x00007e323b335b1b → delete_shift
0x0000000000435b1b → right
0x0000000000415b1b → up
0x0000000000445b1b → left
0x0000000000425b1b → down
0x000043323b315b1b → right_shift
0x000044323b315b1b → left_shift
0x000000000000661b → right_option
0x000000000000621b → left_option
0x000000000000a0c2 → printable_utf8 " "
0x0000000000000020 → space
0x0000000000000040 → nonspace_printable_7bit
0x000000000000000d → nonescape_control_7bit
0x000000000000000a → nonescape_control_7bit
0x000000000000007f → nonescape_control_7bit
0x0000000000000008 → nonescape_control_7bit
0x0000000000000004 → nonescape_control_7bit
% cda
~/devel/proto/aej
% pp c_daejana.h
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
typedef int64_t int_t;
typedef uint64_t uint_t;
typedef double flt_t;
typedef bool bool_t;
#define int_c(Q) ((int_t)(Q))
#define uint_c(Q) ((uint_t)(Q))
void switch_terminal_mode_immediate_on (int_t *, int_t *);
void switch_terminal_mode_immediate_off (void);
uint64_t getk (void);
// c_daejana.h
% gcc -c -I${HOME}/devel/proto/aej c_daejana.c
% cdm
~/devel/quickie
% pp quickie_24001.c
#include <c_daejana.h>
int_t screen_width;
int_t screen_height;
int
main (int argc, char * argv [])
{
printf("\n");
switch_terminal_mode_immediate_on(& screen_width, & screen_height);
printf("%lld\n", getk());
switch_terminal_mode_immediate_off();
printf("\n");
printf("%lld\n", screen_width);
printf("%lld\n", screen_height);
printf("\n");
return EXIT_SUCCESS;
}
// quickie_24001.c
% gcc -c -I${HOME}/devel/proto/aej quickie_24001.c && { gcc -o quickie_24001 ${HOME}/devel/proto/aej/c_daejana.o quickie_24001.o && {
↪ ./quickie_24001; rm quickie_24001; }; rm quickie_24001.o; }
4
160
46
% cdp
~/devel/proto
% pp aej-c.ads
with Aej;
package Aej.C is
use Aej;
procedure Switch_Terminal_Immediate_Mode_On (W : out Int_T; H : out Int_T) with Import => true, Convention => C, External_Name =>
↪ "switch_terminal_immediate_mode_on";
procedure Switch_Terminal_Immediate_Mode_Off with Import => true, Convention => C, External_Name => "switch_terminal_immediate_mode_off";
function Getk return Uint_T with Import => true, Convention => C, External_Name => "getk";
end Aej.C;
% cdq
~/devel/quickie
% pp quickie_24001.adb
with Ada.Command_Line;
with Ada.Exceptions;
with Ada.Text_IO;
with Aej.C;
procedure Quickie_24001 is
use Ada; use Text_IO;
use Aej; use C;
use Int_IO; use Uint_IO;
Screen_Width : Int_T; Screen_Height : Int_T;
begin
Command_Line.Set_Exit_Status(Command_Line.Success);
New_Line;
Switch_Terminal_Immediate_Mode_On(Screen_Width, Screen_Height);
Put(Getk, Width => 1); New_Line;
Switch_Terminal_Immediate_Mode_Off;
New_Line;
Put(Screen_Width, Width => 1); New_Line;
Put(Screen_Height, Width => 1); New_Line;
New_Line;
return;
exception
when E : others =>
New_Line(Standard_Error);
New_Line(Standard_Error);
Put(Standard_Error, "** ");
Put(Standard_Error, Exceptions.Exception_Name(E));
Put(Standard_Error, "! (");
Put(Standard_Error, Exceptions.Exception_Message(E));
Put(Standard_Error, ")");
New_Line(Standard_Error);
New_Line;
Command_Line.Set_Exit_Status(Command_Line.Failure);
end Quickie_24001;
% gcc -c quickie_24001.adb && gcc -c ${HOME}/devel/proto/aej.ads && gcc -c ${HOME}/devel/proto/aej-c.ads && gnatbind -x quickie_24001.ali &&
↪ gnatlink ${HOME}/devel/proto/aej/c_daejana.o quickie_24001.ali && { ./quickie_24001; gnatclean -q quickie_24001; }
4
160
46
% cda
~/devel/proto/aej
% pp scm_daejana.c daejana.scm
#include <c_daejana.h>
#include <libguile.h>
SCM
scm_switch_terminal_mode_immediate_on (SCM p, SCM q)
{
int_t w; int_t h;
switch_terminal_mode_immediate_on(& w, & h);
scm_set_car_x(p, scm_from_int64(w));
scm_set_car_x(q, scm_from_int64(h));
return scm_from_utf8_symbol("nil");
}
SCM
scm_switch_terminal_mode_immediate_off (void)
{
switch_terminal_mode_immediate_off();
return scm_from_utf8_symbol("nil");
}
SCM
scm_getk (void)
{
return scm_from_uint64(getk());
}
void
scm_daejana (void)
{
scm_c_define_gsubr("switch_terminal_mode_immediate_on", 2, 0, 0, scm_switch_terminal_mode_immediate_on);
scm_c_define_gsubr("switch_terminal_mode_immediate_off", 0, 0, 0, scm_switch_terminal_mode_immediate_off);
scm_c_define_gsubr("getk", 0, 0, 0, scm_getk);
return;
}
// scm_daejana.c
(define-module (aej daejana)
#:export (
switch_terminal_mode_immediate_on switch_terminal_mode_immediate_off getk
)
)
(load-extension "libguile-daejana" "scm_daejana")
; daejana.scm
% gcc -c -I${HOME}/devel/proto/aej -D_THREAD_SAFE -I/opt/local/include/guile/2.2 -I/opt/local/include scm_daejana.c && gcc -L/opt/local/lib
↪ -lguile-2.2 -lgc -lpthread -shared -o libguile-daejana.dylib -fPIC c_daejana.o scm_daejana.o
% cdm
~/devel/quickie
% pp quickie_24001.scm
(use-modules (aej daejana))
((lambda ()
(newline)
(let (
(w (cons 'nil '()))
(h (cons 'nil '()))
)
(switch_terminal_mode_immediate_on w h)
(display (getk)) (newline)
(switch_terminal_mode_immediate_off)
(let (
(screen-width (car w))
(screen-height (car h))
)
(newline)
(display screen-width) (newline)
(display screen-height) (newline)
)
)
(newline)
(exit #t)
)
)
; quickie_24001.scm
% scm quickie_24001.scm
4
160
46
% cda
~/devel/proto/aej
% pp caml_daejana.c daejana.ml
#include <c_daejana.h>
#define CAML_NAME_SPACE
#include <caml/mlvalues.h>
#include <caml/memory.h>
value
caml_switch_terminal_mode_immediate_on (value p, value q)
{
int_t w; int_t h;
CAMLparam2(p, q);
switch_terminal_mode_immediate_on(& w, & h);
Store_field(p, 0, Val_int(w));
Store_field(q, 0, Val_int(h));
CAMLreturn(Val_unit);
}
value
caml_switch_terminal_mode_immediate_off (value z)
{
CAMLparam1(z);
switch_terminal_mode_immediate_off();
CAMLreturn(Val_unit);
}
value
caml_getk (value z)
{
CAMLparam1(z);
CAMLreturn(Val_int(getk()));
}
// caml_daejana.c
external switch_terminal_mode_immediate_on : int ref -> int ref -> unit = "caml_switch_terminal_mode_immediate_on"
external switch_terminal_mode_immediate_off : unit -> unit = "caml_switch_terminal_mode_immediate_off"
external getk : unit -> int = "caml_getk"
(* daejana.ml *)
% gcc -c -I${HOME}/devel/proto/aej c_daejana.c && gcc -c -I${HOME}/devel/proto/aej -I/opt/local/lib/ocaml caml_daejana.c && { ar -ru
↪ libcaml-daejana.a c_daejana.o caml_daejana.o; ocamlc -c daejana.ml; }
ar: creating archive libcaml-daejana.a
% cdm
~/devel/quickie
% pp quickie_24001.ml
open Daejana
;;
let _ =
print_newline () ;
let w = ref 0 and h = ref 0 in (
switch_terminal_mode_immediate_on w h ;
print_int (getk ()) ; print_newline () ;
switch_terminal_mode_immediate_off () ;
let screen_width = ! w and screen_height = ! h in (
print_newline () ;
print_int screen_width ; print_newline () ;
print_int screen_height ; print_newline ()
)
) ;
print_newline () ;
ignore ()
;;
(* quickie_24001.ml *)
% ocamlc -c -I ~/devel/proto/aej quickie_24001.ml && { ocamlc -o quickie_24001 -custom -I ${HOME}/devel/proto/aej daejana.cmo quickie_24001.cmo
↪ -cclib -lcaml-daejana && { ./quickie_24001; rm quickie_24001; }; rm quickie_24001.cmi quickie_24001.cmo; }
4
160
46
%