Annotation of mandoc/mdoc_strings.c, Revision 1.6
1.6 ! kristaps 1: /* $Id: mdoc_strings.c,v 1.5 2009/06/15 09:38:37 kristaps Exp $ */
1.1 kristaps 2: /*
3: * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
1.3 kristaps 6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
1.1 kristaps 8: *
1.3 kristaps 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.
1.1 kristaps 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: struct mdoc_secname {
1.6 ! kristaps 28: const char *name; /* Name of section. */
1.1 kristaps 29: int flag;
1.6 ! kristaps 30: #define MSECNAME_META (1 << 0)/* Logical section (not real). */
1.1 kristaps 31: };
32:
33: /* Section names corresponding to mdoc_sec. */
34:
35: static const struct mdoc_secname secnames[] = {
36: { "PROLOGUE", MSECNAME_META },
37: { "BODY", MSECNAME_META },
38: { "NAME", 0 },
39: { "LIBRARY", 0 },
40: { "SYNOPSIS", 0 },
41: { "DESCRIPTION", 0 },
42: { "IMPLEMENTATION NOTES", 0 },
43: { "RETURN VALUES", 0 },
44: { "ENVIRONMENT", 0 },
45: { "FILES", 0 },
46: { "EXAMPLES", 0 },
47: { "DIAGNOSTICS", 0 },
48: { "COMPATIBILITY", 0 },
49: { "ERRORS", 0 },
50: { "SEE ALSO", 0 },
51: { "STANDARDS", 0 },
52: { "HISTORY", 0 },
53: { "AUTHORS", 0 },
54: { "CAVEATS", 0 },
55: { "BUGS", 0 },
56: { NULL, 0 }
57: };
58:
59: #ifdef __linux__
60: extern char *strptime(const char *, const char *, struct tm *);
61: #endif
62:
63:
64: size_t
65: mdoc_isescape(const char *p)
66: {
67: size_t c;
68:
69: if ('\\' != *p++)
70: return(0);
71:
72: switch (*p) {
73: case ('\\'):
74: /* FALLTHROUGH */
75: case ('\''):
76: /* FALLTHROUGH */
77: case ('`'):
78: /* FALLTHROUGH */
79: case ('q'):
80: /* FALLTHROUGH */
81: case ('-'):
82: /* FALLTHROUGH */
1.2 kristaps 83: case ('~'):
84: /* FALLTHROUGH */
85: case ('^'):
86: /* FALLTHROUGH */
1.1 kristaps 87: case ('%'):
88: /* FALLTHROUGH */
89: case ('0'):
90: /* FALLTHROUGH */
91: case (' '):
92: /* FALLTHROUGH */
93: case ('|'):
94: /* FALLTHROUGH */
95: case ('&'):
96: /* FALLTHROUGH */
97: case ('.'):
98: /* FALLTHROUGH */
99: case (':'):
100: /* FALLTHROUGH */
101: case ('e'):
102: return(2);
103: case ('*'):
104: if (0 == *++p || ! isgraph((u_char)*p))
105: return(0);
106: switch (*p) {
107: case ('('):
108: if (0 == *++p || ! isgraph((u_char)*p))
109: return(0);
110: return(4);
111: case ('['):
112: for (c = 3, p++; *p && ']' != *p; p++, c++)
113: if ( ! isgraph((u_char)*p))
114: break;
115: return(*p == ']' ? c : 0);
116: default:
117: break;
118: }
119: return(3);
120: case ('('):
121: if (0 == *++p || ! isgraph((u_char)*p))
122: return(0);
123: if (0 == *++p || ! isgraph((u_char)*p))
124: return(0);
125: return(4);
126: case ('['):
127: break;
128: default:
129: return(0);
130: }
131:
132: for (c = 3, p++; *p && ']' != *p; p++, c++)
133: if ( ! isgraph((u_char)*p))
134: break;
135:
136: return(*p == ']' ? c : 0);
137: }
138:
139:
140: int
141: mdoc_iscdelim(char p)
142: {
143:
144: switch (p) {
1.4 kristaps 145: case('|'):
146: /* FALLTHROUGH */
1.1 kristaps 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: /* FALLTHROUGH */
169: case('}'):
170: return(1);
171: default:
172: break;
173: }
174:
175: return(0);
176: }
177:
178:
179: int
180: mdoc_isdelim(const char *p)
181: {
182:
183: if (0 == *p)
184: return(0);
185: if (0 != *(p + 1))
186: return(0);
187: return(mdoc_iscdelim(*p));
188: }
189:
190:
191: enum mdoc_sec
192: mdoc_atosec(const char *p)
193: {
194: const struct mdoc_secname *n;
195: int i;
196:
197: for (i = 0, n = secnames; n->name; n++, i++)
198: if ( ! (n->flag & MSECNAME_META))
199: if (0 == strcmp(p, n->name))
200: return((enum mdoc_sec)i);
201:
202: return(SEC_CUSTOM);
203: }
204:
205:
206: time_t
207: mdoc_atotime(const char *p)
208: {
209: struct tm tm;
210: char *pp;
211:
212: (void)memset(&tm, 0, sizeof(struct tm));
213:
1.5 kristaps 214: if (0 == strcmp(p, "$" "Mdocdate$"))
1.1 kristaps 215: return(time(NULL));
1.5 kristaps 216: if ((pp = strptime(p, "$" "Mdocdate: %b %d %Y $", &tm)) && 0 == *pp)
1.1 kristaps 217: return(mktime(&tm));
218: /* XXX - this matches "June 1999", which is wrong. */
219: if ((pp = strptime(p, "%b %d %Y", &tm)) && 0 == *pp)
220: return(mktime(&tm));
221: if ((pp = strptime(p, "%b %d, %Y", &tm)) && 0 == *pp)
222: return(mktime(&tm));
223:
224: return(0);
225: }
226:
227:
228: size_t
229: mdoc_macro2len(int macro)
230: {
231:
232: switch (macro) {
233: case(MDOC_Ad):
234: return(12);
235: case(MDOC_Ao):
236: return(12);
237: case(MDOC_An):
238: return(12);
239: case(MDOC_Aq):
240: return(12);
241: case(MDOC_Ar):
242: return(12);
243: case(MDOC_Bo):
244: return(12);
245: case(MDOC_Bq):
246: return(12);
247: case(MDOC_Cd):
248: return(12);
249: case(MDOC_Cm):
250: return(10);
251: case(MDOC_Do):
252: return(10);
253: case(MDOC_Dq):
254: return(12);
255: case(MDOC_Dv):
256: return(12);
257: case(MDOC_Eo):
258: return(12);
259: case(MDOC_Em):
260: return(10);
261: case(MDOC_Er):
262: return(12);
263: case(MDOC_Ev):
264: return(15);
265: case(MDOC_Fa):
266: return(12);
267: case(MDOC_Fl):
268: return(10);
269: case(MDOC_Fo):
270: return(16);
271: case(MDOC_Fn):
272: return(16);
273: case(MDOC_Ic):
274: return(10);
275: case(MDOC_Li):
276: return(16);
277: case(MDOC_Ms):
278: return(6);
279: case(MDOC_Nm):
280: return(10);
281: case(MDOC_No):
282: return(12);
283: case(MDOC_Oo):
284: return(10);
285: case(MDOC_Op):
286: return(14);
287: case(MDOC_Pa):
288: return(32);
289: case(MDOC_Pf):
290: return(12);
291: case(MDOC_Po):
292: return(12);
293: case(MDOC_Pq):
294: return(12);
295: case(MDOC_Ql):
296: return(16);
297: case(MDOC_Qo):
298: return(12);
299: case(MDOC_So):
300: return(12);
301: case(MDOC_Sq):
302: return(12);
303: case(MDOC_Sy):
304: return(6);
305: case(MDOC_Sx):
306: return(16);
307: case(MDOC_Tn):
308: return(10);
309: case(MDOC_Va):
310: return(12);
311: case(MDOC_Vt):
312: return(12);
313: case(MDOC_Xr):
314: return(10);
315: default:
316: break;
317: };
318: return(0);
319: }
CVSweb