Pannyx

devel

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

%