version 1.44, 2015/02/24 21:06:52 |
version 1.45, 2015/02/25 10:01:54 |
Line 537 domacro(struct texi *p, enum texicmd cmd, |
|
Line 537 domacro(struct texi *p, enum texicmd cmd, |
|
start = *pos; |
start = *pos; |
endtok = "\n@end macro\n"; |
endtok = "\n@end macro\n"; |
endtoksz = strlen(endtok); |
endtoksz = strlen(endtok); |
blk = memmem(&buf[start], sz, endtok, endtoksz); |
blk = memmem(&buf[start], sz - start, endtok, endtoksz); |
if (NULL == blk) |
if (NULL == blk) |
texierr(p, "unterminated macro body"); |
texierr(p, "unterminated macro body"); |
while (&buf[*pos] != blk) |
while (&buf[*pos] != blk) |
|
|
doignblock(struct texi *p, enum texicmd cmd, |
doignblock(struct texi *p, enum texicmd cmd, |
const char *buf, size_t sz, size_t *pos) |
const char *buf, size_t sz, size_t *pos) |
{ |
{ |
char end[32]; |
char end[32], start[32]; |
const char *term; |
const char *endt, *startt; |
size_t endsz, endpos; |
size_t esz, ssz, newpos, stack; |
|
|
/* |
/* |
* We want to completely ignore everything in these blocks, so |
* FIXME: this is cheating. |
* simply jump to the @end block. |
* These tokens are supposed to begin on a newline. |
|
* However, if we do that, then we would need to check within |
|
* the loop for trailer (or leading, as the case may be) |
|
* newline, and that's just a bit too complicated right now. |
|
* This is becasue |
|
* @ifset BAR |
|
* @ifset FOO |
|
* @end ifset |
|
* @end ifset |
|
* won't work right now: we'd read after the first "@end ifset" |
|
* to the next line, then look for the next line after that. |
*/ |
*/ |
endsz = snprintf(end, sizeof(end), |
ssz = snprintf(start, sizeof(start), |
"\n@end %s\n", texitoks[cmd].tok); |
"@%s", texitoks[cmd].tok); |
assert(endsz < sizeof(end)); |
assert(ssz < sizeof(start)); |
|
esz = snprintf(end, sizeof(end), |
|
"@end %s\n", texitoks[cmd].tok); |
|
assert(esz < sizeof(end)); |
|
stack = 1; |
|
|
/* |
/* |
* Look up where our end token occurs. |
* Here we look for the end token "end" somewhere in the file in |
* Set our end position based on the relative offset of that |
* front of us. |
* from our current position, or the EOF if we don't have a |
* It's not that easy, of course: if we have a nested block, |
* proper ending point. |
* then there'll be an "end" token of the same kind between us. |
|
* Thus, we keep track of scopes for matching "end" blocks. |
*/ |
*/ |
term = memmem(&buf[*pos], sz, end, endsz); |
while (stack > 0 && *pos < sz) { |
endpos = NULL == term ? sz : |
if (stack > 10) |
*pos + (size_t)(term - &buf[*pos]); |
abort(); |
assert(endpos <= sz); |
endt = memmem(&buf[*pos], sz - *pos, end, esz); |
while (*pos < endpos) |
startt = memmem(&buf[*pos], sz - *pos, start, ssz); |
advance(p, buf, pos); |
if (NULL == endt) { |
|
texiwarn(p, "unterminated \"%s\" " |
|
"block", texitoks[cmd].tok); |
|
*pos = sz; |
|
break; |
|
} |
|
|
/* Only do this if we're not already at the end. */ |
newpos = *pos; |
if (endpos < sz) |
if (NULL == startt || startt > endt) { |
advanceto(p, buf, pos, endpos + endsz); |
newpos += esz + (size_t)(endt - &buf[*pos]); |
|
stack--; |
|
} else { |
|
newpos += ssz + (size_t)(startt - &buf[*pos]); |
|
stack++; |
|
} |
|
|
|
assert(newpos <= sz); |
|
while (*pos < newpos) |
|
advance(p, buf, pos); |
|
} |
} |
} |
|
|
static void |
static void |
Line 705 doverbatim(struct texi *p, enum texicmd cmd, |
|
Line 735 doverbatim(struct texi *p, enum texicmd cmd, |
|
const char *end, *term; |
const char *end, *term; |
size_t endsz, endpos; |
size_t endsz, endpos; |
|
|
advanceeoln(p, buf, sz, pos, 1); |
/* We read from the @verbatim\n newline inclusive! */ |
|
|
/* We end at exactly this token. */ |
|
end = "\n@end verbatim\n"; |
end = "\n@end verbatim\n"; |
endsz = strlen(end); |
endsz = strlen(end); |
|
advanceeoln(p, buf, sz, pos, 0); |
|
if (*pos == sz) { |
|
texiwarn(p, "unexpected end of file"); |
|
return; |
|
} |
|
|
/* |
term = memmem(&buf[*pos], sz - *pos, end, endsz); |
* Look up where our end token occurs. |
if (NULL == term) { |
* Set our end position based on the relative offset of that |
texiwarn(p, "unterminated verbatim block"); |
* from our current position. |
endpos = sz; |
*/ |
} else |
term = memmem(&buf[*pos], sz, end, endsz); |
endpos = *pos + (size_t)(term - &buf[*pos]); |
endpos = NULL == term ? sz : |
|
*pos + (size_t)(term - &buf[*pos]); |
|
|
|
teximacro(p, "Bd -literal -offset indent"); |
|
assert(endpos <= sz); |
assert(endpos <= sz); |
|
assert('\n' == buf[*pos]); |
|
advance(p, buf, pos); |
|
teximacro(p, "Bd -literal -offset indent"); |
while (*pos < endpos) { |
while (*pos < endpos) { |
texiputchar(p, buf[*pos]); |
texiputchar(p, buf[*pos]); |
advance(p, buf, pos); |
advance(p, buf, pos); |
} |
} |
teximacro(p, "Ed"); |
teximacro(p, "Ed"); |
advanceto(p, buf, pos, endpos + endsz); |
if (*pos < sz) |
|
advanceto(p, buf, pos, endpos + endsz); |
} |
} |
|
|
static void |
static void |