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