ACCEPT

( c-addr +n1 -- +n2 )

Receive a string of at most +n1 characters. An ambiguous condition exists if +n1 is zero or greater than 32,767. Display graphic characters as they are received. A program that depends on the presence or absence of non-graphic characters in the string has an environmental dependency. The editing functions, if any, that the system performs in order to construct the string are implementation-defined.

Input terminates when an implementation-defined line terminator is received. When input terminates, nothing is appended to the string, and the display is maintained in an implementation-defined way.

+n2 is the length of the string stored at c-addr.

See:

Rationale:

Specification of a non-zero, positive integer count (+n1) for ACCEPT allows some implementors to continue their practice of using a zero or negative value as a flag to trigger special behavior. Insofar as such behavior is outside the standard, Standard Programs cannot depend upon it, but the committee doesn't wish to preclude it unnecessarily. Because actual values are almost always small integers, no functionality is impaired by this restriction.

It is recommended that all non-graphic characters be reserved for editing or control functions and not be stored in the input string.

Because external system hardware and software may perform the ACCEPT function, when a line terminator is received the action of the cursor, and therefore the display, is implementation-defined. It is recommended that the cursor remain immediately following the entered text after a line terminator is received.

Testing:

CREATE ABUF 80 CHARS ALLOT

: ACCEPT-TEST
     CR ." PLEASE TYPE UP TO 80 CHARACTERS:" CR
     ABUF 80 ACCEPT
     CR ." RECEIVED: " [CHAR] " EMIT
     ABUF SWAP TYPE [CHAR] " EMIT CR
;

T{ ACCEPT-TEST -> }T

ContributeContributions

ruvavatar of ruv Source of a stringRequest for clarification2016-10-01 12:47:01

Should ACCEPT receive a string from the STDIN (standard input) or from the keyboard (as KEY word does)?

BerndPaysanavatar of BerndPaysan 2016-10-01 18:41:58

ACCEPT typically uses KEY (or EKEY) and thus should get the input from the same source as KEY. On a hosted console Forth, that's usually STDIN, but if you run the Forth in a GUI windows, it's the keyboard input events from that window.

StephenPelcavatar of StephenPelc 2016-10-31 10:45:37

Forth does not know about STDIN. Many Forths, both desktop and embedded, allow I/O through KEY and EMIT and friends to be vectored. This could be through a console, a serial line, a TCP/IP connection. How the vectoring occurs is not (yet) standardised. ACCEPT works with KEY and EMIT and friends and so inherits whatever vectoring the Forth system provides. Note that the current input and output device should be vectored separately.

Stephen

Reply

mcondronavatar of mcondron Behavior at end of line and end of dataRequest for clarification2019-05-11 12:15:10

Three questions:

  1. Should ACCEPT echo the line terminator if it is a CR or LF, or just leave the cursor where it was before the terminator?
  2. Should the terminator be placed into the receive buffer, or just the text received up to the terminator?
  3. What is the behavior of ACCEPT when the maximum number is reached with no terminator?

I realize that probably these are all implementation-specific, but are there any conventional norms, especially about #2 and #3?

Thanks!

AntonErtlavatar of AntonErtl 2019-05-12 06:37:04

1) The standard document is clear here: What happens to the display upon receiving the line terminator is implementation-defined, but the recommendation (in the rationale) is to leave the cursor at the end of the entered text without echoing the line terminator. Note that if your ACCEPT supports editing with cursor-left and such, you should move the cursor to the end rather than leaving it where it is.

2) That's also clear in the document: When a line terminator is received, nothing is appended to the string. I.e., the terminator should not be placed into the string.

3) The document specifies termination only on receiving the line terminator, and does not specify any particular behaviour when reaching n1 characters. Gforth places the cursor behind the n1th character, but when you enter a character then, it just beeps.

mcondronavatar of mcondron 2019-05-12 21:04:32

Thanks for the clarifications. I thought that was the case with #1, but now you've made it clear.

About #2, I was not sure if it meant nothing is appended after the terminator, like maybe do not append a 0 (I'm coming from a long history of C programming, so my intuition keeps telling me to think of that there...).

And about #3, yes, the standard didn't tell me what to there...which was a surprise, but I guess there are good reasons for leaving that implementation-dependent. Just so you know, the reason I asked is that the little system I'm developing will be accepting a long string of text copied and pasted into a terminal window, with no editing on the Forth side, and the total amount of text may be longer than what will fit into a local buffer. . So now I know I'm free to handle this situation however I want, which is exactly what I was hoping to hear.

Thanks again!

MarcelHendrixavatar of MarcelHendrix 2019-05-13 07:04:41

Described like this (with "cursor", "end-of-line") ACCEPT seems to require a specific input and output behavior. The original specification allows calling some OS function to accept characters (then there is no control over where/if the input appears and in what fashion). Specifying a requirement for both KEY and EMIT to be used helps, but then editing keys and mouse actions are problematic (at least for the system implementor). Maybe these aspects can be clarified.

-marcel

PS: why can't we see the message we're responding to? (a problem with ACCEPT ?-)

AntonErtlavatar of AntonErtl 2019-05-14 09:41:25

The standard is very clear that nothing is appended when the line-terminator is received, not even a NUL character. Also, if n2=n1, there is no room in the buffer for appending anything.

I guess the reason for not specifying anything for 3) is that when dealing with terminals in cooked mode, the system gets control back only after the user has pressed the terminator, and may have typed far beyond n1. If the system uses the terminal in raw mode (i.e., it can handle each character separately), it can provide immediate feedback (like Gforth is doing) when n1 is reached. So the standard did not specify what to do about this case.

I don't think that we should require that KEY and EMIT is used, because KEY does not work properly on terminals in cooked mode; I have seen some Forth systems (among them, SP-Forth) that use cooked mode, and where KEY does not return after one character has been typed.

Reply

ruvavatar of ruv Receiving a zero-length stringRequest for clarification2019-05-20 20:19:43

Why n2 is specified as non-zero, positive integer?

What if the first received char is a line terminator? It seems that zero should be returned in such case.

AntonErtlavatar of AntonErtl 2019-05-21 05:28:43

+n2 means that n2 is non-negative. It may be zero. (+n1, too, but for n1 non-zero-ness is specified in the prose).

ruvavatar of ruv 2019-05-21 07:53:10

Oh, thank. Forget that +n does not mean positive, but non-negative.

Reply