wbsio: support W83627UHG (0xa2); supported by lm(4) as W83627DHG (0xc1)
[dragonfly.git] / usr.bin / mandoc / mandoc.c
blobef23c680adcfbda2c192d0117d8466c177f45350
1 /* $Id: mandoc.c,v 1.10 2010/01/05 19:51:10 kristaps Exp $ */
2 /*
3 * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
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.
18 #include <sys/types.h>
20 #include <assert.h>
21 #include <ctype.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <time.h>
27 #include "libmandoc.h"
29 static int a2time(time_t *, const char *, const char *);
32 int
33 mandoc_special(const char *p)
35 int terminator; /* Terminator for \s. */
36 int lim; /* Limit for N in \s. */
37 int c, i;
39 if ('\\' != *p++)
40 return(0);
42 switch (*p) {
43 case ('\''):
44 /* FALLTHROUGH */
45 case ('`'):
46 /* FALLTHROUGH */
47 case ('q'):
48 /* FALLTHROUGH */
49 case ('-'):
50 /* FALLTHROUGH */
51 case ('~'):
52 /* FALLTHROUGH */
53 case ('^'):
54 /* FALLTHROUGH */
55 case ('%'):
56 /* FALLTHROUGH */
57 case ('0'):
58 /* FALLTHROUGH */
59 case (' '):
60 /* FALLTHROUGH */
61 case ('|'):
62 /* FALLTHROUGH */
63 case ('&'):
64 /* FALLTHROUGH */
65 case ('.'):
66 /* FALLTHROUGH */
67 case (':'):
68 /* FALLTHROUGH */
69 case ('c'):
70 return(2);
71 case ('e'):
72 return(2);
73 case ('f'):
74 if ('\0' == *++p || ! isgraph((u_char)*p))
75 return(0);
76 return(3);
77 case ('s'):
78 if ('\0' == *++p)
79 return(2);
81 c = 2;
82 terminator = 0;
83 lim = 1;
85 if (*p == '\'') {
86 lim = 0;
87 terminator = 1;
88 ++p;
89 ++c;
90 } else if (*p == '[') {
91 lim = 0;
92 terminator = 2;
93 ++p;
94 ++c;
95 } else if (*p == '(') {
96 lim = 2;
97 terminator = 3;
98 ++p;
99 ++c;
102 if (*p == '+' || *p == '-') {
103 ++p;
104 ++c;
107 if (*p == '\'') {
108 if (terminator)
109 return(0);
110 lim = 0;
111 terminator = 1;
112 ++p;
113 ++c;
114 } else if (*p == '[') {
115 if (terminator)
116 return(0);
117 lim = 0;
118 terminator = 2;
119 ++p;
120 ++c;
121 } else if (*p == '(') {
122 if (terminator)
123 return(0);
124 lim = 2;
125 terminator = 3;
126 ++p;
127 ++c;
130 /* TODO: needs to handle floating point. */
132 if ( ! isdigit((u_char)*p))
133 return(0);
135 for (i = 0; isdigit((u_char)*p); i++) {
136 if (lim && i >= lim)
137 break;
138 ++p;
139 ++c;
142 if (terminator && terminator < 3) {
143 if (1 == terminator && *p != '\'')
144 return(0);
145 if (2 == terminator && *p != ']')
146 return(0);
147 ++p;
148 ++c;
151 return(c);
152 case ('*'):
153 if (0 == *++p || ! isgraph((u_char)*p))
154 return(0);
155 switch (*p) {
156 case ('('):
157 if (0 == *++p || ! isgraph((u_char)*p))
158 return(0);
159 return(4);
160 case ('['):
161 for (c = 3, p++; *p && ']' != *p; p++, c++)
162 if ( ! isgraph((u_char)*p))
163 break;
164 return(*p == ']' ? c : 0);
165 default:
166 break;
168 return(3);
169 case ('('):
170 if (0 == *++p || ! isgraph((u_char)*p))
171 return(0);
172 if (0 == *++p || ! isgraph((u_char)*p))
173 return(0);
174 return(4);
175 case ('['):
176 break;
177 default:
178 return(0);
181 for (c = 3, p++; *p && ']' != *p; p++, c++)
182 if ( ! isgraph((u_char)*p))
183 break;
185 return(*p == ']' ? c : 0);
189 void *
190 mandoc_calloc(size_t num, size_t size)
192 void *ptr;
194 ptr = calloc(num, size);
195 if (NULL == ptr) {
196 perror(NULL);
197 exit(EXIT_FAILURE);
200 return(ptr);
204 void *
205 mandoc_malloc(size_t size)
207 void *ptr;
209 ptr = malloc(size);
210 if (NULL == ptr) {
211 perror(NULL);
212 exit(EXIT_FAILURE);
215 return(ptr);
219 void *
220 mandoc_realloc(void *ptr, size_t size)
223 ptr = realloc(ptr, size);
224 if (NULL == ptr) {
225 perror(NULL);
226 exit(EXIT_FAILURE);
229 return(ptr);
233 char *
234 mandoc_strdup(const char *ptr)
236 char *p;
238 p = strdup(ptr);
239 if (NULL == p) {
240 perror(NULL);
241 exit(EXIT_FAILURE);
244 return(p);
248 static int
249 a2time(time_t *t, const char *fmt, const char *p)
251 struct tm tm;
252 char *pp;
254 memset(&tm, 0, sizeof(struct tm));
256 pp = strptime(p, fmt, &tm);
257 if (NULL != pp && '\0' == *pp) {
258 *t = mktime(&tm);
259 return(1);
262 return(0);
267 * Convert from a manual date string (see mdoc(7) and man(7)) into a
268 * date according to the stipulated date type.
270 time_t
271 mandoc_a2time(int flags, const char *p)
273 time_t t;
275 if (MTIME_MDOCDATE & flags) {
276 if (0 == strcmp(p, "$" "Mdocdate$"))
277 return(time(NULL));
278 if (a2time(&t, "$" "Mdocdate: %b %d %Y $", p))
279 return(t);
282 if (MTIME_CANONICAL & flags || MTIME_REDUCED & flags)
283 if (a2time(&t, "%b %d, %Y", p))
284 return(t);
286 if (MTIME_ISO_8601 & flags)
287 if (a2time(&t, "%Y-%m-%d", p))
288 return(t);
290 if (MTIME_REDUCED & flags) {
291 if (a2time(&t, "%d, %Y", p))
292 return(t);
293 if (a2time(&t, "%Y", p))
294 return(t);
297 return(0);