#include "Clean.h"
static char *cs_answer = (char *)NULL;
+static char **cs_tokens = (char **)NULL;
+static int num_tokens = 0;
HISTORY_STATE *history_state = NULL;
//Helper functions
free(cs_path);
return errno == 0;
}
+
+//History Expansion
+void cleanHistoryExpand(CleanString string, CleanString *output, int *ret)
+{
+ char *cs_output;
+ char *cs_string = cleanStringToCString(string);
+ *ret = history_expand(cs_string, &cs_output);
+
+ CleanStringVariable(cleanOutput, strlen(cs_output));
+ *output = (CleanString) cleanOutput;
+ memcpy(CleanStringCharacters(cleanOutput), cs_output, strlen(cs_output));
+ CleanStringLength(cleanOutput) = strlen(cs_output);
+ free(cs_output);
+ free(cs_string);
+}
+
+void cleanGetHistoryEvent(
+ CleanString string, int qchar, int cindex, CleanString *output,
+ int *retcindex, int *null)
+{
+ char *cs_string = cleanStringToCString(string);
+ char *cs_output = get_history_event(cs_string, &cindex, qchar);
+
+ if(cs_output == NULL){
+ *null = 1;
+ cs_output = "";
+ } else {
+ *null = 0;
+ }
+
+ CleanStringVariable(cleanOutput, strlen(cs_output));
+ *output = (CleanString) cleanOutput;
+ memcpy(CleanStringCharacters(cleanOutput), cs_output, strlen(cs_output));
+ CleanStringLength(cleanOutput) = strlen(cs_output);
+
+ if(*null == 0){
+ free(cs_output);
+ }
+ *retcindex = cindex;
+}
+
+int cleanHistoryTokenizeInit(CleanString string)
+{
+ if(cs_tokens){
+ for(int i = 0; i<num_tokens; i++){
+ free(cs_tokens[i]);
+ }
+ free(cs_tokens);
+ }
+ char *cs_string = cleanStringToCString(string);
+ cs_tokens = history_tokenize(cs_string);
+ free(cs_string);
+
+ num_tokens = 0;
+ for(; cs_tokens[num_tokens]; num_tokens++);
+ return num_tokens;
+}
+
+void cleanHistoryTokenizeItem(int num, CleanString *output)
+{
+ char *cs_output = cs_tokens[num];
+ CleanStringVariable(cleanOutput, strlen(cs_output));
+ *output = (CleanString) cleanOutput;
+ memcpy(CleanStringCharacters(cleanOutput), cs_output, strlen(cs_output));
+ CleanStringLength(cleanOutput) = strlen(cs_output);
+}
+
+void cleanHistoryArgExtract(
+ int first, int last, CleanString string, CleanString *output, int *null)
+{
+ char *cs_string = cleanStringToCString(string);
+ char *cs_output = history_arg_extract(first, last, cs_string);
+ if(cs_output == NULL){
+ *null = 1;
+ cs_output = "";
+ } else {
+ *null = 0;
+ }
+
+ CleanStringVariable(cleanOutput, strlen(cs_output));
+ *output = (CleanString) cleanOutput;
+ memcpy(CleanStringCharacters(cleanOutput), cs_output, strlen(cs_output));
+ CleanStringLength(cleanOutput) = strlen(cs_output);
+
+ if(*null == 0){
+ free(cs_output);
+ }
+}
###Todo
- Check all functions if more maybe's are needed to handle NULL
+ - For example replace history
- Implement history expansion functions
- Use builtin Maybe if available, otherwise fall back on own Maybe
- Complete history api implementation
//History Expansion
historyExpand :: !String !*env -> (!String, !Int, !*env)
-getHistoryEvent :: !String !Int !Int !*env -> (!String, !*env)
+getHistoryEvent :: !String !Int !Int !*env -> (!Maybe String, !Int, !*env)
historyTokenize :: !String !*env -> ([String], !*env)
-historyArgExtract :: !Int !Int !String !*env -> (!String, !*env)
+historyArgExtract :: !Int !Int !String !*env -> (!Maybe String, !*env)
}
historyExpand :: !String !*env -> (!String, !Int, !*env)
-getHistoryEvent :: !String !Int !Int !*env -> (!String, !*env)
+historyExpand s e = code {
+ ccall cleanHistoryExpand "S:VSI:A"
+ }
+
+getHistoryEvent :: !String !Int !Int !*env -> (!Maybe String, !Int, !*env)
+getHistoryEvent s i1 i2 e
+# (string, cindex, null, e) = getHistoryEventItem s i1 i2 e
+= (if null Nothing (Just string), cindex, e)
+ where
+ getHistoryEventItem :: !String !Int !Int !*env -> (!String, !Int, !Bool, !*env)
+ getHistoryEventItem s i1 i2 e = code {
+ ccall cleanGetHistoryEvent "SII:VSII:A"
+ }
+
historyTokenize :: !String !*env -> ([String], !*env)
-historyArgExtract :: !Int !Int !String !*env -> (!String, !*env)
+historyTokenize s e
+# (i, e) = historyTokenizeInit s e
+= historyTokenizeItems i e
+//= ([], e)
+ where
+ historyTokenizeInit :: !String !*env -> (!Int, !*env)
+ historyTokenizeInit s e = code {
+ ccall cleanHistoryTokenizeInit "S:I:A"
+ }
+
+ historyTokenizeItems :: !Int !*env -> (![String], !*env)
+ historyTokenizeItems 0 e = ([], e)
+ historyTokenizeItems i e
+ # (token, e) = historyTokenizeItem (i-1) e
+ # (rest, e) = historyTokenizeItems (i-1) e
+ = ([token:rest], e)
+
+ historyTokenizeItem :: !Int !*env -> (!String, !*env)
+ historyTokenizeItem i e = code {
+ ccall cleanHistoryTokenizeItem "I:S:A"
+ }
+
+historyArgExtract :: !Int !Int !String !*env -> (!Maybe String, !*env)
+historyArgExtract i1 i2 s e
+# (string, null, e) = historyArgExtractItem i1 i2 s e
+= (if null Nothing (Just string), e)
+ where
+ historyArgExtractItem :: !Int !Int !String !*env -> (!String, !Bool, !*env)
+ historyArgExtractItem i1 i2 s e = code {
+ ccall cleanHistoryArgExtract "IIS:VSI:A"
+ }
entries=[{HistoryItem | line="custom", timestamp=""}],
offset=1, flags=0}
-Start :: *World -> (String, *World)
+Start :: *World -> (String, [String], *World)
Start w
#! w = setReadLineName "Test program" w
#! w = usingHistory w
#! (i, w) = historySetPos 1 w
#! (h, w) = previousHistory w
#! (h, w) = nextHistory w
+#! (s, i, w) = historyExpand "hoi" w
+#! (s, i, w) = getHistoryEvent "hoi" 1 0 w
+#! (s, w) = historyArgExtract 1 2 "hoi1 hoi2 hoi3" w
+#! (s, w) = historyArgExtract 98 99 "hoi1 hoi2 hoi3" w
+#! (ss, w) = historyTokenize "hoi1 hoi2 hoi3" w
#! (oh, w) = historyGetHistoryState w
#! w = historySetHistoryState testHistory w
#! (h, w) = historyGetHistoryState w
#! w = clearHistory w
-= (toString h, w)
+= (toString h, ss, w)