Browse Source

klish: Help implementation

Serj Kalichev 1 year ago
parent
commit
4be6e194bd
3 changed files with 68 additions and 62 deletions
  1. 38 61
      bin/klish/interactive.c
  2. 29 0
      klish/ktp/ktp_session.c
  3. 1 1
      klish/ktp/ktpd_session.c

+ 38 - 61
bin/klish/interactive.c

@@ -309,9 +309,10 @@ static void display_help(const tinyrl_t *tinyrl, faux_list_t *help_list,
 	iter = faux_list_head(help_list);
 	while ((node = faux_list_each_node(&iter))) {
 		help_t *help = (help_t *)faux_list_data(node);
-		tinyrl_printf(tinyrl, "%s%*s\n",
+		tinyrl_printf(tinyrl, "%s%*s%s\n",
 			help->prefix,
 			(max + 1 - strlen(help->prefix)),
+			" ",
 			help->line);
 	}
 }
@@ -320,82 +321,58 @@ static void display_help(const tinyrl_t *tinyrl, faux_list_t *help_list,
 bool_t help_ack_cb(ktp_session_t *ktp, const faux_msg_t *msg, void *udata)
 {
 	ctx_t *ctx = (ctx_t *)udata;
+	faux_list_t *help_list = NULL;
 	faux_list_node_t *iter = NULL;
 	uint32_t param_len = 0;
 	char *param_data = NULL;
 	uint16_t param_type = 0;
-	char *prefix = NULL;
-	faux_list_t *completions = NULL;
-	size_t completions_num = 0;
-	size_t max_compl_len = 0;
+	size_t max_prefix_len = 0;
 
 	tinyrl_set_busy(ctx->tinyrl, BOOL_FALSE);
 
-	prefix = faux_msg_get_str_param_by_type(msg, KTP_PARAM_PREFIX);
-
-	completions = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
-		NULL, NULL, (void (*)(void *))faux_str_free);
+	help_list = faux_list_new(FAUX_LIST_SORTED, FAUX_LIST_NONUNIQUE,
+		help_compare, help_kcompare, help_free);
 
+	// Wait for PREFIX - LINE pairs
 	iter = faux_msg_init_param_iter(msg);
-	while (faux_msg_get_param_each(&iter, &param_type, (void **)&param_data, &param_len)) {
-		char *compl = NULL;
-		if (KTP_PARAM_LINE != param_type)
+	while (faux_msg_get_param_each(&iter, &param_type, (void **)&param_data,
+		&param_len)) {
+		char *prefix_str = NULL;
+		char *line_str = NULL;
+		help_t *help = NULL;
+		size_t prefix_len = 0;
+
+		// Get PREFIX
+		if (KTP_PARAM_PREFIX != param_type)
 			continue;
-		compl = faux_str_dupn(param_data, param_len);
-		faux_list_add(completions, compl);
-		if (param_len > max_compl_len)
-			max_compl_len = param_len;
-	}
-
-	completions_num = faux_list_len(completions);
-
-	// Single possible completion
-	if (1 == completions_num) {
-		char *compl = (char *)faux_list_data(faux_list_head(completions));
-		tinyrl_line_insert(ctx->tinyrl, compl, strlen(compl));
-		tinyrl_redisplay(ctx->tinyrl);
-
-	// Multi possible completions
-	} else if (completions_num > 1) {
-		faux_list_node_t *eq_iter = NULL;
-		size_t eq_part = 0;
-		char *str = NULL;
-		char *compl = NULL;
-
-		// Try to find equal part for all possible completions
-		eq_iter = faux_list_head(completions);
-		str = (char *)faux_list_data(eq_iter);
-		eq_part = strlen(str);
-		eq_iter = faux_list_next_node(eq_iter);
-
-		while ((compl = (char *)faux_list_each(&eq_iter)) && (eq_part > 0)) {
-			size_t cur_eq = 0;
-			cur_eq = tinyrl_equal_part(ctx->tinyrl, str, compl);
-			if (cur_eq < eq_part)
-				eq_part = cur_eq;
+		prefix_str = faux_str_dupn(param_data, param_len);
+		prefix_len = param_len;
+
+		// Get LINE
+		if (!faux_msg_get_param_each(&iter, &param_type,
+			(void **)&param_data, &param_len) ||
+			(KTP_PARAM_LINE != param_type)) {
+			faux_str_free(prefix_str);
+			break;
 		}
+		line_str = faux_str_dupn(param_data, param_len);
 
-		// The equal part was found
-		if (eq_part > 0) {
-			tinyrl_line_insert(ctx->tinyrl, str, eq_part);
-			tinyrl_redisplay(ctx->tinyrl);
+		help = help_new(prefix_str, line_str);
+		faux_list_add(help_list, help);
+		if (prefix_len > max_prefix_len)
+			max_prefix_len = prefix_len;
+	}
 
-		// There is no equal part for all completions
-		} else {
-			tinyrl_multi_crlf(ctx->tinyrl);
-			tinyrl_reset_line_state(ctx->tinyrl);
-			display_completions(ctx->tinyrl, completions,
-				prefix, max_compl_len);
-			tinyrl_redisplay(ctx->tinyrl);
-		}
+	if (faux_list_len(help_list) > 0) {
+		tinyrl_multi_crlf(ctx->tinyrl);
+		tinyrl_reset_line_state(ctx->tinyrl);
+		display_help(ctx->tinyrl, help_list, max_prefix_len);
+		tinyrl_redisplay(ctx->tinyrl);
 	}
 
-	faux_list_free(completions);
-	faux_str_free(prefix);
+	faux_list_free(help_list);
 
-	// Happy compiler
-	ktp = ktp;
-	msg = msg;
+	ktp = ktp; // happy compiler
 
 	return BOOL_TRUE;
 }

+ 29 - 0
klish/ktp/ktp_session.c

@@ -389,6 +389,28 @@ static bool_t ktp_session_process_completion_ack(ktp_session_t *ktp, const faux_
 }
 
 
+static bool_t ktp_session_process_help_ack(ktp_session_t *ktp, const faux_msg_t *msg)
+{
+	assert(ktp);
+	assert(msg);
+
+	ktp->request_done = BOOL_TRUE;
+	ktp->state = KTP_SESSION_STATE_IDLE;
+	// Get exit flag from message
+	if (KTP_STATUS_IS_EXIT(faux_msg_get_status(msg)))
+		ktp->done = BOOL_TRUE;
+
+	// Execute external callback
+	if (ktp->cb[KTP_SESSION_CB_HELP_ACK].fn)
+		((ktp_session_event_cb_fn)
+			ktp->cb[KTP_SESSION_CB_HELP_ACK].fn)(
+			ktp, msg,
+			ktp->cb[KTP_SESSION_CB_HELP_ACK].udata);
+
+	return BOOL_TRUE;
+}
+
+
 /*
 static bool_t ktp_session_process_exit(ktp_session_t *ktp, const faux_msg_t *msg)
 {
@@ -435,6 +457,13 @@ static bool_t ktp_session_dispatch(ktp_session_t *ktp, faux_msg_t *msg)
 		}
 		rc = ktp_session_process_completion_ack(ktp, msg);
 		break;
+	case KTP_HELP_ACK:
+		if (ktp->state != KTP_SESSION_STATE_WAIT_FOR_HELP) {
+			syslog(LOG_WARNING, "Unexpected KTP_HELP_ACK was received\n");
+			break;
+		}
+		rc = ktp_session_process_help_ack(ktp, msg);
+		break;
 	case KTP_STDOUT:
 		if (ktp->state != KTP_SESSION_STATE_WAIT_FOR_CMD) {
 			syslog(LOG_WARNING, "Unexpected KTP_STDOUT was received\n");

+ 1 - 1
klish/ktp/ktpd_session.c

@@ -496,7 +496,7 @@ static bool_t ktpd_session_process_help(ktpd_session_t *ktpd, faux_msg_t *msg)
 		faux_list_t *help_list = NULL;
 		help_t *help_struct = NULL;
 
-		help_list = faux_list_new(FAUX_LIST_SORTED, FAUX_LIST_UNIQUE,
+		help_list = faux_list_new(FAUX_LIST_SORTED, FAUX_LIST_NONUNIQUE,
 			help_compare, help_kcompare, help_free);
 		while ((candidate = kpargv_completions_each(&citer))) {
 			const kentry_t *help = NULL;