ref: a579ab3890031df70e0c05a9f301f6798991969e
parent: 74e88bbb0eb0e98021f64a16f04a316d9a9b5021
author: Ali Gholami Rudi <ali@rudi.ir>
date: Fri Nov 23 11:39:35 EST 2012
tr: defining macros with .de
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@
all: xroff
%.o: %.c xroff.h
$(CC) -c $(CFLAGS) $<
-xroff: xroff.o dev.o font.o in.o cp.o tr.o ren.o out.o reg.o
+xroff: xroff.o dev.o font.o in.o cp.o tr.o ren.o out.o reg.o sbuf.o
$(CC) -o $@ $^ $(LDFLAGS)
clean:
rm -f *.o xroff
--- /dev/null
+++ b/sbuf.c
@@ -1,0 +1,47 @@
+#include <stdlib.h>
+#include <string.h>
+#include "xroff.h"
+
+#define SBUF_SZ 1024
+
+void sbuf_init(struct sbuf *sbuf)
+{
+ sbuf->s = malloc(SBUF_SZ);
+ sbuf->sz = SBUF_SZ;
+ sbuf->n = 0;
+}
+
+static void sbuf_extend(struct sbuf *sbuf, int amount)
+{
+ char *s = sbuf->s;
+ sbuf->s = malloc(amount);
+ sbuf->sz = amount;
+ memcpy(sbuf->s, s, sbuf->n);
+}
+
+void sbuf_add(struct sbuf *sbuf, int c)
+{
+ if (sbuf->n + 2 >= sbuf->sz)
+ sbuf_extend(sbuf, sbuf->sz * 2);
+ sbuf->s[sbuf->n++] = c;
+}
+
+void sbuf_append(struct sbuf *sbuf, char *s)
+{
+ int len = strlen(s);
+ if (sbuf->n + len + 1 >= sbuf->sz)
+ sbuf_extend(sbuf, sbuf->n + len + 1);
+ memcpy(sbuf->s + sbuf->n, s, len);
+ sbuf->n += len;
+}
+
+char *sbuf_buf(struct sbuf *sbuf)
+{
+ sbuf->s[sbuf->n] = '\0';
+ return sbuf->s;
+}
+
+void sbuf_done(struct sbuf *sbuf)
+{
+ free(sbuf->s);
+}
--- a/tr.c
+++ b/tr.c
@@ -95,6 +95,34 @@
str_set(N_ID(args[1][0], args[1][1]), args[2]);
}
+static void tr_de(int argc, char **args)
+{
+ struct sbuf sbuf;
+ int c;
+ if (argc <= 1)
+ return;
+ sbuf_init(&sbuf);
+ while ((c = cp_next()) >= 0) {
+ sbuf_add(&sbuf, c);
+ if (c == '\n') {
+ c = cp_next();
+ if (c == '.') {
+ c = cp_next();
+ if (c == '.')
+ break;
+ sbuf_add(&sbuf, '.');
+ if (c >= 0)
+ sbuf_add(&sbuf, c);
+ } else {
+ if (c >= 0)
+ sbuf_add(&sbuf, c);
+ }
+ }
+ }
+ str_set(N_ID(args[1][0], args[1][1]), sbuf_buf(&sbuf));
+ sbuf_done(&sbuf);
+}
+
static void tr_in(int argc, char **args)
{
if (argc >= 2)
@@ -189,6 +217,7 @@
int (*args)(char **args, int maxargs, char *buf, int len);
} cmds[] = {
{"br", tr_br},
+ {"de", tr_de},
{"ds", tr_ds, tr_args_ds},
{"fp", tr_fp},
{"ft", tr_ft},
--- a/xroff.h
+++ b/xroff.h
@@ -97,3 +97,16 @@
void errmsg(char *msg, ...);
int utf8len(int c);
int charwid(int wid, int sz);
+
+/* variable length string buffer */
+struct sbuf {
+ char *s;
+ int sz;
+ int n;
+};
+
+void sbuf_init(struct sbuf *sbuf);
+void sbuf_done(struct sbuf *sbuf);
+char *sbuf_buf(struct sbuf *sbuf);
+void sbuf_add(struct sbuf *sbuf, int c);
+void sbuf_append(struct sbuf *sbuf, char *s);