From: mooseman Date: Wed, 30 Dec 2015 21:46:42 +0000 (+1300) Subject: Cleanup of code. This version is much simpler and (sort of) works. X-Git-Url: https://pd.if.org/git/?p=pd_readline;a=commitdiff_plain;h=050f646dd55e7fef8b2d0dcf5d1740ea8484f9c1 Cleanup of code. This version is much simpler and (sort of) works. --- diff --git a/Makefile b/Makefile deleted file mode 100644 index 1e008fd..0000000 --- a/Makefile +++ /dev/null @@ -1,41 +0,0 @@ - - -# Makefile for pd_readline - - -CC = gcc - -CFLAGS = -O2 -Wall -g -c $(DEFINES) - - -# INCPATH = -I. -INCPATH = . - -LDFLAGS = $(SYSLDFLAGS) $(MYLDFLAGS) - -# LIBS = -l$(SYSLIBS) $(MYLIBS) - -RM = rm -f - -HEADERS= pd_readline.h - -OBJECTS = keyhandler.o funcs.o history.o pd_readline.o - -%.o: %.c - $(CC) $(CFLAGS) $< -o $@ - -pd_readline: $(OBJECTS) - $(CC) $(LDFLAGS) $(OBJECTS) -o $@ $(LIBS) - -keyhandler.o: $(HEADERS) -funcs.o: $(HEADERS) -history.o: $(HEADERS) -pd_readline.o: $(HEADERS) - - -.PHONY: clean -clean: - rm *.o - - - diff --git a/README b/README index 6835e88..d2bed5e 100644 --- a/README +++ b/README @@ -1,39 +1,39 @@ ***** README - pd_readline ***** - This repo is for the storage of a public-domain -readline-and-command-history implementation. + This repo is for the storage of a public-domain +readline-and-command-history implementation. FILES: pd_readline.c - This is a file to test the implementation. Contains the main() function. -keyhandler.c - Reads the keystrokes and calls -functions to handle them. +test.txt - A small text file to test scrolling +up and down with. This would be the "history" file +in a real readline implementation. -funcs.c - Functions to handle the keystrokes. +Status - 31st Dec 2015 - "sort of works". -Update - 6th Sep 2012 - +I'm back into doing work on this code. -Almost there! -The code now pretty much works as expected. +I've reverted the code to a much simpler early version. +This compiles without errors and allows scrolling up +and down through the "test.txt" "dummy history" file. +It also allows editing of the command line. +However, edits are *not* yet saved in a history file. -It looks like the stack-smash problem has now -been fixed. I've give the code a pretty good -hammering and it didn't give me problems. - -Pressing Enter still exits the program rather -than storing the existing command-line and "staying -in the program". I hope to change this soon. +Pressing Enter exits the program rather than storing +the existing command-line and "staying in the program". +I hope to change this soon. You can edit a command-line (using backspace). You can move around with left and right-arrow keys. -Command-history can be recalled from a file with +"Dummy" history (from text.txt) can be recalled from a file with the up-arrow key, and you can scroll up and down -through the command-history. +through that file using the up and down arrows. This code is released to the public domain. "Share and enjoy........ ;) " diff --git a/funcs.c b/funcs.c deleted file mode 100644 index 3623220..0000000 --- a/funcs.c +++ /dev/null @@ -1,190 +0,0 @@ - - -/* funcs.c */ -/* Functions to handle cursor movement for */ -/* pd_readline. */ -/* This code is released to the public domain. */ -/* "Share and enjoy...." ;) */ -/* See the UNLICENSE file for details. */ - - -#include -#include -#include -#include "pd_readline.h" - -/* Note - make the up and down funcs return a buffer. */ -/* A line from the history file can be put into the */ -/* array member of the buffer. */ -/* Also test for the top and bottom of the history file. */ - -/* Error function. */ -void error(void) -{ - printf("Error \n"); -} - - - -/* Display a buffer */ -void show(buf b) -{ - printf("%s", b.array); -} - - - -/* Enter a char into a buffer and display the buffer array. */ -buf set(buf b, int i) -{ - if ( (b.index < 80) ) - { - b.array[b.index] = i; - b.index += 1 ; - } - else - { - memset(&b.array[0], 0, sizeof(b.array) ); - b.array[0] = i; - b.index += 1 ; - } - - show(b); - return b; - -} - - -/* Return a line from hist. */ -buf get(hist h) -{ - buf b; - memcpy(&b.array[0], h.array[h.curindex], 80); - return b; -} - - - -/* Move up in history list. */ -hist up(hist h) -{ - - buf b; - - if ( (h.curindex > 0) ) - { - h.curindex -= 1; - memset(&b.array[0], 0, sizeof(b.array) ); - memcpy(&b.array[0], h.array[h.curindex], 80); - show(b); - return h; - } - - else error(); - -} - - -/* Move down in history list. */ -hist down(hist h) -{ - - buf b; - - if ( (h.curindex < 19) ) - { - h.curindex += 1; - memset(&b.array[0], 0, sizeof(b.array) ); - memcpy(&b.array[0], h.array[h.curindex], 80); - show(b); - return h; - } - - else error(); - -} - - -/* Move cursor to left. */ -buf left(buf b) -{ - - -} - - -/* Move cursor to right. */ -buf right(buf b) -{ - - -} - - -/* Delete a char. */ -buf delch(buf b) -{ - - -} - - -/* Insert a char. */ -buf insch(buf b) -{ - - -} - - -void enter(void) -{ - printf("Enter "); -} - - -/* Find if a number is in a given range. */ -int range(int rstart, int rend, int i) -{ - if ( (rstart <= i) && (i <= rend) ) return 1; - else return 0; - -} - - -/* Assign a type depending on the range that a */ -/* number is in. */ -int type(int i) -{ - int ret; - - if ( range(0, 9, i) == 1 ) ret = 1; - else if ( range(10, 10, i) == 1 ) ret = 2; - else if ( range(27, 27, i) == 1 ) ret = 3; - else if ( range(32, 126, i) == 1 ) ret = 4; - else if ( range(127, 127, i) == 1 ) ret = 5; - else ret = 6; - - return ret; - -} - - -/* Function for special key combinations */ -/* (Ctrl, Alt, function keys. */ -void spec(hist h) -{ - - int j = getch(); - - if ( ( j == 65 ) ) up(h); - else if ( ( j == 66 ) ) down(h); - else if ( ( j == 67 ) ) printf("Right "); - else if ( ( j == 68 ) ) printf("Left "); - -} - - - - - diff --git a/history.c b/history.c deleted file mode 100644 index 498cbe8..0000000 --- a/history.c +++ /dev/null @@ -1,84 +0,0 @@ - - -/* history.c */ -/* Command history. */ -/* This code is released to the public domain. */ -/* "Share and enjoy...." ;) */ -/* See the UNLICENSE file for details. */ - -#include -#include -#include -#include -#include "pd_readline.h" - - -/* Helper function, to let us see if a file */ -/* exists in the current directory. */ -int fexists(char *fname) -{ - FILE *fptr; - fptr = fopen(fname, "r") ; - if ( !fptr ) return -1 ; /* File does not exist in dir. */ - fclose(fptr); - return 0; /* File DOES exist in dir. */ -} - - -/* Helper function to chop newlines off the lines read in. */ -/* Without this being done, an extra newline is inserted */ -/* (which is usually not what is wanted). */ -char *chop(char *s) -{ - s[strcspn(s,"\n")] = '\0'; - return s; -} - - - -/* Read the file into the array of strings. */ -hist readhistory(char *fname) -{ - - /* Create a history buffer. */ - hist h; - - int retval = fexists(fname); - - int i; - if (retval == 0) { - /* File exists, so open it. */ - /* We open it in read-write mode so we can */ - /* append new commands to it. */ - FILE *fptr; - fptr = fopen(fname, "rw"); - - char line[80] ; - - for(i=0; i<20; i++) - { - fgets(line, 80, fptr); - chop(line) ; - - /* TO DO: fix the "too few arguments" bug here.... */ - memcpy(&h.array[i], line, 80) ; - puts(h.array[i]); - } - - } /* retval == 0 */ - - else puts("Error! File does not exist. \n"); - - /* Set the curindex to 19. */ - h.curindex = 19; - - return h; - -} - - - - - - - diff --git a/keyhandler.c b/keyhandler.c deleted file mode 100644 index f4ca5ba..0000000 --- a/keyhandler.c +++ /dev/null @@ -1,94 +0,0 @@ - - - -/* keyhandler.c */ -/* Handle keystrokes for pd_readline. */ -/* This code is released to the public domain. */ -/* "Share and enjoy...." ;) */ -/* See the UNLICENSE file for details. */ - - -#include -#include -#include -#include -#include "pd_readline.h" - - -/* This implementation of getch() is from here - */ -/* http://wesley.vidiqatch.org/ */ -/* Thanks, Wesley! */ -static struct termios old, new; - -/* Initialize new terminal i/o settings */ -void initTermios(int echo) -{ - tcgetattr(0, &old); /* grab old terminal i/o settings */ - new = old; /* make new settings same as old settings */ - new.c_lflag &= ~ICANON; /* disable buffered i/o */ - new.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */ - tcsetattr(0, TCSANOW, &new); /* use these new terminal i/o settings now */ -} - - -/* Restore old terminal i/o settings */ -void resetTermios(void) -{ - tcsetattr(0, TCSANOW, &old); -} - - -/* Read 1 character - echo defines echo mode */ -char getch_(int echo) { - char ch; - initTermios(echo); - ch = getchar(); - resetTermios(); - return ch; -} - - -/* Read 1 character without echo */ -char getch(void) { - return getch_(0); -} - - -/* Read 1 character with echo */ -char getche(void) { - return getch_(1); -} - - - -/* Arrow keys are esc [ A to esc [ D */ -/* Alt keys are just esc then key (e.g. Alt-g is esc g ). */ -/* Ctrl (then letter) keys are just Dec 1 to Dec 26 */ - -void keyhandler(buf b, hist h) -{ - - int a = getch(); - - int t = type(a); - - switch(t) - { - - case (1): break; /* Ctrl a */ - case (2): break; /* Ctrl b */ - case (3): getch(); spec(h); break; /* Ctrl c */ - case (4): set(b, a); break; /* Printable chars. */ - case (5): delch(b); break; - case (6): break; - default: break; - - } - -} - - - - - - diff --git a/pd_readline b/pd_readline deleted file mode 100755 index a54280c..0000000 Binary files a/pd_readline and /dev/null differ diff --git a/pd_readline.c b/pd_readline.c deleted file mode 100644 index 044d6ef..0000000 --- a/pd_readline.c +++ /dev/null @@ -1,56 +0,0 @@ - - -/* pd_readline.c */ -/* Some code to allow the editing of a command-line. */ -/* You can also move around with the left and right */ -/* arrow keys, and recall previous commands with the */ -/* up-arrow key. */ -/* This code is released to the public domain. */ -/* "Share and enjoy...." ;) */ -/* See the UNLICENSE file for details. */ - -/* TO DO - */ -/* a) Add support for Home and End (of line) keys. */ -/* b) Add support for function keys. */ -/* c) Add support for Insert key so that text can be */ -/* inserted. */ -/* d) Put much of the code into a header file. */ -/* e) Change so that pressing Enter adds the current */ -/* line of commands to the command-history. */ -/* ( May look at using Ctrl-D to exit, as Python */ -/* does with its command-line. ) */ -/* f) Add support for copying and pasting text via */ -/* Ctrl-C and Ctrl-V. */ - - -#include "pd_readline.h" - - -int main(void) -{ - - /* Create a buffer for entered text. */ - buf mybuf; - mybuf.index = 0; - - - /* Read in the command history file. */ - hist myhist = readhistory("test.txt"); - - - while(1) - { - - keyhandler(mybuf, myhist); - - } - - return 0; - -} - - - - - - diff --git a/pd_readline.h b/pd_readline.h deleted file mode 100644 index 8be5d8f..0000000 --- a/pd_readline.h +++ /dev/null @@ -1,66 +0,0 @@ - - -/* pd_readline.h */ -/* Header file for pd_readline. */ -/* This code is released to the public domain. */ -/* "Share and enjoy...." ;) */ -/* See the UNLICENSE file for details. */ - - -/* Buffer typedef. */ -typedef struct { - int index; - char array[80] ; -} buf; - - -/* History. */ -typedef struct { - int curindex; - char array[20][80]; -} hist; - - - - -/* Termios funcs. */ -void initTermios(int echo) ; -void resetTermios(void) ; -char getch_(int echo); -char getch(void); -char getche(void); - - -/* Buffer funcs. */ -void error(void); -void show(buf b); -buf set(buf b, int i); -buf get(hist h); - -hist up(hist h); -hist down(hist h); -buf left(buf b); -buf right(buf b); -buf delch(buf b); -buf insch(buf b); -void enter(void); -int range(int rstart, int rend, int i); -int type(int i); - - -/* Special key handling. */ -void spec(hist h); - - -/* Other funcs. */ -hist readhistory(char *fname); -void keyhandler(buf b, hist h); - - - - - - - - - diff --git a/pdrl.c b/pdrl.c new file mode 100644 index 0000000..cdceba1 --- /dev/null +++ b/pdrl.c @@ -0,0 +1,255 @@ + + +/* pdrl.c */ + +/* Some code to allow the editing of a command-line. */ +/* You can also move around with the left and right */ +/* arrow keys, and recall previous commands with the */ +/* up-arrow key. */ +/* This code is released to the public domain. */ +/* "Share and enjoy...." ;) */ +/* See the UNLICENSE file for details. */ + +/* TO DO - */ +/* a) Add support for Home and End (of line) keys. */ +/* b) Add support for function keys. */ +/* c) Add support for Insert key so that text can be */ +/* inserted. */ +/* d) Put much of the code into a header file. */ +/* e) Change so that pressing Enter adds the current */ +/* line of commands to the command-history. */ +/* ( May look at using Ctrl-D to exit, as Python */ +/* does with its command-line. ) */ +/* f) Add support for copying and pasting text via */ +/* Ctrl-C and Ctrl-V. */ + + +#include +#include +#include + +/* This implementation of getch() is from here - */ +/* http://wesley.vidiqatch.org/ */ +/* Thanks, Wesley! */ +static struct termios old, new; + +/* Initialize new terminal i/o settings */ +void initTermios(int echo) { + tcgetattr(0, &old); /* grab old terminal i/o settings */ + new = old; /* make new settings same as old settings */ + new.c_lflag &= ~ICANON; /* disable buffered i/o */ + new.c_lflag &= echo ? ECHO : ~ECHO; /* set echo mode */ + tcsetattr(0, TCSANOW, &new); /* use these new terminal i/o settings now */ +} + + +/* Restore old terminal i/o settings */ +void resetTermios(void) { + tcsetattr(0, TCSANOW, &old); +} + + +/* Read 1 character - echo defines echo mode */ +char getch_(int echo) { + char ch; + initTermios(echo); + ch = getchar(); + resetTermios(); + return ch; +} + + +/* Read 1 character without echo */ +char getch(void) { + return getch_(0); +} + + +/* Read 1 character with echo */ +char getche(void) { + return getch_(1); +} + + + +/* Helper function, to let us see if a file */ +/* exists in the current directory. */ +int fexists(char *fname) +{ + FILE *fptr; + fptr = fopen(fname, "r") ; + if ( !fptr ) return -1 ; /* File does not exist in dir. */ + fclose(fptr); + return 0; /* File DOES exist in dir. */ +} + + +/* Helper function to chop newlines off the lines read in. */ +/* Without this being done, an extra newline is inserted */ +/* (which is usually not what is wanted). */ +char *chop(char *s) +{ + s[strcspn(s,"\n")] = '\0'; + return s; +} + + +/* An array to store the command-history file in. */ +/* Only 20 lines are read. */ +char hist[20][80]; + + + +/* Read the file into the array of strings. */ +void readfile(char *fname) +{ + int retval = fexists(fname); + + int i; + if (retval == 0) { + /* File exists, so open it. */ + /* We open it in read-write mode so we can */ + /* append new commands to it. */ + FILE *fptr; + fptr = fopen(fname, "rw"); + + for(i=0; i<20; i++) + { + chop(fgets(hist[i], 80, fptr) ); + } + + } /* retval == 0 */ + + else puts("Error! File does not exist. \n"); + +} + + +/* Helper function to print the command-history file. */ +void printfile(void) +{ + int j; + + for(j=0; j<20; j++) + { + puts(hist[j]); + } +} + + + + +/* Helper function. Print a previous command-line WITHOUT */ +/* a newline. */ +void putline(char *str) +{ + char *line = chop(str); + printf("%s", line); +} + + + + +int main(void) +{ + +/* Our "command-history" file. */ +readfile("test.txt"); + + +/* "Pointer" for the history file. */ +int histpnt = 20; + + + while(1) + { + + int key = getch(); + + /* Printable chars. */ + if ( (key >= 32) && (key <= 126) ) + { + /* We have a printable key so print it. */ + putchar(key); + } + + /* Up arrow is 27, 91, 65. ( ESC [ A ) */ + /* Down arrow is 27, 91, 66. ( ESC [ B ) */ + /* Right arrow is 27, 91, 67. ( ESC [ C ) */ + /* Left arrow is 27, 91, 68. ( ESC [ D ) */ + /* Function keys. */ + /* F2 is 27, 79, 81. */ + /* F3 is 27, 79, 82. */ + /* F4 is 27, 79, 83. */ + + /* Backspace */ + else if(key == 127) + { + /* Move left 1 char and delete that char */ + printf("\033[1D"); + printf("\040"); + printf("\033[1D"); + } + + /* We have an escape key-sequence */ + else if(key == 27) + { + key = getch(); + if(key == 91) + key = getch(); + + if (key == 65) /* Up Arrow */ + { + /* Move one command "back" in history. */ + histpnt -= 1; + /* Clear to end of line. */ + printf("\033[80D"); + printf("\033[K"); + /* Print the pointed-at command-sequence. */ + putline(hist[histpnt]); + } + + if(key == 66) /* Down Arrow */ + { + /* Move one command "forward" in history. */ + histpnt += 1; + /* Clear to end of line. */ + printf("\033[80D"); + printf("\033[K"); + /* Print the pointed-at command-sequence. */ + putline(hist[histpnt]); + } + + if(key == 67) /* Left arrow */ + { + /* Move one character to the left. */ + printf("\033[1C"); + } + + if(key == 68) /* Right arrow */ + { + /* Move one character to the right. */ + printf("\033[1D"); + } + + } /* End of key=27 key sequence. */ + + + /* The Enter key exits. Enter is 10 decimal */ + else if(key == 10) + { + puts("\n"); + puts("Exiting... \n"); + break; + } /* Key = Enter */ + } + + return 0; + +} + + + + + + diff --git a/range b/range deleted file mode 100755 index 709d9e0..0000000 Binary files a/range and /dev/null differ diff --git a/range.c b/range.c deleted file mode 100644 index c4c6cfe..0000000 --- a/range.c +++ /dev/null @@ -1,61 +0,0 @@ - - -/* range.c */ - -/* See if an int is in a given range. */ - - - -#include -#include -#include - - - -/* Find if a number is in a given range. */ -int range(int rstart, int rend, int i) -{ - if ( (rstart <= i) && (i <= rend) ) return 1; - else return 0; - -} - - - -int main() -{ - -/* Within the range. */ -int a = range(0, 9, 5); -int b = range(0, 9, 0); -int c = range(0, 9, 9); -int d = range(20, 40, 32); - - -/* Outside the range. */ -int e = range(0, 9, -15); -int f = range(20, 40, 75); -int g = range(50, 80, 91); - -printf("%d %d %d %d %d %d %d \n", a, b, c, d, e, f, g); - - -int i = 65; -char s[2]; - -snprintf(s, 2, "%c", i); - -printf("%s \n" , s ); - -return 0; - - -} - - - - - - - -