ref: eb1316e07a07693ae0f2fad1298be40b9e86052b
parent: 0ab9d55cd241a2d311b265c841031156278cb930
author: Ali Gholami Rudi <ali@rudi.ir>
date: Thu Apr 18 17:03:11 EDT 2013
out: add \X Also makes the output cleaner by adding newlines for some of the output commands.
--- a/dev.c
+++ b/dev.c
@@ -25,9 +25,9 @@
static void dev_prologue(void)
{
- OUT("x T utf\n");
- OUT("x res %d %d %d\n", dev_res, dev_hor, dev_ver);
- OUT("x init\n");
+ out("x T utf\n");
+ out("x res %d %d %d\n", dev_res, dev_hor, dev_ver);
+ out("x init\n");
}
int dev_mnt(int pos, char *id, char *name)
@@ -43,7 +43,7 @@
if (fn_name[pos] != name) /* ignore if fn_name[pos] is passed */
strcpy(fn_name[pos], id);
fn_font[pos] = fn;
- OUT("x font %d %s\n", pos, name);
+ out("x font %d %s\n", pos, name);
return pos;
}
@@ -104,8 +104,8 @@
static void dev_epilogue(void)
{
- OUT("x trailer\n");
- OUT("x stop\n");
+ out("x trailer\n");
+ out("x stop\n");
}
void dev_close(void)
--- a/out.c
+++ b/out.c
@@ -1,9 +1,39 @@
#include <ctype.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xroff.h"
+static int out_nl = 1;
+
+/* output troff code; newlines may appear only at the end of s */
+static void out_out(char *s, va_list ap)
+{
+ out_nl = strchr(s, '\n') != NULL;
+ vfprintf(stdout, s, ap);
+}
+
+/* output troff code; no preceding newline is necessary */
+static void outnn(char *s, ...)
+{
+ va_list ap;
+ va_start(ap, s);
+ out_out(s, ap);
+ va_end(ap);
+}
+
+/* output troff cmd; should appear after a newline */
+void out(char *s, ...)
+{
+ va_list ap;
+ if (!out_nl)
+ outnn("\n");
+ va_start(ap, s);
+ out_out(s, ap);
+ va_end(ap);
+}
+
int utf8len(int c)
{
if (c <= 0x7f)
@@ -38,7 +68,7 @@
{
if (o_s != n) {
o_s = n;
- OUT("s%d\n", o_s);
+ out("s%d\n", o_s);
}
}
@@ -46,7 +76,7 @@
{
if (n >= 0 && o_f != n) {
o_f = n;
- OUT("f%d\n", o_f);
+ out("f%d\n", o_f);
}
}
@@ -98,7 +128,7 @@
if (*cc)
*cc += sprintf(*cc, " %du", *d);
else
- OUT(" %d", *d);
+ outnn(" %d", *d);
return s;
}
@@ -111,13 +141,13 @@
if (cc)
*cc++ = c;
else
- OUT("D%c", c);
+ out("D%c", c);
switch (c) {
case 'l':
s = tok_num(&h1, s, &cc, 'm');
s = tok_num(&v1, s, &cc, 'v');
if (!cc) /* dpost requires this */
- OUT(" .");
+ outnn(" .");
hd = h1;
vd = v1;
break;
@@ -156,11 +186,11 @@
if (cc)
*cc = '\0';
else
- OUT("\n");
+ outnn("\n");
return hd;
}
-void output(char *s)
+void out_line(char *s)
{
struct glyph *g;
char c[GNLEN * 2];
@@ -172,7 +202,7 @@
if (c[0] == '(') {
s = utf8get(c, s);
s = utf8get(c + strlen(c), s);
- } else if (strchr("Dfhsv", c[0])) {
+ } else if (strchr("DfhsvX", c[0])) {
s = escarg(s, arg, c[0]);
if (c[0] == 'D') {
out_draw(arg, NULL);
@@ -183,7 +213,7 @@
continue;
}
if (c[0] == 'h') {
- OUT("h%d", eval(arg, 0, 'm'));
+ outnn("h%d", eval(arg, 0, 'm'));
continue;
}
if (c[0] == 's') {
@@ -191,19 +221,23 @@
continue;
}
if (c[0] == 'v') {
- OUT("v%d", eval(arg, 0, 'v'));
+ outnn("v%d", eval(arg, 0, 'v'));
continue;
}
+ if (c[0] == 'X') {
+ out("x X %s\n", arg);
+ continue;
+ }
}
}
g = dev_glyph(c, o_f);
if (g) {
if (utf8len(c[0]) == strlen(c)) {
- OUT("c%s%s", c, c[1] ? "\n" : "");
+ outnn("c%s%s", c, c[1] ? "\n" : "");
} else {
- OUT("C%s\n", c);
+ out("C%s\n", c);
}
}
- OUT("h%d", charwid(g ? g->wid : dev_spacewid(), o_s));
+ outnn("h%d", charwid(g ? g->wid : dev_spacewid(), o_s));
}
}
--- a/ren.c
+++ b/ren.c
@@ -123,8 +123,8 @@
n_h = 0;
n_pg = pg;
bp_next = n_pg + 1;
- OUT("p%d\n", pg);
- OUT("V%d\n", 0);
+ out("p%d\n", pg);
+ out("V%d\n", 0);
}
static void ren_first(void)
@@ -205,7 +205,8 @@
}
}
-static void out_line(char *out, int w, int ll, int li, int lt)
+/* flush the given line and send it to out.c */
+static void ren_line(char *s, int w, int ll, int li, int lt)
{
int ljust = 0;
char cmd[32];
@@ -220,23 +221,23 @@
sprintf(cmd, "\\h'%du'", ljust);
sbuf_append(&cdiv->sbuf, cmd);
}
- sbuf_append(&cdiv->sbuf, out);
+ sbuf_append(&cdiv->sbuf, s);
} else {
- OUT("H%d\n", n_o + li + lt + ljust);
- OUT("V%d\n", n_d);
- output(out);
+ out("H%d\n", n_o + li + lt + ljust);
+ out("V%d\n", n_d);
+ out_line(s);
}
}
static void ren_br(int force)
{
- char out[LNLEN];
+ char buf[LNLEN];
int ll, li, lt, els_neg, els_pos;
int adj_b, w, prev_d;
ren_first();
if (!adj_empty(cadj, n_u)) {
adj_b = n_u && !n_na && n_j == AD_B;
- w = adj_fill(cadj, !force && adj_b, !force && n_u, out,
+ w = adj_fill(cadj, !force && adj_b, !force && n_u, buf,
&ll, &li, <, &els_neg, &els_pos);
prev_d = n_d;
if (els_neg)
@@ -243,7 +244,7 @@
ren_sp(-els_neg);
if (!n_ns || w || els_neg || els_pos) {
ren_sp(0);
- out_line(out, w, ll, li, lt);
+ ren_line(buf, w, ll, li, lt);
n_ns = 0;
}
if (els_pos)
@@ -471,7 +472,7 @@
int l = nextchar(c);
l += nextchar(c + l);
c[l] = '\0';
- } else if (strchr("Dfhksvwx", c[0])) {
+ } else if (strchr("DfhksvwXx", c[0])) {
if (c[0] == 'w') {
render_wid();
return 0;
@@ -493,6 +494,8 @@
ren_ps(arg);
if (c[0] == 'v')
adj_put(adj, 0, "\\v'%du'", eval(arg, 0, 'v'));
+ if (c[0] == 'X')
+ adj_put(adj, 0, "\\X'%s'", arg);
if (c[0] == 'x')
adj_els(adj, eval(arg, 0, 'v'));
return 0;
--- a/xroff.c
+++ b/xroff.c
@@ -18,10 +18,10 @@
static void compile(void)
{
- OUT("s%d\n", n_s);
- OUT("f%d\n", n_f);
+ out("s%d\n", n_s);
+ out("f%d\n", n_f);
render();
- OUT("V%d\n", n_p);
+ out("V%d\n", n_p);
}
void errmsg(char *fmt, ...)
--- a/xroff.h
+++ b/xroff.h
@@ -75,9 +75,6 @@
int n; /* number of characters in charset */
};
-/* troff output function */
-#define OUT printf
-
/* output device functions */
int dev_open(char *path);
void dev_close(void);
@@ -111,8 +108,9 @@
/* rendering */
void render(void); /* read from in.c and print the output */
-void output(char *s); /* output the given rendered line */
+void out_line(char *s); /* output the given rendered line */
int out_draw(char *s, char *cc);
+void out(char *s, ...); /* output troff cmd */
/* troff commands */
void tr_bp(char **args);