Annotation of mandoc/eqn.c, Revision 1.6
1.6 ! kristaps 1: /* $Id: eqn.c,v 1.5 2011/07/12 21:32:43 kristaps Exp $ */
1.1 kristaps 2: /*
3: * Copyright (c) 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
17: #ifdef HAVE_CONFIG_H
18: #include "config.h"
19: #endif
20:
21: #include <assert.h>
22: #include <stdio.h>
23: #include <stdlib.h>
24: #include <string.h>
25: #include <time.h>
26:
27: #include "mandoc.h"
28: #include "libmandoc.h"
29: #include "libroff.h"
30:
1.6 ! kristaps 31: static const char *eqn_nexttok(struct mparse *, int, int,
! 32: const char **, size_t *);
! 33:
1.1 kristaps 34: /* ARGSUSED */
35: enum rofferr
1.6 ! kristaps 36: eqn_read(struct eqn_node **epp, int ln,
! 37: const char *p, int pos, int *offs)
1.1 kristaps 38: {
1.6 ! kristaps 39: size_t sz;
! 40: struct eqn_node *ep;
! 41: const char *start, *end;
! 42: int i;
1.1 kristaps 43:
44: if (0 == strcmp(p, ".EN")) {
45: *epp = NULL;
46: return(ROFF_EQN);
47: }
48:
49: ep = *epp;
1.6 ! kristaps 50: end = p + pos;
! 51: start = eqn_nexttok(ep->parse, ln, pos, &end, &sz);
! 52:
! 53: if (NULL == start)
! 54: return(ROFF_IGN);
! 55:
! 56: if (6 == sz && 0 == strncmp("define", start, 6)) {
! 57: /*
! 58: * TODO: warn if key is quoted: groff doesn't seem to
! 59: * like this (I don't know why).
! 60: */
! 61: start = eqn_nexttok(ep->parse, ln, pos, &end, &sz);
! 62: for (i = 0; i < (int)ep->defsz; i++) {
! 63: if (ep->defs[i].keysz != sz)
! 64: continue;
! 65: if (0 == strncmp(ep->defs[i].key, start, sz))
! 66: break;
! 67: }
! 68:
! 69: /*
! 70: * TODO: merge this code with roff_getstr().
! 71: */
! 72:
! 73: if (i == (int)ep->defsz) {
! 74: ep->defsz++;
! 75: ep->defs = mandoc_realloc
! 76: (ep->defs, ep->defsz *
! 77: sizeof(struct eqn_def));
! 78: ep->defs[i].keysz = sz;
! 79: ep->defs[i].key = mandoc_malloc(sz + 1);
! 80: memcpy(ep->defs[i].key, start, sz);
! 81: ep->defs[i].key[(int)sz] = '\0';
! 82: ep->defs[i].val = NULL;
! 83: ep->defs[i].valsz = 0;
! 84: }
! 85:
! 86: start = eqn_nexttok(ep->parse, ln, pos, &end, &sz);
! 87:
! 88: ep->defs[i].valsz = sz;
! 89: ep->defs[i].val = mandoc_realloc
! 90: (ep->defs[i].val, sz + 1);
! 91: memcpy(ep->defs[i].val, start, sz);
! 92: ep->defs[i].val[(int)sz] = '\0';
! 93:
! 94: if ('\0' == *end)
! 95: return(ROFF_IGN);
! 96:
! 97: *offs = end - (p + pos);
! 98: assert(*offs > 0);
! 99:
! 100: return(ROFF_RERUN);
! 101: } else
! 102: end = p + pos;
! 103:
! 104: if (0 == (sz = strlen(end)))
! 105: return(ROFF_IGN);
1.1 kristaps 106:
107: ep->eqn.data = mandoc_realloc(ep->eqn.data, ep->eqn.sz + sz + 1);
108: if (0 == ep->eqn.sz)
109: *ep->eqn.data = '\0';
110:
111: ep->eqn.sz += sz;
1.6 ! kristaps 112: strlcat(ep->eqn.data, end, ep->eqn.sz + 1);
1.1 kristaps 113: return(ROFF_IGN);
114: }
115:
116: struct eqn_node *
1.5 kristaps 117: eqn_alloc(int pos, int line, struct mparse *parse)
1.1 kristaps 118: {
119: struct eqn_node *p;
120:
121: p = mandoc_calloc(1, sizeof(struct eqn_node));
1.5 kristaps 122: p->parse = parse;
1.2 kristaps 123: p->eqn.line = line;
124: p->eqn.pos = pos;
1.1 kristaps 125:
126: return(p);
127: }
128:
1.3 kristaps 129: /* ARGSUSED */
1.1 kristaps 130: void
131: eqn_end(struct eqn_node *e)
132: {
133:
134: /* Nothing to do. */
135: }
136:
137: void
138: eqn_free(struct eqn_node *p)
139: {
1.6 ! kristaps 140: int i;
1.1 kristaps 141:
142: free(p->eqn.data);
1.6 ! kristaps 143:
! 144: for (i = 0; i < (int)p->defsz; i++) {
! 145: free(p->defs[i].key);
! 146: free(p->defs[i].val);
! 147: }
! 148:
! 149: free(p->defs);
1.1 kristaps 150: free(p);
1.6 ! kristaps 151: }
! 152:
! 153: static const char *
! 154: eqn_nexttok(struct mparse *mp, int ln, int pos,
! 155: const char **next, size_t *sz)
! 156: {
! 157: const char *start;
! 158: int q;
! 159:
! 160: start = *next;
! 161: q = 0;
! 162:
! 163: if ('\0' == *start)
! 164: return(NULL);
! 165:
! 166: if ('"' == *start) {
! 167: start++;
! 168: q = 1;
! 169: }
! 170:
! 171: *next = q ? strchr(start, '"') : strchr(start, ' ');
! 172:
! 173: if (NULL != *next) {
! 174: *sz = (size_t)(*next - start);
! 175: if (q)
! 176: (*next)++;
! 177: while (' ' == **next)
! 178: (*next)++;
! 179: } else {
! 180: if (q)
! 181: mandoc_msg(MANDOCERR_BADQUOTE,
! 182: mp, ln, pos, NULL);
! 183: *next = strchr(start, '\0');
! 184: *sz = (size_t)(*next - start);
! 185: }
! 186:
! 187: return(start);
1.1 kristaps 188: }
CVSweb