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