kernel - Video - Add suppor for Intel IGD chipsets (netbook / N450 etc)
[dragonfly.git] / usr.bin / mandoc / mandoc.c
blob6bc91a139582f64b5380698be79ee8b29ff8cf90
1 /* $Id: mandoc.c,v 1.8 2009/11/05 10:16:01 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.
17 #if defined(__linux__) || defined(__MINT__)
18 # define _GNU_SOURCE /* strptime() */
19 #endif
21 #include <sys/types.h>
23 #include <assert.h>
24 #include <ctype.h>
25 #include <stdlib.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <time.h>
30 #include "libmandoc.h"
32 static int a2time(time_t *, const char *, const char *);
35 int
36 mandoc_special(const char *p)
38 int terminator; /* Terminator for \s. */
39 int lim; /* Limit for N in \s. */
40 int c, i;
42 if ('\\' != *p++)
43 return(0);
45 switch (*p) {
46 case ('\\'):
47 /* FALLTHROUGH */
48 case ('\''):
49 /* FALLTHROUGH */
50 case ('`'):
51 /* FALLTHROUGH */
52 case ('q'):
53 /* FALLTHROUGH */
54 case ('-'):
55 /* FALLTHROUGH */
56 case ('~'):
57 /* FALLTHROUGH */
58 case ('^'):
59 /* FALLTHROUGH */
60 case ('%'):
61 /* FALLTHROUGH */
62 case ('0'):
63 /* FALLTHROUGH */
64 case (' '):
65 /* FALLTHROUGH */
66 case ('|'):
67 /* FALLTHROUGH */
68 case ('&'):
69 /* FALLTHROUGH */
70 case ('.'):
71 /* FALLTHROUGH */
72 case (':'):
73 /* FALLTHROUGH */
74 case ('c'):
75 return(2);
76 case ('e'):
77 return(2);
78 case ('f'):
79 if ('\0' == *++p || ! isgraph((u_char)*p))
80 return(0);
81 return(3);
82 case ('s'):
83 if ('\0' == *++p)
84 return(2);
86 c = 2;
87 terminator = 0;
88 lim = 1;
90 if (*p == '\'') {
91 lim = 0;
92 terminator = 1;
93 ++p;
94 ++c;
95 } else if (*p == '[') {
96 lim = 0;
97 terminator = 2;
98 ++p;
99 ++c;
100 } else if (*p == '(') {
101 lim = 2;
102 terminator = 3;
103 ++p;
104 ++c;
107 if (*p == '+' || *p == '-') {
108 ++p;
109 ++c;
112 if (*p == '\'') {
113 if (terminator)
114 return(0);
115 lim = 0;
116 terminator = 1;
117 ++p;
118 ++c;
119 } else if (*p == '[') {
120 if (terminator)
121 return(0);
122 lim = 0;
123 terminator = 2;
124 ++p;
125 ++c;
126 } else if (*p == '(') {
127 if (terminator)
128 return(0);
129 lim = 2;
130 terminator = 3;
131 ++p;
132 ++c;
135 /* TODO: needs to handle floating point. */
137 if ( ! isdigit((u_char)*p))
138 return(0);
140 for (i = 0; isdigit((u_char)*p); i++) {
141 if (lim && i >= lim)
142 break;
143 ++p;
144 ++c;
147 if (terminator && terminator < 3) {
148 if (1 == terminator && *p != '\'')
149 return(0);
150 if (2 == terminator && *p != ']')
151 return(0);
152 ++p;
153 ++c;
156 return(c);
157 case ('*'):
158 if (0 == *++p || ! isgraph((u_char)*p))
159 return(0);
160 switch (*p) {
161 case ('('):
162 if (0 == *++p || ! isgraph((u_char)*p))
163 return(0);
164 return(4);
165 case ('['):
166 for (c = 3, p++; *p && ']' != *p; p++, c++)
167 if ( ! isgraph((u_char)*p))
168 break;
169 return(*p == ']' ? c : 0);
170 default:
171 break;
173 return(3);
174 case ('('):
175 if (0 == *++p || ! isgraph((u_char)*p))
176 return(0);
177 if (0 == *++p || ! isgraph((u_char)*p))
178 return(0);
179 return(4);
180 case ('['):
181 break;
182 default:
183 return(0);
186 for (c = 3, p++; *p && ']' != *p; p++, c++)
187 if ( ! isgraph((u_char)*p))
188 break;
190 return(*p == ']' ? c : 0);
194 void *
195 mandoc_calloc(size_t num, size_t size)
197 void *ptr;
199 ptr = calloc(num, size);
200 if (NULL == ptr) {
201 perror(NULL);
202 exit(EXIT_FAILURE);
205 return(ptr);
209 void *
210 mandoc_malloc(size_t size)
212 void *ptr;
214 ptr = malloc(size);
215 if (NULL == ptr) {
216 perror(NULL);
217 exit(EXIT_FAILURE);
220 return(ptr);
224 void *
225 mandoc_realloc(void *ptr, size_t size)
228 ptr = realloc(ptr, size);
229 if (NULL == ptr) {
230 perror(NULL);
231 exit(EXIT_FAILURE);
234 return(ptr);
238 char *
239 mandoc_strdup(const char *ptr)
241 char *p;
243 p = strdup(ptr);
244 if (NULL == p) {
245 perror(NULL);
246 exit(EXIT_FAILURE);
249 return(p);
253 static int
254 a2time(time_t *t, const char *fmt, const char *p)
256 struct tm tm;
257 char *pp;
259 memset(&tm, 0, sizeof(struct tm));
261 pp = strptime(p, fmt, &tm);
262 if (NULL != pp && '\0' == *pp) {
263 *t = mktime(&tm);
264 return(1);
267 return(0);
272 * Convert from a manual date string (see mdoc(7) and man(7)) into a
273 * date according to the stipulated date type.
275 time_t
276 mandoc_a2time(int flags, const char *p)
278 time_t t;
280 if (MTIME_MDOCDATE & flags) {
281 if (0 == strcmp(p, "$" "Mdocdate$"))
282 return(time(NULL));
283 if (a2time(&t, "$" "Mdocdate: %b %d %Y $", p))
284 return(t);
287 if (MTIME_CANONICAL & flags || MTIME_REDUCED & flags)
288 if (a2time(&t, "%b %d, %Y", p))
289 return(t);
291 if (MTIME_ISO_8601 & flags)
292 if (a2time(&t, "%Y-%m-%d", p))
293 return(t);
295 if (MTIME_REDUCED & flags) {
296 if (a2time(&t, "%d, %Y", p))
297 return(t);
298 if (a2time(&t, "%Y", p))
299 return(t);
302 return(0);