Module Name:    src
Committed By:   christos
Date:           Sun Nov 19 18:57:11 UTC 2023

Modified Files:
        src/lib/libc/stdlib: strfmon.c

Log Message:
minimize diffs with FreeBSD.


To generate a diff of this commit:
cvs rdiff -u -r1.19 -r1.20 src/lib/libc/stdlib/strfmon.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/stdlib/strfmon.c
diff -u src/lib/libc/stdlib/strfmon.c:1.19 src/lib/libc/stdlib/strfmon.c:1.20
--- src/lib/libc/stdlib/strfmon.c:1.19	Thu Sep 28 06:03:41 2023
+++ src/lib/libc/stdlib/strfmon.c	Sun Nov 19 13:57:11 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: strfmon.c,v 1.19 2023/09/28 10:03:41 martin Exp $	*/
+/*	$NetBSD: strfmon.c,v 1.20 2023/11/19 18:57:11 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001 Alexey Zelkin <phan...@freebsd.org>
@@ -32,7 +32,7 @@
 #if 0
 __FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.14 2003/03/20 08:18:55 ache Exp $");
 #else
-__RCSID("$NetBSD: strfmon.c,v 1.19 2023/09/28 10:03:41 martin Exp $");
+__RCSID("$NetBSD: strfmon.c,v 1.20 2023/11/19 18:57:11 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -61,53 +61,53 @@ __RCSID("$NetBSD: strfmon.c,v 1.19 2023/
 #define	SUPPRESS_CURR_SYMBOL	0x10	/* suppress the currency from output */
 #define	LEFT_JUSTIFY		0x20	/* left justify */
 #define	USE_INTL_CURRENCY	0x40	/* use international currency symbol */
-#define IS_NEGATIVE		0x80	/* is argument value negative ? */
-
-#ifndef NBCHAR_MAX
-#define NBCHAR_MAX ((unsigned char)CHAR_MAX)
-#endif
+#define	IS_NEGATIVE		0x80	/* is argument value negative ? */
 
 /* internal macros */
-#define PRINT(CH) do {						\
+#define	PRINT(CH) do {						\
 	if (dst >= s + maxsize) 				\
 		goto e2big_error;				\
 	*dst++ = CH;						\
 } while (0)
 
-#define PRINTS(STR) do {					\
+#define	PRINTS(STR) do {					\
 	const char *tmps = STR;					\
 	while (*tmps != '\0')					\
 		PRINT(*tmps++);					\
 } while (0)
 
-#define GET_NUMBER(VAR)	do {					\
+#define	GET_NUMBER(VAR, LOC)	do {				\
 	VAR = 0;						\
-	while (isdigit((unsigned char)*fmt)) {			\
+	while (isdigit_l((unsigned char)*fmt, LOC)) {		\
+		if (VAR > INT_MAX / 10)				\
+			goto e2big_error;			\
 		VAR *= 10;					\
 		VAR += *fmt - '0';				\
-		if (VAR > 0x00ffffff)				\
+		if (VAR < 0)					\
 			goto e2big_error;			\
 		fmt++;						\
 	}							\
 } while (0)
 
-#define GRPCPY(howmany) do {					\
+#define	GRPCPY(howmany) do {					\
 	int i = howmany;					\
 	while (i-- > 0) {					\
 		avalue_size--;					\
-		*--bufend = *(avalue+avalue_size+padded);	\
+		*--bufend = *(avalue + avalue_size + padded);	\
 	}							\
 } while (0)
 
-#define GRPSEP do {						\
+#define	GRPSEP do {						\
 	bufend -= thousands_sep_size;				\
 	memcpy(bufend, thousands_sep, thousands_sep_size);	\
 	groups++;						\
 } while (0)
 
-static void __setup_vars(struct lconv *, int, char *, char *, char *, const char **);
-static int __calc_left_pad(struct lconv *, int, char *);
-static char *__format_grouped_double(struct lconv *, double, int *, int, int, int);
+static void __setup_vars(int, char *, char *, char *, const char **,
+    struct lconv *);
+static int __calc_left_pad(int, char *, struct lconv *);
+static char *__format_grouped_double(double, int *, int, int, int,
+    struct lconv *, locale_t loc);
 
 static ssize_t
 vstrfmon_l(char * __restrict s, size_t maxsize, locale_t loc,
@@ -150,7 +150,7 @@ vstrfmon_l(char * __restrict s, size_t m
 		/* '%' found ! */
 
 		/* "%%" mean just '%' */
-		if (*(fmt+1) == '%') {
+		if (*(fmt + 1) == '%') {
 			fmt++;
 	literal:
 			PRINT(*fmt++);
@@ -200,9 +200,9 @@ vstrfmon_l(char * __restrict s, size_t m
 		}
 
 		/* field Width */
-		if (isdigit((unsigned char)*fmt)) {
+		if (isdigit_l((unsigned char)*fmt, loc)) {
 			ptrdiff_t d = dst - s;
-			GET_NUMBER(width);
+			GET_NUMBER(width, loc);
 			/* Do we have enough space to put number with
 			 * required width ?
 			 */
@@ -213,18 +213,18 @@ vstrfmon_l(char * __restrict s, size_t m
 
 		/* Left precision */
 		if (*fmt == '#') {
-			if (!isdigit((unsigned char)*++fmt))
+			if (!isdigit_l((unsigned char)*++fmt, loc))
 				goto format_error;
-			GET_NUMBER(left_prec);
+			GET_NUMBER(left_prec, loc);
 			if ((unsigned int)left_prec >= maxsize - (dst - s))
 				goto e2big_error;
 		}
 
 		/* Right precision */
 		if (*fmt == '.') {
-			if (!isdigit((unsigned char)*++fmt))
+			if (!isdigit_l((unsigned char)*++fmt, loc))
 				goto format_error;
-			GET_NUMBER(right_prec);
+			GET_NUMBER(right_prec, loc);
 			if ((unsigned int)right_prec >= maxsize - (dst - s) -
 			    left_prec)
 				goto e2big_error;
@@ -243,7 +243,7 @@ vstrfmon_l(char * __restrict s, size_t m
 				goto format_error;
 		}
 
-		if (currency_symbol)
+		if (currency_symbol != NULL)
 			free(currency_symbol);
 		if (flags & USE_INTL_CURRENCY) {
 			currency_symbol = strdup(lc->int_curr_symbol);
@@ -252,7 +252,6 @@ vstrfmon_l(char * __restrict s, size_t m
 				space_char = currency_symbol[3];
 				currency_symbol[3] = '\0';
 			}
-
 		} else
 			currency_symbol = strdup(lc->currency_symbol);
 
@@ -270,24 +269,24 @@ vstrfmon_l(char * __restrict s, size_t m
 
 		/* fill left_prec with amount of padding chars */
 		if (left_prec >= 0) {
-			pad_size = __calc_left_pad(lc, (flags ^ IS_NEGATIVE),
-							currency_symbol) -
-				   __calc_left_pad(lc, flags, currency_symbol);
+			pad_size = __calc_left_pad((flags ^ IS_NEGATIVE),
+			    currency_symbol, lc) -
+			    __calc_left_pad(flags, currency_symbol, lc);
 			if (pad_size < 0)
 				pad_size = 0;
 		}
 
 		if (asciivalue != NULL)
 			free(asciivalue);
-		asciivalue = __format_grouped_double(lc, value, &flags,
-				left_prec, right_prec, pad_char);
+		asciivalue = __format_grouped_double(value, &flags,
+		    left_prec, right_prec, pad_char, lc, loc);
 		if (asciivalue == NULL)
 			goto end_error;		/* errno already set     */
 						/* to ENOMEM by malloc() */
 
 		/* set some variables for later use */
-		__setup_vars(lc, flags, &cs_precedes, &sep_by_space,
-				&sign_posn, &signstr);
+		__setup_vars(flags, &cs_precedes, &sep_by_space,
+		    &sign_posn, &signstr, lc);
 
 		/*
 		 * Description of some LC_MONETARY's values:
@@ -295,29 +294,29 @@ vstrfmon_l(char * __restrict s, size_t m
 		 * p_cs_precedes & n_cs_precedes
 		 *
 		 * = 1 - $currency_symbol precedes the value
-		 *       for a monetary quantity with a non-negative value
+		 *	 for a monetary quantity with a non-negative value
 		 * = 0 - symbol succeeds the value
 		 *
 		 * p_sep_by_space & n_sep_by_space
-                 *
+		 *
 		 * = 0 - no space separates $currency_symbol
-		 *       from the value for a monetary quantity with a
+		 *	 from the value for a monetary quantity with a
 		 *	 non-negative value
 		 * = 1 - space separates the symbol from the value
 		 * = 2 - space separates the symbol and the sign string,
-		 *       if adjacent.
-                 *
+		 *	 if adjacent.
+		 *
 		 * p_sign_posn & n_sign_posn
-                 *
+		 *
 		 * = 0 - parentheses enclose the quantity and the
 		 *	 $currency_symbol
 		 * = 1 - the sign string precedes the quantity and the 
-		 *       $currency_symbol
+		 *	 $currency_symbol
 		 * = 2 - the sign string succeeds the quantity and the 
-		 *       $currency_symbol
+		 *	 $currency_symbol
 		 * = 3 - the sign string precedes the $currency_symbol
 		 * = 4 - the sign string succeeds the $currency_symbol
-                 *
+		 *
 		 */
 
 		tmpptr = dst;
@@ -331,7 +330,7 @@ vstrfmon_l(char * __restrict s, size_t m
 		if (cs_precedes == 1) {
 			if (sign_posn == 1 || sign_posn == 3) {
 				PRINTS(signstr);
-				if (sep_by_space == 2)		/* XXX: ? */
+				if (sep_by_space == 2)	/* XXX: ? */
 					PRINT(' ');
 			}
 
@@ -347,8 +346,11 @@ vstrfmon_l(char * __restrict s, size_t m
 				} else if (sep_by_space == 1)
 					PRINT(space_char);
 			}
-		} else if (sign_posn == 1)
+		} else if (sign_posn == 1) {
 			PRINTS(signstr);
+			if (sep_by_space == 2)
+				PRINT(' ');
+		}
 
 		PRINTS(asciivalue);
 
@@ -382,20 +384,27 @@ vstrfmon_l(char * __restrict s, size_t m
 			PRINTS(signstr);
 		}
 
-		if (sign_posn == 0 && (flags & IS_NEGATIVE))
-			PRINT(')');
+		if (sign_posn == 0) {
+			if (flags & IS_NEGATIVE)
+				PRINT(')');
+#if 0
+			else if (left_prec >= 0)
+				PRINT(' ');
+#endif
+		}
 
 		if (dst - tmpptr < width) {
 			if (flags & LEFT_JUSTIFY) {
 				while (dst - tmpptr < width)
 					PRINT(' ');
 			} else {
+				size_t wps;
 				_DIAGASSERT(__type_fit(int, dst - tmpptr));
-				pad_size = dst - tmpptr;
-				memmove(tmpptr + width-pad_size, tmpptr,
-				    (size_t) pad_size);
-				memset(tmpptr, ' ', (size_t) width-pad_size);
-				dst += width-pad_size;
+				pad_size = (int)(dst - tmpptr);
+				wps = width - pad_size;
+				memmove(tmpptr + wps, tmpptr, (size_t)pad_size);
+				memset(tmpptr, ' ', wps);
+				dst += wps;
 			}
 		}
 	}
@@ -423,8 +432,9 @@ end_error:
 }
 
 static void
-__setup_vars(struct lconv *lc, int flags, char *cs_precedes, char *sep_by_space,
-		char *sign_posn, const char **signstr) {
+__setup_vars(int flags, char *cs_precedes, char *sep_by_space,
+    char *sign_posn, const char **signstr, struct lconv *lc)
+{
 
 	if ((flags & IS_NEGATIVE) && (flags & USE_INTL_CURRENCY)) {
 		*cs_precedes = lc->int_n_cs_precedes;
@@ -453,20 +463,21 @@ __setup_vars(struct lconv *lc, int flags
 	/* Set default values for unspecified information. */
 	if (*cs_precedes != 0)
 		*cs_precedes = 1;
-	if ((unsigned char)*sep_by_space == NBCHAR_MAX)
-		*sep_by_space = 1;
-	if ((unsigned char)*sign_posn == NBCHAR_MAX)
+	if (*sep_by_space == CHAR_MAX)
+		*sep_by_space = 0;
+	if (*sign_posn == CHAR_MAX)
 		*sign_posn = 0;
 }
 
 static int
-__calc_left_pad(struct lconv *lc, int flags, char *cur_symb) {
-
+__calc_left_pad(int flags, char *cur_symb, struct lconv *lc)
+{
 	char cs_precedes, sep_by_space, sign_posn;
 	const char *signstr;
 	size_t left_chars = 0;
 
-	__setup_vars(lc, flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr);
+	__setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn,
+	    &signstr, lc);
 
 	if (cs_precedes != 0) {
 		left_chars += strlen(cur_symb);
@@ -475,6 +486,10 @@ __calc_left_pad(struct lconv *lc, int fl
 	}
 
 	switch (sign_posn) {
+		case 0:
+			if (flags & IS_NEGATIVE)
+				left_chars++;
+			break;
 		case 1:
 			left_chars += strlen(signstr);
 			break;
@@ -488,18 +503,18 @@ __calc_left_pad(struct lconv *lc, int fl
 }
 
 static int
-get_groups(int size, char *grouping) {
-
+get_groups(int size, char *grouping)
+{
 	int	chars = 0;
 
-	if ((unsigned char)*grouping == NBCHAR_MAX || *grouping <= 0)	/* no grouping ? */
+	if (*grouping == CHAR_MAX || *grouping <= 0)	/* no grouping ? */
 		return (0);
 
 	while (size > (int)*grouping) {
 		chars++;
 		size -= (int)*grouping++;
 		/* no more grouping ? */
-		if ((unsigned char)*grouping == NBCHAR_MAX)
+		if (*grouping == CHAR_MAX)
 			break;
 		/* rest grouping with same value ? */
 		if (*grouping == 0) {
@@ -512,8 +527,9 @@ get_groups(int size, char *grouping) {
 
 /* convert double to locale-encoded string */
 static char *
-__format_grouped_double(struct lconv *lc, double value, int *flags,
-			int left_prec, int right_prec, int pad_char) {
+__format_grouped_double(double value, int *flags, int left_prec,
+    int right_prec, int pad_char, struct lconv *lc, locale_t loc)
+{
 
 	char		*rslt;
 	char		*avalue;
@@ -549,10 +565,10 @@ __format_grouped_double(struct lconv *lc
 
 	/* fill right_prec with default value */
 	if (right_prec == -1) {
-                if (*flags & USE_INTL_CURRENCY)
-                        right_prec = lc->int_frac_digits;
-                else
-                        right_prec = lc->frac_digits;
+		if (*flags & USE_INTL_CURRENCY)
+			right_prec = lc->int_frac_digits;
+		else
+			right_prec = lc->frac_digits;
 
 		if (right_prec == CHAR_MAX)	/* POSIX locale ? */
 			right_prec = 2;
@@ -562,8 +578,8 @@ __format_grouped_double(struct lconv *lc
 		left_prec += get_groups(left_prec, grouping);
 
 	/* convert to string */
-	avalue_size = asprintf(&avalue, "%*.*f", left_prec + right_prec + 1,
-	    right_prec, value);
+	avalue_size = asprintf_l(&avalue, loc, "%*.*f",
+	    left_prec + right_prec + 1, right_prec, value);
 	if (avalue_size < 0)
 		return (NULL);
 
@@ -586,7 +602,7 @@ __format_grouped_double(struct lconv *lc
 
 	if (right_prec > 0) {
 		bufend -= right_prec;
-		memcpy(bufend, avalue + avalue_size+padded-right_prec,
+		memcpy(bufend, avalue + avalue_size + padded - right_prec,
 		    (size_t) right_prec);
 		bufend -= decimal_point_size;
 		memcpy(bufend, decimal_point, decimal_point_size);
@@ -595,7 +611,7 @@ __format_grouped_double(struct lconv *lc
 
 	if ((*flags & NEED_GROUPING) &&
 	    thousands_sep_size > 0 &&	/* XXX: need investigation */
-	    (unsigned char)*grouping != NBCHAR_MAX &&
+	    *grouping != CHAR_MAX &&
 	    *grouping > 0) {
 		while (avalue_size > (int)*grouping) {
 			GRPCPY(*grouping);
@@ -603,7 +619,7 @@ __format_grouped_double(struct lconv *lc
 			grouping++;
 
 			/* no more grouping ? */
-			if ((unsigned char)*grouping == NBCHAR_MAX)
+			if (*grouping == CHAR_MAX)
 				break;
 
 			/* rest grouping with same value ? */
@@ -618,12 +634,11 @@ __format_grouped_double(struct lconv *lc
 		if (avalue_size != 0)
 			GRPCPY(avalue_size);
 		padded -= groups;
-
 	} else {
 		bufend -= avalue_size;
-		memcpy(bufend, avalue+padded, (size_t) avalue_size);
+		memcpy(bufend, avalue + padded, (size_t) avalue_size);
 		if (right_prec == 0)
-			padded -= decimal_point_size;
+			padded -= (int)decimal_point_size;
 	}
 
 	/* do padding with pad_char */
@@ -642,26 +657,26 @@ ssize_t
 strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
     ...)
 {
-	ssize_t rv;
+	ssize_t ret;
 	va_list ap;
 
 	va_start(ap, format);
-	rv = vstrfmon_l(s, maxsize, _current_locale(), format, ap);
+	ret = vstrfmon_l(s, maxsize, _current_locale(), format, ap);
 	va_end(ap);
 
-	return rv;
+	return ret;
 }
 
 ssize_t
 strfmon_l(char * __restrict s, size_t maxsize, locale_t loc,
     const char * __restrict format, ...)
 {
-	ssize_t rv;
+	ssize_t ret;
 	va_list ap;
 
 	va_start(ap, format);
-	rv = vstrfmon_l(s, maxsize, loc, format, ap);
+	ret = vstrfmon_l(s, maxsize, loc, format, ap);
 	va_end(ap);
 
-	return rv;
+	return ret;
 }

Reply via email to