cs252/lab3-src/read-line.c
2018-10-25 14:45:56 -04:00

161 lines
3.1 KiB
C

/*
* CS354: Operating Systems.
* Purdue University
* Example that shows how to read one line with simple editing
* using raw terminal.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define MAX_BUFFER_LINE 2048
extern void tty_raw_mode(void);
// Buffer where line is stored
int line_length;
char line_buffer[MAX_BUFFER_LINE];
// Simple history array
// This history does not change.
// Yours have to be updated.
int history_index = 0;
char * history [] = {
"ls -al | grep x",
"ps -e",
"cat read-line-example.c",
"vi hello.c",
"make",
"ls -al | grep xxx | grep yyy"
};
int history_length = sizeof(history)/sizeof(char *);
void read_line_print_usage()
{
char * usage = "\n"
" ctrl-? Print usage\n"
" Backspace Deletes last character\n"
" up arrow See last command in the history\n";
write(1, usage, strlen(usage));
}
/*
* Input a line with some basic editing.
*/
char * read_line() {
// Set terminal in raw mode
tty_raw_mode();
line_length = 0;
// Read one line until enter is typed
while (1) {
// Read one character in raw mode.
char ch;
read(0, &ch, 1);
if (ch>=32) {
// It is a printable character.
// Do echo
write(1,&ch,1);
// If max number of character reached return.
if (line_length==MAX_BUFFER_LINE-2) break;
// add char to buffer.
line_buffer[line_length]=ch;
line_length++;
}
else if (ch==10) {
// <Enter> was typed. Return line
// Print newline
write(1,&ch,1);
break;
}
else if (ch == 31) {
// ctrl-?
read_line_print_usage();
line_buffer[0]=0;
break;
}
else if (ch == 8) {
// <backspace> was typed. Remove previous character read.
// Go back one character
ch = 8;
write(1,&ch,1);
// Write a space to erase the last character read
ch = ' ';
write(1,&ch,1);
// Go back one character
ch = 8;
write(1,&ch,1);
// Remove one character from buffer
line_length--;
}
else if (ch==27) {
// Escape sequence. Read two chars more
//
// HINT: Use the program "keyboard-example" to
// see the ascii code for the different chars typed.
//
char ch1;
char ch2;
read(0, &ch1, 1);
read(0, &ch2, 1);
if (ch1==91 && ch2==65) {
// Up arrow. Print next line in history.
// Erase old line
// Print backspaces
int i = 0;
for (i =0; i < line_length; i++) {
ch = 8;
write(1,&ch,1);
}
// Print spaces on top
for (i =0; i < line_length; i++) {
ch = ' ';
write(1,&ch,1);
}
// Print backspaces
for (i =0; i < line_length; i++) {
ch = 8;
write(1,&ch,1);
}
// Copy line from history
strcpy(line_buffer, history[history_index]);
line_length = strlen(line_buffer);
history_index=(history_index+1)%history_length;
// echo line
write(1, line_buffer, line_length);
}
}
}
// Add eol and null char at the end of string
line_buffer[line_length]=10;
line_length++;
line_buffer[line_length]=0;
return line_buffer;
}