diff options
| author | jan.nijtmans <nijtmans@users.sourceforge.net> | 2024-06-17 14:54:07 (GMT) |
|---|---|---|
| committer | jan.nijtmans <nijtmans@users.sourceforge.net> | 2024-06-17 14:54:07 (GMT) |
| commit | 8afc6eacf92cf29e37c07ccf08890f85b5dc1f5a (patch) | |
| tree | 488579b6d6fed04b2dba99334f5783fde92cdb31 /generic/tclScan.c | |
| parent | ba6d47e73b72aff7071511b6eba0d6142eab5d22 (diff) | |
| download | tcl-8afc6eacf92cf29e37c07ccf08890f85b5dc1f5a.zip tcl-8afc6eacf92cf29e37c07ccf08890f85b5dc1f5a.tar.gz tcl-8afc6eacf92cf29e37c07ccf08890f85b5dc1f5a.tar.bz2 | |
Implement %z/%t/%q/%j size modifiers for 'scan'. Part of TIP #697, which is suitable for 8.7 too.
Diffstat (limited to 'generic/tclScan.c')
| -rw-r--r-- | generic/tclScan.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/generic/tclScan.c b/generic/tclScan.c index 8969240..e852d63 100644 --- a/generic/tclScan.c +++ b/generic/tclScan.c @@ -319,7 +319,7 @@ ValidateFormat( if (ul == 0 || ul >= INT_MAX) { goto badIndex; } - objIndex = (int) ul - 1; + objIndex = (int)ul - 1; if (numVars && (objIndex >= numVars)) { goto badIndex; } else if (numVars == 0) { @@ -361,6 +361,13 @@ ValidateFormat( */ switch (ch) { + case 'z': + case 't': + if (sizeof(void *) > sizeof(int)) { + flags |= SCAN_LONGER; + } + format += TclUtfToUniChar(format, &ch); + break; case 'l': if (*format == 'l') { flags |= SCAN_BIG; @@ -370,6 +377,8 @@ ValidateFormat( } /* FALLTHRU */ case 'L': + case 'j': + case 'q': flags |= SCAN_LONGER; /* FALLTHRU */ case 'h': @@ -567,7 +576,7 @@ ValidateFormat( int Tcl_ScanObjCmd( - TCL_UNUSED(ClientData), + TCL_UNUSED(void *), Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ @@ -578,7 +587,8 @@ Tcl_ScanObjCmd( long value; const char *string, *end, *baseString; char op = 0; - int width, underflow = 0; + int underflow = 0; + Tcl_Size width; Tcl_WideInt wideValue; Tcl_UniChar ch = 0, sch = 0; Tcl_Obj **objs = NULL, *objPtr = NULL; @@ -677,7 +687,7 @@ Tcl_ScanObjCmd( if (*formatEnd == '$') { format = formatEnd+1; format += TclUtfToUniChar(format, &ch); - objIndex = (int) value - 1; + objIndex = (int)value - 1; } } @@ -686,7 +696,7 @@ Tcl_ScanObjCmd( */ if ((ch < 0x80) && isdigit(UCHAR(ch))) { /* INTL: "C" locale. */ - width = (int) strtoul(format-1, (char **) &format, 10);/* INTL: "C" locale. */ + width = (int)strtoul(format-1, (char **)&format, 10);/* INTL: "C" locale. */ format += TclUtfToUniChar(format, &ch); } else { width = 0; @@ -899,7 +909,7 @@ Tcl_ScanObjCmd( width = ~0; } if (TCL_OK != TclParseNumber(NULL, objPtr, NULL, string, width, - &end, TCL_PARSE_INTEGER_ONLY | TCL_PARSE_NO_UNDERSCORE | parseFlag)) { + &end, TCL_PARSE_INTEGER_ONLY | TCL_PARSE_NO_UNDERSCORE | parseFlag)) { Tcl_DecrRefCount(objPtr); if (width < 0) { if (*end == '\0') { @@ -918,7 +928,7 @@ Tcl_ScanObjCmd( break; } if (flags & SCAN_LONGER) { - if (Tcl_GetWideIntFromObj(NULL, objPtr, &wideValue) != TCL_OK) { + if (TclGetWideIntFromObj(NULL, objPtr, &wideValue) != TCL_OK) { if (TclGetString(objPtr)[0] == '-') { wideValue = WIDE_MIN; } else { @@ -1070,22 +1080,24 @@ Tcl_ScanObjCmd( } else { /* * Here no vars were specified, we want a list returned (inline scan) + * We create an empty Tcl_Obj to fill missing values rather than + * allocating a new Tcl_Obj every time. */ - + Tcl_Obj *emptyObj = NULL; TclNewObj(objPtr); for (i = 0; i < totalVars; i++) { if (objs[i] != NULL) { Tcl_ListObjAppendElement(NULL, objPtr, objs[i]); Tcl_DecrRefCount(objs[i]); } else { - Tcl_Obj *obj; /* * More %-specifiers than matching chars, so we just spit out * empty strings for these. */ - - TclNewObj(obj); - Tcl_ListObjAppendElement(NULL, objPtr, obj); + if (!emptyObj) { + TclNewObj(emptyObj); + } + Tcl_ListObjAppendElement(NULL, objPtr, emptyObj); } } } |
