diff cmd.c @ 28:e3db02d7f1f4

Add set command for setting or retrieving option values
author Guido Berhoerster <guido+pwm@berhoerster.name>
date Wed, 27 Sep 2017 19:44:05 +0200
parents 722a45b4028b
children 2552eec9b913
line wrap: on
line diff
--- a/cmd.c	Mon Sep 25 21:21:25 2017 +0200
+++ b/cmd.c	Wed Sep 27 19:44:05 2017 +0200
@@ -84,6 +84,13 @@
 	CHARCLASS_GRAPH
 };
 
+enum option_type {
+	OPTION_UNKNOWN = -1,
+	OPTION_FILENAME,
+	OPTION_PIPECOMMAND
+};
+
+static enum cmd_return	cmd_set(struct pwm_ctx *, int, char *[]);
 static enum cmd_return	cmd_define(struct pwm_ctx *, int, char *[]);
 static enum cmd_return	cmd_status(struct pwm_ctx *, int, char *[]);
 static enum cmd_return	cmd_info(struct pwm_ctx *, int, char *[]);
@@ -154,7 +161,15 @@
     CHARS_DIGIT CHARS_UPPER CHARS_LOWER CHARS_PUNCT
 };
 
+static const char *optionv[] = {
+    "filename",
+    "pipecommand",
+    NULL
+};
+
 static struct cmd cmds[] = {
+    { "S", "set", "set [option=value]", "Set an option or show option values",
+    cmd_set },
     { "D", "define", "define name=value", "Define a macro", cmd_define },
     { "t", "status", "status", "Redisplay an error message of the previous "
     "command and unsaved changes", cmd_status },
@@ -221,6 +236,45 @@
 }
 
 static enum cmd_return
+cmd_set(struct pwm_ctx *ctx, int argc, char *argv[])
+{
+	enum option_type type;
+	char		*value;
+
+	if (argc == 1) {
+		/* show options */
+		if ((io_printf("%s: %s\n", optionv[OPTION_FILENAME],
+		    ctx->filename) == IO_SIGNAL) ||
+		    (io_printf("%s: %s\n", optionv[OPTION_PIPECOMMAND],
+		    (ctx->pipecmd != NULL) ? ctx->pipecmd : "") == IO_SIGNAL)) {
+			return (CMD_SIGNAL);
+		}
+
+		return (CMD_OK);
+	} else if (argc != 2) {
+		return (CMD_USAGE);
+	}
+
+	type = parse_arg(argv[1], optionv, '=', &value);
+	switch (type) {
+	case OPTION_FILENAME:
+		free(ctx->filename);
+		ctx->filename = (value[0] != '\0') ? xstrdup(value) :
+		    xasprintf(&ctx->filename, "%s/pwm.psafe3", ctx->dirname);
+		break;
+	case OPTION_PIPECOMMAND:
+		free(ctx->pipecmd);
+		ctx->pipecmd = (value[0] != '\0') ? xstrdup(value) : NULL;
+		break;
+	default:
+		pwm_err(ctx, "bad option name \"%s\"", argv[1]);
+		return (CMD_ERR);
+	}
+
+	return (CMD_OK);
+}
+
+static enum cmd_return
 cmd_define(struct pwm_ctx *ctx, int argc, char *argv[])
 {
 	int		retval = CMD_ERR;
@@ -998,9 +1052,12 @@
 	struct record	*record = NULL;
 	enum field_type	type;
 	int		fields[COUNTOF(field_namev) - 1] = { 0 };
-	struct proc	proc = { 0 };
+	char		*cmd;
+	struct proc	proc = { 0 };	
 
-	if (argc != 4) {
+	/* if pipecommand is set, the last argument is optional */
+	if (((ctx->pipecmd == NULL) && (argc != 4)) ||
+	    ((ctx->pipecmd != NULL) && ((argc < 3) || (argc > 4)))) {
 		return (CMD_USAGE);
 	}
 
@@ -1016,10 +1073,12 @@
 	}
 	fields[type] = 1;
 
-	if (proc_open(&proc, argv[3], "w") != IO_OK) {
+	cmd = (argc == 4) ? argv[3] : ctx->pipecmd;
+	if (proc_open(&proc, cmd, "w") != IO_OK) {
 		goto out;
 	}
 
+
 	record = pwfile_get_record(ctx, id);
 	if (record == NULL) {
 		pwm_err(ctx, "record %u does not exist", id);