Refactor C constants to be class constants of the C class
This commit is contained in:
parent
29026373b8
commit
78a91514b3
9
kilo
9
kilo
@ -3,7 +3,14 @@
|
|||||||
|
|
||||||
namespace Kilo;
|
namespace Kilo;
|
||||||
|
|
||||||
require_once __DIR__ . '/src/constants.php';
|
// -----------------------------------------------------------------------------
|
||||||
|
// ! App Constants
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
define('KILO_VERSION', '0.0.1');
|
||||||
|
define('KILO_TAB_STOP', 4);
|
||||||
|
define('KILO_QUIT_TIMES', 3);
|
||||||
|
|
||||||
|
require_once __DIR__ . '/src/C.php';
|
||||||
require_once __DIR__ . '/src/functions.php';
|
require_once __DIR__ . '/src/functions.php';
|
||||||
require_once __DIR__ . '/src/Editor.php';
|
require_once __DIR__ . '/src/Editor.php';
|
||||||
|
|
||||||
|
146
src/C.php
Normal file
146
src/C.php
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Kilo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just a namespace for C language constants
|
||||||
|
*/
|
||||||
|
class C {
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// ! Misc I/O constants
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
public const STDIN_FILENO = 0;
|
||||||
|
public const STDOUT_FILENO = 1;
|
||||||
|
public const STDERR_FILENO = 2;
|
||||||
|
public const TCSAFLUSH = 2;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// ! Termios flags and constants
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/* Input modes */
|
||||||
|
public const IGNBRK = (1 << 0); /* Ignore break condition. */
|
||||||
|
public const BRKINT = (1 << 1); /* Signal interrupt on break. */
|
||||||
|
public const IGNPAR = (1 << 2); /* Ignore characters with parity errors. */
|
||||||
|
public const PARMRK = (1 << 3); /* Mark parity and framing errors. */
|
||||||
|
public const INPCK = (1 << 4); /* Enable input parity check. */
|
||||||
|
public const ISTRIP = (1 << 5); /* Strip 8th bit off characters. */
|
||||||
|
public const INLCR = (1 << 6); /* Map NL to CR on input. */
|
||||||
|
public const IGNCR = (1 << 7); /* Ignore CR. */
|
||||||
|
public const ICRNL = (1 << 8); /* Map CR to NL on input. */
|
||||||
|
public const IXON = (1 << 9); /* Enable start/stop output control. */
|
||||||
|
public const IXOFF = (1 << 10); /* Enable start/stop input control. */
|
||||||
|
public const IXANY = (1 << 11); /* Any character will restart after stop. */
|
||||||
|
public const IMAXBEL = (1 << 13); /* Ring bell when input queue is full. */
|
||||||
|
public const IUCLC = (1 << 14); /* Translate upper case input to lower case. */
|
||||||
|
|
||||||
|
/* Output modes */
|
||||||
|
public const OPOST = (1 << 0); /* Perform output processing. */
|
||||||
|
public const ONLCR = (1 << 1); /* Map NL to CR-NL on output. */
|
||||||
|
public const OXTABS = (1 << 2); /* Expand tabs to spaces. */
|
||||||
|
public const ONOEOT = (1 << 3); /* Discard EOT (^D) on output. */
|
||||||
|
public const OCRNL = (1 << 4); /* Map CR to NL. */
|
||||||
|
public const ONOCR = (1 << 5); /* Discard CR's when on column 0. */
|
||||||
|
public const ONLRET = (1 << 6); /* Move to column 0 on NL. */
|
||||||
|
public const NLDLY = (3 << 8); /* NL delay. */
|
||||||
|
public const NL0 = (0 << 8); /* NL type 0. */
|
||||||
|
public const NL1 = (1 << 8); /* NL type 1. */
|
||||||
|
public const TABDLY = (3 << 10 | 1 << 2); /* TAB delay. */
|
||||||
|
public const TAB0 = (0 << 10); /* TAB delay type 0. */
|
||||||
|
public const TAB1 = (1 << 10); /* TAB delay type 1. */
|
||||||
|
public const TAB2 = (2 << 10); /* TAB delay type 2. */
|
||||||
|
public const TAB3 = (1 << 2); /* Expand tabs to spaces. */
|
||||||
|
public const CRDLY = (3 << 12); /* CR delay. */
|
||||||
|
public const CR0 = (0 << 12); /* CR delay type 0. */
|
||||||
|
public const CR1 = (1 << 12); /* CR delay type 1. */
|
||||||
|
public const CR2 = (2 << 12); /* CR delay type 2. */
|
||||||
|
public const CR3 = (3 << 12); /* CR delay type 3. */
|
||||||
|
public const FFDLY = (1 << 14); /* FF delay. */
|
||||||
|
public const FF0 = (0 << 14); /* FF delay type 0. */
|
||||||
|
public const FF1 = (1 << 14); /* FF delay type 1. */
|
||||||
|
public const BSDLY = (1 << 15); /* BS delay. */
|
||||||
|
public const BS0 = (0 << 15); /* BS delay type 0. */
|
||||||
|
public const BS1 = (1 << 15); /* BS delay type 1. */
|
||||||
|
public const VTDLY = (1 << 16); /* VT delay. */
|
||||||
|
public const VT0 = (0 << 16); /* VT delay type 0. */
|
||||||
|
public const VT1 = (1 << 16); /* VT delay type 1. */
|
||||||
|
public const OLCUC = (1 << 17); /* Translate lower case output to upper case */
|
||||||
|
public const OFILL = (1 << 18); /* Send fill characters for delays. */
|
||||||
|
public const OFDEL = (1 << 19); /* Fill is DEL. */
|
||||||
|
|
||||||
|
/* Control modes */
|
||||||
|
public const CIGNORE = (1 << 0); /* Ignore these control flags. */
|
||||||
|
public const CS5 = 0; /* 5 bits per byte. */
|
||||||
|
public const CS6 = (1 << 8); /* 6 bits per byte. */
|
||||||
|
public const CS7 = (1 << 9); /* 7 bits per byte. */
|
||||||
|
public const CS8 = (C::CS6|C::CS7); /* 8 bits per byte. */
|
||||||
|
public const CSIZE = (C::CS5|C::CS6|C::CS7|C::CS8); /* Number of bits per byte (mask). */
|
||||||
|
public const CSTOPB = (1 << 10); /* Two stop bits instead of one. */
|
||||||
|
public const CREAD = (1 << 11); /* Enable receiver. */
|
||||||
|
public const PARENB = (1 << 12); /* Parity enable. */
|
||||||
|
public const PARODD = (1 << 13); /* Odd parity instead of even. */
|
||||||
|
public const HUPCL = (1 << 14); /* Hang up on last close. */
|
||||||
|
public const CLOCAL = (1 << 15); /* Ignore modem status lines. */
|
||||||
|
public const CRTSCTS = (1 << 16); /* RTS/CTS flow control. */
|
||||||
|
public const CRTS_IFLOW = C::CRTSCTS; /* Compatibility. */
|
||||||
|
public const CCTS_OFLOW = C::CRTSCTS; /* Compatibility. */
|
||||||
|
public const CDTRCTS = (1 << 17); /* DTR/CTS flow control. */
|
||||||
|
public const MDMBUF = (1 << 20); /* DTR/DCD flow control. */
|
||||||
|
public const CHWFLOW = (C::MDMBUF|C::CRTSCTS|C::CDTRCTS); /* All types of flow control. */
|
||||||
|
|
||||||
|
/* Local modes */
|
||||||
|
public const ECHOKE = (1 << 0); /* Visual erase for KILL. */
|
||||||
|
public const _ECHOE = (1 << 1); /* Visual erase for ERASE. */
|
||||||
|
public const ECHOE = C::_ECHOE;
|
||||||
|
public const _ECHOK = (1 << 2); /* Echo NL after KILL. */
|
||||||
|
public const ECHOK = C::_ECHOK;
|
||||||
|
public const _ECHO = (1 << 3); /* Enable echo. */
|
||||||
|
public const ECHO = C::_ECHO;
|
||||||
|
public const _ECHONL = (1 << 4); /* Echo NL even if ECHO is off. */
|
||||||
|
public const ECHONL = C::_ECHONL;
|
||||||
|
public const ECHOPRT = (1 << 5); /* Hardcopy visual erase. */
|
||||||
|
public const ECHOCTL = (1 << 6); /* Echo control characters as ^X. */
|
||||||
|
public const _ISIG = (1 << 7); /* Enable signals. */
|
||||||
|
public const ISIG = C::_ISIG;
|
||||||
|
public const _ICANON = (1 << 8); /* Do erase and kill processing. */
|
||||||
|
public const ICANON = C::_ICANON;
|
||||||
|
public const ALTWERASE = (1 << 9); /* Alternate WERASE algorithm. */
|
||||||
|
public const _IEXTEN = (1 << 10); /* Enable DISCARD and LNEXT. */
|
||||||
|
public const IEXTEN = C::_IEXTEN;
|
||||||
|
public const EXTPROC = (1 << 11); /* External processing. */
|
||||||
|
public const _TOSTOP = (1 << 22); /* Send SIGTTOU for background output. */
|
||||||
|
public const TOSTOP = C::_TOSTOP;
|
||||||
|
public const FLUSHO = (1 << 23); /* Output being flushed (state). */
|
||||||
|
public const XCASE = (1 << 24); /* Canonical upper/lower case. */
|
||||||
|
public const NOKERNINFO = (1 << 25); /* Disable VSTATUS. */
|
||||||
|
public const PENDIN = (1 << 29); /* Retype pending input (state). */
|
||||||
|
public const _NOFLSH = (1 << 31); /* Disable flush after interrupt. */
|
||||||
|
public const NOFLSH = C::_NOFLSH;
|
||||||
|
|
||||||
|
/* Control characters */
|
||||||
|
public const VEOF = 0; /* End-of-file character [ICANON]. */
|
||||||
|
public const VEOL = 1; /* End-of-line character [ICANON]. */
|
||||||
|
public const VEOL2 = 2; /* Second EOL character [ICANON]. */
|
||||||
|
public const VERASE = 3; /* Erase character [ICANON]. */
|
||||||
|
public const VWERASE = 4; /* Word-erase character [ICANON]. */
|
||||||
|
public const VKILL = 5; /* Kill-line character [ICANON]. */
|
||||||
|
public const VREPRINT = 6; /* Reprint-line character [ICANON]. */
|
||||||
|
public const VINTR = 8; /* Interrupt character [ISIG]. */
|
||||||
|
public const VQUIT = 9; /* Quit character [ISIG]. */
|
||||||
|
public const VSUSP = 10; /* Suspend character [ISIG]. */
|
||||||
|
public const VDSUSP = 11; /* Delayed suspend character [ISIG]. */
|
||||||
|
public const VSTART = 12; /* Start (X-ON) character [IXON, IXOFF]. */
|
||||||
|
public const VSTOP = 13; /* Stop (X-OFF) character [IXON, IXOFF]. */
|
||||||
|
public const VLNEXT = 14; /* Literal-next character [IEXTEN]. */
|
||||||
|
public const VDISCARD = 15; /* Discard character [IEXTEN]. */
|
||||||
|
public const VMIN = 16; /* Minimum number of bytes read at once [!ICANON]. */
|
||||||
|
public const VTIME = 17; /* Time-out value (tenths of a second) [!ICANON]. */
|
||||||
|
public const VSTATUS = 18; /* Status character [ICANON]. */
|
||||||
|
public const NCCS = 20; /* Value duplicated in <hurd/tioctl.defs>. */
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// ! IOCTL constants
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
public const TIOCGWINSZ = 0x5413;
|
||||||
|
}
|
@ -1,148 +0,0 @@
|
|||||||
<?php declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Kilo;
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// ! App Constants
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
define('KILO_VERSION', '0.0.1');
|
|
||||||
define('KILO_TAB_STOP', 4);
|
|
||||||
define('KILO_QUIT_TIMES', 3);
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// ! Misc I/O constants
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
define('STDIN_FILENO', 0);
|
|
||||||
define('STDOUT_FILENO', 1);
|
|
||||||
define('STDERR_FILENO', 2);
|
|
||||||
define('TCSAFLUSH', 2);
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// ! Termios flags and constants
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
/* Input modes */
|
|
||||||
define('IGNBRK', (1 << 0)); /* Ignore break condition. */
|
|
||||||
define('BRKINT', (1 << 1)); /* Signal interrupt on break. */
|
|
||||||
define('IGNPAR', (1 << 2)); /* Ignore characters with parity errors. */
|
|
||||||
define('PARMRK', (1 << 3)); /* Mark parity and framing errors. */
|
|
||||||
define('INPCK', (1 << 4)); /* Enable input parity check. */
|
|
||||||
define('ISTRIP', (1 << 5)); /* Strip 8th bit off characters. */
|
|
||||||
define('INLCR', (1 << 6)); /* Map NL to CR on input. */
|
|
||||||
define('IGNCR', (1 << 7)); /* Ignore CR. */
|
|
||||||
define('ICRNL', (1 << 8)); /* Map CR to NL on input. */
|
|
||||||
define('IXON', (1 << 9)); /* Enable start/stop output control. */
|
|
||||||
define('IXOFF', (1 << 10)); /* Enable start/stop input control. */
|
|
||||||
define('IXANY', (1 << 11)); /* Any character will restart after stop. */
|
|
||||||
define('IMAXBEL', (1 << 13)); /* Ring bell when input queue is full. */
|
|
||||||
define('IUCLC', (1 << 14)); /* Translate upper case input to lower case. */
|
|
||||||
|
|
||||||
/* Output modes */
|
|
||||||
define('OPOST', (1 << 0)); /* Perform output processing. */
|
|
||||||
define('ONLCR', (1 << 1)); /* Map NL to CR-NL on output. */
|
|
||||||
define('OXTABS', (1 << 2)); /* Expand tabs to spaces. */
|
|
||||||
define('ONOEOT', (1 << 3)); /* Discard EOT (^D) on output. */
|
|
||||||
define('OCRNL', (1 << 4)); /* Map CR to NL. */
|
|
||||||
define('ONOCR', (1 << 5)); /* Discard CR's when on column 0. */
|
|
||||||
define('ONLRET', (1 << 6)); /* Move to column 0 on NL. */
|
|
||||||
define('NLDLY', (3 << 8)); /* NL delay. */
|
|
||||||
define('NL0', (0 << 8)); /* NL type 0. */
|
|
||||||
define('NL1', (1 << 8)); /* NL type 1. */
|
|
||||||
define('TABDLY', (3 << 10 | 1 << 2)); /* TAB delay. */
|
|
||||||
define('TAB0', (0 << 10)); /* TAB delay type 0. */
|
|
||||||
define('TAB1', (1 << 10)); /* TAB delay type 1. */
|
|
||||||
define('TAB2', (2 << 10)); /* TAB delay type 2. */
|
|
||||||
define('TAB3', (1 << 2)); /* Expand tabs to spaces. */
|
|
||||||
define('CRDLY', (3 << 12)); /* CR delay. */
|
|
||||||
define('CR0', (0 << 12)); /* CR delay type 0. */
|
|
||||||
define('CR1', (1 << 12)); /* CR delay type 1. */
|
|
||||||
define('CR2', (2 << 12)); /* CR delay type 2. */
|
|
||||||
define('CR3', (3 << 12)); /* CR delay type 3. */
|
|
||||||
define('FFDLY', (1 << 14)); /* FF delay. */
|
|
||||||
define('FF0', (0 << 14)); /* FF delay type 0. */
|
|
||||||
define('FF1', (1 << 14)); /* FF delay type 1. */
|
|
||||||
define('BSDLY', (1 << 15)); /* BS delay. */
|
|
||||||
define('BS0', (0 << 15)); /* BS delay type 0. */
|
|
||||||
define('BS1', (1 << 15)); /* BS delay type 1. */
|
|
||||||
define('VTDLY', (1 << 16)); /* VT delay. */
|
|
||||||
define('VT0', (0 << 16)); /* VT delay type 0. */
|
|
||||||
define('VT1', (1 << 16)); /* VT delay type 1. */
|
|
||||||
define('OLCUC', (1 << 17)); /* Translate lower case output to upper case */
|
|
||||||
define('OFILL', (1 << 18)); /* Send fill characters for delays. */
|
|
||||||
define('OFDEL', (1 << 19)); /* Fill is DEL. */
|
|
||||||
|
|
||||||
/* Control modes */
|
|
||||||
define('CIGNORE', (1 << 0)); /* Ignore these control flags. */
|
|
||||||
define('CS5', 0); /* 5 bits per byte. */
|
|
||||||
define('CS6', (1 << 8)); /* 6 bits per byte. */
|
|
||||||
define('CS7', (1 << 9)); /* 7 bits per byte. */
|
|
||||||
define('CS8', (CS6|CS7)); /* 8 bits per byte. */
|
|
||||||
define('CSIZE', (CS5|CS6|CS7|CS8)); /* Number of bits per byte (mask). */
|
|
||||||
define('CSTOPB', (1 << 10)); /* Two stop bits instead of one. */
|
|
||||||
define('CREAD', (1 << 11)); /* Enable receiver. */
|
|
||||||
define('PARENB', (1 << 12)); /* Parity enable. */
|
|
||||||
define('PARODD', (1 << 13)); /* Odd parity instead of even. */
|
|
||||||
define('HUPCL', (1 << 14)); /* Hang up on last close. */
|
|
||||||
define('CLOCAL', (1 << 15)); /* Ignore modem status lines. */
|
|
||||||
define('CRTSCTS', (1 << 16)); /* RTS/CTS flow control. */
|
|
||||||
define('CRTS_IFLOW', CRTSCTS); /* Compatibility. */
|
|
||||||
define('CCTS_OFLOW', CRTSCTS); /* Compatibility. */
|
|
||||||
define('CDTRCTS', (1 << 17)); /* DTR/CTS flow control. */
|
|
||||||
define('MDMBUF', (1 << 20)); /* DTR/DCD flow control. */
|
|
||||||
define('CHWFLOW', (MDMBUF|CRTSCTS|CDTRCTS)); /* All types of flow control. */
|
|
||||||
|
|
||||||
/* Local modes */
|
|
||||||
define('ECHOKE', (1 << 0)); /* Visual erase for KILL. */
|
|
||||||
define('_ECHOE', (1 << 1)); /* Visual erase for ERASE. */
|
|
||||||
define('ECHOE', _ECHOE);
|
|
||||||
define('_ECHOK', (1 << 2)); /* Echo NL after KILL. */
|
|
||||||
define('ECHOK', _ECHOK);
|
|
||||||
define('_ECHO', (1 << 3)); /* Enable echo. */
|
|
||||||
define('ECHO', _ECHO);
|
|
||||||
define('_ECHONL', (1 << 4)); /* Echo NL even if ECHO is off. */
|
|
||||||
define('ECHONL', _ECHONL);
|
|
||||||
define('ECHOPRT', (1 << 5)); /* Hardcopy visual erase. */
|
|
||||||
define('ECHOCTL', (1 << 6)); /* Echo control characters as ^X. */
|
|
||||||
define('_ISIG', (1 << 7)); /* Enable signals. */
|
|
||||||
define('ISIG', _ISIG);
|
|
||||||
define('_ICANON', (1 << 8)); /* Do erase and kill processing. */
|
|
||||||
define('ICANON', _ICANON);
|
|
||||||
define('ALTWERASE', (1 << 9)); /* Alternate WERASE algorithm. */
|
|
||||||
define('_IEXTEN', (1 << 10)); /* Enable DISCARD and LNEXT. */
|
|
||||||
define('IEXTEN', _IEXTEN);
|
|
||||||
define('EXTPROC', (1 << 11)); /* External processing. */
|
|
||||||
define('_TOSTOP', (1 << 22)); /* Send SIGTTOU for background output. */
|
|
||||||
define('TOSTOP', _TOSTOP);
|
|
||||||
define('FLUSHO', (1 << 23)); /* Output being flushed (state). */
|
|
||||||
define('XCASE', (1 << 24)); /* Canonical upper/lower case. */
|
|
||||||
define('NOKERNINFO', (1 << 25)); /* Disable VSTATUS. */
|
|
||||||
define('PENDIN', (1 << 29)); /* Retype pending input (state). */
|
|
||||||
define('_NOFLSH', (1 << 31)); /* Disable flush after interrupt. */
|
|
||||||
define('NOFLSH', _NOFLSH);
|
|
||||||
|
|
||||||
/* Control characters */
|
|
||||||
define('VEOF', 0); /* End-of-file character [ICANON]. */
|
|
||||||
define('VEOL', 1); /* End-of-line character [ICANON]. */
|
|
||||||
define('VEOL2', 2); /* Second EOL character [ICANON]. */
|
|
||||||
define('VERASE', 3); /* Erase character [ICANON]. */
|
|
||||||
define('VWERASE', 4); /* Word-erase character [ICANON]. */
|
|
||||||
define('VKILL', 5); /* Kill-line character [ICANON]. */
|
|
||||||
define('VREPRINT', 6); /* Reprint-line character [ICANON]. */
|
|
||||||
define('VINTR', 8); /* Interrupt character [ISIG]. */
|
|
||||||
define('VQUIT', 9); /* Quit character [ISIG]. */
|
|
||||||
define('VSUSP', 10); /* Suspend character [ISIG]. */
|
|
||||||
define('VDSUSP', 11); /* Delayed suspend character [ISIG]. */
|
|
||||||
define('VSTART', 12); /* Start (X-ON) character [IXON, IXOFF]. */
|
|
||||||
define('VSTOP', 13); /* Stop (X-OFF) character [IXON, IXOFF]. */
|
|
||||||
define('VLNEXT', 14); /* Literal-next character [IEXTEN]. */
|
|
||||||
define('VDISCARD', 15); /* Discard character [IEXTEN]. */
|
|
||||||
define('VMIN', 16); /* Minimum number of bytes read at once [!ICANON]. */
|
|
||||||
define('VTIME', 17); /* Time-out value (tenths of a second) [!ICANON]. */
|
|
||||||
define('VSTATUS', 18); /* Status character [ICANON]. */
|
|
||||||
define('NCCS', 20); /* Value duplicated in <hurd/tioctl.defs>. */
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// ! IOCTL constants
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
define('TIOCGWINSZ', 0x5413);
|
|
@ -4,8 +4,8 @@ namespace Kilo;
|
|||||||
|
|
||||||
use FFI;
|
use FFI;
|
||||||
|
|
||||||
$ffi = FFI::load(__DIR__ . '/ffi.h');
|
/** @var FFI\CData $original_termios */
|
||||||
$original_termios = $ffi->new('struct termios');
|
$original_termios = get_ffi()->new('struct termios');
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// ! Raw mode / Terminal size
|
// ! Raw mode / Terminal size
|
||||||
@ -13,13 +13,15 @@ $original_termios = $ffi->new('struct termios');
|
|||||||
|
|
||||||
function enable_raw_mode(): void
|
function enable_raw_mode(): void
|
||||||
{
|
{
|
||||||
global $ffi;
|
|
||||||
global $original_termios;
|
global $original_termios;
|
||||||
|
|
||||||
|
// Make sure to restore normal mode on exit/die/crash
|
||||||
register_shutdown_function('Kilo\disable_raw_mode');
|
register_shutdown_function('Kilo\disable_raw_mode');
|
||||||
|
|
||||||
|
$ffi = get_ffi();
|
||||||
|
|
||||||
// Populate the original terminal settings
|
// Populate the original terminal settings
|
||||||
$res = $ffi->tcgetattr(STDIN_FILENO, FFI::addr($original_termios));
|
$res = $ffi->tcgetattr(C::STDIN_FILENO, FFI::addr($original_termios));
|
||||||
if ($res === -1)
|
if ($res === -1)
|
||||||
{
|
{
|
||||||
die('tcgetattr');
|
die('tcgetattr');
|
||||||
@ -27,15 +29,15 @@ function enable_raw_mode(): void
|
|||||||
|
|
||||||
// So, the only thing that seems to really matter here is that c_oflag is 0...
|
// So, the only thing that seems to really matter here is that c_oflag is 0...
|
||||||
$termios = clone $original_termios;
|
$termios = clone $original_termios;
|
||||||
$termios->c_iflag = 0; //$termios->c_iflag & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
|
$termios->c_iflag = 0; //$termios->c_iflag & ~(C::BRKINT | C::ICRNL | C::INPCK | C::ISTRIP | C::IXON);
|
||||||
$termios->c_oflag = 0; // $termios->c_oflag && ~(OPOST);
|
$termios->c_oflag = 0; // $termios->c_oflag && ~(C::OPOST);
|
||||||
$termios->c_cflag |= (CS8);
|
$termios->c_cflag |= (C::CS8);
|
||||||
$termios->c_lflag = $termios->c_lflag & ~(_ECHO | ICANON | IEXTEN | ISIG);
|
$termios->c_lflag = $termios->c_lflag & ~( C::ECHO | C::ICANON | C::IEXTEN | C::ISIG);
|
||||||
$termios->c_cc[VMIN] = 0;
|
$termios->c_cc[C::VMIN] = 0;
|
||||||
$termios->c_cc[VTIME] = 1;
|
$termios->c_cc[C::VTIME] = 1;
|
||||||
|
|
||||||
// Turn on raw mode
|
// Turn on raw mode
|
||||||
$res = $ffi->tcsetattr(STDIN_FILENO, TCSAFLUSH, FFI::addr($termios));
|
$res = $ffi->tcsetattr(C::STDIN_FILENO, C::TCSAFLUSH, FFI::addr($termios));
|
||||||
if ($res === -1)
|
if ($res === -1)
|
||||||
{
|
{
|
||||||
die('tcsetattr');
|
die('tcsetattr');
|
||||||
@ -44,10 +46,10 @@ function enable_raw_mode(): void
|
|||||||
|
|
||||||
function disable_raw_mode(): void
|
function disable_raw_mode(): void
|
||||||
{
|
{
|
||||||
global $ffi;
|
|
||||||
global $original_termios;
|
global $original_termios;
|
||||||
|
|
||||||
$res = $ffi->tcsetattr(STDIN_FILENO, TCSAFLUSH, FFI::addr($original_termios));
|
$ffi = get_ffi();
|
||||||
|
$res = $ffi->tcsetattr(C::STDIN_FILENO, C::TCSAFLUSH, FFI::addr($original_termios));
|
||||||
|
|
||||||
echo "\n";
|
echo "\n";
|
||||||
|
|
||||||
@ -82,10 +84,10 @@ function get_cursor_position()
|
|||||||
|
|
||||||
function get_window_size()
|
function get_window_size()
|
||||||
{
|
{
|
||||||
global $ffi;
|
$ffi = get_ffi();
|
||||||
|
|
||||||
$ws = $ffi->new('struct winsize');
|
$ws = $ffi->new('struct winsize');
|
||||||
$res = $ffi->ioctl(STDOUT_FILENO, TIOCGWINSZ, FFI::addr($ws));
|
$res = $ffi->ioctl(C::STDOUT_FILENO, C::TIOCGWINSZ, FFI::addr($ws));
|
||||||
|
|
||||||
if ($res === -1 || $ws->ws_col === 0)
|
if ($res === -1 || $ws->ws_col === 0)
|
||||||
{
|
{
|
||||||
@ -95,8 +97,6 @@ function get_window_size()
|
|||||||
return [$ws->ws_row, $ws->ws_col];
|
return [$ws->ws_row, $ws->ws_col];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// ! C function/macro equivalents
|
// ! C function/macro equivalents
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
@ -115,11 +115,18 @@ function ctrl_key(string $char): int
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// b1,100,001 (a) & b0,011,111 = b0,000,001
|
// b1,100,001 (a) & b0,011,111 (0x1f) = b0,000,001 (SOH)
|
||||||
// b1,100,010 (b) & b0,011,111 = b0,000,010
|
// b1,100,010 (b) & b0,011,111 (0x1f) = b0,000,010 (STX)
|
||||||
|
// ...and so on
|
||||||
return ord($char) & 0x1f;
|
return ord($char) & 0x1f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the one-character string contain an ascii ordinal value?
|
||||||
|
*
|
||||||
|
* @param string $single_char
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
function is_ascii(string $single_char): bool
|
function is_ascii(string $single_char): bool
|
||||||
{
|
{
|
||||||
if (strlen($single_char) > 1)
|
if (strlen($single_char) > 1)
|
||||||
@ -130,12 +137,24 @@ function is_ascii(string $single_char): bool
|
|||||||
return ord($single_char) < 0x80;
|
return ord($single_char) < 0x80;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the one-character string contain an ascii control character?
|
||||||
|
*
|
||||||
|
* @param string $char
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
function is_cntrl(string $char): bool
|
function is_cntrl(string $char): bool
|
||||||
{
|
{
|
||||||
$c = ord($char);
|
$c = ord($char);
|
||||||
return is_ascii($char) && ( $c < 0x20 || $c === 0x7f );
|
return is_ascii($char) && ( $c < 0x20 || $c === 0x7f );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the one-character string contain an ascii number?
|
||||||
|
*
|
||||||
|
* @param string $char
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
function is_digit(string $char): bool
|
function is_digit(string $char): bool
|
||||||
{
|
{
|
||||||
$c = ord($char);
|
$c = ord($char);
|
||||||
@ -146,6 +165,29 @@ function is_digit(string $char): bool
|
|||||||
// ! Helper functions
|
// ! Helper functions
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A 'singleton' function to replace a global variable
|
||||||
|
*
|
||||||
|
* @return FFI
|
||||||
|
*/
|
||||||
|
function get_ffi(): FFI
|
||||||
|
{
|
||||||
|
static $ffi;
|
||||||
|
|
||||||
|
if ($ffi === NULL)
|
||||||
|
{
|
||||||
|
$ffi = FFI::load(__DIR__ . '/ffi.h');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ffi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pull input from the stdin stream.
|
||||||
|
*
|
||||||
|
* @param int $len
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
function read_stdin(int $len = 128): string
|
function read_stdin(int $len = 128): string
|
||||||
{
|
{
|
||||||
$handle = fopen('php://stdin', 'rb');
|
$handle = fopen('php://stdin', 'rb');
|
||||||
@ -155,6 +197,13 @@ function read_stdin(int $len = 128): string
|
|||||||
return $input;
|
return $input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write to the stdout stream
|
||||||
|
*
|
||||||
|
* @param string $str
|
||||||
|
* @param int|NULL $len
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
function write_stdout(string $str, int $len = NULL): int
|
function write_stdout(string $str, int $len = NULL): int
|
||||||
{
|
{
|
||||||
$handle = fopen('php://stdout', 'ab');
|
$handle = fopen('php://stdout', 'ab');
|
||||||
@ -177,3 +226,20 @@ function read_stdout(int $len = 128): string
|
|||||||
|
|
||||||
return $input;
|
return $input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces a slice of an array with the same value
|
||||||
|
*
|
||||||
|
* @param array $array The array to update
|
||||||
|
* @param int $offset The index of the first location to update
|
||||||
|
* @param int $length The number of indices to update
|
||||||
|
* @param mixed $value The value to replace in the range
|
||||||
|
*/
|
||||||
|
function array_replace_range(array &$array, int $offset, int $length, $value):void
|
||||||
|
{
|
||||||
|
$end = $offset + $length;
|
||||||
|
for ($i = $offset; $i < $end; $i++)
|
||||||
|
{
|
||||||
|
$array[$i] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user