DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T i

⟦ec6edceb4⟧ TextFile

    Length: 8598 (0x2196)
    Types: TextFile
    Names: »input_utils.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/elm/src/input_utils.c« 

TextFile

/**			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);
}