summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile18
-rw-r--r--ml.c184
-rw-r--r--private.h7
-rw-r--r--roff.c4
-rw-r--r--xml.c294
5 files changed, 372 insertions, 135 deletions
diff --git a/Makefile b/Makefile
index d9d25126..c2656cf3 100644
--- a/Makefile
+++ b/Makefile
@@ -2,15 +2,15 @@ CFLAGS += -W -Wall -Wno-unused-parameter -g
LINTFLAGS += -c -e -f -u
-LNS = mdocml.ln html4_strict.ln xml.ln libmdocml.ln roff.ln
+LNS = mdocml.ln html4_strict.ln xml.ln libmdocml.ln roff.ln ml.ln
LLNS = llib-lmdocml.ln
LIBS = libmdocml.a
-OBJS = mdocml.o html4_strict.o xml.o libmdocml.o roff.o
+OBJS = mdocml.o html4_strict.o xml.o libmdocml.o roff.o ml.o
-SRCS = mdocml.c html4_strict.c xml.c libmdocml.c roff.c
+SRCS = mdocml.c html4_strict.c xml.c libmdocml.c roff.c ml.c
HEADS = libmdocml.h private.h
@@ -52,15 +52,15 @@ mdocml.tgz: $(INSTALL)
( cd .dist/ && tar zcf ../mdocml.tgz mdocml/ )
rm -rf .dist/
-llib-lmdocml.ln: mdocml.ln libmdocml.ln html4_strict.ln xml.ln roff.ln
- $(LINT) $(LINTFLAGS) -Cmdocml mdocml.ln libmdocml.ln html4_strict.ln xml.ln roff.ln
+llib-lmdocml.ln: mdocml.ln libmdocml.ln html4_strict.ln xml.ln roff.ln ml.ln
+ $(LINT) $(LINTFLAGS) -Cmdocml mdocml.ln libmdocml.ln html4_strict.ln xml.ln roff.ln ml.ln
mdocml.ln: mdocml.c libmdocml.h
mdocml.o: mdocml.c libmdocml.h
-libmdocml.a: libmdocml.o html4_strict.o xml.o roff.o
- $(AR) rs $@ libmdocml.o html4_strict.o xml.o roff.o
+libmdocml.a: libmdocml.o html4_strict.o xml.o roff.o ml.o
+ $(AR) rs $@ libmdocml.o html4_strict.o xml.o roff.o ml.o
xml.ln: xml.c private.h libmdocml.h
@@ -77,3 +77,7 @@ roff.o: roff.c private.h libmdocml.h
libmdocml.ln: libmdocml.c private.h libmdocml.h
libmdocml.o: libmdocml.c private.h libmdocml.h
+
+ml.ln: ml.c private.h libmdocml.h
+
+ml.o: ml.c private.h libmdocml.h
diff --git a/ml.c b/ml.c
new file mode 100644
index 00000000..96302d53
--- /dev/null
+++ b/ml.c
@@ -0,0 +1,184 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include "libmdocml.h"
+#include "private.h"
+
+
+#define MAXINDENT 8
+
+static ssize_t ml_puts(struct md_mbuf *, const char *);
+static ssize_t ml_putchar(struct md_mbuf *, char);
+static ssize_t ml_putstring(struct md_mbuf *, const char *);
+
+
+static ssize_t
+ml_puts(struct md_mbuf *p, const char *buf)
+{
+
+ return(ml_nputs(p, buf, strlen(buf)));
+}
+
+
+static ssize_t
+ml_putchar(struct md_mbuf *p, char buf)
+{
+
+ return(ml_nputs(p, &buf, 1));
+}
+
+
+static ssize_t
+ml_putstring(struct md_mbuf *p, const char *buf)
+{
+
+ return(ml_nputstring(p, buf, strlen(buf)));
+}
+
+
+ssize_t
+ml_begintag(struct md_mbuf *p, const char *name,
+ int *argc, char **argv)
+{
+ int i;
+ ssize_t res, sz;
+
+ res = 0;
+
+ if (-1 == (sz = ml_nputs(p, "<", 1)))
+ return(-1);
+ res += sz;
+
+ if (-1 == (sz = ml_puts(p, name)))
+ return(-1);
+ res += sz;
+
+ for (i = 0; ROFF_ARGMAX != argc[i]; i++) {
+ if (-1 == (sz = ml_nputs(p, " ", 1)))
+ return(-1);
+ res += sz;
+
+ if (-1 == (sz = ml_puts(p, tokargnames[argc[i]])))
+ return(-1);
+ res += sz;
+
+ if (-1 == (sz = ml_nputs(p, "=\"", 2)))
+ return(-1);
+ res += sz;
+
+ if (-1 == (sz = ml_putstring(p, argv[i] ?
+ argv[i] : "true")))
+ return(-1);
+ res += sz;
+
+ if (-1 == (sz = ml_nputs(p, "\"", 1)))
+ return(-1);
+ res += sz;
+ }
+
+ if (-1 == (sz = ml_nputs(p, ">", 1)))
+ return(-1);
+
+ return(res + sz);
+}
+
+
+ssize_t
+ml_endtag(struct md_mbuf *p, const char *tag)
+{
+ ssize_t res, sz;
+
+ res = 0;
+
+ if (-1 == (sz = ml_nputs(p, "</", 2)))
+ return(-1);
+ res += sz;
+
+ if (-1 == (sz = ml_puts(p, tag)))
+ return(-1);
+ res += sz;
+
+ if (-1 == (sz = ml_nputs(p, ">", 1)))
+ return(-1);
+
+ return(res + sz);
+}
+
+
+ssize_t
+ml_nputstring(struct md_mbuf *p, const char *buf, size_t bufsz)
+{
+ int i;
+ ssize_t res, sz;
+
+ res = 0;
+
+ for (i = 0; i < (int)bufsz; i++) {
+ switch (buf[i]) {
+ case ('&'):
+ if (-1 == (sz = ml_nputs(p, "&amp;", 5)))
+ return(-1);
+ break;
+ case ('"'):
+ if (-1 == (sz = ml_nputs(p, "&quot;", 6)))
+ return(-1);
+ break;
+ case ('<'):
+ if (-1 == (sz = ml_nputs(p, "&lt;", 4)))
+ return(-1);
+ break;
+ case ('>'):
+ if (-1 == (sz = ml_nputs(p, "&gt;", 4)))
+ return(-1);
+ break;
+ default:
+ if (-1 == (sz = ml_putchar(p, buf[i])))
+ return(-1);
+ break;
+ }
+ res += sz;
+ }
+ return(res);
+}
+
+
+ssize_t
+ml_nputs(struct md_mbuf *p, const char *buf, size_t sz)
+{
+
+ return(0 == md_buf_puts(p, buf, sz) ? -1 : (ssize_t)sz);
+}
+
+
+ssize_t
+ml_indent(struct md_mbuf *p, int indent)
+{
+ size_t i;
+ ssize_t res, sz;
+
+ res = sz 0;
+
+ /* LINTED */
+ for (i = 0; i < MIN(indent, MAXINDENT); i++, res += sz)
+ if (-1 == (sz = ml_nputs(p, " ", 4)))
+ return(-1);
+ return(res);
+}
diff --git a/private.h b/private.h
index 3c18184a..5bd5359d 100644
--- a/private.h
+++ b/private.h
@@ -252,6 +252,13 @@ struct rofftree *roff_alloc(const struct roffcb *, void *);
int roff_engine(struct rofftree *, char *);
int roff_free(struct rofftree *, int);
+ssize_t ml_begintag(struct md_mbuf *, const char *,
+ int *, char **);
+ssize_t ml_endtag(struct md_mbuf *, const char *);
+ssize_t ml_nputstring(struct md_mbuf *, const char *, size_t);
+ssize_t ml_nputs(struct md_mbuf *, const char *, size_t);
+ssize_t ml_indent(struct md_mbuf *, int);
+
__END_DECLS
#endif /*!PRIVATE_H*/
diff --git a/roff.c b/roff.c
index 34eabca1..dcb37567 100644
--- a/roff.c
+++ b/roff.c
@@ -134,7 +134,7 @@ static int roffcall(struct rofftree *, int, char **);
static int roffparse(struct rofftree *, char *);
static int textparse(const struct rofftree *, char *);
-#ifdef __linux__
+#ifdef __linux__ /* FIXME: remove */
static size_t strlcat(char *, const char *, size_t);
static size_t strlcpy(char *, const char *, size_t);
extern int vsnprintf(char *, size_t,
@@ -1446,7 +1446,7 @@ roff_err(const struct rofftree *tree, const char *pos, char *fmt, ...)
}
-#ifdef __linux
+#ifdef __linux /* FIXME: remove. */
/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
/*
diff --git a/xml.c b/xml.c
index 509d3071..8bac4389 100644
--- a/xml.c
+++ b/xml.c
@@ -28,7 +28,6 @@
#include "libmdocml.h"
#include "private.h"
-#define MAXINDENT 8
#define COLUMNS 72
enum md_ns {
@@ -73,20 +72,23 @@ static int roffspecial(void *, int, int *, char **, char **);
static void mbuf_mode(struct md_xml *, enum md_ns);
static int mbuf_newline(struct md_xml *);
-static int mbuf_indent(struct md_xml *);
+static int xml_indent(struct md_xml *);
static int mbuf_data(struct md_xml *, int, char *);
-static int mbuf_putstring(struct md_xml *,
- const char *);
-static int mbuf_nputstring(struct md_xml *,
+static int xml_nputstring(struct md_xml *,
const char *, size_t);
-static int mbuf_puts(struct md_xml *, const char *);
-static int mbuf_nputs(struct md_xml *,
+static int xml_puts(struct md_xml *, const char *);
+static int xml_nputs(struct md_xml *,
const char *, size_t);
-static int mbuf_begintag(struct md_xml *, const char *,
+static int xml_begintag(struct md_xml *, const char *,
enum md_ns, int *, char **);
-static int mbuf_endtag(struct md_xml *,
+static int xml_endtag(struct md_xml *,
const char *, enum md_ns);
+#ifdef __linux__ /* FIXME: remove */
+static size_t strlcat(char *, const char *, size_t);
+static size_t strlcpy(char *, const char *, size_t);
+#endif
+
static void
mbuf_mode(struct md_xml *p, enum md_ns ns)
@@ -97,147 +99,110 @@ mbuf_mode(struct md_xml *p, enum md_ns ns)
static int
-mbuf_begintag(struct md_xml *p, const char *name, enum md_ns ns,
+xml_begintag(struct md_xml *p, const char *name, enum md_ns ns,
int *argc, char **argv)
{
- int i;
-
- if ( ! mbuf_nputs(p, "<", 1))
- return(0);
+ char buf[64];
+ ssize_t sz;
+ size_t res;
switch (ns) {
- case (MD_NS_BLOCK):
- if ( ! mbuf_nputs(p, "block:", 6))
- return(0);
- break;
- case (MD_NS_INLINE):
- if ( ! mbuf_nputs(p, "inline:", 7))
- return(0);
- break;
- default:
- break;
+ case (MD_NS_BLOCK):
+ res = strlcpy(buf, "block:", sizeof(buf));
+ assert(res < sizeof(buf));
+ break;
+ case (MD_NS_INLINE):
+ res = strlcpy(buf, "inline:", sizeof(buf));
+ assert(res < sizeof(buf));
+ break;
+ default:
+ *buf = 0;
+ break;
}
- if ( ! mbuf_puts(p, name))
+ res = strlcat(buf, name, sizeof(buf));
+ assert(res < sizeof(buf));
+
+ if (-1 == (sz = ml_begintag(p->mbuf, buf, argc, argv)))
return(0);
- for (i = 0; ROFF_ARGMAX != argc[i]; i++) {
- if ( ! mbuf_nputs(p, " ", 1))
- return(0);
- if ( ! mbuf_puts(p, tokargnames[argc[i]]))
- return(0);
- if ( ! mbuf_nputs(p, "=\"", 2))
- return(0);
- if ( ! mbuf_putstring(p, argv[i] ? argv[i] : "true"))
- return(0);
- if ( ! mbuf_nputs(p, "\"", 1))
- return(0);
- }
- return(mbuf_nputs(p, ">", 1));
+ p->pos += sz;
+ return(1);
}
static int
-mbuf_endtag(struct md_xml *p, const char *tag, enum md_ns ns)
+xml_endtag(struct md_xml *p, const char *name, enum md_ns ns)
{
- if ( ! mbuf_nputs(p, "</", 2))
- return(0);
+ char buf[64];
+ ssize_t sz;
+ size_t res;
switch (ns) {
- case (MD_NS_BLOCK):
- if ( ! mbuf_nputs(p, "block:", 6))
- return(0);
- break;
- case (MD_NS_INLINE):
- if ( ! mbuf_nputs(p, "inline:", 7))
- return(0);
- break;
- default:
- break;
+ case (MD_NS_BLOCK):
+ res = strlcpy(buf, "block:", sizeof(buf));
+ assert(res < sizeof(buf));
+ break;
+ case (MD_NS_INLINE):
+ res = strlcpy(buf, "inline:", sizeof(buf));
+ assert(res < sizeof(buf));
+ break;
+ default:
+ *buf = 0;
+ break;
}
- if ( ! mbuf_puts(p, tag))
- return(0);
- return(mbuf_nputs(p, ">", 1));
-}
-
+ res = strlcat(buf, name, sizeof(buf));
+ assert(res < sizeof(buf));
-static int
-mbuf_putstring(struct md_xml *p, const char *buf)
-{
+ if (-1 == (sz = ml_endtag(p->mbuf, buf)))
+ return(0);
- return(mbuf_nputstring(p, buf, strlen(buf)));
+ p->pos += sz;
+ return(1);
}
static int
-mbuf_nputstring(struct md_xml *p, const char *buf, size_t sz)
+xml_nputstring(struct md_xml *p, const char *buf, size_t sz)
{
- int i;
+ ssize_t res;
- for (i = 0; i < (int)sz; i++) {
- switch (buf[i]) {
- case ('&'):
- if ( ! md_buf_puts(p->mbuf, "&amp;", 5))
- return(0);
- p->pos += 5;
- break;
- case ('"'):
- if ( ! md_buf_puts(p->mbuf, "&quot;", 6))
- return(0);
- p->pos += 6;
- break;
- case ('<'):
- if ( ! md_buf_puts(p->mbuf, "&lt;", 4))
- return(0);
- p->pos += 4;
- break;
- case ('>'):
- if ( ! md_buf_puts(p->mbuf, "&gt;", 4))
- return(0);
- p->pos += 4;
- break;
- default:
- if ( ! md_buf_putchar(p->mbuf, buf[i]))
- return(0);
- p->pos++;
- break;
- }
- }
+ if (-1 == (res = ml_nputstring(p->mbuf, buf, sz)))
+ return(0);
+ p->pos += res;
return(1);
}
static int
-mbuf_nputs(struct md_xml *p, const char *buf, size_t sz)
+xml_nputs(struct md_xml *p, const char *buf, size_t sz)
{
+ ssize_t res;
- p->pos += sz;
- return(md_buf_puts(p->mbuf, buf, sz));
+ if (-1 == (res = ml_nputs(p->mbuf, buf, sz)))
+ return(0);
+ p->pos += res;
+ return(1);
}
static int
-mbuf_puts(struct md_xml *p, const char *buf)
+xml_puts(struct md_xml *p, const char *buf)
{
- return(mbuf_nputs(p, buf, strlen(buf)));
+ return(xml_nputs(p, buf, strlen(buf)));
}
static int
-mbuf_indent(struct md_xml *p)
+xml_indent(struct md_xml *p)
{
- size_t i;
-
- assert(p->pos == 0);
-
- /* LINTED */
- for (i = 0; i < MIN(p->indent, MAXINDENT); i++)
- if ( ! md_buf_putstring(p->mbuf, " "))
- return(0);
+ ssize_t res;
- p->pos += i * 4;
+ if (-1 == (res = ml_indent(p->mbuf, p->indent)))
+ return(0);
+ p->pos += res;
return(1);
}
@@ -267,7 +232,7 @@ mbuf_data(struct md_xml *p, int space, char *buf)
space = 0;
if (MD_LITERAL & p->flags)
- return(mbuf_putstring(p, buf));
+ return(xml_nputstring(p, buf, sizeof(buf)));
while (*buf) {
while (*buf && isspace(*buf))
@@ -286,9 +251,9 @@ mbuf_data(struct md_xml *p, int space, char *buf)
sz = strlen(bufp);
if (0 == p->pos) {
- if ( ! mbuf_indent(p))
+ if ( ! xml_indent(p))
return(0);
- if ( ! mbuf_nputstring(p, bufp, sz))
+ if ( ! xml_nputstring(p, bufp, sz))
return(0);
if (p->indent * MAXINDENT + sz >= COLUMNS)
if ( ! mbuf_newline(p))
@@ -301,14 +266,14 @@ mbuf_data(struct md_xml *p, int space, char *buf)
if (space && sz + p->pos >= COLUMNS) {
if ( ! mbuf_newline(p))
return(0);
- if ( ! mbuf_indent(p))
+ if ( ! xml_indent(p))
return(0);
} else if (space) {
- if ( ! mbuf_nputs(p, " ", 1))
+ if ( ! xml_nputs(p, " ", 1))
return(0);
}
- if ( ! mbuf_nputstring(p, bufp, sz))
+ if ( ! xml_nputstring(p, bufp, sz))
return(0);
if ( ! (MD_OVERRIDE_ALL & p->flags))
@@ -387,10 +352,10 @@ roffhead(void *arg)
assert(arg);
p = (struct md_xml *)arg;
- if ( ! mbuf_puts(p, "<?xml version=\"1.0\" "
+ if (-1 == xml_puts(p, "<?xml version=\"1.0\" "
"encoding=\"UTF-8\"?>\n"))
return(0);
- if ( ! mbuf_puts(p, "<mdoc xmlns:block=\"block\" "
+ if (-1 == xml_puts(p, "<mdoc xmlns:block=\"block\" "
"xmlns:special=\"special\" "
"xmlns:inline=\"inline\">"))
return(0);
@@ -413,7 +378,7 @@ rofftail(void *arg)
return(0);
mbuf_mode(p, MD_BLKOUT);
- if ( ! mbuf_endtag(p, "mdoc", MD_NS_DEFAULT))
+ if ( ! xml_endtag(p, "mdoc", MD_NS_DEFAULT))
return(0);
return(mbuf_newline(p));
}
@@ -460,9 +425,9 @@ roffblkin(void *arg, int tok, int *argc, char **argv)
if (0 != p->pos) {
if ( ! mbuf_newline(p))
return(0);
- if ( ! mbuf_indent(p))
+ if ( ! xml_indent(p))
return(0);
- } else if ( ! mbuf_indent(p))
+ } else if ( ! xml_indent(p))
return(0);
/* FIXME: xml won't like standards args (e.g., p1003.1-90). */
@@ -470,7 +435,7 @@ roffblkin(void *arg, int tok, int *argc, char **argv)
p->indent++;
mbuf_mode(p, MD_BLKIN);
- if ( ! mbuf_begintag(p, toknames[tok], MD_NS_BLOCK,
+ if ( ! xml_begintag(p, toknames[tok], MD_NS_BLOCK,
argc, argv))
return(0);
return(mbuf_newline(p));
@@ -490,13 +455,13 @@ roffblkout(void *arg, int tok)
if (0 != p->pos) {
if ( ! mbuf_newline(p))
return(0);
- if ( ! mbuf_indent(p))
+ if ( ! xml_indent(p))
return(0);
- } else if ( ! mbuf_indent(p))
+ } else if ( ! xml_indent(p))
return(0);
mbuf_mode(p, MD_BLKOUT);
- if ( ! mbuf_endtag(p, toknames[tok], MD_NS_BLOCK))
+ if ( ! xml_endtag(p, toknames[tok], MD_NS_BLOCK))
return(0);
return(mbuf_newline(p));
}
@@ -519,14 +484,14 @@ roffin(void *arg, int tok, int *argc, char **argv)
if (0 != p->pos && (MD_TEXT == p->last || MD_OUT == p->last)
&& ! (MD_OVERRIDE_ONE & p->flags)
&& ! (MD_OVERRIDE_ALL & p->flags))
- if ( ! mbuf_nputs(p, " ", 1))
+ if ( ! xml_nputs(p, " ", 1))
return(0);
- if (0 == p->pos && ! mbuf_indent(p))
+ if (0 == p->pos && ! xml_indent(p))
return(0);
mbuf_mode(p, MD_IN);
- return(mbuf_begintag(p, toknames[tok],
+ return(xml_begintag(p, toknames[tok],
MD_NS_INLINE, argc, argv));
}
@@ -539,11 +504,11 @@ roffout(void *arg, int tok)
assert(arg);
p = (struct md_xml *)arg;
- if (0 == p->pos && ! mbuf_indent(p))
+ if (0 == p->pos && ! xml_indent(p))
return(0);
mbuf_mode(p, MD_OUT);
- return(mbuf_endtag(p, toknames[tok], MD_NS_INLINE));
+ return(xml_endtag(p, toknames[tok], MD_NS_INLINE));
}
@@ -595,3 +560,80 @@ roffdata(void *arg, int space, char *buf)
return(1);
}
+
+#ifdef __linux /* FIXME: remove. */
+/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the
+ * above copyright notice and this permission notice appear in all
+ * copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
+ * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+static size_t
+strlcat(char *dst, const char *src, size_t siz)
+{
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz;
+ size_t dlen;
+
+ /* Find the end of dst and adjust bytes left but don't go past
+ * end */
+ while (n-- != 0 && *d != '\0')
+ d++;
+ dlen = d - dst;
+ n = siz - dlen;
+
+ if (n == 0)
+ return(dlen + strlen(s));
+ while (*s != '\0') {
+ if (n != 1) {
+ *d++ = *s;
+ n--;
+ }
+ s++;
+ }
+ *d = '\0';
+
+ return(dlen + (s - src)); /* count does not include NUL */
+}
+
+
+static size_t
+strlcpy(char *dst, const char *src, size_t siz)
+{
+ char *d = dst;
+ const char *s = src;
+ size_t n = siz;
+
+ /* Copy as many bytes as will fit */
+ if (n != 0) {
+ while (--n != 0) {
+ if ((*d++ = *s++) == '\0')
+ break;
+ }
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src */
+ if (n == 0) {
+ if (siz != 0)
+ *d = '\0'; /* NUL-terminate dst */
+ while (*s++)
+ ;
+ }
+
+ return(s - src - 1); /* count does not include NUL */
+}
+#endif /*__linux__*/