about summary refs log tree commit diff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--template.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/template.c b/template.c
index a47d9f5..e3adcd1 100644
--- a/template.c
+++ b/template.c
@@ -102,21 +102,29 @@ int escapeXML(FILE *file, const char *str) {
 	return 0;
 }
 
+static const char *
+variableValue(const struct Variable vars[], const char *name, size_t len) {
+	for (const struct Variable *var = vars; var && var->name; ++var) {
+		if (strlen(var->name) != len) continue;
+		if (strncmp(var->name, name, len)) continue;
+		return var->value;
+	}
+	return NULL;
+}
+
 int templateRender(
 	FILE *file, const char *template,
 	const struct Variable vars[], EscapeFn *escape
 ) {
 	if (!escape) escape = escapeNull;
-	for (bool subst = false; *template; subst ^= true) {
+	for (bool subst = false, write = true; *template; subst ^= true) {
 		size_t len = strcspn(template, "[]");
-		if (subst) {
-			const char *value = NULL;
-			for (const struct Variable *var = vars; var && var->name; ++var) {
-				if (strlen(var->name) != len) continue;
-				if (strncmp(var->name, template, len)) continue;
-				value = var->value;
-				break;
-			}
+		if (subst && template[0] == '+') {
+			write = variableValue(vars, &template[1], len - 1);
+		} else if (subst && template[0] == '-') {
+			write = true;
+		} else if (subst && write) {
+			const char *value = variableValue(vars, template, len);
 			if (!value) {
 				errx(
 					EX_SOFTWARE, "no value for template variable %.*s",
@@ -125,7 +133,7 @@ int templateRender(
 			}
 			int error = escape(file, value);
 			if (error) return error;
-		} else if (len) {
+		} else if (len && write) {
 			size_t n = fwrite(template, len, 1, file);
 			if (!n) return -1;
 		}