version 1.63, 2017/06/20 17:24:35 |
version 1.64, 2017/06/21 18:04:34 |
|
|
/* $Id$ */ |
/* $Id$ */ |
/* |
/* |
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2011, 2014 Kristaps Dzonsons <kristaps@bsd.lv> |
* Copyright (c) 2014, 2015 Ingo Schwarze <schwarze@openbsd.org> |
* Copyright (c) 2014, 2015, 2017 Ingo Schwarze <schwarze@openbsd.org> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
* purpose with or without fee is hereby granted, provided that the above |
* purpose with or without fee is hereby granted, provided that the above |
|
|
EQN_TOK_TDEFINE, |
EQN_TOK_TDEFINE, |
EQN_TOK_NDEFINE, |
EQN_TOK_NDEFINE, |
EQN_TOK_UNDEF, |
EQN_TOK_UNDEF, |
EQN_TOK_EOF, |
|
EQN_TOK_ABOVE, |
EQN_TOK_ABOVE, |
EQN_TOK__MAX |
EQN_TOK__MAX, |
|
EQN_TOK_FUNC, |
|
EQN_TOK_EOF |
}; |
}; |
|
|
static const char *eqn_toks[EQN_TOK__MAX] = { |
static const char *eqn_toks[EQN_TOK__MAX] = { |
Line 130 static const char *eqn_toks[EQN_TOK__MAX] = { |
|
Line 131 static const char *eqn_toks[EQN_TOK__MAX] = { |
|
"tdefine", /* EQN_TOK_TDEFINE */ |
"tdefine", /* EQN_TOK_TDEFINE */ |
"ndefine", /* EQN_TOK_NDEFINE */ |
"ndefine", /* EQN_TOK_NDEFINE */ |
"undef", /* EQN_TOK_UNDEF */ |
"undef", /* EQN_TOK_UNDEF */ |
NULL, /* EQN_TOK_EOF */ |
|
"above", /* EQN_TOK_ABOVE */ |
"above", /* EQN_TOK_ABOVE */ |
}; |
}; |
|
|
|
static const char *const eqn_func[] = { |
|
"acos", "acsc", "and", "arc", "asec", "asin", "atan", |
|
"cos", "cosh", "coth", "csc", "det", "exp", "for", |
|
"if", "lim", "ln", "log", "max", "min", |
|
"sec", "sin", "sinh", "tan", "tanh", "Im", "Re", |
|
}; |
|
|
enum eqn_symt { |
enum eqn_symt { |
EQNSYM_alpha, |
EQNSYM_alpha, |
EQNSYM_beta, |
EQNSYM_beta, |
Line 498 eqn_tok_parse(struct eqn_node *ep, char **p) |
|
Line 505 eqn_tok_parse(struct eqn_node *ep, char **p) |
|
size_t i, sz; |
size_t i, sz; |
int quoted; |
int quoted; |
|
|
if (NULL != p) |
if (p != NULL) |
*p = NULL; |
*p = NULL; |
|
|
quoted = ep->data[ep->cur] == '"'; |
quoted = ep->data[ep->cur] == '"'; |
|
|
if (NULL == (start = eqn_nexttok(ep, &sz))) |
if ((start = eqn_nexttok(ep, &sz)) == NULL) |
return EQN_TOK_EOF; |
return EQN_TOK_EOF; |
|
|
if (quoted) { |
if (quoted) { |
Line 512 eqn_tok_parse(struct eqn_node *ep, char **p) |
|
Line 519 eqn_tok_parse(struct eqn_node *ep, char **p) |
|
return EQN_TOK__MAX; |
return EQN_TOK__MAX; |
} |
} |
|
|
for (i = 0; i < EQN_TOK__MAX; i++) { |
for (i = 0; i < EQN_TOK__MAX; i++) |
if (NULL == eqn_toks[i]) |
|
continue; |
|
if (STRNEQ(start, sz, eqn_toks[i], strlen(eqn_toks[i]))) |
if (STRNEQ(start, sz, eqn_toks[i], strlen(eqn_toks[i]))) |
break; |
return i; |
} |
|
|
|
if (i == EQN_TOK__MAX && NULL != p) |
if (p != NULL) |
*p = mandoc_strndup(start, sz); |
*p = mandoc_strndup(start, sz); |
|
|
return i; |
for (i = 0; i < sizeof(eqn_func)/sizeof(*eqn_func); i++) |
|
if (STRNEQ(start, sz, eqn_func[i], strlen(eqn_func[i]))) |
|
return EQN_TOK_FUNC; |
|
|
|
return EQN_TOK__MAX; |
} |
} |
|
|
static void |
static void |
|
|
* TODO: make sure we're not in an open subexpression. |
* TODO: make sure we're not in an open subexpression. |
*/ |
*/ |
return ROFF_EQN; |
return ROFF_EQN; |
default: |
case EQN_TOK_FUNC: |
assert(tok == EQN_TOK__MAX); |
case EQN_TOK__MAX: |
assert(NULL != p); |
assert(p != NULL); |
/* |
/* |
* If we already have something in the stack and we're |
* If we already have something in the stack and we're |
* in an expression, then rewind til we're not any more. |
* in an expression, then rewind til we're not any more. |
*/ |
*/ |
while (parent->args == parent->expectargs) |
while (parent->args == parent->expectargs) |
parent = parent->parent; |
parent = parent->parent; |
|
if (tok == EQN_TOK_FUNC) { |
|
for (cur = parent; cur != NULL; cur = cur->parent) |
|
if (cur->font != EQNFONT_NONE) |
|
break; |
|
if (cur == NULL || cur->font != EQNFONT_ROMAN) { |
|
parent = eqn_box_alloc(ep, parent); |
|
parent->type = EQN_LISTONE; |
|
parent->font = EQNFONT_ROMAN; |
|
parent->expectargs = 1; |
|
} |
|
} |
cur = eqn_box_alloc(ep, parent); |
cur = eqn_box_alloc(ep, parent); |
cur->type = EQN_TEXT; |
cur->type = EQN_TEXT; |
for (i = 0; i < EQNSYM__MAX; i++) |
for (i = 0; i < EQNSYM__MAX; i++) |
|
|
parent->args == parent->expectargs) |
parent->args == parent->expectargs) |
parent = parent->parent; |
parent = parent->parent; |
break; |
break; |
|
default: |
|
abort(); |
} |
} |
goto next_tok; |
goto next_tok; |
} |
} |