tbl.c revision 1.4.2.1 1 1.4.2.1 yamt /* Id: tbl.c,v 1.27 2013/05/31 22:08:09 schwarze Exp */
2 1.1 joerg /*
3 1.3 joerg * Copyright (c) 2009, 2010, 2011 Kristaps Dzonsons <kristaps (at) bsd.lv>
4 1.3 joerg * Copyright (c) 2011 Ingo Schwarze <schwarze (at) openbsd.org>
5 1.1 joerg *
6 1.1 joerg * Permission to use, copy, modify, and distribute this software for any
7 1.1 joerg * purpose with or without fee is hereby granted, provided that the above
8 1.1 joerg * copyright notice and this permission notice appear in all copies.
9 1.1 joerg *
10 1.1 joerg * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 1.1 joerg * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 1.1 joerg * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 1.1 joerg * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 1.1 joerg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 1.1 joerg * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 1.1 joerg * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 1.1 joerg */
18 1.2 nakayama #ifdef HAVE_CONFIG_H
19 1.2 nakayama #include "config.h"
20 1.2 nakayama #endif
21 1.2 nakayama
22 1.1 joerg #include <assert.h>
23 1.1 joerg #include <stdio.h>
24 1.1 joerg #include <stdlib.h>
25 1.1 joerg #include <string.h>
26 1.1 joerg #include <time.h>
27 1.1 joerg
28 1.1 joerg #include "mandoc.h"
29 1.1 joerg #include "libmandoc.h"
30 1.1 joerg #include "libroff.h"
31 1.1 joerg
32 1.1 joerg enum rofferr
33 1.1 joerg tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs)
34 1.1 joerg {
35 1.1 joerg int len;
36 1.1 joerg const char *cp;
37 1.1 joerg
38 1.1 joerg cp = &p[offs];
39 1.1 joerg len = (int)strlen(cp);
40 1.1 joerg
41 1.1 joerg /*
42 1.1 joerg * If we're in the options section and we don't have a
43 1.1 joerg * terminating semicolon, assume we've moved directly into the
44 1.1 joerg * layout section. No need to report a warning: this is,
45 1.1 joerg * apparently, standard behaviour.
46 1.1 joerg */
47 1.1 joerg
48 1.1 joerg if (TBL_PART_OPTS == tbl->part && len)
49 1.1 joerg if (';' != cp[len - 1])
50 1.1 joerg tbl->part = TBL_PART_LAYOUT;
51 1.1 joerg
52 1.1 joerg /* Now process each logical section of the table. */
53 1.1 joerg
54 1.1 joerg switch (tbl->part) {
55 1.1 joerg case (TBL_PART_OPTS):
56 1.1 joerg return(tbl_option(tbl, ln, p) ? ROFF_IGN : ROFF_ERR);
57 1.1 joerg case (TBL_PART_LAYOUT):
58 1.1 joerg return(tbl_layout(tbl, ln, p) ? ROFF_IGN : ROFF_ERR);
59 1.1 joerg case (TBL_PART_CDATA):
60 1.1 joerg return(tbl_cdata(tbl, ln, p) ? ROFF_TBL : ROFF_IGN);
61 1.1 joerg default:
62 1.1 joerg break;
63 1.1 joerg }
64 1.1 joerg
65 1.1 joerg /*
66 1.1 joerg * This only returns zero if the line is empty, so we ignore it
67 1.1 joerg * and continue on.
68 1.1 joerg */
69 1.1 joerg return(tbl_data(tbl, ln, p) ? ROFF_TBL : ROFF_IGN);
70 1.1 joerg }
71 1.1 joerg
72 1.1 joerg struct tbl_node *
73 1.3 joerg tbl_alloc(int pos, int line, struct mparse *parse)
74 1.1 joerg {
75 1.4.2.1 yamt struct tbl_node *tbl;
76 1.1 joerg
77 1.4.2.1 yamt tbl = mandoc_calloc(1, sizeof(struct tbl_node));
78 1.4.2.1 yamt tbl->line = line;
79 1.4.2.1 yamt tbl->pos = pos;
80 1.4.2.1 yamt tbl->parse = parse;
81 1.4.2.1 yamt tbl->part = TBL_PART_OPTS;
82 1.4.2.1 yamt tbl->opts.tab = '\t';
83 1.4.2.1 yamt tbl->opts.linesize = 12;
84 1.4.2.1 yamt tbl->opts.decimal = '.';
85 1.4.2.1 yamt return(tbl);
86 1.1 joerg }
87 1.1 joerg
88 1.1 joerg void
89 1.4.2.1 yamt tbl_free(struct tbl_node *tbl)
90 1.1 joerg {
91 1.1 joerg struct tbl_row *rp;
92 1.1 joerg struct tbl_cell *cp;
93 1.1 joerg struct tbl_span *sp;
94 1.1 joerg struct tbl_dat *dp;
95 1.1 joerg struct tbl_head *hp;
96 1.1 joerg
97 1.4.2.1 yamt while (NULL != (rp = tbl->first_row)) {
98 1.4.2.1 yamt tbl->first_row = rp->next;
99 1.1 joerg while (rp->first) {
100 1.1 joerg cp = rp->first;
101 1.1 joerg rp->first = cp->next;
102 1.1 joerg free(cp);
103 1.1 joerg }
104 1.1 joerg free(rp);
105 1.1 joerg }
106 1.1 joerg
107 1.4.2.1 yamt while (NULL != (sp = tbl->first_span)) {
108 1.4.2.1 yamt tbl->first_span = sp->next;
109 1.1 joerg while (sp->first) {
110 1.1 joerg dp = sp->first;
111 1.1 joerg sp->first = dp->next;
112 1.1 joerg if (dp->string)
113 1.1 joerg free(dp->string);
114 1.1 joerg free(dp);
115 1.1 joerg }
116 1.1 joerg free(sp);
117 1.1 joerg }
118 1.1 joerg
119 1.4.2.1 yamt while (NULL != (hp = tbl->first_head)) {
120 1.4.2.1 yamt tbl->first_head = hp->next;
121 1.1 joerg free(hp);
122 1.1 joerg }
123 1.1 joerg
124 1.4.2.1 yamt free(tbl);
125 1.1 joerg }
126 1.1 joerg
127 1.1 joerg void
128 1.1 joerg tbl_restart(int line, int pos, struct tbl_node *tbl)
129 1.1 joerg {
130 1.1 joerg if (TBL_PART_CDATA == tbl->part)
131 1.3 joerg mandoc_msg(MANDOCERR_TBLBLOCK, tbl->parse,
132 1.3 joerg tbl->line, tbl->pos, NULL);
133 1.1 joerg
134 1.1 joerg tbl->part = TBL_PART_LAYOUT;
135 1.1 joerg tbl->line = line;
136 1.1 joerg tbl->pos = pos;
137 1.1 joerg
138 1.1 joerg if (NULL == tbl->first_span || NULL == tbl->first_span->first)
139 1.3 joerg mandoc_msg(MANDOCERR_TBLNODATA, tbl->parse,
140 1.3 joerg tbl->line, tbl->pos, NULL);
141 1.1 joerg }
142 1.1 joerg
143 1.1 joerg const struct tbl_span *
144 1.3 joerg tbl_span(struct tbl_node *tbl)
145 1.1 joerg {
146 1.3 joerg struct tbl_span *span;
147 1.1 joerg
148 1.1 joerg assert(tbl);
149 1.3 joerg span = tbl->current_span ? tbl->current_span->next
150 1.3 joerg : tbl->first_span;
151 1.3 joerg if (span)
152 1.3 joerg tbl->current_span = span;
153 1.3 joerg return(span);
154 1.1 joerg }
155 1.1 joerg
156 1.1 joerg void
157 1.4 joerg tbl_end(struct tbl_node **tblp)
158 1.1 joerg {
159 1.4 joerg struct tbl_node *tbl;
160 1.4 joerg
161 1.4 joerg tbl = *tblp;
162 1.4 joerg *tblp = NULL;
163 1.1 joerg
164 1.1 joerg if (NULL == tbl->first_span || NULL == tbl->first_span->first)
165 1.3 joerg mandoc_msg(MANDOCERR_TBLNODATA, tbl->parse,
166 1.3 joerg tbl->line, tbl->pos, NULL);
167 1.1 joerg
168 1.1 joerg if (tbl->last_span)
169 1.1 joerg tbl->last_span->flags |= TBL_SPAN_LAST;
170 1.1 joerg
171 1.1 joerg if (TBL_PART_CDATA == tbl->part)
172 1.3 joerg mandoc_msg(MANDOCERR_TBLBLOCK, tbl->parse,
173 1.3 joerg tbl->line, tbl->pos, NULL);
174 1.1 joerg }
175 1.1 joerg
176