Skip to content

Instantly share code, notes, and snippets.

@tynanbe
Created January 20, 2024 03:04
Show Gist options
  • Save tynanbe/2821bf712ecb975a4285f6feddcfcba7 to your computer and use it in GitHub Desktop.
Save tynanbe/2821bf712ecb975a4285f6feddcfcba7 to your computer and use it in GitHub Desktop.
Sync read line FFI for Gleam
import type { List } from "../prelude.d.mts";
import { toList } from "../prelude.mjs";
type Nil = undefined;
const Nil = void 0;
const { fs, process } =
await (async () =>
!globalThis.Deno
? {
// Imports for Node.js
fs: await import("node:fs"),
process: (await import("node:process")).default,
}
: {})();
const stdin = process ? process.stdin.fd : Deno.stdin.rid;
const is_piped_into_ = is_fifo(stdin);
function is_fifo(fd: number): boolean {
return Boolean(fs ? fs.fstatSync(fd).isFIFO() : Deno.fstatSync(fd).isFifo);
}
/**
* TODO
*/
export function args(): List<string> {
let args = process ? process.argv.slice(2) : Deno.args;
if (!args.length && is_piped_into_) {
const double_quoted_arg = '"((?:\\\\"|[^"])*?)"';
const single_quoted_arg = "'((?:\\\\'|[^'])*?)'";
const unquoted_arg = "(\\S+)";
const re = RegExp(
[
double_quoted_arg,
single_quoted_arg,
unquoted_arg,
]
.join("|"),
"g",
);
args = read_line().match(re) ?? [];
}
return toList(args);
}
/**
* TODO
*/
function read_line(): string {
const eols = ["\n", "\r"]
.map((eol) => eol.charCodeAt(0));
const chars: Array<number> = [];
while (true) {
const char = read_char();
if (Nil === char) {
continue;
} else if (eols.includes(char)) {
break;
}
chars.push(char);
}
const buffer = new Uint8Array(chars);
const line = new TextDecoder().decode(buffer);
return line;
}
/**
* TODO
*/
function read_char(): number | Nil {
try {
const buffer = new Uint8Array(1);
if (fs && process) {
fs.readSync(stdin, buffer);
} else {
Deno.readSync(stdin, buffer);
}
return buffer[0];
} catch {
return Nil;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment