From 7bd8eb6fd597563da806f043b47072bdcb9776fe Mon Sep 17 00:00:00 2001 From: Mart Lubbers Date: Mon, 25 Jan 2016 11:19:53 +0100 Subject: [PATCH] add history commands --- Clean System Files/readLine.c | 78 +++++++++++++++++++++++++++++------ README.md | 10 ++++- ReadLine.dcl | 23 ++++++++--- ReadLine.icl | 24 +++++++++++ test.icl | 2 + 5 files changed, 118 insertions(+), 19 deletions(-) diff --git a/Clean System Files/readLine.c b/Clean System Files/readLine.c index b39be2e..2855915 100644 --- a/Clean System Files/readLine.c +++ b/Clean System Files/readLine.c @@ -8,17 +8,61 @@ static char *cs_answer = (char *)NULL; -void cleanReadLine(CleanString prompt, int history, CleanString *result) -{ - //Initialize - unsigned long promptlen = CleanStringLength(prompt); - char *cs_prompt = (char *)malloc(promptlen+1); - if(cs_prompt == NULL){ +char *cleanStringToCString(CleanString s){ + unsigned long len = CleanStringLength(s); + char *cs = (char *)malloc(len+1); + if(cs == NULL){ printf("malloc failed...\n"); exit(1); } - memcpy(cs_prompt, CleanStringCharacters(prompt), promptlen); - cs_prompt[promptlen] = '\0'; + memcpy(cs, CleanStringCharacters(s), len); + cs[len] = '\0'; + return cs; +} + +int cleanReadHistory(CleanString path) +{ + char *cs_path = cleanStringToCString(path); + int errno = read_history(cs_path); + free(cs_path); + return errno; +} + +int cleanReadHistoryRange(CleanString path, int from, int to) +{ + char *cs_path = cleanStringToCString(path); + int errno = read_history_range(cs_path, from, to); + free(cs_path); + return errno; +} + +int cleanWriteHistory(CleanString path) +{ + char *cs_path = cleanStringToCString(path); + int errno = write_history(cs_path); + free(cs_path); + return errno; +} + +int cleanAppendHistory(int n, CleanString path) +{ + char *cs_path = cleanStringToCString(path); + int errno = append_history(n, cs_path); + free(cs_path); + return errno; +} + +int cleanHistoryTruncateFile(CleanString path, int nlines) +{ + char *cs_path = cleanStringToCString(path); + int errno = history_truncate_file(cs_path, nlines); + free(cs_path); + return errno; +} + +void cleanReadLine(CleanString prompt, int history, CleanString *result) +{ + char *cs_prompt = cleanStringToCString(prompt); //Get the answer and add to history if not empty if(cs_answer){ @@ -31,9 +75,17 @@ void cleanReadLine(CleanString prompt, int history, CleanString *result) add_history(cs_answer); } - //Transfor answer into cstring - CleanStringVariable(answer, strlen(cs_answer)); - *result = (CleanString) answer; - memcpy(CleanStringCharacters(answer), cs_answer, strlen(cs_answer)); - CleanStringLength(answer) = strlen(cs_answer); + if(!cs_answer){ + //Transfor answer into cstring + CleanStringVariable(answer, 1); + *result = (CleanString) answer; + memcpy(CleanStringCharacters(answer), "", 1); + CleanStringLength(answer) = 1; + } else { + //Transfor answer into cstring + CleanStringVariable(answer, strlen(cs_answer)); + *result = (CleanString) answer; + memcpy(CleanStringCharacters(answer), cs_answer, strlen(cs_answer)); + CleanStringLength(answer) = strlen(cs_answer); + } } diff --git a/README.md b/README.md index c50a825..b2a9865 100644 --- a/README.md +++ b/README.md @@ -19,9 +19,17 @@ make When you want to use the library in your program you should compile with the `-l /usr/lib/libreadline.so` linker flag +###Changelog + +- 0.2 (2016-01-25) + - History file operations added + - EOF is now properly handled +- 0.1 (2016-01-25) + - Readline is working + - History works but no control over it + ###Todo -- Test how the library reacts on non terminal stdin and EOF - Embed the readline library in the object files in such a way that no special compiler flag is needed. - Control over history, right now entries are added automatically to the diff --git a/ReadLine.dcl b/ReadLine.dcl index da953d7..540886a 100644 --- a/ReadLine.dcl +++ b/ReadLine.dcl @@ -1,8 +1,21 @@ definition module ReadLine -/* - Reads a line from stdin with the readline library - The value in the String argument will be used as a prompt - To enable history the Boolean variable has to be set to True -*/ +//Readline readLine :: !String !Bool !*env -> (!String, !*env) + +//Initializing History and State Management + +//History List Management + +//Information About the History List + +//Moving Around the History List + +//Searching the History List + +//Managing the History File +readHistory :: !String !*env -> (!Bool, !*env) +readHistoryRange :: !String !Int !Int !*env -> (!Bool, !*env) +writeHistory :: !String !*env -> (!Bool, !*env) +appendHistory :: !Int !String !*env -> (!Bool, !*env) +historyTruncateFile :: !String !Int !*env -> (!Bool, !*env) diff --git a/ReadLine.icl b/ReadLine.icl index b8c3053..8807f4f 100644 --- a/ReadLine.icl +++ b/ReadLine.icl @@ -9,3 +9,27 @@ readLine s h e = code { ccall cleanReadLine "SI:S:A" } +readHistory :: !String !*env -> (!Bool, !*env) +readHistory s e = code { + ccall cleanReadHistory "S:I:A" + } + +readHistoryRange :: !String !Int !Int !*env -> (!Bool, !*env) +readHistoryRange s i1 i2 e = code { + ccall cleanReadHistoryRange "SII:I:A" + } + +writeHistory :: !String !*env -> (!Bool, !*env) +writeHistory s e = code { + ccall cleanWriteHistory "S:I:A" + } + +appendHistory :: !Int !String !*env -> (!Bool, !*env) +appendHistory i s e = code { + ccall cleanWriteHistory "IS:I:A" + } + +historyTruncateFile :: !String !Int !*env -> (!Bool, !*env) +historyTruncateFile i s e = code { + ccall cleanWriteHistory "SI:I:A" + } diff --git a/test.icl b/test.icl index 0919253..26ced3c 100644 --- a/test.icl +++ b/test.icl @@ -6,6 +6,8 @@ import ReadLine Start :: *World -> (String, *World) Start w # (f, w) = stdio w +#! (_, w) = readHistory "readline.history" w #! (s, w) = readLine "first prompt: " True w #! (s, w) = readLine "uparrow should word with history: " False w +#! (_, w) = writeHistory "readline.history" w = (s, w) -- 2.20.1