/*
* static prototypes
*/
-static int match (char *, char *);
+static int match (char *, char *) PURE;
static char *get_x400_friendly (char *, char *, int);
static int get_x400_comp (char *, char *, char *, int);
* copy a number to the destination subject to a maximum width
*/
void
-cpnumber(charstring_t dest, int num, unsigned int wid, char fill, size_t max) {
- if (wid < (num >= 0 ? max : max-1)) {
+cpnumber(charstring_t dest, int num, int wid, char fill, size_t max) {
+ /* Maybe we should handle left padding at some point? */
+ if (wid == 0)
+ return;
+ if (wid < 0)
+ wid = -wid; /* OK because wid originally a short. */
+ if ((size_t)wid < (num >= 0 ? max : max-1)) {
/* Build up the string representation of num in reverse. */
charstring_t rev = charstring_create (0);
int i = num >= 0 ? num : -num;
static void
cpstripped (charstring_t dest, size_t max, char *str)
{
- int prevCtrl = 1; /* This is 1 so we strip out leading spaces */
- int len;
- int char_len, w;
- wchar_t wide_char;
- char *altstr = NULL;
-
- if (!str) {
- return;
- }
+ static bool deja_vu;
+ static char *oddchar;
+ static size_t oddlen;
+ static char *spacechar;
+ static size_t spacelen;
+ char *end;
+ bool squash;
+ char *src;
+ int srclen;
+ wchar_t rune;
+ int w;
- len = strlen(str);
+ if (!deja_vu) {
+ size_t two;
- if (mbtowc(NULL, NULL, 0)) {} /* Reset shift state */
+ deja_vu = true;
- /*
- * Process each character at a time; if we have multibyte support
- * then deal with that here.
- */
+ two = MB_CUR_MAX * 2; /* Varies at run-time. */
- while (*str != '\0' && len > 0 && max > 0) {
- char_len = mbtowc(&wide_char, str, len);
+ oddchar = mh_xmalloc(two);
+ oddlen = wcstombs(oddchar, L"?", two);
+ assert(oddlen > 0);
- /*
- * If mbrtowc() failed, then we have a character that isn't valid
- * in the current encoding, or len wasn't enough for the whole
- * multi-byte rune to be read. Replace it with a '?'. We do that by
- * setting the alstr variable to the value of the replacement string;
- * altstr is used below when the bytes are copied into the output
- * buffer.
- */
- if (char_len < 0) {
- altstr = "?";
- char_len = mbtowc(&wide_char, altstr, 1);
- }
+ assert(wcwidth(L' ') == 1); /* Need to pad in ones. */
+ spacechar = mh_xmalloc(two);
+ spacelen = wcstombs(spacechar, L" ", two);
+ assert(spacelen > 0);
+ }
- if (char_len <= 0) {
- break;
- }
+ if (!str)
+ return; /* It's unclear why no padding in this case. */
+ end = str + strlen(str);
+
+ if (mbtowc(NULL, NULL, 0))
+ {} /* Reset shift state. */
+
+ squash = true; /* Trim `space' or `cntrl' from the start. */
+ while (max) {
+ if (!*str)
+ return; /* It's unclear why no padding in this case. */
+
+ srclen = mbtowc(&rune, str, end - str);
+ if (srclen == -1) {
+ /* Invalid rune, or not enough bytes to finish it. */
+ rune = L'?';
+ src = oddchar;
+ srclen = oddlen;
+ str++; /* Skip one byte. */
+ } else {
+ src = str;
+ str += srclen;
+ }
- len -= char_len;
+ if (iswspace(rune) || iswcntrl(rune)) {
+ if (squash)
+ continue; /* Amidst a run of these. */
+ rune = L' ';
+ src = spacechar;
+ srclen = spacelen;
+ squash = true;
+ } else
+ squash = false;
- if (iswcntrl(wide_char) || iswspace(wide_char)) {
- str += char_len;
- if (! prevCtrl) {
- charstring_push_back (dest, ' ');
- --max;
- }
+ w = wcwidth(rune);
+ if (w == -1) {
+ rune = L'?';
+ w = wcwidth(rune);
+ assert(w != -1);
+ src = oddchar;
+ srclen = oddlen;
+ }
- prevCtrl = 1;
- continue;
- }
+ if ((size_t)w > max) {
+ /* No room for rune; pad. */
+ while (max--)
+ charstring_push_back_chars(dest, spacechar, spacelen, 1);
+ return;
+ }
- prevCtrl = 0;
-
- w = wcwidth(wide_char);
- assert(w >= 0);
- if (max >= (size_t) w) {
- charstring_push_back_chars (dest, altstr ? altstr : str, char_len, w);
- max -= w;
- str += char_len;
- altstr = NULL;
- } else {
- /* Not enough width available for the last character. Output
- space(s) to fill. */
- while (max-- > 0) {
- charstring_push_back (dest, ' ');
- }
- break;
- }
+ charstring_push_back_chars(dest, src, srclen, w);
+ max -= w;
}
}
#endif
case FT_LV_RCLOCK:
if ((value = fmt->f_comp->c_tws->tw_clock) == 0)
value = dmktime(fmt->f_comp->c_tws);
- value = time((time_t *) 0) - value;
+ value = time(NULL) - value;
break;
case FT_LV_DAYF:
if (!(((tws = fmt->f_comp->c_tws)->tw_flags) & (TW_SEXP|TW_SIMP)))
*comp->c_tws = *tws;
comp->c_flags &= ~CF_TRUE;
} else if ((comp->c_flags & CF_DATEFAB) == 0) {
- memset (comp->c_tws, 0, sizeof *comp->c_tws);
+ ZERO(comp->c_tws);
comp->c_flags = CF_TRUE;
}
comp->c_flags |= CF_PARSED;
}
}
- return (NULL);
+ return NULL;
}