299 lines
5.6 KiB
C
299 lines
5.6 KiB
C
/* $NetBSD: shell_input.c,v 1.5 1996/10/13 03:06:07 christos Exp $ */
|
|
|
|
/*
|
|
* Copyright (c) 1994 Mark Brinicombe.
|
|
* Copyright (c) 1994 Brini.
|
|
* All rights reserved.
|
|
*
|
|
* This code is derived from software written for Brini by Mark Brinicombe
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
* must display the following acknowledgement:
|
|
* This product includes software developed by Brini.
|
|
* 4. The name of the company nor the name of the author may be used to
|
|
* endorse or promote products derived from this software without specific
|
|
* prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
* IN NO EVENT SHALL BRINI OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
|
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
* SUCH DAMAGE.
|
|
*
|
|
* RiscBSD kernel project
|
|
*
|
|
* shell_input.c
|
|
*
|
|
* string input functions
|
|
*
|
|
* Created : 09/10/94
|
|
*/
|
|
|
|
#include <sys/param.h>
|
|
#include <sys/systm.h>
|
|
#include <sys/malloc.h>
|
|
#include <dev/cons.h>
|
|
|
|
/*#define SOFT_CURSOR*/
|
|
|
|
/* Declare global variables */
|
|
|
|
/* Prototype declarations */
|
|
|
|
char *strchr __P((const char *, int));
|
|
|
|
void deleteline __P((int, int));
|
|
|
|
/*
|
|
* Reads a line from the keyboard into an input buffer allowing
|
|
* cursor editing and input history.
|
|
*/
|
|
|
|
int
|
|
readstring(string, length, valid_string, insert)
|
|
char *string;
|
|
int length;
|
|
char *valid_string;
|
|
char *insert;
|
|
{
|
|
int key;
|
|
int loop;
|
|
int entered;
|
|
int insert_mode = 1;
|
|
|
|
/*
|
|
* If we have text to preinsert into the buffer enter it and echo it
|
|
* to the display.
|
|
*/
|
|
|
|
if (insert && insert[0] != 0) {
|
|
strcpy(string, insert);
|
|
loop = strlen(insert);
|
|
printf("%s", insert);
|
|
} else
|
|
loop = 0;
|
|
|
|
entered = loop;
|
|
|
|
/*
|
|
* The main loop.
|
|
* Keep looping until return or CTRL-D is pressed.
|
|
*/
|
|
|
|
do {
|
|
#ifdef SOFT_CURSOR
|
|
/*
|
|
* Display the cursor depending on what mode we are in
|
|
*/
|
|
if (!insert_mode)
|
|
printf("\xe2");
|
|
else
|
|
printf("\xe1");
|
|
#endif
|
|
|
|
/*
|
|
* Read the keyboard
|
|
*/
|
|
|
|
key = cngetc();
|
|
|
|
#ifdef SOFT_CURSOR
|
|
/*
|
|
* Remove the cursor, restoring the text under it if necessary.
|
|
*/
|
|
|
|
if (loop == entered || entered == 0)
|
|
printf("\x7f");
|
|
else
|
|
printf("\x08%c\x08", string[loop]);
|
|
#endif
|
|
|
|
/*
|
|
* Decode the key
|
|
*/
|
|
|
|
switch (key) {
|
|
/*
|
|
* DELETE
|
|
*/
|
|
|
|
case 0x109 :
|
|
case 0x7f :
|
|
{
|
|
int loop1;
|
|
|
|
if (loop == entered) break;
|
|
for (loop1 = loop; loop1 < (entered - 1); ++loop1) {
|
|
string[loop1] = string[loop1+1];
|
|
}
|
|
--entered;
|
|
string[entered] = 0;
|
|
/* printf("\x1b[s%s \x1b[u", &string[loop]);*/
|
|
printf("\r%s \r", string);
|
|
for (loop1 = 0; loop1 <= loop; ++loop1)
|
|
printf("\x09");
|
|
}
|
|
break;
|
|
|
|
/*
|
|
* BACKSPACE
|
|
*/
|
|
|
|
case 0x08 :
|
|
{
|
|
int loop1;
|
|
|
|
if (loop == 0) {
|
|
printf("\x07");
|
|
break;
|
|
}
|
|
for (loop1 = loop-1; loop1 < (entered - 1); ++loop1) {
|
|
string[loop1] = string[loop1+1];
|
|
}
|
|
--loop;
|
|
--entered;
|
|
string[entered] = 0;
|
|
/* printf("\x1b[D\x1b[s%s \x1b[u", &string[loop]);*/
|
|
printf("\r%s \r", string);
|
|
for (loop1 = 0; loop1 < loop; ++loop1)
|
|
printf("\x09");
|
|
}
|
|
break;
|
|
|
|
/*
|
|
* CTRL-U
|
|
*/
|
|
case 0x15 :
|
|
deleteline(loop, entered);
|
|
loop = 0;
|
|
entered = 0;
|
|
break;
|
|
|
|
/*
|
|
* CTRL-A
|
|
*/
|
|
case 0x01 :
|
|
insert_mode = !insert_mode;
|
|
break;
|
|
|
|
/*
|
|
* CTRL-D
|
|
*/
|
|
case 0x04 :
|
|
return(-1);
|
|
break;
|
|
|
|
/*
|
|
* CURSOR LEFT
|
|
*/
|
|
|
|
case 0x102 :
|
|
--loop;
|
|
if (loop < 0)
|
|
loop = 0;
|
|
else
|
|
printf("\x1b[D");
|
|
break;
|
|
|
|
/*
|
|
* CURSOR RIGHT
|
|
*/
|
|
|
|
case 0x103 :
|
|
++loop;
|
|
if (loop > entered)
|
|
loop = entered;
|
|
else
|
|
printf("\x1b[C");
|
|
break;
|
|
|
|
/*
|
|
* RETURN
|
|
*/
|
|
|
|
case 0x0d :
|
|
case 0x0a :
|
|
break;
|
|
|
|
/*
|
|
* Another key
|
|
*/
|
|
|
|
default :
|
|
|
|
/*
|
|
* Check for a valid key to enter
|
|
*/
|
|
|
|
if (key < 0x100 && key > 0x1f
|
|
&& (valid_string == NULL || strchr(valid_string, key))) {
|
|
if (!insert_mode && loop < length) {
|
|
string[loop] = key;
|
|
printf("%c", key);
|
|
++loop;
|
|
if (loop > entered) entered = loop;
|
|
}
|
|
else if (entered < length) {
|
|
int loop1;
|
|
|
|
for (loop1 = entered; loop1 >= loop; --loop1) {
|
|
string[loop1+1] = string[loop1];
|
|
}
|
|
string[loop] = key;
|
|
++loop;
|
|
++entered;
|
|
string[entered] = 0;
|
|
if (loop != entered) printf("\x1b[s");
|
|
printf("%s", &string[loop-1]);
|
|
if (loop != entered) printf("\x1b[u\x1b[C");
|
|
} else {
|
|
printf("\x07");
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
} while (key != 0x0d && key != 0x0a);
|
|
|
|
printf("\n\r");
|
|
|
|
string[entered] = 0;
|
|
|
|
return(entered);
|
|
}
|
|
|
|
|
|
/* This erases a line of text */
|
|
|
|
void
|
|
deleteline(loop, entered)
|
|
int loop;
|
|
int entered;
|
|
{
|
|
while (loop < entered) {
|
|
++loop;
|
|
printf("\x1b[C");
|
|
}
|
|
|
|
while (loop > 0) {
|
|
--loop;
|
|
--entered;
|
|
printf("\x7f");
|
|
}
|
|
}
|
|
|
|
/* End of shell_input.c */
|