]> git.cameronkatri.com Git - mandoc.git/blob - mdoc_strings.c
mandoc.1 reflects actual use of -f option (schwarze@openbsd.org)
[mandoc.git] / mdoc_strings.c
1 /* $Id: mdoc_strings.c,v 1.7 2009/06/17 10:53:32 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 size_t
225 mdoc_macro2len(int macro)
226 {
227
228 switch (macro) {
229 case(MDOC_Ad):
230 return(12);
231 case(MDOC_Ao):
232 return(12);
233 case(MDOC_An):
234 return(12);
235 case(MDOC_Aq):
236 return(12);
237 case(MDOC_Ar):
238 return(12);
239 case(MDOC_Bo):
240 return(12);
241 case(MDOC_Bq):
242 return(12);
243 case(MDOC_Cd):
244 return(12);
245 case(MDOC_Cm):
246 return(10);
247 case(MDOC_Do):
248 return(10);
249 case(MDOC_Dq):
250 return(12);
251 case(MDOC_Dv):
252 return(12);
253 case(MDOC_Eo):
254 return(12);
255 case(MDOC_Em):
256 return(10);
257 case(MDOC_Er):
258 return(12);
259 case(MDOC_Ev):
260 return(15);
261 case(MDOC_Fa):
262 return(12);
263 case(MDOC_Fl):
264 return(10);
265 case(MDOC_Fo):
266 return(16);
267 case(MDOC_Fn):
268 return(16);
269 case(MDOC_Ic):
270 return(10);
271 case(MDOC_Li):
272 return(16);
273 case(MDOC_Ms):
274 return(6);
275 case(MDOC_Nm):
276 return(10);
277 case(MDOC_No):
278 return(12);
279 case(MDOC_Oo):
280 return(10);
281 case(MDOC_Op):
282 return(14);
283 case(MDOC_Pa):
284 return(32);
285 case(MDOC_Pf):
286 return(12);
287 case(MDOC_Po):
288 return(12);
289 case(MDOC_Pq):
290 return(12);
291 case(MDOC_Ql):
292 return(16);
293 case(MDOC_Qo):
294 return(12);
295 case(MDOC_So):
296 return(12);
297 case(MDOC_Sq):
298 return(12);
299 case(MDOC_Sy):
300 return(6);
301 case(MDOC_Sx):
302 return(16);
303 case(MDOC_Tn):
304 return(10);
305 case(MDOC_Va):
306 return(12);
307 case(MDOC_Vt):
308 return(12);
309 case(MDOC_Xr):
310 return(10);
311 default:
312 break;
313 };
314 return(0);
315 }