tbl.c revision 1.2 1 1.1 joerg /* $Vendor-Id: tbl.c,v 1.21 2011/01/04 15:02:00 kristaps Exp $ */
2 1.1 joerg /*
3 1.1 joerg * Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps (at) bsd.lv>
4 1.1 joerg *
5 1.1 joerg * Permission to use, copy, modify, and distribute this software for any
6 1.1 joerg * purpose with or without fee is hereby granted, provided that the above
7 1.1 joerg * copyright notice and this permission notice appear in all copies.
8 1.1 joerg *
9 1.1 joerg * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 1.1 joerg * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 1.1 joerg * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 1.1 joerg * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 1.1 joerg * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 1.1 joerg * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 1.1 joerg * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 1.1 joerg */
17 1.2 nakayama #ifdef HAVE_CONFIG_H
18 1.2 nakayama #include "config.h"
19 1.2 nakayama #endif
20 1.2 nakayama
21 1.1 joerg #include <assert.h>
22 1.1 joerg #include <stdio.h>
23 1.1 joerg #include <stdlib.h>
24 1.1 joerg #include <string.h>
25 1.1 joerg #include <time.h>
26 1.1 joerg
27 1.1 joerg #include "mandoc.h"
28 1.1 joerg #include "roff.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.1 joerg tbl_alloc(int pos, int line, void *data, const mandocmsg msg)
74 1.1 joerg {
75 1.1 joerg struct tbl_node *p;
76 1.1 joerg
77 1.1 joerg p = mandoc_calloc(1, sizeof(struct tbl_node));
78 1.1 joerg p->line = line;
79 1.1 joerg p->pos = pos;
80 1.1 joerg p->data = data;
81 1.1 joerg p->msg = msg;
82 1.1 joerg p->part = TBL_PART_OPTS;
83 1.1 joerg p->opts.tab = '\t';
84 1.1 joerg p->opts.linesize = 12;
85 1.1 joerg p->opts.decimal = '.';
86 1.1 joerg return(p);
87 1.1 joerg }
88 1.1 joerg
89 1.1 joerg void
90 1.1 joerg tbl_free(struct tbl_node *p)
91 1.1 joerg {
92 1.1 joerg struct tbl_row *rp;
93 1.1 joerg struct tbl_cell *cp;
94 1.1 joerg struct tbl_span *sp;
95 1.1 joerg struct tbl_dat *dp;
96 1.1 joerg struct tbl_head *hp;
97 1.1 joerg
98 1.1 joerg while (NULL != (rp = p->first_row)) {
99 1.1 joerg p->first_row = rp->next;
100 1.1 joerg while (rp->first) {
101 1.1 joerg cp = rp->first;
102 1.1 joerg rp->first = cp->next;
103 1.1 joerg free(cp);
104 1.1 joerg }
105 1.1 joerg free(rp);
106 1.1 joerg }
107 1.1 joerg
108 1.1 joerg while (NULL != (sp = p->first_span)) {
109 1.1 joerg p->first_span = sp->next;
110 1.1 joerg while (sp->first) {
111 1.1 joerg dp = sp->first;
112 1.1 joerg sp->first = dp->next;
113 1.1 joerg if (dp->string)
114 1.1 joerg free(dp->string);
115 1.1 joerg free(dp);
116 1.1 joerg }
117 1.1 joerg free(sp);
118 1.1 joerg }
119 1.1 joerg
120 1.1 joerg while (NULL != (hp = p->first_head)) {
121 1.1 joerg p->first_head = hp->next;
122 1.1 joerg free(hp);
123 1.1 joerg }
124 1.1 joerg
125 1.1 joerg free(p);
126 1.1 joerg }
127 1.1 joerg
128 1.1 joerg void
129 1.1 joerg tbl_restart(int line, int pos, struct tbl_node *tbl)
130 1.1 joerg {
131 1.1 joerg if (TBL_PART_CDATA == tbl->part)
132 1.1 joerg TBL_MSG(tbl, MANDOCERR_TBLBLOCK, tbl->line, tbl->pos);
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.1 joerg TBL_MSG(tbl, MANDOCERR_TBLNODATA, tbl->line, tbl->pos);
140 1.1 joerg }
141 1.1 joerg
142 1.1 joerg const struct tbl_span *
143 1.1 joerg tbl_span(const struct tbl_node *tbl)
144 1.1 joerg {
145 1.1 joerg
146 1.1 joerg assert(tbl);
147 1.1 joerg return(tbl->last_span);
148 1.1 joerg }
149 1.1 joerg
150 1.1 joerg void
151 1.1 joerg tbl_end(struct tbl_node *tbl)
152 1.1 joerg {
153 1.1 joerg
154 1.1 joerg if (NULL == tbl->first_span || NULL == tbl->first_span->first)
155 1.1 joerg TBL_MSG(tbl, MANDOCERR_TBLNODATA, tbl->line, tbl->pos);
156 1.1 joerg
157 1.1 joerg if (tbl->last_span)
158 1.1 joerg tbl->last_span->flags |= TBL_SPAN_LAST;
159 1.1 joerg
160 1.1 joerg if (TBL_PART_CDATA == tbl->part)
161 1.1 joerg TBL_MSG(tbl, MANDOCERR_TBLBLOCK, tbl->line, tbl->pos);
162 1.1 joerg }
163 1.1 joerg
164