[BACK]Return to strfmon.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / stdlib

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

Diff for /src/lib/libc/stdlib/strfmon.c between version 1.9 and 1.11

version 1.9, 2012/03/13 21:13:48 version 1.11, 2017/08/16 13:53:20
Line 36  __RCSID("$NetBSD$");
Line 36  __RCSID("$NetBSD$");
 #endif  #endif
 #endif /* LIBC_SCCS and not lint */  #endif /* LIBC_SCCS and not lint */
   
 #if defined(__NetBSD__)  
 #include "namespace.h"  #include "namespace.h"
 #include <monetary.h>  
 #endif  
   
 #include <sys/types.h>  #include <sys/types.h>
 #include <assert.h>  #include <assert.h>
Line 47  __RCSID("$NetBSD$");
Line 44  __RCSID("$NetBSD$");
 #include <errno.h>  #include <errno.h>
 #include <limits.h>  #include <limits.h>
 #include <locale.h>  #include <locale.h>
   #include <monetary.h>
 #include <stdarg.h>  #include <stdarg.h>
   #include <stddef.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
 #include <stddef.h>  
   #include "setlocale_local.h"
   
 /* internal flags */  /* internal flags */
 #define NEED_GROUPING           0x01    /* print digits grouped (default) */  #define NEED_GROUPING           0x01    /* print digits grouped (default) */
Line 63  __RCSID("$NetBSD$");
Line 63  __RCSID("$NetBSD$");
 #define USE_INTL_CURRENCY       0x40    /* use international currency symbol */  #define USE_INTL_CURRENCY       0x40    /* use international currency symbol */
 #define IS_NEGATIVE             0x80    /* is argument value negative ? */  #define IS_NEGATIVE             0x80    /* is argument value negative ? */
   
   #ifndef NBCHAR_MAX
   #define NBCHAR_MAX ((unsigned char)CHAR_MAX)
   #endif
   
 /* internal macros */  /* internal macros */
 #define PRINT(CH) do {                                          \  #define PRINT(CH) do {                                          \
         if (dst >= s + maxsize)                                 \          if (dst >= s + maxsize)                                 \
Line 100  __RCSID("$NetBSD$");
Line 104  __RCSID("$NetBSD$");
         groups++;                                               \          groups++;                                               \
 } while (/* CONSTCOND */ 0)  } while (/* CONSTCOND */ 0)
   
 static void __setup_vars(int, char *, char *, char *, const char **);  static void __setup_vars(struct lconv *, int, char *, char *, char *, const char **);
 static int __calc_left_pad(int, char *);  static int __calc_left_pad(struct lconv *, int, char *);
 static char *__format_grouped_double(double, int *, int, int, int);  static char *__format_grouped_double(struct lconv *, double, int *, int, int, int);
   
 ssize_t  static ssize_t
 strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,  vstrfmon_l(char * __restrict s, size_t maxsize, locale_t loc,
     ...)      const char * __restrict format, va_list ap)
 {  {
         va_list         ap;  
         char            *dst;           /* output destination pointer */          char            *dst;           /* output destination pointer */
         const char      *fmt;           /* current format poistion pointer */          const char      *fmt;           /* current format poistion pointer */
         struct lconv    *lc;            /* pointer to lconv structure */          struct lconv    *lc;            /* pointer to lconv structure */
Line 132  strfmon(char * __restrict s, size_t maxs
Line 135  strfmon(char * __restrict s, size_t maxs
         char            *tmpptr;        /* temporary vars */          char            *tmpptr;        /* temporary vars */
         int             sverrno;          int             sverrno;
   
         va_start(ap, format);          lc = localeconv_l(loc);
   
         lc = localeconv();  
         dst = s;          dst = s;
         fmt = format;          fmt = format;
         asciivalue = NULL;          asciivalue = NULL;
Line 259  strfmon(char * __restrict s, size_t maxs
Line 260  strfmon(char * __restrict s, size_t maxs
   
                 /* fill left_prec with amount of padding chars */                  /* fill left_prec with amount of padding chars */
                 if (left_prec >= 0) {                  if (left_prec >= 0) {
                         pad_size = __calc_left_pad((flags ^ IS_NEGATIVE),                          pad_size = __calc_left_pad(lc, (flags ^ IS_NEGATIVE),
                                                         currency_symbol) -                                                          currency_symbol) -
                                    __calc_left_pad(flags, currency_symbol);                                     __calc_left_pad(lc, flags, currency_symbol);
                         if (pad_size < 0)                          if (pad_size < 0)
                                 pad_size = 0;                                  pad_size = 0;
                 }                  }
   
                 asciivalue = __format_grouped_double(value, &flags,                  asciivalue = __format_grouped_double(lc, value, &flags,
                                 left_prec, right_prec, pad_char);                                  left_prec, right_prec, pad_char);
                 if (asciivalue == NULL)                  if (asciivalue == NULL)
                         goto end_error;         /* errno already set     */                          goto end_error;         /* errno already set     */
                                                 /* to ENOMEM by malloc() */                                                  /* to ENOMEM by malloc() */
   
                 /* set some variables for later use */                  /* set some variables for later use */
                 __setup_vars(flags, &cs_precedes, &sep_by_space,                  __setup_vars(lc, flags, &cs_precedes, &sep_by_space,
                                 &sign_posn, &signstr);                                  &sign_posn, &signstr);
   
                 /*                  /*
Line 388  strfmon(char * __restrict s, size_t maxs
Line 389  strfmon(char * __restrict s, size_t maxs
         }          }
   
         PRINT('\0');          PRINT('\0');
         va_end(ap);  
         free(asciivalue);          free(asciivalue);
         free(currency_symbol);          free(currency_symbol);
         return (dst - s - 1);   /* return size of put data except trailing '\0' */          return (dst - s - 1);   /* return size of put data except trailing '\0' */
Line 407  end_error:
Line 407  end_error:
         if (currency_symbol != NULL)          if (currency_symbol != NULL)
                 free(currency_symbol);                  free(currency_symbol);
         errno = sverrno;          errno = sverrno;
         va_end(ap);  
         return (-1);          return (-1);
 }  }
   
 static void  static void
 __setup_vars(int flags, char *cs_precedes, char *sep_by_space,  __setup_vars(struct lconv *lc, int flags, char *cs_precedes, char *sep_by_space,
                 char *sign_posn, const char **signstr) {                  char *sign_posn, const char **signstr) {
         struct lconv *lc = localeconv();  
   
         if ((flags & IS_NEGATIVE) && (flags & USE_INTL_CURRENCY)) {          if ((flags & IS_NEGATIVE) && (flags & USE_INTL_CURRENCY)) {
                 *cs_precedes = lc->int_n_cs_precedes;                  *cs_precedes = lc->int_n_cs_precedes;
Line 443  __setup_vars(int flags, char *cs_precede
Line 441  __setup_vars(int flags, char *cs_precede
         /* Set defult values for unspecified information. */          /* Set defult values for unspecified information. */
         if (*cs_precedes != 0)          if (*cs_precedes != 0)
                 *cs_precedes = 1;                  *cs_precedes = 1;
         if (*sep_by_space == CHAR_MAX)          if ((unsigned char)*sep_by_space == NBCHAR_MAX)
                 *sep_by_space = 0;                  *sep_by_space = 0;
         if (*sign_posn == CHAR_MAX)          if ((unsigned char)*sign_posn == NBCHAR_MAX)
                 *sign_posn = 0;                  *sign_posn = 0;
 }  }
   
 static int  static int
 __calc_left_pad(int flags, char *cur_symb) {  __calc_left_pad(struct lconv *lc, int flags, char *cur_symb) {
   
         char cs_precedes, sep_by_space, sign_posn;          char cs_precedes, sep_by_space, sign_posn;
         const char *signstr;          const char *signstr;
         size_t left_chars = 0;          size_t left_chars = 0;
   
         __setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr);          __setup_vars(lc, flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr);
   
         if (cs_precedes != 0) {          if (cs_precedes != 0) {
                 left_chars += strlen(cur_symb);                  left_chars += strlen(cur_symb);
Line 482  get_groups(int size, char *grouping) {
Line 480  get_groups(int size, char *grouping) {
   
         int     chars = 0;          int     chars = 0;
   
         if (*grouping == CHAR_MAX || *grouping <= 0)    /* no grouping ? */          if ((unsigned char)*grouping == NBCHAR_MAX || *grouping <= 0)   /* no grouping ? */
                 return (0);                  return (0);
   
         while (size > (int)*grouping) {          while (size > (int)*grouping) {
                 chars++;                  chars++;
                 size -= (int)*grouping++;                  size -= (int)*grouping++;
                 /* no more grouping ? */                  /* no more grouping ? */
                 if (*grouping == CHAR_MAX)                  if ((unsigned char)*grouping == NBCHAR_MAX)
                         break;                          break;
                 /* rest grouping with same value ? */                  /* rest grouping with same value ? */
                 if (*grouping == 0) {                  if (*grouping == 0) {
Line 502  get_groups(int size, char *grouping) {
Line 500  get_groups(int size, char *grouping) {
   
 /* convert double to ASCII */  /* convert double to ASCII */
 static char *  static char *
 __format_grouped_double(double value, int *flags,  __format_grouped_double(struct lconv *lc, double value, int *flags,
                         int left_prec, int right_prec, int pad_char) {                          int left_prec, int right_prec, int pad_char) {
   
         char            *rslt;          char            *rslt;
Line 514  __format_grouped_double(double value, in
Line 512  __format_grouped_double(double value, in
   
         int             padded;          int             padded;
   
         struct lconv    *lc = localeconv();  
         char            *grouping;          char            *grouping;
         char            decimal_point;          char            decimal_point;
         char            thousands_sep;          char            thousands_sep;
Line 581  __format_grouped_double(double value, in
Line 578  __format_grouped_double(double value, in
         /* XXX: Why not use %' instead? */          /* XXX: Why not use %' instead? */
         if ((*flags & NEED_GROUPING) &&          if ((*flags & NEED_GROUPING) &&
             thousands_sep != '\0' &&    /* XXX: need investigation */              thousands_sep != '\0' &&    /* XXX: need investigation */
             *grouping != CHAR_MAX &&              (unsigned char)*grouping != NBCHAR_MAX &&
             *grouping > 0) {              *grouping > 0) {
                 while (avalue_size > (int)*grouping) {                  while (avalue_size > (int)*grouping) {
                         GRPCPY(*grouping);                          GRPCPY(*grouping);
Line 589  __format_grouped_double(double value, in
Line 586  __format_grouped_double(double value, in
                         grouping++;                          grouping++;
   
                         /* no more grouping ? */                          /* no more grouping ? */
                         if (*grouping == CHAR_MAX)                          if ((unsigned char)*grouping == NBCHAR_MAX)
                                 break;                                  break;
   
                         /* rest grouping with same value ? */                          /* rest grouping with same value ? */
Line 623  __format_grouped_double(double value, in
Line 620  __format_grouped_double(double value, in
         free(avalue);          free(avalue);
         return (rslt);          return (rslt);
 }  }
   
   ssize_t
   strfmon(char * __restrict s, size_t maxsize, const char * __restrict format,
       ...)
   {
           ssize_t rv;
           va_list ap;
   
           va_start(ap, format);
           rv = vstrfmon_l(s, maxsize, _current_locale(), format, ap);
           va_end(ap);
   
           return rv;
   }
   
   ssize_t
   strfmon_l(char * __restrict s, size_t maxsize, locale_t loc,
       const char * __restrict format, ...)
   {
           ssize_t rv;
           va_list ap;
   
           va_start(ap, format);
           rv = vstrfmon_l(s, maxsize, loc, format, ap);
           va_end(ap);
   
           return rv;
   }

Legend:
Removed from v.1.9  
changed lines
  Added in v.1.11

CVSweb <webmaster@jp.NetBSD.org>