Restrict -Werror to gcc41.
[dragonfly.git] / usr.bin / mandoc / out.c
blobbfd43373351606514db6ba9787ccb90a6c1f73ef
1 /* $Id: out.c,v 1.2 2009/10/27 21:40:07 schwarze Exp $ */
2 /*
3 * Copyright (c) 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 #include <sys/types.h>
19 #include <assert.h>
20 #include <ctype.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <time.h>
26 #include "out.h"
29 * Convert a `scaling unit' to a consistent form, or fail. Scaling
30 * units are documented in groff.7, mdoc.7, man.7.
32 int
33 a2roffsu(const char *src, struct roffsu *dst, enum roffscale def)
35 char buf[BUFSIZ], hasd;
36 int i;
37 enum roffscale unit;
39 if ('\0' == *src)
40 return(0);
42 i = hasd = 0;
44 switch (*src) {
45 case ('+'):
46 src++;
47 break;
48 case ('-'):
49 buf[i++] = *src++;
50 break;
51 default:
52 break;
55 if ('\0' == *src)
56 return(0);
58 while (i < BUFSIZ) {
59 if ( ! isdigit((u_char)*src)) {
60 if ('.' != *src)
61 break;
62 else if (hasd)
63 break;
64 else
65 hasd = 1;
67 buf[i++] = *src++;
70 if (BUFSIZ == i || (*src && *(src + 1)))
71 return(0);
73 buf[i] = '\0';
75 switch (*src) {
76 case ('c'):
77 unit = SCALE_CM;
78 break;
79 case ('i'):
80 unit = SCALE_IN;
81 break;
82 case ('P'):
83 unit = SCALE_PC;
84 break;
85 case ('p'):
86 unit = SCALE_PT;
87 break;
88 case ('f'):
89 unit = SCALE_FS;
90 break;
91 case ('v'):
92 unit = SCALE_VS;
93 break;
94 case ('m'):
95 unit = SCALE_EM;
96 break;
97 case ('\0'):
98 if (SCALE_MAX == def)
99 return(0);
100 unit = SCALE_BU;
101 break;
102 case ('u'):
103 unit = SCALE_BU;
104 break;
105 case ('M'):
106 unit = SCALE_MM;
107 break;
108 case ('n'):
109 unit = SCALE_EN;
110 break;
111 default:
112 return(0);
115 if ((dst->scale = atof(buf)) < 0)
116 dst->scale = 0;
117 dst->unit = unit;
118 dst->pt = hasd;
120 return(1);
125 * Correctly writes the time in nroff form, which differs from standard
126 * form in that a space isn't printed in lieu of the extra %e field for
127 * single-digit dates.
129 void
130 time2a(time_t t, char *dst, size_t sz)
132 struct tm tm;
133 char buf[5];
134 char *p;
135 size_t nsz;
137 assert(sz > 1);
138 localtime_r(&t, &tm);
140 p = dst;
141 nsz = 0;
143 dst[0] = '\0';
145 if (0 == (nsz = strftime(p, sz, "%B ", &tm)))
146 return;
148 p += (int)nsz;
149 sz -= nsz;
151 if (0 == strftime(buf, sizeof(buf), "%e, ", &tm))
152 return;
154 nsz = strlcat(p, buf + (' ' == buf[0] ? 1 : 0), sz);
156 if (nsz >= sz)
157 return;
159 p += (int)nsz;
160 sz -= nsz;
162 (void)strftime(p, sz, "%Y", &tm);