version 1.4, 2006/03/19 01:50:49 |
version 1.10, 2012/03/21 14:19:15 |
Line 42 __RCSID("$NetBSD$"); |
|
Line 42 __RCSID("$NetBSD$"); |
|
#endif |
#endif |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
|
#include <assert.h> |
#include <ctype.h> |
#include <ctype.h> |
#include <errno.h> |
#include <errno.h> |
#include <limits.h> |
#include <limits.h> |
Line 50 __RCSID("$NetBSD$"); |
|
Line 51 __RCSID("$NetBSD$"); |
|
#include <stdio.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
|
#include <stddef.h> |
|
|
/* internal flags */ |
/* internal flags */ |
#define NEED_GROUPING 0x01 /* print digits grouped (default) */ |
#define NEED_GROUPING 0x01 /* print digits grouped (default) */ |
Line 61 __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 79 __RCSID("$NetBSD$"); |
|
Line 85 __RCSID("$NetBSD$"); |
|
while (isdigit((unsigned char)*fmt)) { \ |
while (isdigit((unsigned char)*fmt)) { \ |
VAR *= 10; \ |
VAR *= 10; \ |
VAR += *fmt - '0'; \ |
VAR += *fmt - '0'; \ |
|
if (VAR > 0x00ffffff) \ |
|
goto e2big_error; \ |
fmt++; \ |
fmt++; \ |
} \ |
} \ |
} while (/* CONSTCOND */ 0) |
} while (/* CONSTCOND */ 0) |
Line 195 strfmon(char * __restrict s, size_t maxs |
|
Line 203 strfmon(char * __restrict s, size_t maxs |
|
|
|
/* field Width */ |
/* field Width */ |
if (isdigit((unsigned char)*fmt)) { |
if (isdigit((unsigned char)*fmt)) { |
|
ptrdiff_t d = dst - s; |
GET_NUMBER(width); |
GET_NUMBER(width); |
/* Do we have enough space to put number with |
/* Do we have enough space to put number with |
* required width ? |
* required width ? |
*/ |
*/ |
if (dst + width >= s + maxsize) |
|
|
if ((size_t)(d + width) >= maxsize) |
goto e2big_error; |
goto e2big_error; |
} |
} |
|
|
Line 371 strfmon(char * __restrict s, size_t maxs |
|
Line 381 strfmon(char * __restrict s, size_t maxs |
|
while (dst - tmpptr < width) |
while (dst - tmpptr < width) |
PRINT(' '); |
PRINT(' '); |
} else { |
} else { |
pad_size = dst-tmpptr; |
_DIAGASSERT(__type_fit(int, dst - tmpptr)); |
|
pad_size = dst - tmpptr; |
memmove(tmpptr + width-pad_size, tmpptr, |
memmove(tmpptr + width-pad_size, tmpptr, |
(size_t) pad_size); |
(size_t) pad_size); |
memset(tmpptr, ' ', (size_t) width-pad_size); |
memset(tmpptr, ' ', (size_t) width-pad_size); |
Line 436 __setup_vars(int flags, char *cs_precede |
|
Line 447 __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; |
} |
} |
|
|
Line 447 __calc_left_pad(int flags, char *cur_sym |
|
Line 458 __calc_left_pad(int flags, char *cur_sym |
|
|
|
char cs_precedes, sep_by_space, sign_posn; |
char cs_precedes, sep_by_space, sign_posn; |
const char *signstr; |
const char *signstr; |
int left_chars = 0; |
size_t left_chars = 0; |
|
|
__setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr); |
__setup_vars(flags, &cs_precedes, &sep_by_space, &sign_posn, &signstr); |
|
|
Line 466 __calc_left_pad(int flags, char *cur_sym |
|
Line 477 __calc_left_pad(int flags, char *cur_sym |
|
if (cs_precedes != 0) |
if (cs_precedes != 0) |
left_chars += strlen(signstr); |
left_chars += strlen(signstr); |
} |
} |
return (left_chars); |
_DIAGASSERT(__type_fit(int, left_chars)); |
|
return (int)left_chars; |
} |
} |
|
|
static int |
static int |
Line 474 get_groups(int size, char *grouping) { |
|
Line 486 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 500 __format_grouped_double(double value, in |
|
Line 512 __format_grouped_double(double value, in |
|
char *rslt; |
char *rslt; |
char *avalue; |
char *avalue; |
int avalue_size; |
int avalue_size; |
char fmt[32]; |
|
|
|
size_t bufsize; |
size_t bufsize; |
char *bufend; |
char *bufend; |
Line 541 __format_grouped_double(double value, in |
|
Line 552 __format_grouped_double(double value, in |
|
left_prec += get_groups(left_prec, grouping); |
left_prec += get_groups(left_prec, grouping); |
|
|
/* convert to string */ |
/* convert to string */ |
snprintf(fmt, sizeof(fmt), "%%%d.%df", left_prec + right_prec + 1, |
avalue_size = asprintf(&avalue, "%*.*f", left_prec + right_prec + 1, |
right_prec); |
right_prec, value); |
avalue_size = asprintf(&avalue, fmt, value); |
|
if (avalue_size < 0) |
if (avalue_size < 0) |
return (NULL); |
return (NULL); |
|
|
/* make sure that we've enough space for result string */ |
/* make sure that we've enough space for result string */ |
bufsize = strlen(avalue)*2+1; |
bufsize = avalue_size * 2 + 1; |
rslt = malloc(bufsize); |
rslt = malloc(bufsize); |
if (rslt == NULL) { |
if (rslt == NULL) { |
free(avalue); |
free(avalue); |
Line 572 __format_grouped_double(double value, in |
|
Line 582 __format_grouped_double(double value, in |
|
avalue_size -= (right_prec + 1); |
avalue_size -= (right_prec + 1); |
} |
} |
|
|
|
/* 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 582 __format_grouped_double(double value, in |
|
Line 593 __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 ? */ |