tbl.c revision 1.1 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.1 joerg #include <assert.h>
18 1.1 joerg #include <stdio.h>
19 1.1 joerg #include <stdlib.h>
20 1.1 joerg #include <string.h>
21 1.1 joerg #include <time.h>
22 1.1 joerg
23 1.1 joerg #include "mandoc.h"
24 1.1 joerg #include "roff.h"
25 1.1 joerg #include "libmandoc.h"
26 1.1 joerg #include "libroff.h"
27 1.1 joerg
28 1.1 joerg enum rofferr
29 1.1 joerg tbl_read(struct tbl_node *tbl, int ln, const char *p, int offs)
30 1.1 joerg {
31 1.1 joerg int len;
32 1.1 joerg const char *cp;
33 1.1 joerg
34 1.1 joerg cp = &p[offs];
35 1.1 joerg len = (int)strlen(cp);
36 1.1 joerg
37 1.1 joerg /*
38 1.1 joerg * If we're in the options section and we don't have a
39 1.1 joerg * terminating semicolon, assume we've moved directly into the
40 1.1 joerg * layout section. No need to report a warning: this is,
41 1.1 joerg * apparently, standard behaviour.
42 1.1 joerg */
43 1.1 joerg
44 1.1 joerg if (TBL_PART_OPTS == tbl->part && len)
45 1.1 joerg if (';' != cp[len - 1])
46 1.1 joerg tbl->part = TBL_PART_LAYOUT;
47 1.1 joerg
48 1.1 joerg /* Now process each logical section of the table. */
49 1.1 joerg
50 1.1 joerg switch (tbl->part) {
51 1.1 joerg case (TBL_PART_OPTS):
52 1.1 joerg return(tbl_option(tbl, ln, p) ? ROFF_IGN : ROFF_ERR);
53 1.1 joerg case (TBL_PART_LAYOUT):
54 1.1 joerg return(tbl_layout(tbl, ln, p) ? ROFF_IGN : ROFF_ERR);
55 1.1 joerg case (TBL_PART_CDATA):
56 1.1 joerg return(tbl_cdata(tbl, ln, p) ? ROFF_TBL : ROFF_IGN);
57 1.1 joerg default:
58 1.1 joerg break;
59 1.1 joerg }
60 1.1 joerg
61 1.1 joerg /*
62 1.1 joerg * This only returns zero if the line is empty, so we ignore it
63 1.1 joerg * and continue on.
64 1.1 joerg */
65 1.1 joerg return(tbl_data(tbl, ln, p) ? ROFF_TBL : ROFF_IGN);
66 1.1 joerg }
67 1.1 joerg
68 1.1 joerg struct tbl_node *
69 1.1 joerg tbl_alloc(int pos, int line, void *data, const mandocmsg msg)
70 1.1 joerg {
71 1.1 joerg struct tbl_node *p;
72 1.1 joerg
73 1.1 joerg p = mandoc_calloc(1, sizeof(struct tbl_node));
74 1.1 joerg p->line = line;
75 1.1 joerg p->pos = pos;
76 1.1 joerg p->data = data;
77 1.1 joerg p->msg = msg;
78 1.1 joerg p->part = TBL_PART_OPTS;
79 1.1 joerg p->opts.tab = '\t';
80 1.1 joerg p->opts.linesize = 12;
81 1.1 joerg p->opts.decimal = '.';
82 1.1 joerg return(p);
83 1.1 joerg }
84 1.1 joerg
85 1.1 joerg void
86 1.1 joerg tbl_free(struct tbl_node *p)
87 1.1 joerg {
88 1.1 joerg struct tbl_row *rp;
89 1.1 joerg struct tbl_cell *cp;
90 1.1 joerg struct tbl_span *sp;
91 1.1 joerg struct tbl_dat *dp;
92 1.1 joerg struct tbl_head *hp;
93 1.1 joerg
94 1.1 joerg while (NULL != (rp = p->first_row)) {
95 1.1 joerg p->first_row = rp->next;
96 1.1 joerg while (rp->first) {
97 1.1 joerg cp = rp->first;
98 1.1 joerg rp->first = cp->next;
99 1.1 joerg free(cp);
100 1.1 joerg }
101 1.1 joerg free(rp);
102 1.1 joerg }
103 1.1 joerg
104 1.1 joerg while (NULL != (sp = p->first_span)) {
105 1.1 joerg p->first_span = sp->next;
106 1.1 joerg while (sp->first) {
107 1.1 joerg dp = sp->first;
108 1.1 joerg sp->first = dp->next;
109 1.1 joerg if (dp->string)
110 1.1 joerg free(dp->string);
111 1.1 joerg free(dp);
112 1.1 joerg }
113 1.1 joerg free(sp);
114 1.1 joerg }
115 1.1 joerg
116 1.1 joerg while (NULL != (hp = p->first_head)) {
117 1.1 joerg p->first_head = hp->next;
118 1.1 joerg free(hp);
119 1.1 joerg }
120 1.1 joerg
121 1.1 joerg free(p);
122 1.1 joerg }
123 1.1 joerg
124 1.1 joerg void
125 1.1 joerg tbl_restart(int line, int pos, struct tbl_node *tbl)
126 1.1 joerg {
127 1.1 joerg if (TBL_PART_CDATA == tbl->part)
128 1.1 joerg TBL_MSG(tbl, MANDOCERR_TBLBLOCK, tbl->line, tbl->pos);
129 1.1 joerg
130 1.1 joerg tbl->part = TBL_PART_LAYOUT;
131 1.1 joerg tbl->line = line;
132 1.1 joerg tbl->pos = pos;
133 1.1 joerg
134 1.1 joerg if (NULL == tbl->first_span || NULL == tbl->first_span->first)
135 1.1 joerg TBL_MSG(tbl, MANDOCERR_TBLNODATA, tbl->line, tbl->pos);
136 1.1 joerg }
137 1.1 joerg
138 1.1 joerg const struct tbl_span *
139 1.1 joerg tbl_span(const struct tbl_node *tbl)
140 1.1 joerg {
141 1.1 joerg
142 1.1 joerg assert(tbl);
143 1.1 joerg return(tbl->last_span);
144 1.1 joerg }
145 1.1 joerg
146 1.1 joerg void
147 1.1 joerg tbl_end(struct tbl_node *tbl)
148 1.1 joerg {
149 1.1 joerg
150 1.1 joerg if (NULL == tbl->first_span || NULL == tbl->first_span->first)
151 1.1 joerg TBL_MSG(tbl, MANDOCERR_TBLNODATA, tbl->line, tbl->pos);
152 1.1 joerg
153 1.1 joerg if (tbl->last_span)
154 1.1 joerg tbl->last_span->flags |= TBL_SPAN_LAST;
155 1.1 joerg
156 1.1 joerg if (TBL_PART_CDATA == tbl->part)
157 1.1 joerg TBL_MSG(tbl, MANDOCERR_TBLBLOCK, tbl->line, tbl->pos);
158 1.1 joerg }
159 1.1 joerg
160