-/* $Id: mandoc.c,v 1.49 2011/04/30 10:18:24 kristaps Exp $ */
+/* $Id: mandoc.c,v 1.58 2011/07/27 07:32:26 kristaps Exp $ */
/*
* Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
#include <assert.h>
#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
break;
case ('['):
gly = ESCAPE_SPECIAL;
+ /*
+ * Unicode escapes are defined in groff as \[uXXXX] to
+ * \[u10FFFF], where the contained value must be a valid
+ * Unicode codepoint. Here, however, only check whether
+ * it's not a zero-width escape.
+ */
+ if ('u' == cp[i] && ']' != cp[i + 1])
+ gly = ESCAPE_UNICODE;
term = ']';
break;
case ('C'):
if (ESCAPE_ERROR == gly)
gly = ESCAPE_IGNORE;
/* FALLTHROUGH */
- case ('*'):
- if (ESCAPE_ERROR == gly)
- gly = ESCAPE_PREDEF;
- /* FALLTHROUGH */
case ('f'):
if (ESCAPE_ERROR == gly)
gly = ESCAPE_FONT;
return(ptr);
}
+char *
+mandoc_strndup(const char *ptr, size_t sz)
+{
+ char *p;
+
+ p = mandoc_malloc(sz + 1);
+ memcpy(p, ptr, sz);
+ p[(int)sz] = '\0';
+ return(p);
+}
char *
mandoc_strdup(const char *ptr)
memset(&tm, 0, sizeof(struct tm));
+ pp = NULL;
+#ifdef HAVE_STRPTIME
pp = strptime(p, fmt, &tm);
+#endif
if (NULL != pp && '\0' == *pp) {
*t = mktime(&tm);
return(1);
static char *
time2a(time_t t)
{
- struct tm tm;
+ struct tm *tm;
char *buf, *p;
size_t ssz;
int isz;
- localtime_r(&t, &tm);
+ tm = localtime(&t);
/*
* Reserve space:
*/
p = buf = mandoc_malloc(10 + 4 + 4 + 1);
- if (0 == (ssz = strftime(p, 10 + 1, "%B ", &tm)))
+ if (0 == (ssz = strftime(p, 10 + 1, "%B ", tm)))
goto fail;
p += (int)ssz;
- if (-1 == (isz = snprintf(p, 4 + 1, "%d, ", tm.tm_mday)))
+ if (-1 == (isz = snprintf(p, 4 + 1, "%d, ", tm->tm_mday)))
goto fail;
p += isz;
- if (0 == strftime(p, 4 + 1, "%Y", &tm))
+ if (0 == strftime(p, 4 + 1, "%Y", tm))
goto fail;
return(buf);
return(found && !enclosed);
}
-int
-mandoc_hyph(const char *start, const char *c)
-{
-
- /*
- * Choose whether to break at a hyphenated character. We only
- * do this if it's free-standing within a word.
- */
-
- /* Skip first/last character of buffer. */
- if (c == start || '\0' == *(c + 1))
- return(0);
- /* Skip first/last character of word. */
- if ('\t' == *(c + 1) || '\t' == *(c - 1))
- return(0);
- if (' ' == *(c + 1) || ' ' == *(c - 1))
- return(0);
- /* Skip double invocations. */
- if ('-' == *(c + 1) || '-' == *(c - 1))
- return(0);
- /* Skip escapes. */
- if ('\\' == *(c - 1))
- return(0);
-
- return(1);
-}
-
/*
* Find out whether a line is a macro line or not. If it is, adjust the
* current position and return one; if it isn't, return zero and don't
*ppos = pos;
return(1);
}
+
+/*
+ * Convert a string to a long that may not be <0.
+ * If the string is invalid, or is less than 0, return -1.
+ */
+int
+mandoc_strntoi(const char *p, size_t sz, int base)
+{
+ char buf[32];
+ char *ep;
+ long v;
+
+ if (sz > 31)
+ return(-1);
+
+ memcpy(buf, p, sz);
+ buf[(int)sz] = '\0';
+
+ errno = 0;
+ v = strtol(buf, &ep, base);
+
+ if (buf[0] == '\0' || *ep != '\0')
+ return(-1);
+
+ if (v > INT_MAX)
+ v = INT_MAX;
+ if (v < INT_MIN)
+ v = INT_MIN;
+
+ return((int)v);
+}