]> git.cameronkatri.com Git - mandoc.git/blob - strings.c
Easier integration into FreeBSD (sys/types.h, time.h, etc.).
[mandoc.git] / strings.c
1 /* $Id: strings.c,v 1.27 2009/03/09 13:17:49 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 ('-'):
87 /* FALLTHROUGH */
88 case (' '):
89 /* FALLTHROUGH */
90 case ('&'):
91 /* FALLTHROUGH */
92 case ('.'):
93 /* FALLTHROUGH */
94 case ('e'):
95 return(2);
96 case ('*'):
97 if (0 == *++p || ! isgraph((u_char)*p))
98 return(0);
99 switch (*p) {
100 case ('('):
101 if (0 == *++p || ! isgraph((u_char)*p))
102 return(0);
103 return(4);
104 case ('['):
105 for (c = 3, p++; *p && ']' != *p; p++, c++)
106 if ( ! isgraph((u_char)*p))
107 break;
108 return(*p == ']' ? c : 0);
109 default:
110 break;
111 }
112 return(3);
113 case ('('):
114 if (0 == *++p || ! isgraph((u_char)*p))
115 return(0);
116 if (0 == *++p || ! isgraph((u_char)*p))
117 return(0);
118 return(4);
119 case ('['):
120 break;
121 default:
122 return(0);
123 }
124
125 for (c = 3, p++; *p && ']' != *p; p++, c++)
126 if ( ! isgraph((u_char)*p))
127 break;
128
129 return(*p == ']' ? c : 0);
130 }
131
132
133 int
134 mdoc_iscdelim(char p)
135 {
136
137 switch (p) {
138 case('.'):
139 /* FALLTHROUGH */
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 return(1);
162 default:
163 break;
164 }
165
166 return(0);
167 }
168
169
170 int
171 mdoc_isdelim(const char *p)
172 {
173
174 if (0 == *p)
175 return(0);
176 if (0 != *(p + 1))
177 return(0);
178 return(mdoc_iscdelim(*p));
179 }
180
181
182 enum mdoc_sec
183 mdoc_atosec(const char *p)
184 {
185 const struct mdoc_secname *n;
186 int i;
187
188 for (i = 0, n = secnames; n->name; n++, i++)
189 if ( ! (n->flag & MSECNAME_META))
190 if (xstrcmp(p, n->name))
191 return((enum mdoc_sec)i);
192
193 return(SEC_CUSTOM);
194 }
195
196
197 time_t
198 mdoc_atotime(const char *p)
199 {
200 struct tm tm;
201 char *pp;
202
203 (void)memset(&tm, 0, sizeof(struct tm));
204
205 if (xstrcmp(p, "$Mdocdate: March 9 2009 $"))
206 return(time(NULL));
207 if ((pp = strptime(p, "$Mdocdate: March 9 2009 $", &tm)) && 0 == *pp)
208 return(mktime(&tm));
209 /* XXX - this matches "June 1999", which is wrong. */
210 if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
211 return(mktime(&tm));
212 if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
213 return(mktime(&tm));
214
215 return(0);
216 }
217
218
219 size_t
220 mdoc_macro2len(int macro)
221 {
222
223 switch (macro) {
224 case(MDOC_Ad):
225 return(12);
226 case(MDOC_Ao):
227 return(12);
228 case(MDOC_An):
229 return(12);
230 case(MDOC_Aq):
231 return(12);
232 case(MDOC_Ar):
233 return(12);
234 case(MDOC_Bo):
235 return(12);
236 case(MDOC_Bq):
237 return(12);
238 case(MDOC_Cd):
239 return(12);
240 case(MDOC_Cm):
241 return(10);
242 case(MDOC_Do):
243 return(10);
244 case(MDOC_Dq):
245 return(12);
246 case(MDOC_Dv):
247 return(12);
248 case(MDOC_Eo):
249 return(12);
250 case(MDOC_Em):
251 return(10);
252 case(MDOC_Er):
253 return(12);
254 case(MDOC_Ev):
255 return(15);
256 case(MDOC_Fa):
257 return(12);
258 case(MDOC_Fl):
259 return(10);
260 case(MDOC_Fo):
261 return(16);
262 case(MDOC_Fn):
263 return(16);
264 case(MDOC_Ic):
265 return(10);
266 case(MDOC_Li):
267 return(16);
268 case(MDOC_Ms):
269 return(6);
270 case(MDOC_Nm):
271 return(10);
272 case(MDOC_No):
273 return(12);
274 case(MDOC_Oo):
275 return(10);
276 case(MDOC_Op):
277 return(14);
278 case(MDOC_Pa):
279 return(32);
280 case(MDOC_Pf):
281 return(12);
282 case(MDOC_Po):
283 return(12);
284 case(MDOC_Pq):
285 return(12);
286 case(MDOC_Ql):
287 return(16);
288 case(MDOC_Qo):
289 return(12);
290 case(MDOC_So):
291 return(12);
292 case(MDOC_Sq):
293 return(12);
294 case(MDOC_Sy):
295 return(6);
296 case(MDOC_Sx):
297 return(16);
298 case(MDOC_Tn):
299 return(10);
300 case(MDOC_Va):
301 return(12);
302 case(MDOC_Vt):
303 return(12);
304 case(MDOC_Xr):
305 return(10);
306 default:
307 break;
308 };
309 return(0);
310 }