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