]>
git.cameronkatri.com Git - mandoc.git/blob - mandoc.c
1 /* $Id: mandoc.c,v 1.121 2022/05/19 15:37:47 schwarze Exp $ */
3 * Copyright (c) 2010, 2011, 2015, 2017, 2018, 2019, 2020, 2021
4 * Ingo Schwarze <schwarze@openbsd.org>
5 * Copyright (c) 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 * Utility functions to handle end of sentence punctuation
20 * and dates and times, for use by mdoc(7) and man(7) parsers.
21 * Utility functions to handle fonts and numbers,
22 * for use by mandoc(1) parsers and formatters.
26 #include <sys/types.h>
37 #include "mandoc_aux.h"
40 #include "libmandoc.h"
43 static int a2time(time_t *, const char *, const char *);
44 static char *time2a(time_t);
48 mandoc_font(const char *cp
, int sz
)
52 return ESCAPE_FONTPREV
;
57 return ESCAPE_FONTBOLD
;
60 return ESCAPE_FONTITALIC
;
62 return ESCAPE_FONTPREV
;
65 return ESCAPE_FONTROMAN
;
101 a2time(time_t *t
, const char *fmt
, const char *p
)
106 memset(&tm
, 0, sizeof(struct tm
));
110 pp
= strptime(p
, fmt
, &tm
);
112 if (NULL
!= pp
&& '\0' == *pp
) {
135 * up to 9 characters for the month (September) + blank
136 * up to 2 characters for the day + comma + blank
137 * 4 characters for the year and a terminating '\0'
140 p
= buf
= mandoc_malloc(10 + 4 + 4 + 1);
142 if ((ssz
= strftime(p
, 10 + 1, "%B ", tm
)) == 0)
147 * The output format is just "%d" here, not "%2d" or "%02d".
148 * That's also the reason why we can't just format the
149 * date as a whole with "%B %e, %Y" or "%B %d, %Y".
150 * Besides, the present approach is less prone to buffer
151 * overflows, in case anybody should ever introduce the bug
152 * of looking at LC_TIME.
155 isz
= snprintf(p
, 4 + 1, "%d, ", tm
->tm_mday
);
156 if (isz
< 0 || isz
> 4)
160 if (strftime(p
, 4 + 1, "%Y", tm
) == 0)
166 return mandoc_strdup("");
170 mandoc_normdate(struct roff_node
*nch
, struct roff_node
*nbl
)
175 /* No date specified. */
179 mandoc_msg(MANDOCERR_DATE_MISSING
, 0, 0, NULL
);
181 mandoc_msg(MANDOCERR_DATE_MISSING
, nbl
->line
,
182 nbl
->pos
, "%s", roff_name
[nbl
->tok
]);
183 return mandoc_strdup("");
185 if (*nch
->string
== '\0') {
186 mandoc_msg(MANDOCERR_DATE_MISSING
, nch
->line
,
187 nch
->pos
, "%s", roff_name
[nbl
->tok
]);
188 return mandoc_strdup("");
190 if (strcmp(nch
->string
, "$" "Mdocdate$") == 0)
191 return time2a(time(NULL
));
193 /* Valid mdoc(7) date format. */
195 if (a2time(&t
, "$" "Mdocdate: %b %d %Y $", nch
->string
) ||
196 a2time(&t
, "%b %d, %Y", nch
->string
)) {
198 if (t
> time(NULL
) + 86400)
199 mandoc_msg(MANDOCERR_DATE_FUTURE
, nch
->line
,
200 nch
->pos
, "%s %s", roff_name
[nbl
->tok
], cp
);
201 else if (*nch
->string
!= '$' &&
202 strcmp(nch
->string
, cp
) != 0)
203 mandoc_msg(MANDOCERR_DATE_NORM
, nch
->line
,
204 nch
->pos
, "%s %s", roff_name
[nbl
->tok
], cp
);
208 /* In man(7), do not warn about the legacy format. */
210 if (a2time(&t
, "%Y-%m-%d", nch
->string
) == 0)
211 mandoc_msg(MANDOCERR_DATE_BAD
, nch
->line
, nch
->pos
,
212 "%s %s", roff_name
[nbl
->tok
], nch
->string
);
213 else if (t
> time(NULL
) + 86400)
214 mandoc_msg(MANDOCERR_DATE_FUTURE
, nch
->line
, nch
->pos
,
215 "%s %s", roff_name
[nbl
->tok
], nch
->string
);
216 else if (nbl
->tok
== MDOC_Dd
)
217 mandoc_msg(MANDOCERR_DATE_LEGACY
, nch
->line
, nch
->pos
,
218 "Dd %s", nch
->string
);
220 /* Use any non-mdoc(7) date verbatim. */
222 return mandoc_strdup(nch
->string
);
226 mandoc_eos(const char *p
, size_t sz
)
235 * End-of-sentence recognition must include situations where
236 * some symbols, such as `)', allow prior EOS punctuation to
240 enclosed
= found
= 0;
241 for (q
= p
+ (int)sz
- 1; q
>= p
; q
--) {
257 (!enclosed
|| isalnum((unsigned char)*q
));
261 return found
&& !enclosed
;
265 * Convert a string to a long that may not be <0.
266 * If the string is invalid, or is less than 0, return -1.
269 mandoc_strntoi(const char *p
, size_t sz
, int base
)
282 v
= strtol(buf
, &ep
, base
);
284 if (buf
[0] == '\0' || *ep
!= '\0')