#include <stdio.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <string.h>
#include "writer.h"
FILE *fh;
int level;
int attrs;
+ int lastnl;
};
+static void
+txt_fprintf(struct txt_writer_private *p, const char *fmt, ...)
+{
+ va_list ap;
+
+ // Don't add a newline if we already had one.
+ while (p->lastnl && fmt[0] == '\n') {
+ fmt += 1;
+ }
+ if (fmt[0] == '\0') return;
+
+ va_start(ap, fmt);
+ vfprintf(p->fh, fmt, ap);
+ va_end(ap);
+
+ p->lastnl = (strlen(fmt) > 0 && fmt[strlen(fmt) - 1] == '\n');
+}
+
static void
txt_start(struct writer *w, const char *tag, const char *descr)
{
char buf[128];
if (p->level == 0) {
- fprintf(p->fh, "%s\n", sep);
- } else {
- fprintf(p->fh, "\n");
+ txt_fprintf(p, "%s\n", sep);
+ } else if (!p->lastnl) {
+ txt_fprintf(p, "\n");
}
for (i = 1; i < p->level; i++) {
- fprintf(p->fh, " ");
+ txt_fprintf(p, " ");
}
snprintf(buf, sizeof(buf), "%s:", descr);
- fprintf(p->fh, "%-13s", buf);
+ txt_fprintf(p, "%-13s", buf);
- if (p->level == 0) fprintf(p->fh, "\n%s", sep);
+ if (p->level == 0) txt_fprintf(p, "\n%s", sep);
p->level++;
p->attrs = 0;
struct txt_writer_private *p = w->priv;
if (descr == NULL || strlen(descr) == 0) {
- fprintf(p->fh, "%s%s", (p->attrs > 0 ? ", " : " "),
+ txt_fprintf(p, "%s%s", (p->attrs > 0 ? ", " : " "),
value ? value : "(none)");
} else {
- fprintf(p->fh, "%s%s: %s", (p->attrs > 0 ? ", " : " "), descr,
+ txt_fprintf(p, "%s%s: %s", (p->attrs > 0 ? ", " : " "), descr,
value ? value : "(none)");
}
char *v = begin = data ? strdup(data) : NULL;
if (v == NULL) {
- fprintf(p->fh, " %s", data ? data : "(none)");
+ txt_fprintf(p, " %s", data ? data : "(none)");
return;
}
- fprintf(p->fh, " ");
+ txt_fprintf(p, " ");
while ((nl = strchr(v, '\n')) != NULL) {
*nl = '\0';
- fprintf(p->fh, "%s\n", v);
+ txt_fprintf(p, "%s\n", v);
v = nl + 1;
/* Indent */
int i;
for (i = 1; i < p->level - 1; i++) {
- fprintf(p->fh, " ");
+ txt_fprintf(p, " ");
}
- fprintf(p->fh, "%-14s", " ");
+ txt_fprintf(p, "%-14s", " ");
}
- fprintf(p->fh, "%s", v);
+ txt_fprintf(p, "%s", v);
free(begin);
}
p->level--;
if (p->level == 1) {
- fprintf(p->fh, "\n%s", sep);
+ txt_fprintf(p, "\n%s", sep);
fflush(p->fh);
}
}
{
struct txt_writer_private *p = w->priv;
- fprintf(p->fh, "\n");
+ txt_fprintf(p, "\n");
free(w->priv);
w->priv = NULL;
priv->fh = fh;
priv->level = 0;
priv->attrs = 0;
+ priv->lastnl = 1;
result = malloc(sizeof(struct writer));
if (!result) {