35
35
* Private routines
36
36
************************************************************************/
37
37
38
- static const char *
39
- num_word ( Cash value )
38
+ static void
39
+ append_num_word ( StringInfo buf , Cash value )
40
40
{
41
- static char buf [128 ];
42
41
static const char * const small [] = {
43
42
"zero" , "one" , "two" , "three" , "four" , "five" , "six" , "seven" ,
44
43
"eight" , "nine" , "ten" , "eleven" , "twelve" , "thirteen" , "fourteen" ,
@@ -50,41 +49,42 @@ num_word(Cash value)
50
49
51
50
/* deal with the simple cases first */
52
51
if (value <= 20 )
53
- return small [value ];
52
+ {
53
+ appendStringInfoString (buf , small [value ]);
54
+ return ;
55
+ }
54
56
55
57
/* is it an even multiple of 100? */
56
58
if (!tu )
57
59
{
58
- sprintf (buf , "%s hundred" , small [value / 100 ]);
59
- return buf ;
60
+ appendStringInfo (buf , "%s hundred" , small [value / 100 ]);
61
+ return ;
60
62
}
61
63
62
64
/* more than 99? */
63
65
if (value > 99 )
64
66
{
65
67
/* is it an even multiple of 10 other than 10? */
66
68
if (value % 10 == 0 && tu > 10 )
67
- sprintf (buf , "%s hundred %s" ,
68
- small [value / 100 ], big [tu / 10 ]);
69
+ appendStringInfo (buf , "%s hundred %s" ,
70
+ small [value / 100 ], big [tu / 10 ]);
69
71
else if (tu < 20 )
70
- sprintf (buf , "%s hundred and %s" ,
71
- small [value / 100 ], small [tu ]);
72
+ appendStringInfo (buf , "%s hundred and %s" ,
73
+ small [value / 100 ], small [tu ]);
72
74
else
73
- sprintf (buf , "%s hundred %s %s" ,
74
- small [value / 100 ], big [tu / 10 ], small [tu % 10 ]);
75
+ appendStringInfo (buf , "%s hundred %s %s" ,
76
+ small [value / 100 ], big [tu / 10 ], small [tu % 10 ]);
75
77
}
76
78
else
77
79
{
78
80
/* is it an even multiple of 10 other than 10? */
79
81
if (value % 10 == 0 && tu > 10 )
80
- sprintf (buf , "%s" , big [tu / 10 ]);
82
+ appendStringInfoString (buf , big [tu / 10 ]);
81
83
else if (tu < 20 )
82
- sprintf (buf , "%s" , small [tu ]);
84
+ appendStringInfoString (buf , small [tu ]);
83
85
else
84
- sprintf (buf , "%s %s" , big [tu / 10 ], small [tu % 10 ]);
86
+ appendStringInfo (buf , "%s %s" , big [tu / 10 ], small [tu % 10 ]);
85
87
}
86
-
87
- return buf ;
88
88
} /* num_word() */
89
89
90
90
static inline Cash
@@ -960,8 +960,9 @@ cash_words(PG_FUNCTION_ARGS)
960
960
{
961
961
Cash value = PG_GETARG_CASH (0 );
962
962
uint64 val ;
963
- char buf [256 ];
964
- char * p = buf ;
963
+ StringInfoData buf ;
964
+ text * res ;
965
+ Cash dollars ;
965
966
Cash m0 ;
966
967
Cash m1 ;
967
968
Cash m2 ;
@@ -970,19 +971,19 @@ cash_words(PG_FUNCTION_ARGS)
970
971
Cash m5 ;
971
972
Cash m6 ;
972
973
974
+ initStringInfo (& buf );
975
+
973
976
/* work with positive numbers */
974
977
if (value < 0 )
975
978
{
976
979
value = - value ;
977
- strcpy (buf , "minus " );
978
- p += 6 ;
980
+ appendStringInfoString (& buf , "minus " );
979
981
}
980
- else
981
- buf [0 ] = '\0' ;
982
982
983
983
/* Now treat as unsigned, to avoid trouble at INT_MIN */
984
984
val = (uint64 ) value ;
985
985
986
+ dollars = val / INT64CONST (100 );
986
987
m0 = val % INT64CONST (100 ); /* cents */
987
988
m1 = (val / INT64CONST (100 )) % 1000 ; /* hundreds */
988
989
m2 = (val / INT64CONST (100000 )) % 1000 ; /* thousands */
@@ -993,49 +994,51 @@ cash_words(PG_FUNCTION_ARGS)
993
994
994
995
if (m6 )
995
996
{
996
- strcat ( buf , num_word ( m6 ) );
997
- strcat ( buf , " quadrillion " );
997
+ append_num_word ( & buf , m6 );
998
+ appendStringInfoString ( & buf , " quadrillion " );
998
999
}
999
1000
1000
1001
if (m5 )
1001
1002
{
1002
- strcat ( buf , num_word ( m5 ) );
1003
- strcat ( buf , " trillion " );
1003
+ append_num_word ( & buf , m5 );
1004
+ appendStringInfoString ( & buf , " trillion " );
1004
1005
}
1005
1006
1006
1007
if (m4 )
1007
1008
{
1008
- strcat ( buf , num_word ( m4 ) );
1009
- strcat ( buf , " billion " );
1009
+ append_num_word ( & buf , m4 );
1010
+ appendStringInfoString ( & buf , " billion " );
1010
1011
}
1011
1012
1012
1013
if (m3 )
1013
1014
{
1014
- strcat ( buf , num_word ( m3 ) );
1015
- strcat ( buf , " million " );
1015
+ append_num_word ( & buf , m3 );
1016
+ appendStringInfoString ( & buf , " million " );
1016
1017
}
1017
1018
1018
1019
if (m2 )
1019
1020
{
1020
- strcat ( buf , num_word ( m2 ) );
1021
- strcat ( buf , " thousand " );
1021
+ append_num_word ( & buf , m2 );
1022
+ appendStringInfoString ( & buf , " thousand " );
1022
1023
}
1023
1024
1024
1025
if (m1 )
1025
- strcat ( buf , num_word ( m1 ) );
1026
+ append_num_word ( & buf , m1 );
1026
1027
1027
- if (! * p )
1028
- strcat ( buf , "zero" );
1028
+ if (dollars == 0 )
1029
+ appendStringInfoString ( & buf , "zero" );
1029
1030
1030
- strcat ( buf , ( val / 100 ) == 1 ? " dollar and " : " dollars and " );
1031
- strcat ( buf , num_word ( m0 ) );
1032
- strcat ( buf , m0 == 1 ? " cent" : " cents" );
1031
+ appendStringInfoString ( & buf , dollars == 1 ? " dollar and " : " dollars and " );
1032
+ append_num_word ( & buf , m0 );
1033
+ appendStringInfoString ( & buf , m0 == 1 ? " cent" : " cents" );
1033
1034
1034
1035
/* capitalize output */
1035
- buf [0 ] = pg_toupper ((unsigned char ) buf [0 ]);
1036
+ buf . data [0 ] = pg_toupper ((unsigned char ) buf . data [0 ]);
1036
1037
1037
1038
/* return as text datum */
1038
- PG_RETURN_TEXT_P (cstring_to_text (buf ));
1039
+ res = cstring_to_text_with_len (buf .data , buf .len );
1040
+ pfree (buf .data );
1041
+ PG_RETURN_TEXT_P (res );
1039
1042
}
1040
1043
1041
1044
0 commit comments