+++ /dev/null
-
-
-# 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
-
-
-
***** 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........ ;) "
+++ /dev/null
-
-
-/* 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 <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#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 ");
-
-}
-
-
-
-
-
+++ /dev/null
-
-
-/* history.c */
-/* Command history. */
-/* This code is released to the public domain. */
-/* "Share and enjoy...." ;) */
-/* See the UNLICENSE file for details. */
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <malloc.h>
-#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;
-
-}
-
-
-
-
-
-
-
+++ /dev/null
-
-
-
-/* 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 <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <termios.h>
-#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;
-
- }
-
-}
-
-
-
-
-
-
+++ /dev/null
-
-
-/* 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;
-
-}
-
-
-
-
-
-
+++ /dev/null
-
-
-/* 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);
-
-
-
-
-
-
-
-
-
--- /dev/null
+
+
+/* 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 <string.h>
+#include <stdio.h>
+#include <termios.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);
+}
+
+
+
+/* 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;
+
+}
+
+
+
+
+
+
+++ /dev/null
-
-
-/* range.c */
-
-/* See if an int is in a given range. */
-
-
-
-#include <string.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-
-
-/* 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;
-
-
-}
-
-
-
-
-
-
-
-