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