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