Browse Source

Compare session paths

Serj Kalichev 1 year ago
parent
commit
32f57a7670
5 changed files with 107 additions and 0 deletions
  1. 5 0
      klish/kpath.h
  2. 30 0
      klish/ksession/kexec.c
  3. 27 0
      klish/ksession/klevel.c
  4. 44 0
      klish/ksession/kpath.c
  5. 1 0
      klish/ktp.h

+ 5 - 0
klish/kpath.h

@@ -23,6 +23,8 @@ klevel_t *klevel_new(const kentry_t *entry);
 void klevel_free(klevel_t *level);
 
 const kentry_t *klevel_entry(const klevel_t *level);
+klevel_t *klevel_clone(const klevel_t *level);
+bool_t klevel_is_equal(const klevel_t *f, const klevel_t *s);
 
 // Path
 
@@ -38,6 +40,9 @@ kpath_levels_node_t *kpath_iterr(const kpath_t *path);
 klevel_t *kpath_eachr(kpath_levels_node_t **iterr);
 kpath_levels_node_t *kpath_iter(const kpath_t *path);
 klevel_t *kpath_each(kpath_levels_node_t **iter);
+kpath_t *kpath_clone(const kpath_t *path);
+bool_t kpath_is_equal(const kpath_t *f, const kpath_t *s);
+
 
 C_DECL_END
 

+ 30 - 0
klish/ksession/kexec.c

@@ -13,6 +13,7 @@
 #include <faux/eloop.h>
 #include <klish/khelper.h>
 #include <klish/kcontext.h>
+#include <klish/kpath.h>
 #include <klish/kexec.h>
 
 // Declaration of grabber. Implementation is in the grabber.c
@@ -27,6 +28,7 @@ struct kexec_s {
 	faux_buf_t *bufin;
 	faux_buf_t *bufout;
 	faux_buf_t *buferr;
+	kpath_t *saved_path;
 };
 
 // Dry-run
@@ -75,6 +77,7 @@ kexec_t *kexec_new()
 		return NULL;
 
 	exec->dry_run = BOOL_FALSE;
+	exec->saved_path = NULL;
 
 	// List of execute contexts
 	exec->contexts = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
@@ -112,6 +115,8 @@ void kexec_free(kexec_t *exec)
 	faux_buf_free(exec->bufout);
 	faux_buf_free(exec->buferr);
 
+	kpath_free(exec->saved_path);
+
 	free(exec);
 }
 
@@ -179,6 +184,24 @@ bool_t kexec_retcode(const kexec_t *exec, int *status)
 }
 
 
+bool_t kexec_path_is_changed(const kexec_t *exec)
+{
+	kpath_t *path = NULL;
+	kcontext_t *context = NULL;
+
+	assert(exec);
+	if (!exec)
+		return BOOL_FALSE;
+
+	context = (kcontext_t *)faux_list_data(faux_list_head(exec->contexts));
+	path = ksession_path(kcontext_session(context));
+	if (kpath_is_equal(exec->saved_path, path))
+		return BOOL_FALSE;
+
+	return BOOL_TRUE;
+}
+
+
 bool_t kexec_add(kexec_t *exec, kcontext_t *context)
 {
 	assert(exec);
@@ -246,6 +269,13 @@ static bool_t kexec_prepare(kexec_t *exec)
 		faux_list_node_t *next = faux_list_next_node(iter);
 		kcontext_t *context = (kcontext_t *)faux_list_data(iter);
 
+		// The first context is a context of main command. The other
+		// contexts are contexts of filters. So save current path from
+		// first context.
+		if (iter == faux_list_head(exec->contexts))
+			exec->saved_path = kpath_clone(
+				ksession_path(kcontext_session(context)));
+
 		// Set the same STDERR to all contexts
 		kcontext_set_stderr(context, global_stderr);
 

+ 27 - 0
klish/ksession/klevel.c

@@ -45,3 +45,30 @@ void klevel_free(klevel_t *level)
 
 	faux_free(level);
 }
+
+
+klevel_t *klevel_clone(const klevel_t *level)
+{
+	klevel_t *new_level = NULL;
+
+	assert(level);
+	if (!level)
+		return NULL;
+
+	new_level = klevel_new(klevel_entry(level));
+
+	return new_level;
+}
+
+
+bool_t klevel_is_equal(const klevel_t *f, const klevel_t *s)
+{
+	if (!f && !s)
+		return BOOL_TRUE;
+	if (!f || !s)
+		return BOOL_FALSE;
+	if (klevel_entry(f) == klevel_entry(s))
+		return BOOL_TRUE;
+
+	return BOOL_FALSE;
+}

+ 44 - 0
klish/ksession/kpath.c

@@ -131,3 +131,47 @@ klevel_t *kpath_each(kpath_levels_node_t **iter)
 {
 	return (klevel_t *)faux_list_each((faux_list_node_t **)iter);
 }
+
+
+kpath_t *kpath_clone(const kpath_t *path)
+{
+	kpath_t *new_path = NULL;
+	kpath_levels_node_t *iter = NULL;
+	klevel_t *level = NULL;
+
+	assert(path);
+	if (!path)
+		return NULL;
+
+	new_path = kpath_new();
+	iter = kpath_iter(path);
+	while ((level = kpath_each(&iter)))
+		kpath_push(new_path, klevel_clone(level));
+
+	return new_path;
+}
+
+
+bool_t kpath_is_equal(const kpath_t *f, const kpath_t *s)
+{
+	kpath_levels_node_t *iter_f = NULL;
+	kpath_levels_node_t *iter_s = NULL;
+	klevel_t *level_f = NULL;
+	klevel_t *level_s = NULL;
+
+	if (!f && !s)
+		return BOOL_TRUE;
+	if (!f || !s)
+		return BOOL_FALSE;
+
+	iter_f = kpath_iterr(f);
+	iter_s = kpath_iterr(s);
+	do {
+		level_f = kpath_eachr(&iter_f);
+		level_s = kpath_eachr(&iter_s);
+		if (!klevel_is_equal(level_f, level_s))
+			return BOOL_FALSE;
+	} while(level_f);
+
+	return BOOL_TRUE;
+}

+ 1 - 0
klish/ktp.h

@@ -35,6 +35,7 @@ typedef enum {
 	KTP_PARAM_LINE = 'L',
 	KTP_PARAM_PREFIX = 'P', // Same as line but differ by meaning
 	KTP_PARAM_PROMPT = '$', // Same as line but differ by meaning
+	KTP_PARAM_HOTKEY = 'H', // key '\0' cmd
 	KTP_PARAM_ERROR = 'E',
 	KTP_PARAM_RETCODE = 'R',
 } ktp_param_e;