]> git.cameronkatri.com Git - mandoc.git/blob - mdoc_strings.c
Fixed STRUCTURE repeat (schwarze@openbsd.org).
[mandoc.git] / mdoc_strings.c
1 /* $Id: mdoc_strings.c,v 1.8 2009/06/22 12:22:35 kristaps Exp $ */
2 /*
3 * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
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 #include <sys/types.h>
18
19 #include <assert.h>
20 #include <ctype.h>
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24
25 #include "libmdoc.h"
26
27 /* FIXME: this file is poorly named. */
28
29 struct mdoc_secname {
30 const char *name; /* Name of section. */
31 enum mdoc_sec sec; /* Corresponding section. */
32 };
33
34 #define SECNAME_MAX (18)
35
36 static const struct mdoc_secname secnames[SECNAME_MAX] = {
37 { "NAME", SEC_NAME },
38 { "LIBRARY", SEC_LIBRARY },
39 { "SYNOPSIS", SEC_SYNOPSIS },
40 { "DESCRIPTION", SEC_DESCRIPTION },
41 { "IMPLEMENTATION NOTES", SEC_IMPLEMENTATION },
42 { "RETURN VALUES", SEC_RETURN_VALUES },
43 { "ENVIRONMENT", SEC_ENVIRONMENT },
44 { "FILES", SEC_FILES },
45 { "EXAMPLES", SEC_EXAMPLES },
46 { "DIAGNOSTICS", SEC_DIAGNOSTICS },
47 { "COMPATIBILITY", SEC_COMPATIBILITY },
48 { "ERRORS", SEC_ERRORS },
49 { "SEE ALSO", SEC_SEE_ALSO },
50 { "STANDARDS", SEC_STANDARDS },
51 { "HISTORY", SEC_HISTORY },
52 { "AUTHORS", SEC_AUTHORS },
53 { "CAVEATS", SEC_CAVEATS },
54 { "BUGS", SEC_BUGS },
55 };
56
57 #ifdef __linux__
58 extern char *strptime(const char *, const char *, struct tm *);
59 #endif
60
61
62 size_t
63 mdoc_isescape(const char *p)
64 {
65 size_t c;
66
67 if ('\\' != *p++)
68 return(0);
69
70 switch (*p) {
71 case ('\\'):
72 /* FALLTHROUGH */
73 case ('\''):
74 /* FALLTHROUGH */
75 case ('`'):
76 /* FALLTHROUGH */
77 case ('q'):
78 /* FALLTHROUGH */
79 case ('-'):
80 /* FALLTHROUGH */
81 case ('~'):
82 /* FALLTHROUGH */
83 case ('^'):
84 /* FALLTHROUGH */
85 case ('%'):
86 /* FALLTHROUGH */
87 case ('0'):
88 /* FALLTHROUGH */
89 case (' '):
90 /* FALLTHROUGH */
91 case ('|'):
92 /* FALLTHROUGH */
93 case ('&'):
94 /* FALLTHROUGH */
95 case ('.'):
96 /* FALLTHROUGH */
97 case (':'):
98 /* FALLTHROUGH */
99 case ('e'):
100 return(2);
101 case ('*'):
102 if (0 == *++p || ! isgraph((u_char)*p))
103 return(0);
104 switch (*p) {
105 case ('('):
106 if (0 == *++p || ! isgraph((u_char)*p))
107 return(0);
108 return(4);
109 case ('['):
110 for (c = 3, p++; *p && ']' != *p; p++, c++)
111 if ( ! isgraph((u_char)*p))
112 break;
113 return(*p == ']' ? c : 0);
114 default:
115 break;
116 }
117 return(3);
118 case ('('):
119 if (0 == *++p || ! isgraph((u_char)*p))
120 return(0);
121 if (0 == *++p || ! isgraph((u_char)*p))
122 return(0);
123 return(4);
124 case ('['):
125 break;
126 default:
127 return(0);
128 }
129
130 for (c = 3, p++; *p && ']' != *p; p++, c++)
131 if ( ! isgraph((u_char)*p))
132 break;
133
134 return(*p == ']' ? c : 0);
135 }
136
137
138 int
139 mdoc_iscdelim(char p)
140 {
141
142 switch (p) {
143 case('|'):
144 /* FALLTHROUGH */
145 case('.'):
146 /* FALLTHROUGH */
147 case(','):
148 /* FALLTHROUGH */
149 case(';'):
150 /* FALLTHROUGH */
151 case(':'):
152 /* FALLTHROUGH */
153 case('?'):
154 /* FALLTHROUGH */
155 case('!'):
156 /* FALLTHROUGH */
157 case('('):
158 /* FALLTHROUGH */
159 case(')'):
160 /* FALLTHROUGH */
161 case('['):
162 /* FALLTHROUGH */
163 case(']'):
164 /* FALLTHROUGH */
165 case('{'):
166 /* FALLTHROUGH */
167 case('}'):
168 return(1);
169 default:
170 break;
171 }
172
173 return(0);
174 }
175
176
177 int
178 mdoc_isdelim(const char *p)
179 {
180
181 if (0 == *p)
182 return(0);
183 if (0 != *(p + 1))
184 return(0);
185 return(mdoc_iscdelim(*p));
186 }
187
188
189 enum mdoc_sec
190 mdoc_atosec(const char *p)
191 {
192 int i;
193
194 for (i = 0; i < SECNAME_MAX; i++)
195 if (0 == strcmp(p, secnames[i].name))
196 return(secnames[i].sec);
197
198 return(SEC_CUSTOM);
199 }
200
201
202 time_t
203 mdoc_atotime(const char *p)
204 {
205 struct tm tm;
206 char *pp;
207
208 bzero(&tm, sizeof(struct tm));
209
210 if (0 == strcmp(p, "$" "Mdocdate$"))
211 return(time(NULL));
212 if ((pp = strptime(p, "$" "Mdocdate: %b %d %Y $", &tm)) && 0 == *pp)
213 return(mktime(&tm));
214 /* XXX - this matches "June 1999", which is wrong. */
215 if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
216 return(mktime(&tm));
217 if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
218 return(mktime(&tm));
219
220 return(0);
221 }
222
223
224 /* FIXME: move this into an editable .in file. */
225 size_t
226 mdoc_macro2len(int macro)
227 {
228
229 switch (macro) {
230 case(MDOC_Ad):
231 return(12);
232 case(MDOC_Ao):
233 return(12);
234 case(MDOC_An):
235 return(12);
236 case(MDOC_Aq):
237 return(12);
238 case(MDOC_Ar):
239 return(12);
240 case(MDOC_Bo):
241 return(12);
242 case(MDOC_Bq):
243 return(12);
244 case(MDOC_Cd):
245 return(12);
246 case(MDOC_Cm):
247 return(10);
248 case(MDOC_Do):
249 return(10);
250 case(MDOC_Dq):
251 return(12);
252 case(MDOC_Dv):
253 return(12);
254 case(MDOC_Eo):
255 return(12);
256 case(MDOC_Em):
257 return(10);
258 case(MDOC_Er):
259 return(17);
260 case(MDOC_Ev):
261 return(15);
262 case(MDOC_Fa):
263 return(12);
264 case(MDOC_Fl):
265 return(10);
266 case(MDOC_Fo):
267 return(16);
268 case(MDOC_Fn):
269 return(16);
270 case(MDOC_Ic):
271 return(10);
272 case(MDOC_Li):
273 return(16);
274 case(MDOC_Ms):
275 return(6);
276 case(MDOC_Nm):
277 return(10);
278 case(MDOC_No):
279 return(12);
280 case(MDOC_Oo):
281 return(10);
282 case(MDOC_Op):
283 return(14);
284 case(MDOC_Pa):
285 return(32);
286 case(MDOC_Pf):
287 return(12);
288 case(MDOC_Po):
289 return(12);
290 case(MDOC_Pq):
291 return(12);
292 case(MDOC_Ql):
293 return(16);
294 case(MDOC_Qo):
295 return(12);
296 case(MDOC_So):
297 return(12);
298 case(MDOC_Sq):
299 return(12);
300 case(MDOC_Sy):
301 return(6);
302 case(MDOC_Sx):
303 return(16);
304 case(MDOC_Tn):
305 return(10);
306 case(MDOC_Va):
307 return(12);
308 case(MDOC_Vt):
309 return(12);
310 case(MDOC_Xr):
311 return(10);
312 default:
313 break;
314 };
315 return(0);
316 }