|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T i
Length: 8598 (0x2196)
Types: TextFile
Names: »input_utils.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦this⟧ »EUUGD11/euug-87hel/sec1/elm/src/input_utils.c«
/** input_utils.c **/
/** Mindless I/O routines for ELM
(C) Copyright 1985 Dave Taylor
**/
#include "headers.h"
#include <errno.h>
extern int errno; /* system error number */
unsigned alarm();
#define special_char(c) (c == ' ' || c == '\t' || c == '/' || c == ',' \
|| c == '\0')
#define erase_a_char() { Writechar(BACKSPACE); Writechar(' '); \
Writechar(BACKSPACE); fflush(stdout); }
int
want_to(question, dflt, echo_answer)
char *question, dflt;
int echo_answer;
{
/** Ask 'question' at LINES-2, COLUMNS-40, returning the answer in
lower case. If 'echo_answer', then echo answer. 'dflt' is the
default answer if <return> is pressed. (Note: 'dflt' is also what
will be returned if <return> is pressed!)
**/
register char ch, cols;
cols = (strlen(question) < 30)? COLUMNS-40 : COLUMNS-50;
PutLine3(LINES-3, cols,"%s%c%c", question, dflt, BACKSPACE);
fflush(stdout);
fflush(stdin);
ch = tolower(ReadCh());
if (echo_answer && ch > (char) ' ') {
Writechar(ch);
fflush(stdout);
}
return(ch == '\n' || ch == '\r' ? dflt : ch);
}
int
read_number(ch)
char ch;
{
/** Read a number, where 'ch' is the leading digit! **/
char buff[SHORT_SLEN];
int num;
buff[0] = ch;
buff[1] = '\0';
PutLine0(LINES-3, COLUMNS-40,"Set current message to :");
if (optionally_enter(buff, LINES-3, COLUMNS-15, TRUE) == -1)
return(current);
sscanf(buff,"%d", &num);
return(num);
}
int
optionally_enter(string, x, y, append_current)
char *string;
int x,y, append_current;
{
/** Display the string on the screen and if RETURN is pressed, return
it. Otherwise, allow standard text input, including backspaces
and such until RETURN is hit.
If "append_current" is set, then leave the default string in
place and edit AFTER it...assume 'x,y' is placing us at the
beginning of the string...
This routine returns zero unless INTERRUPT hit, then it returns
-1 and must be treated accordingly.
Added ^W and ^R support...
Also added that if x and y are < 0 don't try any cursor stuff
**/
char ch;
register int index = 0, use_cursor_control;
use_cursor_control = ((! mail_only) && x >= 0 && y >= 0);
if (use_cursor_control)
PutLine1(x,y, "%s", string);
else
printf("%s", string);
CleartoEOLN();
if (! append_current)
if (use_cursor_control)
MoveCursor(x,y);
else
non_destructive_back_up(strlen(string));
if (cursor_control)
transmit_functions(OFF);
ch = getchar();
if (ch == '\n' || ch == '\r') {
if (cursor_control)
transmit_functions(ON);
return(0); /* we're done. No change needed */
}
CleartoEOLN();
index = (append_current? strlen(string) : 0);
if (ch == kill_line) {
if (use_cursor_control)
MoveCursor(x,y);
else
back_up(index);
CleartoEOLN();
index = 0;
}
else if (ch != backspace) {
Writechar(ch);
string[index++] = ch;
}
else if (index > 0) {
index--;
erase_a_char();
}
else {
Writechar(' ');
Writechar(BACKSPACE);
fflush(stdout);
}
do {
ch = getchar();
/* the following is converted from a case statement to
allow the variable characters (backspace, kill_line
and break) to be processed. Case statements in
C require constants as labels, so it failed ...
*/
if (ch == backspace) {
if (index > 0) {
erase_a_char();
index--;
}
else {
Writechar(' ');
Writechar(BACKSPACE);
fflush(stdout);
}
}
else if (ch == '\n' || ch == '\r') {
string[index] = '\0';
if (cursor_control)
transmit_functions(ON);
return(0);
}
else if (ch == ctrl('W')) { /* back up a word! */
if (special_char(string[index]) && index > 0) {
index--;
erase_a_char();
}
while (index > 0 && ! special_char(string[index])) {
index--;
erase_a_char();
}
}
else if (ch == ctrl('R')) {
string[index] = '\0';
if (use_cursor_control) {
PutLine1(x,y, "%s", string);
CleartoEOLN();
}
else
printf("\n%s", string);
}
else if (ch == kill_line) {
if (use_cursor_control)
MoveCursor(x,y);
else
back_up(index+1);
CleartoEOLN();
index = 0;
}
else if (ch == NULL) {
if (cursor_control)
transmit_functions(ON);
fflush(stdin); /* remove extraneous chars, if any */
string[0] = '\0'; /* clean up string, and... */
return(-1);
}
else { /* default case */
string[index++] = ch;
Writechar(ch);
}
} while (index < SLEN);
string[index] = '\0';
if (cursor_control)
transmit_functions(ON);
return(0);
}
int
pattern_enter(string, alt_string, x, y, alternate_prompt)
char *string, *alt_string, *alternate_prompt;
int x,y;
{
/** This function is functionally similar to the routine
optionally-enter, but if the first character pressed
is a '/' character, then the alternate prompt and string
are used rather than the normal one. This routine
returns 1 if alternate was used, 0 if not
**/
char ch;
register index = 0;
PutLine1(x, y, "%s", string);
CleartoEOLN();
MoveCursor(x,y);
if (cursor_control)
transmit_functions(OFF);
ch = getchar();
if (ch == '\n' || ch == '\r') {
if (cursor_control)
transmit_functions(ON);
return(0); /* we're done. No change needed */
}
if (ch == '/') {
PutLine1(x, 0, "%s", alternate_prompt);
CleartoEOLN();
(void) optionally_enter(alt_string, x, strlen(alternate_prompt)+1,
FALSE);
return(1);
}
CleartoEOLN();
index = 0;
if (ch == kill_line) {
MoveCursor(x,y);
CleartoEOLN();
index = 0;
}
else if (ch != backspace) {
Writechar(ch);
string[index++] = ch;
}
else if (index > 0) {
index--;
erase_a_char();
}
else {
Writechar(' ');
Writechar(BACKSPACE);
}
do {
fflush(stdout);
ch = getchar();
/* the following is converted from a case statement to
allow the variable characters (backspace, kill_line
and break) to be processed. Case statements in
C require constants as labels, so it failed ...
*/
if (ch == backspace) {
if (index > 0) {
index--;
erase_a_char();
}
else {
Writechar(' ');
Writechar(BACKSPACE);
}
}
else if (ch == '\n' || ch == '\r') {
string[index] = '\0';
if (cursor_control)
transmit_functions(ON);
return(0);
}
else if (ch == ctrl('W')) {
/* get to rightmost non-alpha */
if (special_char (string[index]) && index > 0)
index--;
while (index > 0 && ! special_char(string[index])) {
erase_a_char();
index--;
}
}
else if (ch == ctrl('R')) {
string[index] = '\0';
if (!mail_only) {
PutLine1(x,y, "%s", string);
CleartoEOLN();
}
else
printf("\n%s", string);
}
else if (ch == kill_line) {
MoveCursor(x,y);
CleartoEOLN();
index = 0;
}
else if (ch == NULL) {
if (cursor_control)
transmit_functions(ON);
fflush(stdin); /* remove extraneous chars, if any */
string[0] = '\0'; /* clean up string, and... */
return(-1);
}
else { /* default case */
string[index++] = ch;
Writechar(ch);
}
} while (index < SLEN);
string[index] = '\0';
if (cursor_control)
transmit_functions(ON);
return(0);
}
back_up(spaces)
int spaces;
{
/** this routine is to replace the goto x,y call for when sending
mail without starting the entire "elm" system up... **/
while (spaces--) {
erase_a_char();
}
}
non_destructive_back_up(spaces)
int spaces;
{
/** same as back_up() but doesn't ERASE the characters on the screen **/
while (spaces--)
Writechar(BACKSPACE);
fflush(stdout);
}
int
GetPrompt()
{
/** This routine does a read/timeout for a single character.
The way that this is determined is that the routine to
read a character is called, then the "errno" is checked
against EINTR (interrupted call). If they match, this
returns NO_OP_COMMAND otherwise it returns the normal
command.
**/
int ch;
if (timeout > 0) {
alarm((unsigned) timeout);
errno = 0; /* we actually have to do this. *sigh* */
ch = ReadCh();
if (errno == EINTR) ch = NO_OP_COMMAND;
alarm((unsigned) 0);
}
else
ch = ReadCh();
return(ch);
}