struct mailname fmt_mnull = { NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0,
NULL, NULL };
struct mailname fmt_mnull = { NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0,
NULL, NULL };
- c1 = (isalpha(c1) && isupper(c1)) ? tolower(c1) : c1;
- while ((c2 = *str++) && c1 != ((isalpha(c2) && isupper(c2)) ? tolower(c2) : c2))
+ c1 = (isascii((unsigned char) c1) && isalpha((unsigned char) c1) &&
+ isupper((unsigned char) c1)) ? tolower((unsigned char) c1) : c1;
+ while ((c2 = *str++) && c1 != ((isascii((unsigned char) c2) &&
+ isalpha((unsigned char) c2) &&
+ isupper((unsigned char) c2)) ?
+ tolower((unsigned char) c2) : c2))
- while ((c1 = *s1++) && ((isalpha(c1) && isupper(c1)) ? tolower(c1) : c1) == ((isalpha(c2 =*s2++) && isupper(c2)) ? tolower(c2) : c2))
+ while ((c1 = *s1++) && ((isascii((unsigned char) c1) &&
+ isalpha((unsigned char) c1) &&
+ isupper((unsigned char) c1)) ?
+ tolower(c1) : c1) ==
+ ((isascii((unsigned char) (c2 =*s2++)) &&
+ isalpha((unsigned char) c2) &&
+ isupper((unsigned char) c2)) ?
+ tolower((unsigned char) c2) : c2))
-cptrimmed(char **dest, char *str, unsigned int wid, char fill, size_t n,
- size_t max) {
+cptrimmed(char **dest, char **ep, char *str, unsigned int wid, char fill,
+ char *epmax) {
int remaining; /* remaining output width available */
int c, ljust;
int end; /* number of input bytes remaining in str */
int remaining; /* remaining output width available */
int c, ljust;
int end; /* number of input bytes remaining in str */
#endif
char *sp; /* current position in source string */
char *cp = *dest; /* current position in destination string */
#endif
char *sp; /* current position in source string */
char *cp = *dest; /* current position in destination string */
end = strlen(str);
while (*sp && remaining > 0 && end > 0) {
#ifdef MULTIBYTE_SUPPORT
char_len = mbtowc(&wide_char, sp, end);
end = strlen(str);
while (*sp && remaining > 0 && end > 0) {
#ifdef MULTIBYTE_SUPPORT
char_len = mbtowc(&wide_char, sp, end);
- /* Account for multibyte characters taking only one character's
- width of output. */
- if (char_len > 1 && epmax - ep >= char_len - 1) {
- ep += char_len - 1;
+ /*
+ * See the relevant comments in cpstripped() to explain what's
+ * going on here; we want to handle the case where we get
+ * characters that mbtowc() cannot handle
+ */
+
+ if (char_len < 0) {
+ altstr = "?";
+ char_len = mbtowc(&wide_char, altstr, 1);
+ }
+
+ if (char_len <= 0)
+ break;
+
+ w = wcwidth(wide_char);
+
+ /*
+ * Multibyte characters can have a variable number of column
+ * widths, so use the column width to bump the end pointer when
+ * appropriate.
+ */
+ if (w >= 0 && char_len > 1 && epmax - *ep >= char_len - w) {
+ *ep += char_len - w;
end--;
/* isnctrl(), etc., take an int argument. Cygwin's ctype.h
intentionally warns if they are passed a char. */
end--;
/* isnctrl(), etc., take an int argument. Cygwin's ctype.h
intentionally warns if they are passed a char. */
-cpstripped (char **dest, char *end, char *max, char *str)
+cpstripped (char **dest, char **end, char *max, char *str)
+ w = wcwidth(wide_char);
+
+ /*
+ * Account for multibyte characters, and increment the end pointer
+ * by the number of "extra" bytes in this character. That's the
+ * character length (char_len) minus the column width (w).
+ */
+ if (w >= 0 && char_len > 1 && max - *end >= char_len - w) {
+ *end += char_len - w;
+ }
- /* Account for multibyte characters taking only one character's
- width of output. */
- if (char_len > 1 && max - end >= char_len - 1) {
- end += char_len - 1;
+ /*
+ * If mbrtowc() failed, then we have a character that isn't valid
+ * in the current encoding. 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);
fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat,
struct fmt_callbacks *callbacks)
{
fmt_scan (struct format *format, char *scanl, size_t max, int width, int *dat,
struct fmt_callbacks *callbacks)
{
- cpstripped (&cp, ep, scanl + max - 1, fmt->f_comp->c_text);
+ cpstripped (&cp, &ep, scanl + max - 1, fmt->f_comp->c_text);
- cptrimmed (&cp, fmt->f_comp->c_text, fmt->f_width, fmt->f_fill,
- ep - cp, scanl - cp + max - 1);
+ cptrimmed (&cp, &ep, fmt->f_comp->c_text, fmt->f_width, fmt->f_fill,
+ scanl + max - 1);
- cpstripped (&cp, ep, scanl + max - 1, str);
+ cpstripped (&cp, &ep, scanl + max - 1, str);
- cptrimmed (&cp, str, fmt->f_width, fmt->f_fill, ep - cp,
- scanl - cp + max - 1);
+ cptrimmed (&cp, &ep, str, fmt->f_width, fmt->f_fill,
+ scanl + max - 1);
- case FT_STRLITZ: {
- size_t len = strlen (str);
-
- /* Don't want to emit part of an escape sequence. So if
- there isn't enough room in the buffer for the entire
- string, skip it completely. */
- if (cp - scanl + len + 1 < max) {
- for (sp = str; *sp; *cp++ = *sp++) continue;
-
- /* This string doesn't count against the width. So
- increase ep the same amount as cp, only if the
- scan buffer will always be large enough. */
- if (ep - scanl + len + 1 < max) {
- ep += len;
+ case FT_STRLITZ:
+ if (str) {
+ size_t len = strlen (str);
+
+ /* Don't want to emit part of an escape sequence. So if
+ there isn't enough room in the buffer for the entire
+ string, skip it completely. */
+ if (cp - scanl + len + 1 < max) {
+ for (sp = str; *sp; *cp++ = *sp++) continue;
+
+ /* This string doesn't count against the width.
+ So increase ep the same amount as cp, only if the
+ scan buffer will always be large enough. */
+ if (ep - scanl + len + 1 < max) {
+ ep += len;
+ }
strncpy(buffer, str, sizeof(buffer));
buffer[sizeof(buffer)-1] = '\0';
str = buffer;
strncpy(buffer, str, sizeof(buffer));
buffer[sizeof(buffer)-1] = '\0';
str = buffer;
strncpy(buffer, str, sizeof(buffer));
/* strncpy doesn't NUL-terminate if it fills the buffer */
buffer[sizeof(buffer)-1] = '\0';
strncpy(buffer, str, sizeof(buffer));
/* strncpy doesn't NUL-terminate if it fills the buffer */
buffer[sizeof(buffer)-1] = '\0';
- str = buffer;
-
- /* we will parse from buffer to buffer2 */
- n = 0; /* n is the input position in str */
- m = 0; /* m is the ouput position in buffer2 */
-
- while ( str[n] != '\0') {
- switch ( str[n] ) {
- case '\\':
- n++;
- if ( str[n] != '\0')
- buffer2[m++] = str[n++];
- break;
- case '"':
- n++;
- break;
- default:
- buffer2[m++] = str[n++];
- break;
- }
- }
- buffer2[m] = '\0';
+ unquote_string(buffer, buffer2);
adios(NULL, "putaddr -- num register (%d) must be greater "
"than label width (%d)", value, indent);
}
adios(NULL, "putaddr -- num register (%d) must be greater "
"than label width (%d)", value, indent);
}
while (len > wid) {
/* try to break at a comma; failing that, break at a
* space.
*/
lastb = 0; sp = lp + wid;
while (len > wid) {
/* try to break at a comma; failing that, break at a
* space.
*/
lastb = 0; sp = lp + wid;
- cpstripped (&cp, ep, scanl + max - 1, lp);
+ cpstripped (&cp, &ep, scanl + max - 1, lp);
- (mn = getm (sp, NULL, 0, fmt_norm, NULL))) {
+ (mn = getm (sp, NULL, 0, NULL, 0))) {
- (mn = getm (sp, NULL, 0, AD_NAME, NULL))) {
+ (mn = getm (sp, NULL, 0, NULL, 0))) {
comp->c_flags &= ~CF_TRUE;
while ((sp = getname(sp)))
if ((comp->c_flags & CF_TRUE) == 0 &&
comp->c_flags &= ~CF_TRUE;
while ((sp = getname(sp)))
if ((comp->c_flags & CF_TRUE) == 0 &&
- (mn = getm (sp, NULL, 0, AD_NAME, NULL)))
+ (mn = getm (sp, NULL, 0, NULL, 0)))
+
+ /*
+ * Call our tracing callback function, if one was supplied
+ */
+
+ if (callbacks && callbacks->trace_func)
+ callbacks->trace_func(callbacks->trace_context, fmt, value,
+ str, scanl);
} else if (fmt->f_type == FT_STRLITZ) {
/* Don't want to emit part of an escape sequence. So if
there isn't enough room in the buffer for the entire
string, skip it completely. Need room for null
terminator, and maybe trailing newline (added below). */
} else if (fmt->f_type == FT_STRLITZ) {
/* Don't want to emit part of an escape sequence. So if
there isn't enough room in the buffer for the entire
string, skip it completely. Need room for null
terminator, and maybe trailing newline (added below). */