From 95ae145cd11e1721e3f0d0a4fb7ff136d4191aed Mon Sep 17 00:00:00 2001 From: Jeremiah Orians Date: Mon, 18 Jul 2016 18:30:03 -0400 Subject: [PATCH] Added Minimal TTY library required for proper user interface approximation and fixed bugs in SET --- SET.c | 44 +++++++++++++++++++++++++++--------- tty.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 11 deletions(-) create mode 100644 tty.c diff --git a/SET.c b/SET.c index bfab39c..25015eb 100644 --- a/SET.c +++ b/SET.c @@ -13,6 +13,7 @@ bool Reached_EOF; char temp[max_string + 1]; +char tty_getchar(); struct Line { @@ -21,6 +22,16 @@ struct Line struct Line* prev; }; +int get_linenum(struct Line* p) +{ + if(NULL == p->prev) + { + return 0; + } + + return get_linenum(p->prev) + 1; +} + struct Line* newLine() { struct Line* p; @@ -32,6 +43,7 @@ struct Line* newLine() exit (EXIT_FAILURE); } + p->Text[0] = '\n'; return p; } @@ -128,10 +140,13 @@ struct Line* RemoveLine(struct Line* p) if(NULL != p->prev) { p->prev->next = p->next; - return p->prev; } - return p->next; + if(NULL != p->next) + { + return p->next; + } + return p->prev; } struct Line* InsertLine(struct Line* head) @@ -176,10 +191,9 @@ struct Line* AppendLine(struct Line* head) return head; } -void Editor_loop(struct Line* head, FILE* source_file) +void Editor_loop(struct Line* head, char* file_name) { - Readline(stdin); - switch(temp[0]) + switch(tty_getchar()) { case 'a': { @@ -190,7 +204,7 @@ void Editor_loop(struct Line* head, FILE* source_file) { if(NULL != head->prev) { - Editor_loop(head->prev, source_file); + Editor_loop(head->prev, file_name); } break; } @@ -209,7 +223,7 @@ void Editor_loop(struct Line* head, FILE* source_file) { if(NULL != head->next) { - Editor_loop(head->next, source_file); + Editor_loop(head->next, file_name); } break; } @@ -220,6 +234,7 @@ void Editor_loop(struct Line* head, FILE* source_file) } case 'p': { + printf("Showing contents of line %04x:\n", get_linenum(head)); fputs(head->Text, stdout); break; } @@ -229,8 +244,10 @@ void Editor_loop(struct Line* head, FILE* source_file) } case 'w': { - rewind(source_file); + FILE* source_file; + source_file = fopen(file_name, "w"); WriteOut(GetHead(head), source_file); + fclose(source_file); break; } case '?': @@ -240,7 +257,7 @@ void Editor_loop(struct Line* head, FILE* source_file) } } - Editor_loop(head,source_file); + Editor_loop(head, file_name); } /* Standard C main program */ @@ -254,7 +271,10 @@ int main(int argc, char **argv) } FILE* source_file; - source_file = fopen(argv[1], "rw+"); + char file_name[256] = {0}; + + strncpy(file_name, argv[1], 255); + source_file = fopen(file_name, "rw+"); Reached_EOF = false; struct Line* head = NULL; @@ -267,7 +287,9 @@ int main(int argc, char **argv) head = addLine(head, p); } - Editor_loop(head, source_file); + fclose(source_file); + + Editor_loop(head, file_name); return EXIT_SUCCESS; } diff --git a/tty.c b/tty.c new file mode 100644 index 0000000..6166e12 --- /dev/null +++ b/tty.c @@ -0,0 +1,72 @@ +#include +#include +#include + +/**************************************************** + * To make effective use of this library function: * + * add prototypes for the bellow functions that you * + * wish to use. Please note that they contain bugs * + ****************************************************/ + + +/* In order to restore at exit.*/ +static struct termios orig_termios; + +/* Raw mode: 1960 magic shit. */ +void enableRawMode() +{ + struct termios raw; + + if(!isatty(STDIN_FILENO)) + { + exit(EXIT_FAILURE); + } + + if(tcgetattr(STDIN_FILENO, &orig_termios) == -1) + { + exit(EXIT_FAILURE); + } + + raw = orig_termios; /* modify the original mode */ + /* input modes: no break, no CR to NL, no parity check, no strip char, + * no start/stop output control. */ + raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); + /* output modes - disable post processing */ + raw.c_oflag &= ~(OPOST); + /* control modes - set 8 bit chars */ + raw.c_cflag |= (CS8); + /* local modes - choing off, canonical off, no extended functions, + * no signal chars (^Z,^C) */ + raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); + /* control chars - set return condition: min number of bytes and timer. */ + raw.c_cc[VMIN] = 0; /* Return each byte, or zero for timeout. */ + raw.c_cc[VTIME] = 1; /* 100 ms timeout (unit is tens of second). */ + + /* put terminal in raw mode after flushing */ + if(tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) < 0) + { + exit(EXIT_FAILURE); + } + + return; +} + +void disableRawMode() +{ + tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios); +} + +char tty_getchar() +{ + int nread; + char c; + + enableRawMode(); + do + { + nread = read(STDIN_FILENO, &c, 1); + } while(nread == 0); + disableRawMode(); + + return c; +}