Skip to content

Commit

Permalink
GH-62 Fix ACCEPT to read from standard input when the input source
Browse files Browse the repository at this point in the history
a string or block.
  • Loading branch information
SirWumpus committed Nov 8, 2024
1 parent da86e40 commit cbf67fb
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 25 deletions.
10 changes: 10 additions & 0 deletions doc/file.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,3 +126,13 @@ If the file `caddr` `u` has been `INCLUDED` or `REQUIRED` already, discard `cadd
ok S" ed.p4" REQUIRED-PATH

- - -
#### stdin
( -- `fid` )
Push the standard input file handle. For use with `READ-FILE` or `READ-LINE`. Closing the file handle will have undefined behaviour.

- - -
#### stdout
( -- `fid` )
Push the standard output file handle. For use with `WRITE-FILE` or `WRITE-LINE`. Closing the file handle will have undefined behaviour.

- - -
23 changes: 18 additions & 5 deletions src/aline.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <fcntl.h>
#include <unistd.h>

#undef HAVE_CTERMID

int is_tty;

static int tty_fd = -1;
Expand Down Expand Up @@ -68,6 +70,9 @@ void
alineFini(void)
{
alineSetMode(ALINE_CANONICAL);
#ifdef HAVE_CTERMID
(void) close(tty_fd);
#endif
}

void
Expand All @@ -76,12 +81,11 @@ alineInit(void)
if (tty_fd != -1 || !(is_tty = isatty(fileno(stdin)))) {
return;
}
// Not sure this is needed (yet). Keeping this as a reminder.
// #ifdef HAVE_CTERMID
// tty_fd = open(ctermid(NULL), O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO);
// #else
#ifdef HAVE_CTERMID
tty_fd = open(ctermid(NULL), O_RDWR, S_IRWXU|S_IRWXG|S_IRWXO);
#else
tty_fd = fileno(stdin);
// #endif
#endif
sig_winch(SIGWINCH);
signal(SIGWINCH, sig_winch);

Expand Down Expand Up @@ -181,15 +185,24 @@ alineInput(FILE *fp, const char *prompt, char *buf, size_t size)
for (size--, buf[i = 0] = '\0'; ; ) {
(void) printf(ANSI_RESTORE_CURSOR"%s%s"ANSI_ERASE_TAIL""ANSI_GOTO, prompt, buf, pos[0], pos[1]+pcol+i);
(void) fflush(stdout);
#ifdef HAVE_CTERMID
ch = alineReadByte();
#else
clearerr(stdin);
ch = fgetc(stdin);
#endif
if (ch == EOF || ch == tty_saved.c_cc[VEOL] || ch == '\r' || ch == '\n') {
(void) fputs("\r\n", stdout);
break;
}
if (ch == '\e') {
#ifdef HAVE_CTERMID
if ((ch = alineReadByte()) == '[') {
ch = alineReadByte();
#else
if ((ch = fgetc(stdin)) == '[') {
ch = fgetc(stdin);
#endif
if (ch == 'A') {
ch = '\v';
} else if (ch == 'B') {
Expand Down
31 changes: 14 additions & 17 deletions src/post4.c
Original file line number Diff line number Diff line change
Expand Up @@ -654,35 +654,22 @@ p4Divs(P4_Int dend0, P4_Int dend1, P4_Int dsor, P4_Int *rem)
}

/***********************************************************************
*** Input / Ouput
*** Core
***********************************************************************/

int
p4Accept(P4_Input *input, char *buf, P4_Size size)
{
if (input->fp == (FILE *) -1) {
return EOF;
}
return alineInput(input->fp, "", buf, (size_t) size);
}

P4_Int
p4Refill(P4_Input *input)
{
int n;
if (P4_INPUT_IS_STR(input)
|| (n = p4Accept(input, input->buffer, P4_INPUT_SIZE)) < 0) {
if (P4_INPUT_IS_EVAL(input)

This comment has been minimized.

Copy link
@ruv

ruv Nov 8, 2024

Contributor

P4_INPUT_IS_EVAL is true when the input source is a block. Thus, p4Refill returns false in this case.

But REFILL shall work for blocks, see 7.6.2.2125 REFILL

Perhaps REFILL should be redefined in src/post4.p4 to work correctly when the input source is a block.

This comment has been minimized.

Copy link
@SirWumpus

SirWumpus Nov 8, 2024

Author Owner

Post4 treats block evaluate (LOAD) like a 1K string of 64 byte lines, which does handle \.

|| (n = alineInput(input->fp, "", input->buffer, P4_INPUT_SIZE)) < 0) {
return P4_FALSE;
}
input->length = n;
input->offset = 0;
return P4_TRUE;
}

/***********************************************************************
*** Core
***********************************************************************/

void
p4WordFree(P4_Word *word)
{
Expand Down Expand Up @@ -1110,6 +1097,8 @@ p4Repl(P4_Ctx *ctx, int thrown)
P4_WORD("fs>rs", &&_fs_to_rs, 0, 0x100100), // p4
P4_WORD("rs>fs", &&_rs_to_fs, 0, 0x011000), // p4
#endif
P4_WORD("stdin", &&_fa_stdin, 0, 0x01), // p4
P4_WORD("stdout", &&_fa_stdout, 0, 0x01), // p4
P4_WORD("BIN", &&_fa_bin, 0, 0x01),
P4_WORD("CLOSE-FILE", &&_fa_close, 0, 0x11),
P4_WORD("CREATE-FILE", &&_fa_create, 0, 0x22),
Expand Down Expand Up @@ -1962,7 +1951,7 @@ _source_id: P4_PUSH(ctx->ds, (P4_Int)(ctx->input->fp == stdin ? NULL : ctx->inpu

// ( caddr +n1 -- +n2 )
_accept: w = P4_DROPTOP(ctx->ds);
if ((x.n = p4Accept(ctx->input, w.s, x.z)) < 0) {
if ((x.n = alineInput(stdin, "", w.s, x.z)) < 0) {
THROW(P4_THROW_BAD_EOF);
}
P4_TOP(ctx->ds) = x;
Expand Down Expand Up @@ -2076,6 +2065,14 @@ _stack_dump: P4_DROP(ctx->ds, 1);
FILE *fp;
struct stat sb;

// ( -- fd )
_fa_stdin: P4_PUSH(ctx->ds, (void *) stdin);
NEXT;

// ( -- fd )
_fa_stdout: P4_PUSH(ctx->ds, (void *) stdout);
NEXT;

// ( fam1 -- fam2 )
_fa_bin: P4_TOP(ctx->ds).u = x.u | 2;
NEXT;
Expand Down
7 changes: 4 additions & 3 deletions src/post4.h
Original file line number Diff line number Diff line change
Expand Up @@ -312,10 +312,11 @@ typedef struct {
char data[P4_INPUT_SIZE];
} P4_Input;

#define P4_INPUT_IS_BLK(input) ((input)->fp == (FILE *) -1 && (input)->blk > 0)
#define P4_INPUT_IS_STR(input) ((input)->fp == (FILE *) -1 && (input)->blk == 0)
#define P4_INPUT_IS_FILE(input) ((input)->fp != (FILE *) -1 && !P4_INPUT_IS_TERM(input))
#define P4_INPUT_IS_TERM(input) ((input)->fp == stdin)
#define P4_INPUT_IS_EVAL(input) ((input)->fp == (FILE *) -1)
#define P4_INPUT_IS_BLK(input) (P4_INPUT_IS_EVAL(input) && (input)->blk > 0)
#define P4_INPUT_IS_STR(input) (P4_INPUT_IS_EVAL(input) && (input)->blk == 0)
#define P4_INPUT_IS_FILE(input) (!P4_INPUT_IS_EVAL(input) && !P4_INPUT_IS_TERM(input))
#define P4_INPUT_PUSH(input) { P4_Input *input_save = (input); input = p4CreateInput()
#define P4_INPUT_POP(input) free(input); (input) = input_save; }

Expand Down

0 comments on commit cbf67fb

Please sign in to comment.