Browse Source

kcontext_printf() for 'silent' syms

Serj Kalichev 4 months ago
parent
commit
5b0a0df04f

+ 4 - 0
klish/kcontext.h

@@ -105,6 +105,10 @@ FAUX_HIDDEN bool_t kcontext_set_pipeline_stage(kcontext_t *context, size_t pipel
 bool_t kcontext_is_last_pipeline_stage(const kcontext_t *context);
 FAUX_HIDDEN bool_t kcontext_set_is_last_pipeline_stage(kcontext_t *context, bool_t is_last_pipeline_stage);
 
+// Output
+int kcontext_printf(const kcontext_t *context, const char *fmt, ...);
+int kcontext_printf_err(const kcontext_t *context, const char *fmt, ...);
+
 // Wrappers
 kparg_t *kcontext_candidate_parg(const kcontext_t *context);
 const kentry_t *kcontext_candidate_entry(const kcontext_t *context);

+ 72 - 0
klish/ksession/kcontext.c

@@ -335,3 +335,75 @@ kplugin_t *kcontext_plugin(const kcontext_t *context)
 
 	return kaction_plugin(action);
 }
+
+
+static int kcontext_vprintf(const kcontext_t *context,
+	bool_t is_stderr, const char *fmt, va_list ap)
+{
+	const kaction_t *action = NULL;
+	const ksym_t *sym = NULL;
+	faux_buf_t *buf = NULL;
+	int rc = -1;
+	FILE *f = NULL;
+
+	if (!context)
+		return -1;
+	action = kcontext_action(context);
+	if (!action)
+		return -1;
+	sym = kaction_sym(action);
+	if (!sym)
+		return -1;
+
+	if (is_stderr) {
+		buf = kcontext_buferr(context);
+		f = stderr;
+	} else {
+		buf = kcontext_bufout(context);
+		f = stdout;
+	}
+
+	// "Silent" output
+	if (ksym_sync(sym) &&
+		ksym_silent(sym) &&
+		kcontext_is_last_pipeline_stage(context) &&
+		buf) {
+		char *line = NULL;
+		line = faux_str_vsprintf(fmt, ap);
+		rc = strlen(line);
+		if (rc > 0)
+			faux_buf_write(buf, line, rc);
+		faux_str_free(line);
+	} else {
+		rc = vfprintf(f, fmt, ap);
+		fflush(f);
+	}
+
+	return rc;
+}
+
+
+int kcontext_printf(const kcontext_t *context, const char *fmt, ...)
+{
+	int rc = -1;
+	va_list ap;
+
+	va_start(ap, fmt);
+	rc = kcontext_vprintf(context, BOOL_FALSE, fmt, ap);
+	va_end(ap);
+
+	return rc;
+}
+
+
+int kcontext_printf_err(const kcontext_t *context, const char *fmt, ...)
+{
+	int rc = -1;
+	va_list ap;
+
+	va_start(ap, fmt);
+	rc = kcontext_vprintf(context, BOOL_TRUE, fmt, ap);
+	va_end(ap);
+
+	return rc;
+}

+ 3 - 1
klish/ksession/kexec.c

@@ -471,11 +471,13 @@ static bool_t exec_action_sync(const kexec_t *exec, kcontext_t *context,
 	// Only last in pipeline stage can be silent because last stage
 	// has bufout
 	if (ksym_silent(sym) && kcontext_is_last_pipeline_stage(context)) {
+fprintf(stderr, "silent %s\n", ksym_name(sym));
 		exitcode = fn(context);
 		if (retcode)
 			*retcode = exitcode;
 		return BOOL_TRUE;
 	}
+fprintf(stderr, "sync %s\n", ksym_name(sym));
 
 	// Create pipes beetween sym function and grabber
 	if (pipe(pipe_stdout) < 0)
@@ -486,7 +488,6 @@ static bool_t exec_action_sync(const kexec_t *exec, kcontext_t *context,
 		return BOOL_FALSE;
 	}
 
-
 	// Prepare streams before fork
 	fflush(stdout);
 	fflush(stderr);
@@ -573,6 +574,7 @@ static bool_t exec_action_async(const kexec_t *exec, kcontext_t *context,
 	sigset_t sigs;
 
 	fn = ksym_function(kaction_sym(action));
+fprintf(stderr, "Async %s\n", ksym_name(kaction_sym(action)));
 
 	// Oh, it's amazing world of stdio!
 	// Flush buffers before fork() because buffer content will be inherited

+ 1 - 24
plugins/klish/misc.c

@@ -146,31 +146,8 @@ int klish_prompt(kcontext_t *context)
 	if (pos > start)
 		faux_str_catn(&prompt, start, pos - start);
 
-	printf("%s", prompt);
+	kcontext_printf(context, "%s", prompt);
 	faux_str_free(prompt);
-	fflush(stdout);
-
-	return 0;
-}
-
-
-int klish_silent_test(kcontext_t *context)
-{
-	const char *script = NULL;
-	char *str = NULL;
-	faux_buf_t *bufout = kcontext_bufout(context);
-
-	script = kcontext_script(context);
-	if (faux_str_is_empty(script))
-		script = "";
-
-	str = faux_str_sprintf("%s\n", script);
-
-	if (bufout)
-		faux_buf_write(kcontext_bufout(context), str, strlen(str));
-	else
-		printf("%s", str);
-	faux_str_free(str);
 
 	return 0;
 }

+ 4 - 4
plugins/klish/plugin_init.c

@@ -33,12 +33,12 @@ int kplugin_klish_init(kcontext_t *context)
 	kplugin_add_syms(plugin, ksym_new("printl", klish_printl));
 	kplugin_add_syms(plugin, ksym_new_ext("pwd", klish_pwd,
 		KSYM_PERMANENT, KSYM_SYNC, KSYM_NONSILENT));
-	kplugin_add_syms(plugin, ksym_new("prompt", klish_prompt));
-kplugin_add_syms(plugin, ksym_new_ext("silent-test", klish_silent_test,
-	KSYM_PERMANENT, KSYM_SYNC, KSYM_SILENT));
+	kplugin_add_syms(plugin, ksym_new_ext("prompt", klish_prompt,
+		KSYM_USERDEFINED_PERMANENT, KSYM_SYNC, KSYM_SILENT));
 
 	// Log
-	kplugin_add_syms(plugin, ksym_new("syslog", klish_syslog));
+	kplugin_add_syms(plugin, ksym_new_ext("syslog", klish_syslog,
+		KSYM_USERDEFINED_PERMANENT, KSYM_SYNC, KSYM_SILENT));
 
 	// Navigation
 	// Navigation must be permanent (no dry-run) and sync. Because unsync

+ 0 - 2
plugins/klish/private.h

@@ -19,8 +19,6 @@ int klish_printl(kcontext_t *context);
 int klish_pwd(kcontext_t *context);
 int klish_prompt(kcontext_t *context);
 
-int klish_silent_test(kcontext_t *context);
-
 // Log
 int klish_syslog(kcontext_t *context);