]> git.cameronkatri.com Git - mandoc.git/blob - strings.c
Added canonical mdoc.7.
[mandoc.git] / strings.c
1 /* $Id: strings.c,v 1.28 2009/03/13 07:46:10 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
7 * above copyright notice and this permission notice appear in all
8 * copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
18 */
19 #include <sys/types.h>
20
21 #include <assert.h>
22 #include <ctype.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26
27 #include "private.h"
28
29 /*
30 * Various string-literal operations: converting scalars to and from
31 * strings, etc.
32 */
33
34 struct mdoc_secname {
35 const char *name;
36 int flag;
37 #define MSECNAME_META (1 << 0)
38 };
39
40 /* Section names corresponding to mdoc_sec. */
41
42 static const struct mdoc_secname secnames[] = {
43 { "PROLOGUE", MSECNAME_META },
44 { "BODY", MSECNAME_META },
45 { "NAME", 0 },
46 { "LIBRARY", 0 },
47 { "SYNOPSIS", 0 },
48 { "DESCRIPTION", 0 },
49 { "IMPLEMENTATION NOTES", 0 },
50 { "RETURN VALUES", 0 },
51 { "ENVIRONMENT", 0 },
52 { "FILES", 0 },
53 { "EXAMPLES", 0 },
54 { "DIAGNOSTICS", 0 },
55 { "COMPATIBILITY", 0 },
56 { "ERRORS", 0 },
57 { "SEE ALSO", 0 },
58 { "STANDARDS", 0 },
59 { "HISTORY", 0 },
60 { "AUTHORS", 0 },
61 { "CAVEATS", 0 },
62 { "BUGS", 0 },
63 { NULL, 0 }
64 };
65
66 #ifdef __linux__
67 extern char *strptime(const char *, const char *, struct tm *);
68 #endif
69
70
71 size_t
72 mdoc_isescape(const char *p)
73 {
74 size_t c;
75
76 if ('\\' != *p++)
77 return(0);
78
79 switch (*p) {
80 case ('\\'):
81 /* FALLTHROUGH */
82 case ('\''):
83 /* FALLTHROUGH */
84 case ('`'):
85 /* FALLTHROUGH */
86 case ('q'):
87 /* FALLTHROUGH */
88 case ('-'):
89 /* FALLTHROUGH */
90 case (' '):
91 /* FALLTHROUGH */
92 case ('&'):
93 /* FALLTHROUGH */
94 case ('.'):
95 /* FALLTHROUGH */
96 case ('e'):
97 return(2);
98 case ('*'):
99 if (0 == *++p || ! isgraph((u_char)*p))
100 return(0);
101 switch (*p) {
102 case ('('):
103 if (0 == *++p || ! isgraph((u_char)*p))
104 return(0);
105 return(4);
106 case ('['):
107 for (c = 3, p++; *p && ']' != *p; p++, c++)
108 if ( ! isgraph((u_char)*p))
109 break;
110 return(*p == ']' ? c : 0);
111 default:
112 break;
113 }
114 return(3);
115 case ('('):
116 if (0 == *++p || ! isgraph((u_char)*p))
117 return(0);
118 if (0 == *++p || ! isgraph((u_char)*p))
119 return(0);
120 return(4);
121 case ('['):
122 break;
123 default:
124 return(0);
125 }
126
127 for (c = 3, p++; *p && ']' != *p; p++, c++)
128 if ( ! isgraph((u_char)*p))
129 break;
130
131 return(*p == ']' ? c : 0);
132 }
133
134
135 int
136 mdoc_iscdelim(char p)
137 {
138
139 switch (p) {
140 case('.'):
141 /* FALLTHROUGH */
142 case(','):
143 /* FALLTHROUGH */
144 case(';'):
145 /* FALLTHROUGH */
146 case(':'):
147 /* FALLTHROUGH */
148 case('?'):
149 /* FALLTHROUGH */
150 case('!'):
151 /* FALLTHROUGH */
152 case('('):
153 /* FALLTHROUGH */
154 case(')'):
155 /* FALLTHROUGH */
156 case('['):
157 /* FALLTHROUGH */
158 case(']'):
159 /* FALLTHROUGH */
160 case('{'):
161 /* FALLTHROUGH */
162 case('}'):
163 return(1);
164 default:
165 break;
166 }
167
168 return(0);
169 }
170
171
172 int
173 mdoc_isdelim(const char *p)
174 {
175
176 if (0 == *p)
177 return(0);
178 if (0 != *(p + 1))
179 return(0);
180 return(mdoc_iscdelim(*p));
181 }
182
183
184 enum mdoc_sec
185 mdoc_atosec(const char *p)
186 {
187 const struct mdoc_secname *n;
188 int i;
189
190 for (i = 0, n = secnames; n->name; n++, i++)
191 if ( ! (n->flag & MSECNAME_META))
192 if (xstrcmp(p, n->name))
193 return((enum mdoc_sec)i);
194
195 return(SEC_CUSTOM);
196 }
197
198
199 time_t
200 mdoc_atotime(const char *p)
201 {
202 struct tm tm;
203 char *pp;
204
205 (void)memset(&tm, 0, sizeof(struct tm));
206
207 if (xstrcmp(p, "$Mdocdate: March 13 2009 $"))
208 return(time(NULL));
209 if ((pp = strptime(p, "$Mdocdate: March 13 2009 $", &tm)) && 0 == *pp)
210 return(mktime(&tm));
211 /* XXX - this matches "June 1999", which is wrong. */
212 if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
213 return(mktime(&tm));
214 if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
215 return(mktime(&tm));
216
217 return(0);
218 }
219
220
221 size_t
222 mdoc_macro2len(int macro)
223 {
224
225 switch (macro) {
226 case(MDOC_Ad):
227 return(12);
228 case(MDOC_Ao):
229 return(12);
230 case(MDOC_An):
231 return(12);
232 case(MDOC_Aq):
233 return(12);
234 case(MDOC_Ar):
235 return(12);
236 case(MDOC_Bo):
237 return(12);
238 case(MDOC_Bq):
239 return(12);
240 case(MDOC_Cd):
241 return(12);
242 case(MDOC_Cm):
243 return(10);
244 case(MDOC_Do):
245 return(10);
246 case(MDOC_Dq):
247 return(12);
248 case(MDOC_Dv):
249 return(12);
250 case(MDOC_Eo):
251 return(12);
252 case(MDOC_Em):
253 return(10);
254 case(MDOC_Er):
255 return(12);
256 case(MDOC_Ev):
257 return(15);
258 case(MDOC_Fa):
259 return(12);
260 case(MDOC_Fl):
261 return(10);
262 case(MDOC_Fo):
263 return(16);
264 case(MDOC_Fn):
265 return(16);
266 case(MDOC_Ic):
267 return(10);
268 case(MDOC_Li):
269 return(16);
270 case(MDOC_Ms):
271 return(6);
272 case(MDOC_Nm):
273 return(10);
274 case(MDOC_No):
275 return(12);
276 case(MDOC_Oo):
277 return(10);
278 case(MDOC_Op):
279 return(14);
280 case(MDOC_Pa):
281 return(32);
282 case(MDOC_Pf):
283 return(12);
284 case(MDOC_Po):
285 return(12);
286 case(MDOC_Pq):
287 return(12);
288 case(MDOC_Ql):
289 return(16);
290 case(MDOC_Qo):
291 return(12);
292 case(MDOC_So):
293 return(12);
294 case(MDOC_Sq):
295 return(12);
296 case(MDOC_Sy):
297 return(6);
298 case(MDOC_Sx):
299 return(16);
300 case(MDOC_Tn):
301 return(10);
302 case(MDOC_Va):
303 return(12);
304 case(MDOC_Vt):
305 return(12);
306 case(MDOC_Xr):
307 return(10);
308 default:
309 break;
310 };
311 return(0);
312 }