* texi2mdoc: Completely re-write @value and @macro handling to work
@ 2015-02-25 14:37 kristaps
0 siblings, 0 replies; only message in thread
From: kristaps @ 2015-02-25 14:37 UTC (permalink / raw)
To: source
Log Message:
-----------
Completely re-write @value and @macro handling to work exactly as Texinfo
specifies and not how I really want it to work.
In a word, macros and values are pasted into the text: they're not self-
contained bodies that can be recursively executed.
In other words,
@macro hello{}
@ifset foo
@end macro
@hello
@end ifset
...is completely valid.
While here, stop paying attention to the manual's lies about macro newlines.
The terminal newline (i.e., before "@end macro") is part of the macro, which
is why so many macros are @r{}@c -- to swallow the newline.
This required a significant mechanical change to get the buffer pointer and
size out of all arguments, as the buffer can now be reallocated.
Modified Files:
--------------
texi2mdoc:
extern.h
main.c
texi2mdoc.1
util.c
version_0_1_2.xml
Revision Data
-------------
Index: texi2mdoc.1
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/texi2mdoc.1,v
retrieving revision 1.11
retrieving revision 1.12
diff -Ltexi2mdoc.1 -Ltexi2mdoc.1 -u -p -r1.11 -r1.12
--- texi2mdoc.1
+++ texi2mdoc.1
@@ -108,13 +108,7 @@ The comma in Texinfo macro arguments may
This is
.Em not
supported.
-.Sh BUGS
-Macros in
-.Nm
-are assumed to be self-contained (with matching block and respective
-.Li @end
-pairs).
-In Texinfo, they aren't: they're considered as if typed in place.
+.\" .Sh BUGS
.Sh SECURITY CONSIDERATIONS
As a security precaution,
.Nm
Index: main.c
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/main.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -Lmain.c -Lmain.c -u -p -r1.45 -r1.46
--- main.c
+++ main.c
@@ -38,43 +38,43 @@ static const char *const sects[SECTSZ] =
"No",
};
-static void doaccent(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doblock(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dobracket(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dobye(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dodefindex(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dodefn(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dodisplay(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doend(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doenumerate(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doexample(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doignargn(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doignblock(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doignbracket(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doignline(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doinline(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doinclude(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doitem(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doitemize(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dolink(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void domacro(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void domath(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void domultitable(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doquotation(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dotable(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dotop(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dosecoffs(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dosection(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dosp(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dosubsection(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dosubsubsection(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dosymbol(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dotab(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dotitle(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void dovalue(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doverb(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doverbatim(struct texi *, enum texicmd, const char *, size_t, size_t *);
-static void doverbinclude(struct texi *, enum texicmd, const char *, size_t, size_t *);
+static void doaccent(struct texi *, enum texicmd, size_t *);
+static void doblock(struct texi *, enum texicmd, size_t *);
+static void dobracket(struct texi *, enum texicmd, size_t *);
+static void dobye(struct texi *, enum texicmd, size_t *);
+static void dodefindex(struct texi *, enum texicmd, size_t *);
+static void dodefn(struct texi *, enum texicmd, size_t *);
+static void dodisplay(struct texi *, enum texicmd, size_t *);
+static void doend(struct texi *, enum texicmd, size_t *);
+static void doenumerate(struct texi *, enum texicmd, size_t *);
+static void doexample(struct texi *, enum texicmd, size_t *);
+static void doignargn(struct texi *, enum texicmd, size_t *);
+static void doignblock(struct texi *, enum texicmd, size_t *);
+static void doignbracket(struct texi *, enum texicmd, size_t *);
+static void doignline(struct texi *, enum texicmd, size_t *);
+static void doinline(struct texi *, enum texicmd, size_t *);
+static void doinclude(struct texi *, enum texicmd, size_t *);
+static void doitem(struct texi *, enum texicmd, size_t *);
+static void doitemize(struct texi *, enum texicmd, size_t *);
+static void dolink(struct texi *, enum texicmd, size_t *);
+static void domacro(struct texi *, enum texicmd, size_t *);
+static void domath(struct texi *, enum texicmd, size_t *);
+static void domultitable(struct texi *, enum texicmd, size_t *);
+static void doquotation(struct texi *, enum texicmd, size_t *);
+static void dotable(struct texi *, enum texicmd, size_t *);
+static void dotop(struct texi *, enum texicmd, size_t *);
+static void dosecoffs(struct texi *, enum texicmd, size_t *);
+static void dosection(struct texi *, enum texicmd, size_t *);
+static void dosp(struct texi *, enum texicmd, size_t *);
+static void dosubsection(struct texi *, enum texicmd, size_t *);
+static void dosubsubsection(struct texi *, enum texicmd, size_t *);
+static void dosymbol(struct texi *, enum texicmd, size_t *);
+static void dotab(struct texi *, enum texicmd, size_t *);
+static void dotitle(struct texi *, enum texicmd, size_t *);
+static void dovalue(struct texi *, enum texicmd, size_t *);
+static void doverb(struct texi *, enum texicmd, size_t *);
+static void doverbatim(struct texi *, enum texicmd, size_t *);
+static void doverbinclude(struct texi *, enum texicmd, size_t *);
static const struct texitok __texitoks[TEXICMD__MAX] = {
/* TEXICMD__BEGIN */
@@ -342,26 +342,25 @@ static const struct texitok __texitoks[T
const struct texitok *const texitoks = __texitoks;
static void
-dodefindex(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dodefindex(struct texi *p, enum texicmd cmd, size_t *pos)
{
size_t start, end;
char *cp;
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
start = end = *pos;
- while (end < sz && ! ismspace(buf[end]))
+ while (end < BUFSZ(p) && ! ismspace(BUF(p)[end]))
end++;
if (start == end) {
- advanceeoln(p, buf, sz, pos, 1);
+ advanceeoln(p, pos, 1);
return;
} else if (NULL == (cp = malloc(end - start + 1)))
texiabort(p, NULL);
- memcpy(cp, &buf[start], end - start);
+ memcpy(cp, &BUF(p)[start], end - start);
cp[end - start] = '\0';
p->indexs = realloc(p->indexs,
@@ -373,8 +372,7 @@ dodefindex(struct texi *p, enum texicmd
}
static void
-dodefn(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dodefn(struct texi *p, enum texicmd cmd, size_t *pos)
{
const char *blk;
@@ -399,8 +397,8 @@ dodefn(struct texi *p, enum texicmd cmd,
if (p->ign) {
NULL != blk ?
- parseto(p, buf, sz, pos, blk) :
- parseeoln(p, buf, sz, pos);
+ parseto(p, pos, blk) :
+ parseeoln(p, pos);
return;
}
@@ -429,7 +427,7 @@ dodefn(struct texi *p, enum texicmd cmd,
texiputchars(p, "Function");
break;
default:
- parselinearg(p, buf, sz, pos);
+ parselinearg(p, pos);
break;
}
@@ -439,7 +437,7 @@ dodefn(struct texi *p, enum texicmd cmd,
case (TEXICMD_DEFMAC):
case (TEXICMD_DEFMACX):
teximacroopen(p, "Dv");
- while (parselinearg(p, buf, sz, pos))
+ while (parselinearg(p, pos))
/* Spin. */ ;
teximacroclose(p);
break;
@@ -448,10 +446,10 @@ dodefn(struct texi *p, enum texicmd cmd,
case (TEXICMD_DEFUN):
case (TEXICMD_DEFUNX):
teximacroopen(p, "Fo");
- parselinearg(p, buf, sz, pos);
+ parselinearg(p, pos);
teximacroclose(p);
teximacroopen(p, "Fa");
- while (parselinearg(p, buf, sz, pos))
+ while (parselinearg(p, pos))
/* Spin. */ ;
teximacroclose(p);
teximacro(p, "Fc");
@@ -463,13 +461,13 @@ dodefn(struct texi *p, enum texicmd cmd,
case (TEXICMD_DEFTYPEMETHOD):
case (TEXICMD_DEFTYPEMETHODX):
teximacroopen(p, "Ft");
- parselinearg(p, buf, sz, pos);
+ parselinearg(p, pos);
teximacroclose(p);
teximacroopen(p, "Fo");
- parselinearg(p, buf, sz, pos);
+ parselinearg(p, pos);
teximacroclose(p);
teximacroopen(p, "Fa");
- while (parselinearg(p, buf, sz, pos))
+ while (parselinearg(p, pos))
/* Spin. */ ;
teximacroclose(p);
teximacro(p, "Fc");
@@ -481,7 +479,7 @@ dodefn(struct texi *p, enum texicmd cmd,
case (TEXICMD_DEFTYPEVR):
case (TEXICMD_DEFTYPEVRX):
teximacroopen(p, "Vt");
- while (parselinearg(p, buf, sz, pos))
+ while (parselinearg(p, pos))
/* Spin. */ ;
teximacroclose(p);
break;
@@ -490,7 +488,7 @@ dodefn(struct texi *p, enum texicmd cmd,
case (TEXICMD_DEFVR):
case (TEXICMD_DEFVRX):
teximacroopen(p, "Va");
- while (parselinearg(p, buf, sz, pos))
+ while (parselinearg(p, pos))
/* Spin. */ ;
teximacroclose(p);
break;
@@ -500,12 +498,11 @@ dodefn(struct texi *p, enum texicmd cmd,
texivspace(p);
if (NULL != blk)
- parseto(p, buf, sz, pos, blk);
+ parseto(p, pos, blk);
}
static void
-domacro(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+domacro(struct texi *p, enum texicmd cmd, size_t *pos)
{
size_t start, end, endtoksz, len;
struct teximacro m;
@@ -513,42 +510,58 @@ domacro(struct texi *p, enum texicmd cmd
memset(&m, 0, sizeof(struct teximacro));
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
- for (start = end = *pos; end < sz; end++)
- if (ismspace(buf[end]) || '{' == buf[end])
+ for (start = end = *pos; end < BUFSZ(p); end++)
+ if (ismspace(BUF(p)[end]) || '{' == BUF(p)[end])
break;
if (start == end)
texierr(p, "zero-length macro name");
- advanceto(p, buf, pos, end);
+ advanceto(p, pos, end);
m.key = malloc(end - start + 1);
if (NULL == m.key)
texiabort(p, NULL);
- memcpy(m.key, &buf[start], end - start);
+ memcpy(m.key, &BUF(p)[start], end - start);
m.key[end - start] = '\0';
- m.args = argparse(p, buf, sz, pos, &m.argsz, 0);
- advanceeoln(p, buf, sz, pos, 0);
+ m.args = argparse(p, pos, &m.argsz, 0);
+ /* Note: we advance to the beginning of the macro. */
+ advanceeoln(p, pos, 1);
+
+ /*
+ * According to the Texinfo manual, the macro ends on the
+ * newline subsequent the @end macro.
+ * That's COMPLETELY FUCKING WRONG.
+ * It ends inclusive the newline, which is why so many macros
+ * say things like @r{hello}@c, where the subsequent @c swallows
+ * the newline.
+ * However, it does swallow the leading newline, so look for the
+ * @end macro without the leading newline else we might look
+ * past empty macros.
+ */
start = *pos;
- endtok = "\n@end macro\n";
+ endtok = "@end macro\n";
endtoksz = strlen(endtok);
- blk = memmem(&buf[start], sz - start, endtok, endtoksz);
+ blk = memmem(&BUF(p)[start], BUFSZ(p) - start, endtok, endtoksz);
if (NULL == blk)
texierr(p, "unterminated macro body");
- while (&buf[*pos] != blk)
- advance(p, buf, pos);
- assert('\n' == buf[*pos]);
- advance(p, buf, pos);
- len = blk - &buf[start];
+ /* Roll us back one character. */
+ while (&BUF(p)[*pos] != blk)
+ advance(p, pos);
+ assert('@' == BUF(p)[*pos]);
+ if ('\n' != BUF(p)[*pos - 1])
+ texierr(p, "cannot handle @end macro in-line");
+
+ len = blk - &BUF(p)[start];
m.value = malloc(len + 1);
if (NULL == m.value)
texiabort(p, NULL);
- memcpy(m.value, &buf[start], len);
+ memcpy(m.value, &BUF(p)[start], len);
m.value[len] = '\0';
p->macros = realloc
@@ -559,12 +572,11 @@ domacro(struct texi *p, enum texicmd cmd
texiabort(p, NULL);
p->macros[p->macrosz++] = m;
- advanceeoln(p, buf, sz, pos, 1);
+ advanceeoln(p, pos, 1);
}
static void
-doignblock(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doignblock(struct texi *p, enum texicmd cmd, size_t *pos)
{
char end[32], start[32];
const char *endt, *startt;
@@ -599,44 +611,42 @@ doignblock(struct texi *p, enum texicmd
* then there'll be an "end" token of the same kind between us.
* Thus, we keep track of scopes for matching "end" blocks.
*/
- while (stack > 0 && *pos < sz) {
+ while (stack > 0 && *pos < BUFSZ(p)) {
if (stack > 10)
abort();
- endt = memmem(&buf[*pos], sz - *pos, end, esz);
- startt = memmem(&buf[*pos], sz - *pos, start, ssz);
+ endt = memmem(&BUF(p)[*pos], BUFSZ(p) - *pos, end, esz);
+ startt = memmem(&BUF(p)[*pos], BUFSZ(p) - *pos, start, ssz);
if (NULL == endt) {
texiwarn(p, "unterminated \"%s\" "
"block", texitoks[cmd].tok);
- *pos = sz;
+ *pos = BUFSZ(p);
break;
}
newpos = *pos;
if (NULL == startt || startt > endt) {
- newpos += esz + (size_t)(endt - &buf[*pos]);
+ newpos += esz + (size_t)(endt - &BUF(p)[*pos]);
stack--;
} else {
- newpos += ssz + (size_t)(startt - &buf[*pos]);
+ newpos += ssz + (size_t)(startt - &BUF(p)[*pos]);
stack++;
}
- assert(newpos <= sz);
+ assert(newpos <= BUFSZ(p));
while (*pos < newpos)
- advance(p, buf, pos);
+ advance(p, pos);
}
}
static void
-doblock(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doblock(struct texi *p, enum texicmd cmd, size_t *pos)
{
- parseto(p, buf, sz, pos, texitoks[cmd].tok);
+ parseto(p, pos, texitoks[cmd].tok);
}
static void
-doinline(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doinline(struct texi *p, enum texicmd cmd, size_t *pos)
{
const char *macro = NULL;
@@ -678,59 +688,57 @@ doinline(struct texi *p, enum texicmd cm
}
if (NULL == macro || p->literal || TEXILIST_TABLE == p->list) {
- parsebracket(p, buf, sz, pos);
+ parsebracket(p, pos);
return;
}
teximacroopen(p, macro);
p->seenws = 0;
- parsebracket(p, buf, sz, pos);
- texipunctuate(p, buf, sz, pos);
+ parsebracket(p, pos);
+ texipunctuate(p, pos);
teximacroclose(p);
}
static void
-doverb(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doverb(struct texi *p, enum texicmd cmd, size_t *pos)
{
char delim;
size_t start;
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
- if (*pos == sz || '{' != buf[*pos])
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
+ if (*pos == BUFSZ(p) || '{' != BUF(p)[*pos])
return;
- advance(p, buf, pos);
- if (*pos == sz)
+ advance(p, pos);
+ if (*pos == BUFSZ(p))
return;
- delim = buf[*pos];
- advance(p, buf, pos);
+ delim = BUF(p)[*pos];
+ advance(p, pos);
/* Make sure we flush out our initial whitespace... */
if (p->seenws && p->outcol && 0 == p->literal)
texiputchar(p, ' ');
p->seenws = 0;
start = *pos;
/* Read until we see the delimiter then end-brace. */
- while (*pos < sz - 1) {
- if (buf[*pos] == delim && buf[*pos + 1] == '}')
+ while (*pos < BUFSZ(p) - 1) {
+ if (BUF(p)[*pos] == delim && BUF(p)[*pos + 1] == '}')
break;
- advance(p, buf, pos);
+ advance(p, pos);
}
- if (*pos == sz - 1)
+ if (*pos == BUFSZ(p) - 1)
return;
- texiputbuf(p, buf, start, *pos);
+ texiputbuf(p, start, *pos);
/* Make sure we read after the end-brace. */
- assert(delim == buf[*pos]);
- advance(p, buf, pos);
- assert('}' == buf[*pos]);
- advance(p, buf, pos);
+ assert(delim == BUF(p)[*pos]);
+ advance(p, pos);
+ assert('}' == BUF(p)[*pos]);
+ advance(p, pos);
}
static void
-doverbatim(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doverbatim(struct texi *p, enum texicmd cmd, size_t *pos)
{
const char *end, *term;
size_t endsz, endpos;
@@ -738,35 +746,34 @@ doverbatim(struct texi *p, enum texicmd
/* We read from the @verbatim\n newline inclusive! */
end = "\n@end verbatim\n";
endsz = strlen(end);
- advanceeoln(p, buf, sz, pos, 0);
- if (*pos == sz) {
+ advanceeoln(p, pos, 0);
+ if (*pos == BUFSZ(p)) {
texiwarn(p, "unexpected end of file");
return;
}
- term = memmem(&buf[*pos], sz - *pos, end, endsz);
+ term = memmem(&BUF(p)[*pos], BUFSZ(p) - *pos, end, endsz);
if (NULL == term) {
texiwarn(p, "unterminated verbatim block");
- endpos = sz;
+ endpos = BUFSZ(p);
} else
- endpos = *pos + (size_t)(term - &buf[*pos]);
+ endpos = *pos + (size_t)(term - &BUF(p)[*pos]);
- assert(endpos <= sz);
- assert('\n' == buf[*pos]);
- advance(p, buf, pos);
+ assert(endpos <= BUFSZ(p));
+ assert('\n' == BUF(p)[*pos]);
+ advance(p, pos);
teximacro(p, "Bd -literal -offset indent");
while (*pos < endpos) {
- texiputchar(p, buf[*pos]);
- advance(p, buf, pos);
+ texiputchar(p, BUF(p)[*pos]);
+ advance(p, pos);
}
teximacro(p, "Ed");
- if (*pos < sz)
- advanceto(p, buf, pos, endpos + endsz);
+ if (*pos < BUFSZ(p))
+ advanceto(p, pos, endpos + endsz);
}
static void
-doverbinclude(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doverbinclude(struct texi *p, enum texicmd cmd, size_t *pos)
{
char fname[PATH_MAX], path[PATH_MAX];
int rc;
@@ -774,22 +781,22 @@ doverbinclude(struct texi *p, enum texic
const char *v;
enum texicmd type;
- while (*pos < sz && ' ' == buf[*pos])
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && ' ' == BUF(p)[*pos])
+ advance(p, pos);
- for (i = 0; *pos < sz && '\n' != buf[*pos]; ) {
+ for (i = 0; *pos < BUFSZ(p) && '\n' != BUF(p)[*pos]; ) {
if (i == sizeof(fname) - 1)
break;
- if ('@' != buf[*pos]) {
- fname[i++] = buf[*pos];
- advance(p, buf, pos);
+ if ('@' != BUF(p)[*pos]) {
+ fname[i++] = BUF(p)[*pos];
+ advance(p, pos);
continue;
}
- type = texicmd(p, buf, *pos, sz, &end, NULL);
- advanceto(p, buf, pos, end);
+ type = texicmd(p, *pos, &end, NULL);
+ advanceto(p, pos, end);
if (TEXICMD_VALUE != type)
texierr(p, "unknown verbatiminclude command");
- v = valueblookup(p, buf, sz, pos);
+ v = valueblookup(p, pos);
if (NULL == v)
continue;
while ('\0' != *v) {
@@ -803,7 +810,7 @@ doverbinclude(struct texi *p, enum texic
if (i == 0)
texierr(p, "path too short");
- else if ('\n' != buf[*pos])
+ else if ('\n' != BUF(p)[*pos])
texierr(p, "path too long");
else if ('/' == fname[0])
texierr(p, "no absolute paths");
@@ -823,8 +830,7 @@ doverbinclude(struct texi *p, enum texic
}
static void
-doinclude(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doinclude(struct texi *p, enum texicmd cmd, size_t *pos)
{
char fname[PATH_MAX], path[PATH_MAX];
size_t i, end;
@@ -832,23 +838,23 @@ doinclude(struct texi *p, enum texicmd c
const char *v;
enum texicmd type;
- while (*pos < sz && ' ' == buf[*pos])
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && ' ' == BUF(p)[*pos])
+ advance(p, pos);
/* Read in the filename. */
- for (i = 0; *pos < sz && '\n' != buf[*pos]; ) {
+ for (i = 0; *pos < BUFSZ(p) && '\n' != BUF(p)[*pos]; ) {
if (i == sizeof(fname) - 1)
break;
- if ('@' != buf[*pos]) {
- fname[i++] = buf[*pos];
- advance(p, buf, pos);
+ if ('@' != BUF(p)[*pos]) {
+ fname[i++] = BUF(p)[*pos];
+ advance(p, pos);
continue;
}
- type = texicmd(p, buf, *pos, sz, &end, NULL);
- advanceto(p, buf, pos, end);
+ type = texicmd(p, *pos, &end, NULL);
+ advanceto(p, pos, end);
if (TEXICMD_VALUE != type)
texierr(p, "unknown include command");
- v = valueblookup(p, buf, sz, pos);
+ v = valueblookup(p, pos);
if (NULL == v)
continue;
while ('\0' != *v) {
@@ -862,7 +868,7 @@ doinclude(struct texi *p, enum texicmd c
if (i == 0)
texierr(p, "path too short");
- else if ('\n' != buf[*pos])
+ else if ('\n' != BUF(p)[*pos])
texierr(p, "path too long");
else if ('/' == fname[0])
texierr(p, "no absolute paths");
@@ -889,16 +895,14 @@ doinclude(struct texi *p, enum texicmd c
}
static void
-dobracket(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dobracket(struct texi *p, enum texicmd cmd, size_t *pos)
{
- parsebracket(p, buf, sz, pos);
+ parsebracket(p, pos);
}
static void
-dodisplay(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dodisplay(struct texi *p, enum texicmd cmd, size_t *pos)
{
switch (cmd) {
@@ -913,28 +917,26 @@ dodisplay(struct texi *p, enum texicmd c
p->seenvs = 1;
/* FIXME: ignore and parseeoln. */
- advanceeoln(p, buf, sz, pos, 1);
- parseto(p, buf, sz, pos, texitoks[cmd].tok);
+ advanceeoln(p, pos, 1);
+ parseto(p, pos, texitoks[cmd].tok);
teximacro(p, "Ed");
}
static void
-doexample(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doexample(struct texi *p, enum texicmd cmd, size_t *pos)
{
teximacro(p, "Bd -literal -offset indent");
/* FIXME: ignore and parseeoln. */
- advanceeoln(p, buf, sz, pos, 1);
+ advanceeoln(p, pos, 1);
p->literal++;
- parseto(p, buf, sz, pos, texitoks[cmd].tok);
+ parseto(p, pos, texitoks[cmd].tok);
p->literal--;
teximacro(p, "Ed");
}
static void
-dobye(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dobye(struct texi *p, enum texicmd cmd, size_t *pos)
{
texiexit(p);
@@ -942,32 +944,30 @@ dobye(struct texi *p, enum texicmd cmd,
}
static void
-dotitle(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dotitle(struct texi *p, enum texicmd cmd, size_t *pos)
{
size_t start, end;
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
start = end = *pos;
- while (end < sz && '\n' != buf[end])
+ while (end < BUFSZ(p) && '\n' != BUF(p)[end])
end++;
- advanceeoln(p, buf, sz, pos, 1);
+ advanceeoln(p, pos, 1);
free(p->subtitle);
p->subtitle = malloc(end - start + 1);
if (NULL == p->subtitle)
texiabort(p, NULL);
- memcpy(p->subtitle, &buf[start], end - start);
+ memcpy(p->subtitle, &BUF(p)[start], end - start);
p->subtitle[end - start] = '\0';
}
static void
-doaccent(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doaccent(struct texi *p, enum texicmd cmd, size_t *pos)
{
int brace = 0;
- if (*pos == sz) {
+ if (*pos == BUFSZ(p)) {
texiwarn(p, "truncated: @%s", texitoks[cmd].tok);
return;
}
@@ -985,21 +985,21 @@ doaccent(struct texi *p, enum texicmd cm
* the critical one.
* Otherwise, space can sit between us and our argument.
*/
- if ('{' == buf[*pos]) {
+ if ('{' == BUF(p)[*pos]) {
brace = 1;
- advance(p, buf, pos);
+ advance(p, pos);
} else if (isalpha(texitoks[cmd].tok[0]))
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
- if (*pos == sz) {
+ if (*pos == BUFSZ(p)) {
texiwarn(p, "truncated: @%s", texitoks[cmd].tok);
return;
}
switch (cmd) {
case (TEXICMD_ACUTE):
- switch (buf[*pos]) {
+ switch (BUF(p)[*pos]) {
case ('a'): case ('A'):
case ('e'): case ('E'):
case ('i'): case ('I'):
@@ -1011,19 +1011,19 @@ doaccent(struct texi *p, enum texicmd cm
texiwarn(p, "ignoring accent");
break;
}
- texiputchar(p, buf[*pos]);
- advance(p, buf, pos);
+ texiputchar(p, BUF(p)[*pos]);
+ advance(p, pos);
break;
case (TEXICMD_CEDILLA):
- if ('c' == buf[*pos] || 'C' == buf[*pos])
+ if ('c' == BUF(p)[*pos] || 'C' == BUF(p)[*pos])
texiputchars(p, "\\(,");
else
texiwarn(p, "ignoring accent");
- texiputchar(p, buf[*pos]);
- advance(p, buf, pos);
+ texiputchar(p, BUF(p)[*pos]);
+ advance(p, pos);
break;
case (TEXICMD_CIRCUMFLEX):
- switch (buf[*pos]) {
+ switch (BUF(p)[*pos]) {
case ('a'): case ('A'):
case ('e'): case ('E'):
case ('i'): case ('I'):
@@ -1035,19 +1035,19 @@ doaccent(struct texi *p, enum texicmd cm
texiwarn(p, "ignoring accent");
break;
}
- texiputchar(p, buf[*pos]);
- advance(p, buf, pos);
+ texiputchar(p, BUF(p)[*pos]);
+ advance(p, pos);
break;
case (TEXICMD_DOTLESS):
- if ('i' == buf[*pos] || 'j' == buf[*pos])
+ if ('i' == BUF(p)[*pos] || 'j' == BUF(p)[*pos])
texiputchars(p, "\\(.");
else
texiwarn(p, "ignoring accent");
- texiputchar(p, buf[*pos]);
- advance(p, buf, pos);
+ texiputchar(p, BUF(p)[*pos]);
+ advance(p, pos);
break;
case (TEXICMD_GRAVE):
- switch (buf[*pos]) {
+ switch (BUF(p)[*pos]) {
case ('a'): case ('A'):
case ('e'): case ('E'):
case ('i'): case ('I'):
@@ -1059,11 +1059,11 @@ doaccent(struct texi *p, enum texicmd cm
texiwarn(p, "ignoring accent");
break;
}
- texiputchar(p, buf[*pos]);
- advance(p, buf, pos);
+ texiputchar(p, BUF(p)[*pos]);
+ advance(p, pos);
break;
case (TEXICMD_TILDE):
- switch (buf[*pos]) {
+ switch (BUF(p)[*pos]) {
case ('a'): case ('A'):
case ('n'): case ('N'):
case ('o'): case ('O'):
@@ -1073,11 +1073,11 @@ doaccent(struct texi *p, enum texicmd cm
texiwarn(p, "ignoring accent");
break;
}
- texiputchar(p, buf[*pos]);
- advance(p, buf, pos);
+ texiputchar(p, BUF(p)[*pos]);
+ advance(p, pos);
break;
case (TEXICMD_UMLAUT):
- switch (buf[*pos]) {
+ switch (BUF(p)[*pos]) {
case ('a'): case ('A'):
case ('e'): case ('E'):
case ('i'): case ('I'):
@@ -1090,22 +1090,22 @@ doaccent(struct texi *p, enum texicmd cm
texiwarn(p, "ignoring accent");
break;
}
- texiputchar(p, buf[*pos]);
- advance(p, buf, pos);
+ texiputchar(p, BUF(p)[*pos]);
+ advance(p, pos);
break;
default:
- texiputchar(p, buf[*pos]);
- advance(p, buf, pos);
+ texiputchar(p, BUF(p)[*pos]);
+ advance(p, pos);
break;
}
if (brace) {
- while (*pos < sz && '}' != buf[*pos]) {
- texiputchar(p, buf[*pos]);
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && '}' != BUF(p)[*pos]) {
+ texiputchar(p, BUF(p)[*pos]);
+ advance(p, pos);
}
- if (*pos < sz)
- advance(p, buf, pos);
+ if (*pos < BUFSZ(p))
+ advance(p, pos);
}
switch (cmd) {
@@ -1121,8 +1121,7 @@ doaccent(struct texi *p, enum texicmd cm
}
static void
-dosymbol(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dosymbol(struct texi *p, enum texicmd cmd, size_t *pos)
{
/* Remember to pad us. */
@@ -1312,22 +1311,20 @@ dosymbol(struct texi *p, enum texicmd cm
/* Alphabetic commands have braces we ignore. */
if (isalpha(texitoks[cmd].tok[0]))
- doignbracket(p, cmd, buf, sz, pos);
+ doignbracket(p, cmd, pos);
}
static void
-doquotation(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doquotation(struct texi *p, enum texicmd cmd, size_t *pos)
{
teximacro(p, "Qo");
- parseto(p, buf, sz, pos, "quotation");
+ parseto(p, pos, "quotation");
teximacro(p, "Qc");
}
static void
-domath(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+domath(struct texi *p, enum texicmd cmd, size_t *pos)
{
size_t nest, start;
@@ -1337,102 +1334,91 @@ domath(struct texi *p, enum texicmd cmd,
* terms of @-commands.
* This departs from GNU's rules, but whatever.
*/
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
- if (*pos == sz || '{' != buf[*pos])
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
+ if (*pos == BUFSZ(p) || '{' != BUF(p)[*pos])
return;
- advance(p, buf, pos);
+ advance(p, pos);
if (p->seenws && p->outcol && 0 == p->literal)
texiputchar(p, ' ');
p->seenws = 0;
- for (nest = 1, start = *pos; *pos < sz && nest > 0; ) {
- if ('{' == buf[*pos])
+ for (nest = 1, start = *pos; *pos < BUFSZ(p) && nest > 0; ) {
+ if ('{' == BUF(p)[*pos])
nest++;
- else if ('}' == buf[*pos])
+ else if ('}' == BUF(p)[*pos])
if (0 == --nest)
continue;
- advance(p, buf, pos);
+ advance(p, pos);
}
- if (*pos == sz)
+ if (*pos == BUFSZ(p))
return;
- assert('}' == buf[*pos]);
- texiputbuf(p, buf, start, *pos);
- advance(p, buf, pos);
+ assert('}' == BUF(p)[*pos]);
+ texiputbuf(p, start, *pos);
+ advance(p, pos);
}
static void
-dovalue(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dovalue(struct texi *p, enum texicmd cmd, size_t *pos)
{
- size_t start, end, i;
+ size_t start, end;
char *key, *val;
const char *cp;
if (TEXICMD_SET == cmd) {
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
- for (start = end = *pos; end < sz; end++)
- if (ismspace(buf[end]))
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
+ for (start = end = *pos; end < BUFSZ(p); end++)
+ if (ismspace(BUF(p)[end]))
break;
/* We don't allow empty keys. */
if (start == end)
return;
- advanceto(p, buf, pos, end);
+ advanceto(p, pos, end);
key = malloc(end - start + 1);
if (NULL == key)
texiabort(p, NULL);
- memcpy(key, &buf[start], end - start);
+ memcpy(key, &BUF(p)[start], end - start);
key[end - start] = '\0';
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
- for (start = end = *pos; end < sz; end++)
- if ('\n' == buf[end])
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
+ for (start = end = *pos; end < BUFSZ(p); end++)
+ if ('\n' == BUF(p)[end])
break;
/* We do allow empty values. */
- advanceeoln(p, buf, sz, pos, 1);
+ advanceeoln(p, pos, 1);
val = malloc(end - start + 1);
if (NULL == val)
texiabort(p, NULL);
- memcpy(val, &buf[start], end - start);
+ memcpy(val, &BUF(p)[start], end - start);
val[end - start] = '\0';
valueadd(p, key, val);
} else if (TEXICMD_VALUE == cmd) {
if (p->seenws)
texiputchar(p, ' ');
p->seenws = 0;
- if (NULL != (cp = valueblookup(p, buf, sz, pos))) {
- for (i = 0; i < p->valstackpos; i++)
- if (cp == p->valstack[i])
- break;
- if (i < p->valstackpos)
- texierr(p, "recursive value");
- if (64 == p->valstackpos)
- texierr(p, "too many nested values");
- p->valstack[p->valstackpos++] = cp;
- parsemembuf(p, cp, strlen(cp));
- p->valstackpos--;
- } else
+ if (NULL != (cp = valueblookup(p, pos)))
+ texisplice(p, cp, strlen(cp), pos);
+ else
texiputchars(p, "{No value}");
} else if (TEXICMD_IFCLEAR == cmd) {
- if (NULL != valuellookup(p, buf, sz, pos))
- doignblock(p, cmd, buf, sz, pos);
+ if (NULL != valuellookup(p, pos))
+ doignblock(p, cmd, pos);
else
- parseto(p, buf, sz, pos, texitoks[cmd].tok);
+ parseto(p, pos, texitoks[cmd].tok);
} else if (TEXICMD_IFSET == cmd) {
- if (NULL == valuellookup(p, buf, sz, pos))
- doignblock(p, cmd, buf, sz, pos);
+ if (NULL == valuellookup(p, pos))
+ doignblock(p, cmd, pos);
else
- parseto(p, buf, sz, pos, texitoks[cmd].tok);
+ parseto(p, pos, texitoks[cmd].tok);
} else if (TEXICMD_CLEAR == cmd)
- valuelclear(p, buf, sz, pos);
+ valuelclear(p, pos);
}
static void
-dolink(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dolink(struct texi *p, enum texicmd cmd, size_t *pos)
{
int c;
@@ -1461,26 +1447,25 @@ dolink(struct texi *p, enum texicmd cmd,
abort();
}
- c = parsearg(p, buf, sz, pos, 0);
+ c = parsearg(p, pos, 0);
p->ign++;
while (c > 0)
- c = parsearg(p, buf, sz, pos, 1);
+ c = parsearg(p, pos, 1);
p->ign--;
- texipunctuate(p, buf, sz, pos);
+ texipunctuate(p, pos);
teximacroclose(p);
}
static void
-doignargn(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doignargn(struct texi *p, enum texicmd cmd, size_t *pos)
{
int c;
- c = parsearg(p, buf, sz, pos, 0);
+ c = parsearg(p, pos, 0);
p->ign++;
while (c > 0)
- c = parsearg(p, buf, sz, pos, 1);
+ c = parsearg(p, pos, 1);
p->ign--;
}
@@ -1505,8 +1490,7 @@ sectioner(struct texi *p, int sec)
}
static void
-dosubsubsection(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dosubsubsection(struct texi *p, enum texicmd cmd, size_t *pos)
{
int sec;
@@ -1515,14 +1499,13 @@ dosubsubsection(struct texi *p, enum tex
/* We don't have a subsubsubsection, so make one up. */
texivspace(p);
teximacroopen(p, sects[sec]);
- parseeoln(p, buf, sz, pos);
+ parseeoln(p, pos);
teximacroclose(p);
texivspace(p);
}
static void
-dosubsection(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dosubsection(struct texi *p, enum texicmd cmd, size_t *pos)
{
int sec;
@@ -1537,15 +1520,14 @@ dosubsection(struct texi *p, enum texicm
if (sec > 1)
texivspace(p);
teximacroopen(p, sects[sec]);
- parseeoln(p, buf, sz, pos);
+ parseeoln(p, pos);
teximacroclose(p);
if (sec > 1)
texivspace(p);
}
static void
-dosecoffs(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dosecoffs(struct texi *p, enum texicmd cmd, size_t *pos)
{
if (TEXICMD_RAISESECTIONS == cmd)
@@ -1555,8 +1537,7 @@ dosecoffs(struct texi *p, enum texicmd c
}
static void
-dosection(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dosection(struct texi *p, enum texicmd cmd, size_t *pos)
{
int sec;
@@ -1583,14 +1564,13 @@ dosection(struct texi *p, enum texicmd c
texierr(p, "\"%s\" in a literal scope!?", sects[sec]);
teximacroopen(p, sects[sec]);
- parseeoln(p, buf, sz, pos);
+ parseeoln(p, pos);
teximacroclose(p);
p->seenvs = 1;
}
static void
-dosp(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dosp(struct texi *p, enum texicmd cmd, size_t *pos)
{
if (p->literal)
@@ -1598,19 +1578,18 @@ dosp(struct texi *p, enum texicmd cmd,
else
texivspace(p);
/* FIXME: ignore and parseeoln. */
- advanceeoln(p, buf, sz, pos, 1);
+ advanceeoln(p, pos, 1);
}
static void
-dotop(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dotop(struct texi *p, enum texicmd cmd, size_t *pos)
{
const char *cp;
time_t t;
char date[32];
if (--p->ign)
- texierr(p, "@top command while ignoring (%d)", p->ign);
+ texierr(p, "@top command while ignoring");
/*
* Here we print our standard mdoc(7) prologue.
@@ -1644,12 +1623,11 @@ dotop(struct texi *p, enum texicmd cmd,
texiputchars(p, "Unknown description");
teximacroclose(p);
p->seenvs = 1;
- dosection(p, cmd, buf, sz, pos);
+ dosection(p, cmd, pos);
}
static void
-doitem(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doitem(struct texi *p, enum texicmd cmd, size_t *pos)
{
/* Multitable is using raw tbl(7). */
@@ -1677,7 +1655,7 @@ doitem(struct texi *p, enum texicmd cmd,
/* Trick so we don't start with Pp. */
p->seenvs = 1;
- parseeoln(p, buf, sz, pos);
+ parseeoln(p, pos);
if (TEXILIST_ITEM == p->list)
teximacroclose(p);
@@ -1686,8 +1664,7 @@ doitem(struct texi *p, enum texicmd cmd,
}
static void
-dotab(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dotab(struct texi *p, enum texicmd cmd, size_t *pos)
{
/* This command is only useful in @multitable. */
@@ -1696,8 +1673,7 @@ dotab(struct texi *p, enum texicmd cmd,
}
static void
-domultitable(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+domultitable(struct texi *p, enum texicmd cmd, size_t *pos)
{
enum texilist sv = p->list;
int svliteral = p->literal;
@@ -1714,29 +1690,29 @@ domultitable(struct texi *p, enum texicm
columns = 0;
/* Advance to the first argument... */
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
/* Make sure we don't print anything when scanning. */
p->ign++;
- if ('@' == buf[*pos]) {
+ if ('@' == BUF(p)[*pos]) {
/*
* Look for @columnfractions.
* We ignore these, but we do use the number of
* arguments to set the number of columns that we'll
* have.
*/
- type = texicmd(p, buf, *pos, sz, &end, NULL);
- advanceto(p, buf, pos, end);
+ type = texicmd(p, *pos, &end, NULL);
+ advanceto(p, pos, end);
if (TEXICMD_COLUMNFRACTIONS != type)
texierr(p, "unknown multitable command");
- while (*pos < sz && '\n' != buf[*pos]) {
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
- while (*pos < sz && ! isws(buf[*pos])) {
- if ('\n' == buf[*pos])
+ while (*pos < BUFSZ(p) && '\n' != BUF(p)[*pos]) {
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
+ while (*pos < BUFSZ(p) && ! isws(BUF(p)[*pos])) {
+ if ('\n' == BUF(p)[*pos])
break;
- advance(p, buf, pos);
+ advance(p, pos);
}
columns++;
}
@@ -1747,7 +1723,7 @@ domultitable(struct texi *p, enum texicm
* tbl(7) figure it out.
* So use this only to count arguments.
*/
- while (parselinearg(p, buf, sz, pos) > 0)
+ while (parselinearg(p, pos) > 0)
columns++;
p->ign--;
@@ -1759,7 +1735,7 @@ domultitable(struct texi *p, enum texicm
}
texiputchars(p, ".\n");
p->outmacro++;
- parseto(p, buf, sz, pos, texitoks[cmd].tok);
+ parseto(p, pos, texitoks[cmd].tok);
p->outmacro--;
teximacro(p, "TE");
p->literal = svliteral;
@@ -1767,40 +1743,37 @@ domultitable(struct texi *p, enum texicm
}
static void
-dotable(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+dotable(struct texi *p, enum texicmd cmd, size_t *pos)
{
enum texilist sv = p->list;
p->list = TEXILIST_ITEM;
teximacro(p, "Bl -tag -width Ds");
/* FIXME: ignore and parseeoln. */
- advanceeoln(p, buf, sz, pos, 1);
+ advanceeoln(p, pos, 1);
p->seenvs = 1;
- parseto(p, buf, sz, pos, texitoks[cmd].tok);
+ parseto(p, pos, texitoks[cmd].tok);
teximacro(p, "El");
p->list = sv;
}
static void
-doend(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doend(struct texi *p, enum texicmd cmd, size_t *pos)
{
size_t start;
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
start = *pos;
- while (*pos < sz && '\n' != buf[*pos])
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && '\n' != BUF(p)[*pos])
+ advance(p, pos);
- texiwarn(p, "unexpected \"end\": %.*s", (int)(*pos - start), &buf[start]);
- advanceeoln(p, buf, sz, pos, 1);
+ texiwarn(p, "unexpected \"end\": %.*s", (int)(*pos - start), &BUF(p)[start]);
+ advanceeoln(p, pos, 1);
}
static void
-doenumerate(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doenumerate(struct texi *p, enum texicmd cmd, size_t *pos)
{
enum texilist sv = p->list;
@@ -1808,15 +1781,14 @@ doenumerate(struct texi *p, enum texicmd
teximacro(p, "Bl -enum");
p->seenvs = 1;
/* FIXME: ignore and parseeoln. */
- advanceeoln(p, buf, sz, pos, 1);
- parseto(p, buf, sz, pos, "enumerate");
+ advanceeoln(p, pos, 1);
+ parseto(p, pos, "enumerate");
teximacro(p, "El");
p->list = sv;
}
static void
-doitemize(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doitemize(struct texi *p, enum texicmd cmd, size_t *pos)
{
enum texilist sv = p->list;
@@ -1824,29 +1796,27 @@ doitemize(struct texi *p, enum texicmd c
teximacro(p, "Bl -bullet");
p->seenvs = 1;
/* FIXME: ignore and parseeoln. */
- advanceeoln(p, buf, sz, pos, 1);
- parseto(p, buf, sz, pos, "itemize");
+ advanceeoln(p, pos, 1);
+ parseto(p, pos, "itemize");
teximacro(p, "El");
p->list = sv;
}
static void
-doignbracket(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doignbracket(struct texi *p, enum texicmd cmd, size_t *pos)
{
p->ign++;
- parsebracket(p, buf, sz, pos);
+ parsebracket(p, pos);
p->ign--;
}
static void
-doignline(struct texi *p, enum texicmd cmd,
- const char *buf, size_t sz, size_t *pos)
+doignline(struct texi *p, enum texicmd cmd, size_t *pos)
{
/* FIXME: ignore and parseeoln. */
- advanceeoln(p, buf, sz, pos, 1);
+ advanceeoln(p, pos, 1);
}
/*
Index: extern.h
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/extern.h,v
retrieving revision 1.14
retrieving revision 1.15
diff -Lextern.h -Lextern.h -u -p -r1.14 -r1.15
--- extern.h
+++ extern.h
@@ -298,8 +298,9 @@ struct texifile {
const char *name; /* name of the file */
size_t line; /* current line (from zero) */
size_t col; /* current column in line (from zero) */
- char *map; /* mmap'd file OR allocated buffer */
- size_t mapsz; /* size of mmap */
+ char *map; /* allocated file buffer */
+ size_t mapsz; /* size of map */
+ size_t mapmaxsz; /* full size of map */
};
struct texi;
@@ -307,8 +308,7 @@ struct texi;
/*
* Callback for functions implementing texi commands.
*/
-typedef void (*texicmdfp)(struct texi *,
- enum texicmd, const char *, size_t, size_t *);
+typedef void (*texicmdfp)(struct texi *, enum texicmd, size_t *);
/*
* Describes Texinfo commands, whether native or overriden.
@@ -383,6 +383,9 @@ struct texi {
int literal; /* if >0, literal context */
};
+#define BUF(_p) ((_p)->files[(_p)->filepos - 1].map)
+#define BUFSZ(_p) ((_p)->files[(_p)->filepos - 1].mapsz)
+
#define isws(_x) \
(' ' == (_x) || '\t' == (_x))
#define ismspace(_x) \
@@ -390,27 +393,24 @@ struct texi {
__BEGIN_DECLS
-void advance(struct texi *, const char *, size_t *);
-size_t advanceeoln(struct texi *, const char *, size_t, size_t *, int);
-void advanceto(struct texi *, const char *, size_t *, size_t);
+void advance(struct texi *, size_t *);
+size_t advanceeoln(struct texi *, size_t *, int);
+void advanceto(struct texi *, size_t *, size_t);
-char **argparse(struct texi *, const char *, size_t, size_t *, size_t *, size_t);
+char **argparse(struct texi *, size_t *, size_t *, size_t);
-int parsearg(struct texi *, const char *, size_t, size_t *, size_t);
-void parsebracket(struct texi *, const char *, size_t, size_t *);
+int parsearg(struct texi *, size_t *, size_t);
+void parsebracket(struct texi *, size_t *);
void parsestdin(struct texi *);
void parsefile(struct texi *, const char *, int);
-int parselinearg(struct texi *, const char *, size_t, size_t *);
-void parseeof(struct texi *, const char *, size_t);
-void parsemembuf(struct texi *, const char *, size_t);
-void parseeoln(struct texi *, const char *, size_t, size_t *);
-void parsesingle(struct texi *, const char *, size_t, size_t *);
-void parseto(struct texi *, const char *, size_t, size_t *, const char *);
+int parselinearg(struct texi *, size_t *);
+void parseeoln(struct texi *, size_t *);
+void parseto(struct texi *, size_t *, const char *);
void texiabort(struct texi *, const char *)
__attribute__((noreturn));
enum texicmd
- texicmd(struct texi *, const char *, size_t, size_t,
+ texicmd(struct texi *, size_t,
size_t *, struct teximacro **);
void texierr(struct texi *, const char *, ...)
__attribute__((format(printf, 2, 3)))
@@ -420,20 +420,21 @@ void texifilepop(struct texi *);
void teximacro(struct texi *, const char *);
void teximacroclose(struct texi *);
void teximacroopen(struct texi *, const char *);
-void texipunctuate(struct texi *, const char *, size_t, size_t *);
-void texiputbuf(struct texi *p, const char *, size_t, size_t);
+void texipunctuate(struct texi *, size_t *);
+void texiputbuf(struct texi *p, size_t, size_t);
void texiputchar(struct texi *p, char);
void texiputchars(struct texi *, const char *);
void texivspace(struct texi *);
void texiwarn(const struct texi *, const char *, ...)
__attribute__((format(printf, 2, 3)));
+void texisplice(struct texi *, const char *, size_t, size_t *);
void valueadd(struct texi *, char *, char *);
const char *
- valueblookup(struct texi *, const char *, size_t, size_t *);
-void valuelclear(struct texi *, const char *, size_t, size_t *);
+ valueblookup(struct texi *, size_t *);
+void valuelclear(struct texi *, size_t *);
const char *
- valuellookup(struct texi *, const char *, size_t, size_t *);
+ valuellookup(struct texi *, size_t *);
extern const struct texitok *const texitoks;
Index: util.c
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/util.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -Lutil.c -Lutil.c -u -p -r1.13 -r1.14
--- util.c
+++ util.c
@@ -43,10 +43,7 @@ texifilepop(struct texi *p)
assert(p->filepos > 0);
f = &p->files[--p->filepos];
- if (TEXISRC_FILE == f->type)
- munmap(f->map, f->mapsz);
- else
- free(f->map);
+ free(f->map);
}
static void
@@ -206,16 +203,14 @@ texiputchars(struct texi *p, const char
/*
* This puts all characters onto the output stream but makes sure to
* escape mdoc(7) slashes.
+ * FIXME: useless.
*/
void
-texiputbuf(struct texi *p, const char *buf, size_t start, size_t end)
+texiputbuf(struct texi *p, size_t start, size_t end)
{
- for ( ; start < end; start++) {
- texiputchar(p, buf[start]);
- if ('\\' == buf[start])
- texiputchar(p, 'e');
- }
+ for ( ; start < end; start++)
+ texiputchar(p, BUF(p)[start]);
}
/*
@@ -309,10 +304,10 @@ texivspace(struct texi *p)
* in the current input file.
*/
void
-advance(struct texi *p, const char *buf, size_t *pos)
+advance(struct texi *p, size_t *pos)
{
- if ('\n' == buf[*pos]) {
+ if ('\n' == BUF(p)[*pos]) {
p->files[p->filepos - 1].line++;
p->files[p->filepos - 1].col = 0;
} else
@@ -329,15 +324,15 @@ advance(struct texi *p, const char *buf,
* appropriately flush-left punctuation alongside the macro.
*/
void
-texipunctuate(struct texi *p, const char *buf, size_t sz, size_t *pos)
+texipunctuate(struct texi *p, size_t *pos)
{
size_t start, end;
if (1 != p->outmacro)
return;
- for (start = end = *pos; end < sz; end++) {
- switch (buf[end]) {
+ for (start = end = *pos; end < BUFSZ(p); end++) {
+ switch (BUF(p)[end]) {
case (','):
case (')'):
case ('.'):
@@ -353,11 +348,12 @@ texipunctuate(struct texi *p, const char
}
if (end == *pos)
return;
- if (end + 1 == sz || ' ' == buf[end] || '\n' == buf[end]) {
+ if (end + 1 == BUFSZ(p) || ' ' == BUF(p)[end] ||
+ '\n' == BUF(p)[end]) {
for ( ; start < end; start++) {
texiputchar(p, ' ');
- texiputchar(p, buf[start]);
- advance(p, buf, pos);
+ texiputchar(p, BUF(p)[start]);
+ advance(p, pos);
}
}
}
@@ -368,27 +364,27 @@ texipunctuate(struct texi *p, const char
* doing so.
*/
static size_t
-advancenext(struct texi *p, const char *buf, size_t sz, size_t *pos)
+advancenext(struct texi *p, size_t *pos)
{
if (p->literal) {
- while (*pos < sz && ismspace(buf[*pos])) {
- texiputchar(p, buf[*pos]);
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && ismspace(BUF(p)[*pos])) {
+ texiputchar(p, BUF(p)[*pos]);
+ advance(p, pos);
}
return(*pos);
}
- while (*pos < sz && ismspace(buf[*pos])) {
+ while (*pos < BUFSZ(p) && ismspace(BUF(p)[*pos])) {
p->seenws = 1;
/*
* If it looks like we've printed a double-line, then
* output a paragraph.
* FIXME: this is stupid.
*/
- if (*pos && '\n' == buf[*pos] && '\n' == buf[*pos - 1])
+ if (*pos && '\n' == BUF(p)[*pos] && '\n' == BUF(p)[*pos - 1])
texivspace(p);
- advance(p, buf, pos);
+ advance(p, pos);
}
return(*pos);
}
@@ -399,14 +395,13 @@ advancenext(struct texi *p, const char *
* the @\n.
*/
size_t
-advanceeoln(struct texi *p, const char *buf,
- size_t sz, size_t *pos, int consumenl)
+advanceeoln(struct texi *p, size_t *pos, int consumenl)
{
- while (*pos < sz && '\n' != buf[*pos])
- advance(p, buf, pos);
- if (*pos < sz && consumenl)
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && '\n' != BUF(p)[*pos])
+ advance(p, pos);
+ if (*pos < BUFSZ(p) && consumenl)
+ advance(p, pos);
return(*pos);
}
@@ -415,17 +410,16 @@ advanceeoln(struct texi *p, const char *
* current buffer greater than or equal to the current position.
*/
void
-advanceto(struct texi *p, const char *buf, size_t *pos, size_t end)
+advanceto(struct texi *p, size_t *pos, size_t end)
{
assert(*pos <= end);
while (*pos < end)
- advance(p, buf, pos);
+ advance(p, pos);
}
static void
-texiexecmacro(struct texi *p, struct teximacro *m,
- const char *buf, size_t sz, size_t *pos)
+texiexecmacro(struct texi *p, struct teximacro *m, size_t *pos)
{
size_t valsz, realsz, aasz, asz,
ssz, i, j, k, start, end;
@@ -433,13 +427,13 @@ texiexecmacro(struct texi *p, struct tex
char **args;
const char *cp;
- args = argparse(p, buf, sz, pos, &asz, m->argsz);
+ args = argparse(p, pos, &asz, m->argsz);
if (asz != m->argsz)
texiwarn(p, "invalid macro argument length");
aasz = asz < m->argsz ? asz : m->argsz;
if (0 == aasz) {
- parsemembuf(p, m->value, strlen(m->value));
+ texisplice(p, m->value, strlen(m->value), pos);
return;
}
@@ -482,15 +476,10 @@ texiexecmacro(struct texi *p, struct tex
/*
* Argument didn't exist in argument table.
- * No need to reallocate here: we just copy the text
- * directly from the macro value into the buffer.
+ * Just ignore it.
*/
if (k == aasz) {
- for ( ; i < end; i++)
- val[j++] = m->value[i];
- assert('\\' == m->value[i]);
- val[j++] = m->value[i];
- val[j] = '\0';
+ i = end;
continue;
}
@@ -508,7 +497,7 @@ texiexecmacro(struct texi *p, struct tex
i = end;
}
- parsemembuf(p, val, strlen(val));
+ texisplice(p, val, strlen(val), pos);
for (i = 0; i < asz; i++)
free(args[i]);
@@ -522,8 +511,7 @@ texiexecmacro(struct texi *p, struct tex
* This also will advance the input stream.
*/
static void
-texiword(struct texi *p, const char *buf,
- size_t sz, size_t *pos, char extra)
+parseword(struct texi *p, size_t *pos, char extra)
{
if (p->seenws && 0 == p->outmacro &&
@@ -535,28 +523,28 @@ texiword(struct texi *p, const char *buf
p->seenws = 0;
- while (*pos < sz && ! ismspace(buf[*pos])) {
- switch (buf[*pos]) {
+ while (*pos < BUFSZ(p) && ! ismspace(BUF(p)[*pos])) {
+ switch (BUF(p)[*pos]) {
case ('@'):
case ('}'):
case ('{'):
return;
}
- if ('\0' != extra && buf[*pos] == extra)
+ if ('\0' != extra && BUF(p)[*pos] == extra)
return;
- if (*pos < sz - 1 &&
- '`' == buf[*pos] &&
- '`' == buf[*pos + 1]) {
+ if (*pos < BUFSZ(p) - 1 &&
+ '`' == BUF(p)[*pos] &&
+ '`' == BUF(p)[*pos + 1]) {
texiputchars(p, "\\(lq");
- advance(p, buf, pos);
- } else if (*pos < sz - 1 &&
- '\'' == buf[*pos] &&
- '\'' == buf[*pos + 1]) {
+ advance(p, pos);
+ } else if (*pos < BUFSZ(p) - 1 &&
+ '\'' == BUF(p)[*pos] &&
+ '\'' == BUF(p)[*pos + 1]) {
texiputchars(p, "\\(rq");
- advance(p, buf, pos);
+ advance(p, pos);
} else
- texiputchar(p, buf[*pos]);
- advance(p, buf, pos);
+ texiputchar(p, BUF(p)[*pos]);
+ advance(p, pos);
}
}
@@ -566,39 +554,38 @@ texiword(struct texi *p, const char *buf
* index after the command name.
*/
enum texicmd
-texicmd(struct texi *p, const char *buf, size_t pos,
- size_t sz, size_t *end, struct teximacro **macro)
+texicmd(struct texi *p, size_t pos, size_t *end, struct teximacro **macro)
{
size_t i, len, toksz;
- assert('@' == buf[pos]);
+ assert('@' == BUF(p)[pos]);
if (NULL != macro)
*macro = NULL;
- if ((*end = pos) == sz)
+ if ((*end = pos) == BUFSZ(p))
return(TEXICMD__MAX);
- else if ((*end = ++pos) == sz)
+ else if ((*end = ++pos) == BUFSZ(p))
return(TEXICMD__MAX);
/* Alphabetic commands are special. */
- if ( ! isalpha(buf[pos])) {
- if ((*end = pos + 1) == sz)
+ if ( ! isalpha(BUF(p)[pos])) {
+ if ((*end = pos + 1) == BUFSZ(p))
return(TEXICMD__MAX);
for (i = 0; i < TEXICMD__MAX; i++) {
if (1 != texitoks[i].len)
continue;
- if (0 == strncmp(texitoks[i].tok, &buf[pos], 1))
+ if (0 == strncmp(texitoks[i].tok, &BUF(p)[pos], 1))
return(i);
}
- texiwarn(p, "bad command: @%c", buf[pos]);
+ texiwarn(p, "bad command: @%c", BUF(p)[pos]);
return(TEXICMD__MAX);
}
/* Scan to the end of the possible command name. */
- for (*end = pos; *end < sz && ! ismspace(buf[*end]); (*end)++)
- if ((*end > pos && ('@' == buf[*end] ||
- '{' == buf[*end] || '}' == buf[*end])))
+ for (*end = pos; *end < BUFSZ(p) && ! ismspace(BUF(p)[*end]); (*end)++)
+ if ((*end > pos && ('@' == BUF(p)[*end] ||
+ '{' == BUF(p)[*end] || '}' == BUF(p)[*end])))
break;
/* Look for the command. */
@@ -606,7 +593,7 @@ texicmd(struct texi *p, const char *buf,
for (i = 0; i < TEXICMD__MAX; i++) {
if (len != texitoks[i].len)
continue;
- if (0 == strncmp(texitoks[i].tok, &buf[pos], len))
+ if (0 == strncmp(texitoks[i].tok, &BUF(p)[pos], len))
return(i);
}
@@ -615,23 +602,23 @@ texicmd(struct texi *p, const char *buf,
toksz = strlen(p->indexs[i]);
if (len != 5 + toksz)
continue;
- if (strncmp(&buf[pos], p->indexs[i], toksz))
+ if (strncmp(&BUF(p)[pos], p->indexs[i], toksz))
continue;
- if (0 == strncmp(&buf[pos + toksz], "index", 5))
+ if (0 == strncmp(&BUF(p)[pos + toksz], "index", 5))
return(TEXICMD_USER_INDEX);
}
for (i = 0; i < p->macrosz; i++) {
if (len != strlen(p->macros[i].key))
continue;
- if (strncmp(&buf[pos], p->macros[i].key, len))
+ if (strncmp(&BUF(p)[pos], p->macros[i].key, len))
continue;
if (NULL != macro)
*macro = &p->macros[i];
return(TEXICMD__MAX);
}
- texiwarn(p, "bad command: @%.*s", (int)len, &buf[pos]);
+ texiwarn(p, "bad command: @%.*s", (int)len, &BUF(p)[pos]);
return(TEXICMD__MAX);
}
@@ -644,48 +631,47 @@ texicmd(struct texi *p, const char *buf,
* bracket for the zeroth parse.
*/
int
-parsearg(struct texi *p, const char *buf,
- size_t sz, size_t *pos, size_t num)
+parsearg(struct texi *p, size_t *pos, size_t num)
{
size_t end;
enum texicmd cmd;
struct teximacro *macro;
- while (*pos < sz && ismspace(buf[*pos]))
- advance(p, buf, pos);
- if (*pos == sz || (0 == num && '{' != buf[*pos]))
+ while (*pos < BUFSZ(p) && ismspace(BUF(p)[*pos]))
+ advance(p, pos);
+ if (*pos == BUFSZ(p) || (0 == num && '{' != BUF(p)[*pos]))
return(0);
if (0 == num)
- advance(p, buf, pos);
+ advance(p, pos);
- while ((*pos = advancenext(p, buf, sz, pos)) < sz) {
- switch (buf[*pos]) {
+ while ((*pos = advancenext(p, pos)) < BUFSZ(p)) {
+ switch (BUF(p)[*pos]) {
case (','):
- advance(p, buf, pos);
+ advance(p, pos);
return(1);
case ('}'):
- advance(p, buf, pos);
+ advance(p, pos);
return(0);
case ('{'):
if (0 == p->ign)
texiwarn(p, "unexpected \"{\"");
- advance(p, buf, pos);
+ advance(p, pos);
continue;
case ('@'):
break;
default:
- texiword(p, buf, sz, pos, ',');
+ parseword(p, pos, ',');
continue;
}
- cmd = texicmd(p, buf, *pos, sz, &end, ¯o);
- advanceto(p, buf, pos, end);
+ cmd = texicmd(p, *pos, &end, ¯o);
+ advanceto(p, pos, end);
if (NULL != macro)
- texiexecmacro(p, macro, buf, sz, pos);
+ texiexecmacro(p, macro, pos);
if (TEXICMD__MAX == cmd)
continue;
if (NULL != texitoks[cmd].fp)
- (*texitoks[cmd].fp)(p, cmd, buf, sz, pos);
+ (*texitoks[cmd].fp)(p, cmd, pos);
}
return(0);
}
@@ -695,44 +681,44 @@ parsearg(struct texi *p, const char *buf
* This will stop in the event of EOF or if we're not at a bracket.
*/
void
-parsebracket(struct texi *p, const char *buf, size_t sz, size_t *pos)
+parsebracket(struct texi *p, size_t *pos)
{
size_t end;
enum texicmd cmd;
struct teximacro *macro;
- while (*pos < sz && ismspace(buf[*pos]))
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && ismspace(BUF(p)[*pos]))
+ advance(p, pos);
- if (*pos == sz || '{' != buf[*pos])
+ if (*pos == BUFSZ(p) || '{' != BUF(p)[*pos])
return;
- advance(p, buf, pos);
+ advance(p, pos);
- while ((*pos = advancenext(p, buf, sz, pos)) < sz) {
- switch (buf[*pos]) {
+ while ((*pos = advancenext(p, pos)) < BUFSZ(p)) {
+ switch (BUF(p)[*pos]) {
case ('}'):
- advance(p, buf, pos);
+ advance(p, pos);
return;
case ('{'):
if (0 == p->ign)
texiwarn(p, "unexpected \"{\"");
- advance(p, buf, pos);
+ advance(p, pos);
continue;
case ('@'):
break;
default:
- texiword(p, buf, sz, pos, '\0');
+ parseword(p, pos, '\0');
continue;
}
- cmd = texicmd(p, buf, *pos, sz, &end, ¯o);
- advanceto(p, buf, pos, end);
+ cmd = texicmd(p, *pos, &end, ¯o);
+ advanceto(p, pos, end);
if (NULL != macro)
- texiexecmacro(p, macro, buf, sz, pos);
+ texiexecmacro(p, macro, pos);
if (TEXICMD__MAX == cmd)
continue;
if (NULL != texitoks[cmd].fp)
- (*texitoks[cmd].fp)(p, cmd, buf, sz, pos);
+ (*texitoks[cmd].fp)(p, cmd, pos);
}
}
@@ -742,88 +728,91 @@ parsebracket(struct texi *p, const char
* the way.
*/
void
-parseeoln(struct texi *p, const char *buf, size_t sz, size_t *pos)
+parseeoln(struct texi *p, size_t *pos)
{
size_t end;
enum texicmd cmd;
struct teximacro *macro;
- while (*pos < sz && '\n' != buf[*pos]) {
- while (*pos < sz && isws(buf[*pos])) {
+ while (*pos < BUFSZ(p) && '\n' != BUF(p)[*pos]) {
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) {
p->seenws = 1;
if (p->literal)
- texiputchar(p, buf[*pos]);
- advance(p, buf, pos);
+ texiputchar(p, BUF(p)[*pos]);
+ advance(p, pos);
}
- switch (buf[*pos]) {
+ switch (BUF(p)[*pos]) {
case ('}'):
if (0 == p->ign)
texiwarn(p, "unexpected \"}\"");
- advance(p, buf, pos);
+ advance(p, pos);
continue;
case ('{'):
if (0 == p->ign)
texiwarn(p, "unexpected \"{\"");
- advance(p, buf, pos);
+ advance(p, pos);
continue;
case ('@'):
break;
default:
- texiword(p, buf, sz, pos, '\0');
+ parseword(p, pos, '\0');
continue;
}
- cmd = texicmd(p, buf, *pos, sz, &end, ¯o);
- advanceto(p, buf, pos, end);
+ cmd = texicmd(p, *pos, &end, ¯o);
+ advanceto(p, pos, end);
if (NULL != macro)
- texiexecmacro(p, macro, buf, sz, pos);
+ texiexecmacro(p, macro, pos);
if (TEXICMD__MAX == cmd)
continue;
if (NULL != texitoks[cmd].fp)
- (*texitoks[cmd].fp)(p, cmd, buf, sz, pos);
+ (*texitoks[cmd].fp)(p, cmd, pos);
}
+
+ if (*pos < BUFSZ(p) && '\n' == BUF(p)[*pos])
+ advance(p, pos);
}
/*
* Parse a single word or command.
* This will return immediately at the EOF.
*/
-void
-parsesingle(struct texi *p, const char *buf, size_t sz, size_t *pos)
+static void
+parsesingle(struct texi *p, size_t *pos)
{
size_t end;
enum texicmd cmd;
struct teximacro *macro;
- if ((*pos = advancenext(p, buf, sz, pos)) >= sz)
+ if ((*pos = advancenext(p, pos)) >= BUFSZ(p))
return;
- switch (buf[*pos]) {
+ switch (BUF(p)[*pos]) {
case ('}'):
if (0 == p->ign)
texiwarn(p, "unexpected \"}\"");
- advance(p, buf, pos);
+ advance(p, pos);
return;
case ('{'):
if (0 == p->ign)
texiwarn(p, "unexpected \"{\"");
- advance(p, buf, pos);
+ advance(p, pos);
return;
case ('@'):
break;
default:
- texiword(p, buf, sz, pos, '\0');
+ parseword(p, pos, '\0');
return;
}
- cmd = texicmd(p, buf, *pos, sz, &end, ¯o);
- advanceto(p, buf, pos, end);
+ cmd = texicmd(p, *pos, &end, ¯o);
+ advanceto(p, pos, end);
if (NULL != macro)
- texiexecmacro(p, macro, buf, sz, pos);
+ texiexecmacro(p, macro, pos);
if (TEXICMD__MAX == cmd)
return;
if (NULL != texitoks[cmd].fp)
- (*texitoks[cmd].fp)(p, cmd, buf, sz, pos);
+ (*texitoks[cmd].fp)(p, cmd, pos);
}
/*
@@ -835,18 +824,18 @@ parsesingle(struct texi *p, const char *
* line or 1 otherwise.
*/
int
-parselinearg(struct texi *p, const char *buf, size_t sz, size_t *pos)
+parselinearg(struct texi *p, size_t *pos)
{
- while (*pos < sz && isws(buf[*pos])) {
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos])) {
p->seenws = 1;
- advance(p, buf, pos);
+ advance(p, pos);
}
- if (*pos < sz && '{' == buf[*pos])
- parsebracket(p, buf, sz, pos);
- else if (*pos < sz && '\n' != buf[*pos])
- parsesingle(p, buf, sz, pos);
+ if (*pos < BUFSZ(p) && '{' == BUF(p)[*pos])
+ parsebracket(p, pos);
+ else if (*pos < BUFSZ(p) && '\n' != BUF(p)[*pos])
+ parsesingle(p, pos);
else
return(0);
@@ -856,41 +845,35 @@ parselinearg(struct texi *p, const char
/*
* Parse til the end of the buffer.
*/
-void
-parseeof(struct texi *p, const char *buf, size_t sz)
+static void
+parseeof(struct texi *p)
{
size_t pos;
- for (pos = 0; pos < sz; )
- parsesingle(p, buf, sz, &pos);
+ for (pos = 0; pos < BUFSZ(p); )
+ parsesingle(p, &pos);
}
-/*
- * This is like parseeof() except that it's to be invoked on memory
- * buffers while parsing a larger scope.
- * This is useful for parsing macro sequences.
- * The line, column, and name of the calling file context are saved, the
- * column and line reset, then all of these restored after parse.
- */
void
-parsemembuf(struct texi *p, const char *buf, size_t sz)
+texisplice(struct texi *p, const char *buf, size_t sz, size_t *pos)
{
- size_t svln, svcol;
- const char *svname;
-
- svln = p->files[p->filepos - 1].line;
- svcol = p->files[p->filepos - 1].col;
- svname = p->files[p->filepos - 1].name;
+ char *cp;
+ struct texifile *f;
- p->files[p->filepos - 1].line = 0;
- p->files[p->filepos - 1].col = 0;
- p->files[p->filepos - 1].name = "<macro buffer>";
+ assert(p->filepos > 0);
+ f = &p->files[p->filepos - 1];
- parseeof(p, buf, sz);
+ if (f->mapsz + sz > f->mapmaxsz) {
+ f->mapmaxsz = f->mapsz + sz + 1024;
+ cp = realloc(f->map, f->mapmaxsz);
+ if (NULL == cp)
+ texiabort(p, NULL);
+ f->map = cp;
+ }
- p->files[p->filepos - 1].line = svln;
- p->files[p->filepos - 1].col = svcol;
- p->files[p->filepos - 1].name = svname;
+ memmove(f->map + *pos + sz, f->map + *pos, f->mapsz - *pos);
+ memcpy(f->map + *pos, buf, sz);
+ f->mapsz += sz;
}
/*
@@ -899,8 +882,7 @@ parsemembuf(struct texi *p, const char *
* This will return immediately at EOF.
*/
void
-parseto(struct texi *p, const char *buf,
- size_t sz, size_t *pos, const char *endtoken)
+parseto(struct texi *p, size_t *pos, const char *endtoken)
{
size_t end;
enum texicmd cmd;
@@ -910,50 +892,50 @@ parseto(struct texi *p, const char *buf,
endtoksz = strlen(endtoken);
assert(endtoksz > 0);
- while ((*pos = advancenext(p, buf, sz, pos)) < sz) {
- switch (buf[*pos]) {
+ while ((*pos = advancenext(p, pos)) < BUFSZ(p)) {
+ switch (BUF(p)[*pos]) {
case ('}'):
if (0 == p->ign)
texiwarn(p, "unexpected \"}\"");
- advance(p, buf, pos);
+ advance(p, pos);
continue;
case ('{'):
if (0 == p->ign)
texiwarn(p, "unexpected \"{\"");
- advance(p, buf, pos);
+ advance(p, pos);
continue;
case ('@'):
break;
default:
- texiword(p, buf, sz, pos, '\0');
+ parseword(p, pos, '\0');
continue;
}
- cmd = texicmd(p, buf, *pos, sz, &end, ¯o);
- advanceto(p, buf, pos, end);
+ cmd = texicmd(p, *pos, &end, ¯o);
+ advanceto(p, pos, end);
if (TEXICMD_END == cmd) {
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
/*
* FIXME: check the full word, not just its
* initial substring!
*/
- if (sz - *pos >= endtoksz && 0 == strncmp
- (&buf[*pos], endtoken, endtoksz)) {
- advanceeoln(p, buf, sz, pos, 0);
+ if (BUFSZ(p) - *pos >= endtoksz && 0 == strncmp
+ (&BUF(p)[*pos], endtoken, endtoksz)) {
+ advanceeoln(p, pos, 0);
break;
}
if (0 == p->ign)
texiwarn(p, "unexpected \"end\"");
- advanceeoln(p, buf, sz, pos, 0);
+ advanceeoln(p, pos, 0);
continue;
}
if (NULL != macro)
- texiexecmacro(p, macro, buf, sz, pos);
+ texiexecmacro(p, macro, pos);
if (TEXICMD__MAX == cmd)
continue;
if (NULL != texitoks[cmd].fp)
- (*texitoks[cmd].fp)(p, cmd, buf, sz, pos);
+ (*texitoks[cmd].fp)(p, cmd, pos);
}
}
@@ -965,7 +947,6 @@ void
parsestdin(struct texi *p)
{
struct texifile *f;
- size_t off;
ssize_t ssz;
assert(0 == p->filepos);
@@ -975,18 +956,18 @@ parsestdin(struct texi *p)
f->type = TEXISRC_STDIN;
f->name = "<stdin>";
- for (off = 0; ; off += (size_t)ssz) {
- if (off == f->mapsz) {
- if (f->mapsz == (1U << 31))
+ for (f->mapsz = 0; ; f->mapsz += (size_t)ssz) {
+ if (f->mapsz == f->mapmaxsz) {
+ if (f->mapmaxsz == (1U << 31))
texierr(p, "stdin buffer too long");
- f->mapsz = f->mapsz > 65536 / 2 ?
- 2 * f->mapsz : 65536;
- f->map = realloc(f->map, f->mapsz);
+ f->mapmaxsz = f->mapmaxsz > 65536 / 2 ?
+ 2 * f->mapmaxsz : 65536;
+ f->map = realloc(f->map, f->mapmaxsz);
if (NULL == f->map)
texiabort(p, NULL);
}
- ssz = read(STDIN_FILENO,
- f->map + (int)off, f->mapsz - off);
+ ssz = read(STDIN_FILENO, f->map +
+ (int)f->mapsz, f->mapmaxsz - f->mapsz);
if (0 == ssz)
break;
else if (-1 == ssz)
@@ -994,7 +975,7 @@ parsestdin(struct texi *p)
}
p->filepos++;
- parseeof(p, f->map, off);
+ parseeof(p);
texifilepop(p);
}
@@ -1011,6 +992,7 @@ parsefile(struct texi *p, const char *fn
int fd;
struct stat st;
size_t i;
+ char *map;
if (64 == p->filepos)
texierr(p, "too many open files");
@@ -1026,22 +1008,28 @@ parsefile(struct texi *p, const char *fn
texiabort(p, fname);
}
- f->mapsz = st.st_size;
- f->map = mmap(NULL, f->mapsz,
+ f->mapsz = f->mapmaxsz = st.st_size;
+ map = mmap(NULL, f->mapsz,
PROT_READ, MAP_SHARED, fd, 0);
close(fd);
- if (MAP_FAILED == f->map)
+ if (MAP_FAILED == map)
texiabort(p, fname);
- p->filepos++;
if ( ! parse) {
for (i = 0; i < f->mapsz; i++)
- texiputchar(p, f->map[i]);
+ texiputchar(p, map[i]);
if (p->outcol)
texiputchar(p, '\n');
- } else
- parseeof(p, f->map, f->mapsz);
+ munmap(map, f->mapsz);
+ return;
+ }
+
+ p->filepos++;
+ f->map = malloc(f->mapsz);
+ memcpy(f->map, map, f->mapsz);
+ munmap(map, f->mapsz);
+ parseeof(p);
texifilepop(p);
}
@@ -1053,8 +1041,7 @@ parsefile(struct texi *p, const char *fn
* The pointer can point to NULL if the value has been unset.
*/
static char **
-valuequery(const struct texi *p,
- const char *buf, size_t start, size_t end)
+valuequery(const struct texi *p, size_t start, size_t end)
{
size_t i, sz, len;
@@ -1066,7 +1053,7 @@ valuequery(const struct texi *p,
sz = strlen(p->vals[i].key);
if (sz != len)
continue;
- if (0 == strncmp(p->vals[i].key, &buf[start], len))
+ if (0 == strncmp(p->vals[i].key, &BUF(p)[start], len))
return(&p->vals[i].value);
}
return(NULL);
@@ -1077,45 +1064,45 @@ valuequery(const struct texi *p,
* pointer to its value via valuequery().
*/
static char **
-valuelquery(struct texi *p, const char *buf, size_t sz, size_t *pos)
+valuelquery(struct texi *p, size_t *pos)
{
size_t start, end;
char **ret;
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
- if (*pos == sz)
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
+ if (*pos == BUFSZ(p))
return(NULL);
- for (start = end = *pos; end < sz; end++)
- if ('\n' == buf[end])
+ for (start = end = *pos; end < BUFSZ(p); end++)
+ if ('\n' == BUF(p)[end])
break;
- advanceto(p, buf, pos, end);
- if (*pos < sz) {
- assert('\n' == buf[*pos]);
- advance(p, buf, pos);
+ advanceto(p, pos, end);
+ if (*pos < BUFSZ(p)) {
+ assert('\n' == BUF(p)[*pos]);
+ advance(p, pos);
}
- if (NULL == (ret = valuequery(p, buf, start, end)))
+ if (NULL == (ret = valuequery(p, start, end)))
return(NULL);
return(ret);
}
void
-valuelclear(struct texi *p, const char *buf, size_t sz, size_t *pos)
+valuelclear(struct texi *p, size_t *pos)
{
char **ret;
- if (NULL == (ret = valuelquery(p, buf, sz, pos)))
+ if (NULL == (ret = valuelquery(p, pos)))
return;
free(*ret);
*ret = NULL;
}
const char *
-valuellookup(struct texi *p, const char *buf, size_t sz, size_t *pos)
+valuellookup(struct texi *p, size_t *pos)
{
char **ret;
- if (NULL == (ret = valuelquery(p, buf, sz, pos)))
+ if (NULL == (ret = valuelquery(p, pos)))
return(NULL);
return(*ret);
}
@@ -1128,25 +1115,25 @@ valuellookup(struct texi *p, const char
* value had previously been unset.
*/
const char *
-valueblookup(struct texi *p, const char *buf, size_t sz, size_t *pos)
+valueblookup(struct texi *p, size_t *pos)
{
size_t start, end;
char **ret;
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
- if (*pos == sz || '{' != buf[*pos])
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
+ if (*pos == BUFSZ(p) || '{' != BUF(p)[*pos])
return(NULL);
- advance(p, buf, pos);
- for (start = end = *pos; end < sz; end++)
- if ('}' == buf[end])
+ advance(p, pos);
+ for (start = end = *pos; end < BUFSZ(p); end++)
+ if ('}' == BUF(p)[end])
break;
- advanceto(p, buf, pos, end);
- if (*pos < sz) {
- assert('}' == buf[*pos]);
- advance(p, buf, pos);
+ advanceto(p, pos, end);
+ if (*pos < BUFSZ(p)) {
+ assert('}' == BUF(p)[*pos]);
+ advance(p, pos);
}
- if (NULL == (ret = valuequery(p, buf, start, end)))
+ if (NULL == (ret = valuequery(p, start, end)))
return(NULL);
return(*ret);
}
@@ -1190,19 +1177,18 @@ valueadd(struct texi *p, char *key, char
* Ergo, textual: this doesn't interpret the arguments in any way.
*/
char **
-argparse(struct texi *p, const char *buf,
- size_t sz, size_t *pos, size_t *argsz, size_t hint)
+argparse(struct texi *p, size_t *pos, size_t *argsz, size_t hint)
{
char **args;
size_t start, end, stack;
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
args = NULL;
*argsz = 0;
- if ('{' != buf[*pos] && hint) {
+ if ('{' != BUF(p)[*pos] && hint) {
/*
* Special case: if we encounter an unbracketed argument
* and we're being invoked with non-zero arguments
@@ -1214,51 +1200,51 @@ argparse(struct texi *p, const char *buf
if (NULL == args)
texiabort(p, NULL);
start = *pos;
- while (*pos < sz) {
- if ('\n' == buf[*pos])
+ while (*pos < BUFSZ(p)) {
+ if ('\n' == BUF(p)[*pos])
break;
- advance(p, buf, pos);
+ advance(p, pos);
}
args[0] = malloc(*pos - start + 1);
- memcpy(args[0], &buf[start], *pos - start);
+ memcpy(args[0], &BUF(p)[start], *pos - start);
args[0][*pos - start] = '\0';
- if (*pos < sz && '\n' == buf[*pos])
- advance(p, buf, pos);
+ if (*pos < BUFSZ(p) && '\n' == BUF(p)[*pos])
+ advance(p, pos);
return(args);
- } else if ('{' != buf[*pos])
+ } else if ('{' != BUF(p)[*pos])
return(args);
/* Parse til the closing '}', putting into the array. */
- advance(p, buf, pos);
- while (*pos < sz) {
- while (*pos < sz && isws(buf[*pos]))
- advance(p, buf, pos);
+ advance(p, pos);
+ while (*pos < BUFSZ(p)) {
+ while (*pos < BUFSZ(p) && isws(BUF(p)[*pos]))
+ advance(p, pos);
start = *pos;
stack = 0;
- while (*pos < sz) {
+ while (*pos < BUFSZ(p)) {
/*
* According to the manual, commas within
* embedded commands are escaped.
* We keep track of embedded-ness in the "stack"
* state anyway, so this is free.
*/
- if (',' == buf[*pos] && 0 == stack && 1 != hint)
+ if (',' == BUF(p)[*pos] && 0 == stack && 1 != hint)
break;
- else if (0 == stack && '}' == buf[*pos])
+ else if (0 == stack && '}' == BUF(p)[*pos])
break;
- else if (0 != stack && '}' == buf[*pos])
+ else if (0 != stack && '}' == BUF(p)[*pos])
stack--;
- else if ('{' == buf[*pos])
+ else if ('{' == BUF(p)[*pos])
stack++;
- advance(p, buf, pos);
+ advance(p, pos);
}
if (stack)
texiwarn(p, "unterminated macro "
"in macro arguments");
- if ((end = *pos) == sz)
+ if ((end = *pos) == BUFSZ(p))
break;
/* Test for zero-length '{ }'. */
- if (start == end && '}' == buf[*pos] && 0 == *argsz)
+ if (start == end && '}' == BUF(p)[*pos] && 0 == *argsz)
break;
/* FIXME: use reallocarray. */
args = realloc
@@ -1270,17 +1256,17 @@ argparse(struct texi *p, const char *buf
if (NULL == args[*argsz])
texiabort(p, NULL);
memcpy(args[*argsz],
- &buf[start], end - start);
+ &BUF(p)[start], end - start);
args[*argsz][end - start] = '\0';
(*argsz)++;
- if ('}' == buf[*pos])
+ if ('}' == BUF(p)[*pos])
break;
- advance(p, buf, pos);
+ advance(p, pos);
}
- if (*pos == sz)
+ if (*pos == BUFSZ(p))
texierr(p, "unterminated arguments");
- assert('}' == buf[*pos]);
- advance(p, buf, pos);
+ assert('}' == BUF(p)[*pos]);
+ advance(p, pos);
return(args);
}
Index: version_0_1_2.xml
===================================================================
RCS file: /home/cvs/mdocml/texi2mdoc/version_0_1_2.xml,v
retrieving revision 1.2
retrieving revision 1.3
diff -Lversion_0_1_2.xml -Lversion_0_1_2.xml -u -p -r1.2 -r1.3
--- version_0_1_2.xml
+++ version_0_1_2.xml
@@ -9,5 +9,6 @@
Added a few macros for viewing <a href="https://gmplib.org/">GMP</a> manuals.
Also allow reading from standard input (instead of always from a file).
Consolidate mdoc(7)-escaping of opaque output.
+ Let conditionally-ignored text (e.g., <code>@ifset</code>) allow for nested conditionals as stipulate in the Texinfo manual.
</aside>
</article>
--
To unsubscribe send an email to source+unsubscribe@mdocml.bsd.lv
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2015-02-25 14:37 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-25 14:37 texi2mdoc: Completely re-write @value and @macro handling to work kristaps
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).