summaryrefslogtreecommitdiffstats
path: root/generic/tclStringObj.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclStringObj.c')
-rw-r--r--generic/tclStringObj.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index bc2d4e9..3ce22f0 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -2079,7 +2079,7 @@ AppendUtfToUtfRep(
/*
*----------------------------------------------------------------------
*
- * TclAppendUtfToUtf --
+ * TclAppendUtfToUtf --
*
* This function appends "numBytes" bytes of "bytes" to the UTF string
* rep of "objPtr" (objPtr's internal rep converted to string on demand).
@@ -3017,6 +3017,28 @@ Tcl_Format(
*---------------------------------------------------------------------------
*/
+static Tcl_Obj *
+NewIntObj(
+ char c,
+ Tcl_WideUInt max,
+ Tcl_WideInt value)
+{
+ if (!((max+1) & (Tcl_WideUInt)value)) {
+ /* sign-bit is not set, so handle the positive value */
+ return Tcl_NewWideIntObj(value & (Tcl_WideInt)max);
+ }
+
+ if (strchr("puoxX", c) && (max == WIDE_MAX)) {
+ /* Value > WIDE_MAX, so we need to use bignum */
+ mp_int bignumValue;
+ if (mp_init_u64(&bignumValue, (uint64_t)value) != MP_OKAY) {
+ Tcl_Panic("%s: memory overflow", "AppendPrintfToObjVA");
+ }
+ return Tcl_NewBignumObj(&bignumValue);
+ }
+ return Tcl_NewWideIntObj(value | ~(Tcl_WideInt)max);
+}
+
static void
AppendPrintfToObjVA(
Tcl_Obj *objPtr,
@@ -3100,15 +3122,15 @@ AppendPrintfToObjVA(
switch (size) {
case -1:
case 0:
- Tcl_ListObjAppendElement(NULL, list, Tcl_NewWideIntObj(
+ Tcl_ListObjAppendElement(NULL, list, NewIntObj(*p, INT_MAX,
va_arg(argList, int)));
break;
case 1:
- Tcl_ListObjAppendElement(NULL, list, Tcl_NewWideIntObj(
+ Tcl_ListObjAppendElement(NULL, list, NewIntObj(*p, LONG_MAX,
va_arg(argList, long)));
break;
case 2:
- Tcl_ListObjAppendElement(NULL, list, Tcl_NewWideIntObj(
+ Tcl_ListObjAppendElement(NULL, list, NewIntObj(*p, WIDE_MAX,
va_arg(argList, Tcl_WideInt)));
break;
case 3: