version 1.7, 2015/02/23 11:44:30 |
version 1.8, 2015/02/23 11:56:39 |
Line 409 texiexecmacro(struct texi *p, struct teximacro *m, |
|
Line 409 texiexecmacro(struct texi *p, struct teximacro *m, |
|
char *val; |
char *val; |
char **args; |
char **args; |
|
|
args = argparse(p, buf, sz, pos, &asz); |
args = argparse(p, buf, sz, pos, &asz, m->argsz); |
if (asz != m->argsz) |
if (asz != m->argsz) |
texiwarn(p, "invalid macro argument length"); |
texiwarn(p, "invalid macro argument length"); |
aasz = asz < m->argsz ? asz : m->argsz; |
aasz = asz < m->argsz ? asz : m->argsz; |
|
|
if (0 == aasz) { |
if (0 == aasz) { |
parseeof(p, m->value, strlen(m->value)); |
parsemembuf(p, m->value, strlen(m->value)); |
return; |
return; |
} |
} |
|
|
Line 481 texiexecmacro(struct texi *p, struct teximacro *m, |
|
Line 481 texiexecmacro(struct texi *p, struct teximacro *m, |
|
i = end; |
i = end; |
} |
} |
|
|
parseeof(p, val, strlen(val)); |
parsemembuf(p, val, strlen(val)); |
|
|
for (i = 0; i < asz; i++) |
for (i = 0; i < asz; i++) |
free(args[i]); |
free(args[i]); |
Line 839 parseeof(struct texi *p, const char *buf, size_t sz) |
|
Line 839 parseeof(struct texi *p, const char *buf, size_t sz) |
|
} |
} |
|
|
/* |
/* |
|
* 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) |
|
{ |
|
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; |
|
|
|
p->files[p->filepos - 1].line = 0; |
|
p->files[p->filepos - 1].col = 0; |
|
p->files[p->filepos - 1].name = "<macro buffer>"; |
|
|
|
parseeof(p, buf, sz); |
|
|
|
p->files[p->filepos - 1].line = svln; |
|
p->files[p->filepos - 1].col = svcol; |
|
p->files[p->filepos - 1].name = svname; |
|
} |
|
|
|
/* |
* Parse a block sequence until we have the "@end endtoken" command |
* Parse a block sequence until we have the "@end endtoken" command |
* invocation. |
* invocation. |
* This will return immediately at EOF. |
* This will return immediately at EOF. |
Line 1104 valueadd(struct texi *p, char *key, char *val) |
|
Line 1132 valueadd(struct texi *p, char *key, char *val) |
|
*/ |
*/ |
char ** |
char ** |
argparse(struct texi *p, const char *buf, |
argparse(struct texi *p, const char *buf, |
size_t sz, size_t *pos, size_t *argsz) |
size_t sz, size_t *pos, size_t *argsz, size_t hint) |
{ |
{ |
char **args; |
char **args; |
size_t start, end, stack; |
size_t start, end, stack; |
Line 1133 argparse(struct texi *p, const char *buf, |
|
Line 1161 argparse(struct texi *p, const char *buf, |
|
* We keep track of embedded-ness in the "stack" |
* We keep track of embedded-ness in the "stack" |
* state anyway, so this is free. |
* state anyway, so this is free. |
*/ |
*/ |
if (0 == stack && ',' == buf[*pos]) |
if (',' == buf[*pos] && 0 == stack && 1 != hint) |
break; |
break; |
else if (0 == stack && '}' == buf[*pos]) |
else if (0 == stack && '}' == buf[*pos]) |
break; |
break; |