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