home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 14
/
CD_ASCQ_14_0694.iso
/
maj
/
653
/
editgets.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-03
|
13KB
|
372 lines
/* editgets.c - line input w/editing */
/* this code is released to the public domain */
/* written by Jon Burchmore */
/* modifications & enhancements by Bob Stout */
/* This is as close to ANSI compliant C that I could come, but it was made */
/* on an IBM compatable computer, so I designed it for that platform. */
/* If you're porting it to another computer type, please note how the IBM */
/* passes enhanced keys. First, it sends an ASCIIZ (character 0), then a */
/* standard character. Anyway, what the switch() statement does is check */
/* to see if there WAS a zero sent, and if there wasn't, it just "falls" */
/* through to the default, which handles normal characters. */
/* The conio header file provides the getch() function, which returns a */
/* single character from the KEYBOARD, not stdin, and waits if it must. */
/* It is be possible to re-write this function for a computer besides an */
/* IBM PC. */
/* It would be possible to check the variable insert, and if it's on, make */
/* the cursor large, and if it's off, make the cursor small, but my primary */
/* goal is portability, not fancy add-ons */
/* Pardon the lack of comments. I'm a coder, not an author. Besides, if */
/* you can't understand this, DON'T USE IT! (Words to live by) */
#include <conio.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#undef min
#define min(x,y) (((x) <= (y)) ? (x) : (y))
#define NUL 0x00
#define ESC 0x1B
#define LEFT 0x4B
#define RIGHT 0x4D
#define HOME 0x47
#define END 0x4F
#define INSERT 0x52
#define DELETE 0x53
#define BACKSPC 0x08
#define ENTER 0x0D
#define CTLEND 0x75
#define CTLHOME 0x77
#define CTLRT 0x74
#define CTLLFT 0x73
/*
** Password mode - '*' is echoed for all characters, only ESC, ENTER,
** BACKSPC, and CTLHOME are active.
*/
int password_mode = 0;
/*
** Aruments: 1) Buffer to receive string
** 2) Size of buffer
** 3) Default string
*/
int jgets(char *s, int maxlen, char *string)
{
char temp[500];
int insert = 1, done = 0, pos, len, i, j, c, zeroflag;
if (NULL == string)
string = "";
if (0 != (pos = len = strlen(string)))
strncpy(temp, string, min(len, maxlen));
for (i = 0; i < maxlen; ++i)
{
if (NUL == *string)
putchar('_');
else putchar(*string++);
}
for (i = 0; i < (maxlen - len); ++i)
putchar(BACKSPC);
while (!done)
{
zeroflag = 0;
if ((c = getch()) == 0)
{
zeroflag = 1;
c = getch();
}
switch (c)
{
case ESC :
if (len == 0)
break;
if (pos != len)
{
for (i = pos; i < len; i++)
putch('_');
for (i = len; i >= 0; i--)
{
putch(BACKSPC);
putch('_');
putch(BACKSPC);
}
pos = len = 0;
break;
}
case LEFT :
if (zeroflag)
{
if (password_mode)
break;
if (pos == 0)
break;
pos--;
putch(BACKSPC);
break;
}
case RIGHT :
if (zeroflag)
{
if (password_mode)
break;
if (pos == len)
break;
if (pos != maxlen)
{
putch(temp[pos]);
pos++;
}
break;
}
case HOME :
if (zeroflag)
{
if (password_mode)
break;
while (pos-- > 0)
putch(BACKSPC);
pos = 0;
break;
}
case END :
if (zeroflag)
{
if (password_mode)
break;
while (pos < len)
putch(temp[pos++]);
break;
}
case INSERT :
if (zeroflag)
{
if (password_mode)
break;
insert = (!(insert));
break;
}
case DELETE :
if (zeroflag)
{
if (password_mode)
break;
if (pos == len)
break;
for (i = pos; i < len; i++)
temp[i] = temp[i + 1];
len--;
for (i = pos; i < len; i++)
putch(temp[i]);
putch('_');
for (i = len + 1; i > pos; i--)
putch(BACKSPC);
break;
}
case BACKSPC :
if (c == BACKSPC)
{
if (pos == 0)
break;
if (pos != len)
{
for (i = pos - 1; i < len; i++)
temp[i] = temp[i + 1];
pos--;
len--;
putch(BACKSPC);
for (i = pos; i < len; i++)
putch(temp[i]);
putch('_');
for (i = len; i >= pos; i--)
putch(BACKSPC);
}
else
{
putch(BACKSPC);
putch('_');
putch(BACKSPC);
pos = --len;
}
break;
}
case ENTER :
if (c == ENTER)
{
done = 1;
break;
}
case CTLEND :
if (zeroflag)
{
if (password_mode)
break;
for (i = pos; i < len; ++i)
putch('_');
for (i = pos; i < len; ++i)
putch(BACKSPC);
len = pos;
break;
}
case CTLHOME :
if (zeroflag)
{
if (pos == 0)
break;
if (pos != len)
{
while (0 != pos)
{
for (i = pos - 1; i < len; i++)
temp[i] = temp[i + 1];
pos--;
len--;
putch(BACKSPC);
for (i = pos; i < len; i++)
putch(temp[i]);
putch('_');
for (i = len; i >= pos; i--)
putch(BACKSPC);
}
}
else
{
while (0 != pos)
{
putch(BACKSPC);
putch('_');
putch(BACKSPC);
pos = --len;
}
}
break;
}
case CTLRT :
if (zeroflag)
{
if (password_mode)
break;
do
{
if (pos == len)
break;
if (pos != maxlen)
{
putch(temp[pos]);
pos++;
}
} while (isspace(temp[pos]));
do
{
if (pos == len)
break;
if (pos != maxlen)
{
putch(temp[pos]);
pos++;
}
} while (!isspace(temp[pos]));
break;
}
case CTLLFT :
if (zeroflag)
{
if (password_mode)
break;
do
{
if (pos == 0)
break;
pos--;
putch(BACKSPC);
} while (isspace(temp[pos]));
do
{
if (pos == 0)
break;
pos--;
putch(BACKSPC);
} while (!isspace(temp[pos]));
break;
}
default :
if (zeroflag)
break;
if (c == 0 || pos == maxlen)
break;
if ((!(insert)) || pos == len)
{
temp[pos++] = (char)c;
if (pos > len) len++;
if (password_mode)
putch('*');
else putch(c);
}
else
{
if (len == maxlen)
break;
for (i = len++; i >= pos; i--)
temp[i + 1] = temp[i];
temp[pos++] = (char)c;
if (password_mode)
putch('*');
else putch(c);
for (i = pos; i < len; i++)
putch(temp[i]);
for (i = len; i > pos; i--)
putch(BACKSPC);
}
}
}
temp[len] = '\0';
strcpy(s, temp);
return len;
}
#ifdef TEST
void main(void)
{
char mystring[60];
memset(mystring, 0, 60);
fputs("Enter any string: ", stdout);
jgets(mystring, 60, "This is a test");
puts("");
printf("editgets() returned:\n%s\n", mystring);
password_mode = 1;
memset(mystring, 0, 60);
fputs("Enter any password: ", stdout);
jgets(mystring, 50, NULL);
puts("");
printf("editgets() returned:\n%s\n", mystring);
}
#endif