Category : Files from Magazines
Archive   : CUJ9201.ZIP
Filename : 1001038A

 
Output of file : 1001038A contained in archive : CUJ9201.ZIP
/*
* Get input string, with VMS-style input line editing
* and previous-command scrolling.
*
* Written for Turbo C 2.0 / Borland C++ 2.0
* Bob Bybee, 2/91
*/
#include
#include

/* ASCII key definitions */
#define ESC_KEY 0x1b
#define DELETE_KEY 0x7f
#define BACKSPACE_KEY 0x08
#define RETURN_KEY 0x0d
#define CTRL(x) ((x) & 0x1f)

/* Arbitrary values for tracking cursor key entry.
* These happen to match PC BIOS scan codes, but any
* unique values would work.
*/
#define UP_ARROW 0x4800
#define DOWN_ARROW 0x5000
#define RIGHT_ARROW 0x4d00
#define LEFT_ARROW 0x4b00

/* MAX_RECALL is two greater than the number of lines
* we want in the "lastlines" recall buffer.
*/
#define MAX_RECALL 22
#define RECSUB(x) (((x) + MAX_RECALL) % MAX_RECALL)
#define RECALL_LEN 100
static char lastlines[MAX_RECALL][RECALL_LEN];

static int num_got; /* # chars in input buffer */
static int cursor_pos; /* cursor position on line */
static int lastptr = 0; /* ptr to last line entered */
static char erase_one[] = "\b \b"; /* erase one character */
static char *str_ptr; /* ptr to current input string */


/* prototypes for this file */
static void clear_line( void );
static int cursor_right( void );
static int cursor_left( void );
static int get_char_esc( void );
static void put_str( char *str );

/* external functions (see listing2.c) */
void sys_putchar( char ch );
int sys_getchar( void );



/*
* get_str() is called by main() to get a line of input.
* The input line is placed in "str" and will be no
* more than "len" characters.
*/
void get_str( char *str, int len )
{
int i, c, curptr, insert_mode = 1;

num_got = 0;
cursor_pos = 0;
str_ptr = str; /* copy the buffer pointer */
curptr = RECSUB(lastptr + 1);
lastlines[curptr][0] = '\0';
lastlines[RECSUB(curptr + 1)][0] = '\0';
if (len > RECALL_LEN - 1) /* limit len to RECALL_LEN */
len = RECALL_LEN - 1;

while (1)
{
c = get_char_esc();

if (c == RETURN_KEY)
break;
else if (c == DELETE_KEY || c == BACKSPACE_KEY)
{
if (cursor_left())
{
++cursor_pos;
for (i = cursor_pos; i < num_got; ++i)
{
str[i - 1] = str[i];
sys_putchar(str[i]);
}
sys_putchar(' ');
for (i = cursor_pos; i <= num_got; ++i)
sys_putchar('\b');
--num_got;
--cursor_pos;
}
}
else if (c == CTRL('X')) /* erase line? */
clear_line();
else if (c == CTRL('A')) /* insert/overtype? */
insert_mode ^= 1;
else if (c == CTRL('B')) /* beginning-of-line? */
{
while (cursor_left())
;
}
else if (c == CTRL('E')) /* end-of-line? */
{
while (cursor_right())
;
}
else if (c == CTRL('R')) /* recall last line? */
{
clear_line();
strcpy(str, lastlines[lastptr]);
if ((num_got = strlen(str)) > 0)
{
put_str(str);
break;
}
}
else if (c == UP_ARROW)
{
clear_line();
if (lastlines[curptr][0] != '\0' ||
lastlines[RECSUB(curptr - 1)][0] != '\0')
{
curptr = RECSUB(curptr - 1);
strcpy(str, lastlines[curptr]);
put_str(str);
cursor_pos = num_got = strlen(str);
}
}
else if (c == DOWN_ARROW)
{
clear_line();
if (lastlines[curptr][0] != '\0' ||
lastlines[RECSUB(curptr + 1)][0] != '\0')
{
curptr = RECSUB(curptr + 1);
strcpy(str, lastlines[curptr]);
put_str(str);
cursor_pos = num_got = strlen(str);
}
}
else if (c == LEFT_ARROW)
{
if (cursor_pos > 0)
{
sys_putchar('\b');
--cursor_pos;
}
}
else if (c == RIGHT_ARROW)
cursor_right();
else if (' ' <= c && c < 0x7f && num_got < len - 1)
{
if (insert_mode)
{
/* Move right, all the characters
* to the right of cursor_pos.
*/
for (i = num_got; i > cursor_pos; --i)
str[i] = str[i - 1];
str[cursor_pos] = c;
for (i = cursor_pos; i <= num_got; ++i)
sys_putchar(str[i]);
for (i = cursor_pos; i < num_got; ++i)
sys_putchar('\b');
++num_got;
++cursor_pos;
}
else /* insert is off, use overtype mode */
{
str[cursor_pos] = c;
sys_putchar(c);
if (cursor_pos == num_got)
++num_got;
++cursor_pos;
}
}
}

str[num_got] = '\0';
sys_putchar('\n');

/* If this line is non-empty, and different
* from the last one accepted, store it into
* the recall buffer.
*/
if (num_got > 0 && strcmp(str, lastlines[lastptr]) != 0)
{
lastptr = RECSUB(lastptr + 1);
strcpy(lastlines[lastptr], str);
}
}


/*
* Move the cursor right one position, by echoing the
* character it's currently over.
* Return 1-OK, 0-can't move.
*/
static int cursor_right( void )
{
if (cursor_pos < num_got)
{
sys_putchar(str_ptr[cursor_pos]);
++cursor_pos;
return (1);
}
return (0);
}


/*
* Move the cursor left one position, by echoing
* a backspace. Return 1-OK, 0-can't move.
*/
static int cursor_left( void )
{
if (cursor_pos > 0)
{
sys_putchar('\b');
--cursor_pos;
return (1);
}
return (0);
}


/*
* Erase all characters on the current line.
*/
static void clear_line( void )
{

while (cursor_right())
; /* move right, to end of line */

cursor_pos = 0;
while (num_got > 0)
{
put_str(erase_one); /* then, erase to left */
--num_got;
}
}


/*
* Get a character, with escape processing.
* Handles special sequences like "ESC [ A" for up-arrow.
* This function would need to be modified to handle
* keyboards that are neither PC's nor VT-100's.
*/
static int get_char_esc( void )
{
int ch;

ch = sys_getchar();
if (ch != ESC_KEY)
return (ch);

ch = sys_getchar();
if (ch != '[')
return (ch);

ch = sys_getchar();
if (ch == 'A')
return (UP_ARROW); /* was ESC [ A */
else if (ch == 'B')
return (DOWN_ARROW); /* was ESC [ B */
else if (ch == 'C')
return (RIGHT_ARROW); /* was ESC [ C */
else if (ch == 'D')
return (LEFT_ARROW); /* was ESC [ D */
else
return (ch);
}


/*
* Put a string to sys_putchar().
*/
static void put_str( char *str )
{
while (*str != '\0')
sys_putchar(*str++);
}


  3 Responses to “Category : Files from Magazines
Archive   : CUJ9201.ZIP
Filename : 1001038A

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/