Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | merge 8.7 |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
961ccb69d20daba27750ea5e3028ca7f |
User & Date: | dgp 2018-03-14 16:17:48.800 |
Context
2018-03-14
| ||
17:21 | merge 8.7 check-in: 86f7de7c98 user: dgp tags: trunk | |
16:17 | merge 8.7 check-in: 961ccb69d2 user: dgp tags: trunk | |
15:17 | New routine TclStringReplace() serves as a common implementation for both compiled and direct eval p... check-in: 190272213a user: dgp tags: core-8-branch | |
05:51 | merge 8.7 check-in: 3ba4c8e05a user: dgp tags: trunk | |
Changes
Changes to generic/tclCmdMZ.c.
︙ | ︙ | |||
2333 2334 2335 2336 2337 2338 2339 | * have (first <= end < 0 <= last) and an empty string is permitted * to be replaced. */ Tcl_SetObjResult(interp, objv[1]); } else { Tcl_Obj *resultPtr; | < < < < < < < < > > | < < < | < | | > | | 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 | * have (first <= end < 0 <= last) and an empty string is permitted * to be replaced. */ Tcl_SetObjResult(interp, objv[1]); } else { Tcl_Obj *resultPtr; if (first < 0) { first = 0; } if (last > end) { last = end; } resultPtr = TclStringReplace(interp, objv[1], first, last + 1 - first, (objc == 5) ? objv[4] : NULL, TCL_STRING_IN_PLACE); Tcl_SetObjResult(interp, resultPtr); } return TCL_OK; } /* *---------------------------------------------------------------------- |
︙ | ︙ |
Changes to generic/tclExecute.c.
︙ | ︙ | |||
5253 5254 5255 5256 5257 5258 5259 | if (fromIdx == 0 && toIdx == endIdx) { TclDecrRefCount(OBJ_AT_TOS); OBJ_AT_TOS = value3Ptr; TRACE_APPEND(("\"%.30s\"\n", O2S(value3Ptr))); NEXT_INST_F(1, 0, 0); } | < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 5266 5267 5268 5269 | if (fromIdx == 0 && toIdx == endIdx) { TclDecrRefCount(OBJ_AT_TOS); OBJ_AT_TOS = value3Ptr; TRACE_APPEND(("\"%.30s\"\n", O2S(value3Ptr))); NEXT_INST_F(1, 0, 0); } objResultPtr = TclStringReplace(interp, valuePtr, fromIdx, toIdx - fromIdx + 1, value3Ptr, TCL_STRING_IN_PLACE); if (objResultPtr == value3Ptr) { /* See [Bug 82e7f67325] */ TclDecrRefCount(OBJ_AT_TOS); OBJ_AT_TOS = value3Ptr; TRACE_APPEND(("\"%.30s\"\n", O2S(value3Ptr))); NEXT_INST_F(1, 0, 0); } |
︙ | ︙ |
Changes to generic/tclInt.h.
︙ | ︙ | |||
3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 | Tcl_Obj *const objv[], int flags); MODULE_SCOPE int TclStringFirst(Tcl_Obj *needle, Tcl_Obj *haystack, int start); MODULE_SCOPE int TclStringLast(Tcl_Obj *needle, Tcl_Obj *haystack, int last); MODULE_SCOPE Tcl_Obj * TclStringRepeat(Tcl_Interp *interp, Tcl_Obj *objPtr, int count, int flags); MODULE_SCOPE Tcl_Obj * TclStringReverse(Tcl_Obj *objPtr, int flags); /* Flag values for the [string] ensemble functions. */ #define TCL_STRING_MATCH_NOCASE TCL_MATCH_NOCASE /* (1<<0) in tcl.h */ #define TCL_STRING_IN_PLACE (1<<1) | > > > | 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 | Tcl_Obj *const objv[], int flags); MODULE_SCOPE int TclStringFirst(Tcl_Obj *needle, Tcl_Obj *haystack, int start); MODULE_SCOPE int TclStringLast(Tcl_Obj *needle, Tcl_Obj *haystack, int last); MODULE_SCOPE Tcl_Obj * TclStringRepeat(Tcl_Interp *interp, Tcl_Obj *objPtr, int count, int flags); MODULE_SCOPE Tcl_Obj * TclStringReplace(Tcl_Interp *interp, Tcl_Obj *objPtr, int first, int count, Tcl_Obj *insertPtr, int flags); MODULE_SCOPE Tcl_Obj * TclStringReverse(Tcl_Obj *objPtr, int flags); /* Flag values for the [string] ensemble functions. */ #define TCL_STRING_MATCH_NOCASE TCL_MATCH_NOCASE /* (1<<0) in tcl.h */ #define TCL_STRING_IN_PLACE (1<<1) |
︙ | ︙ |
Changes to generic/tclStringObj.c.
︙ | ︙ | |||
34 35 36 37 38 39 40 41 42 43 44 45 46 47 | * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" #include "tommath.h" #include "tclStringRep.h" /* * Prototypes for functions defined later in this file: */ static void AppendPrintfToObjVA(Tcl_Obj *objPtr, const char *format, va_list argList); static void AppendUnicodeToUnicodeRep(Tcl_Obj *objPtr, | > | 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tclInt.h" #include "tommath.h" #include "tclStringRep.h" #include "assert.h" /* * Prototypes for functions defined later in this file: */ static void AppendPrintfToObjVA(Tcl_Obj *objPtr, const char *format, va_list argList); static void AppendUnicodeToUnicodeRep(Tcl_Obj *objPtr, |
︙ | ︙ | |||
3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 | } /* Pass 2. Reverse all the bytes. */ ReverseBytes((unsigned char *)to, (unsigned char *)from, numBytes); } return objPtr; } /* *--------------------------------------------------------------------------- * * FillUnicodeRep -- * * Populate the Unicode internal rep with the Unicode form of its string | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 | } /* Pass 2. Reverse all the bytes. */ ReverseBytes((unsigned char *)to, (unsigned char *)from, numBytes); } return objPtr; } /* *--------------------------------------------------------------------------- * * TclStringReplace -- * * Implements the inner engine of the [string replace] command. * * The result is a concatenation of a prefix from objPtr, characters * 0 through first-1, the insertPtr string value, and a suffix from * objPtr, characters from first + count to the end. The effect is * as if the inner substring of characters first through first+count-1 * are removed and replaced with insertPtr. * If insertPtr is NULL, it is treated as an empty string. * When passed the flag TCL_STRING_IN_PLACE, this routine will try * to do the work within objPtr, so long as no sharing forbids it. * Without that request, or as needed, a new Tcl value will be allocated * to be the result. * * Results: * A Tcl value that is the result of the substring replacement. * May return NULL in case of an error. When NULL is returned and * interp is non-NULL, error information is left in interp * *--------------------------------------------------------------------------- */ Tcl_Obj * TclStringReplace( Tcl_Interp *interp, /* For error reporting, may be NULL */ Tcl_Obj *objPtr, /* String to act upon */ int first, /* First index to replace */ int count, /* How many chars to replace */ Tcl_Obj *insertPtr, /* Replacement string, may be NULL */ int flags) /* TCL_STRING_IN_PLACE => attempt in-place */ { int inPlace = flags & TCL_STRING_IN_PLACE; Tcl_Obj *result; /* Caller is expected to pass sensible arguments */ assert ( count >= 0 ) ; assert ( first >= 0 ) ; /* Replace nothing with nothing */ if ((insertPtr == NULL) && (count == 0)) { if (inPlace) { return objPtr; } else { return Tcl_DuplicateObj(objPtr); } } /* * The caller very likely had to call Tcl_GetCharLength() or similar * to be able to process index values. This means it is like that * objPtr is either a proper "bytearray" or a "string" or else it has * a known and short string rep. */ if (TclIsPureByteArray(objPtr)) { int numBytes; unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, &numBytes); if (insertPtr == NULL) { /* Replace something with nothing. */ assert ( first <= numBytes ) ; assert ( count <= numBytes ) ; assert ( first + count <= numBytes ) ; result = Tcl_NewByteArrayObj(NULL, numBytes - count);/* PANIC? */ TclAppendBytesToByteArray(result, bytes, first); TclAppendBytesToByteArray(result, bytes + first + count, numBytes - count - first); return result; } /* Replace everything */ if ((first == 0) && (count == numBytes)) { return insertPtr; } if (TclIsPureByteArray(insertPtr)) { int newBytes; unsigned char *iBytes = Tcl_GetByteArrayFromObj(insertPtr, &newBytes); if (count == newBytes && inPlace && !Tcl_IsShared(objPtr)) { /* * Removal count and replacement count are equal. * Other conditions permit. Do in-place splice. */ memcpy(bytes + first, iBytes, count); Tcl_InvalidateStringRep(objPtr); return objPtr; } if (newBytes > INT_MAX - (numBytes - count)) { if (interp) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "max size for a Tcl value (%d bytes) exceeded", INT_MAX)); Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); } return NULL; } result = Tcl_NewByteArrayObj(NULL, numBytes - count + newBytes); /* PANIC? */ TclAppendBytesToByteArray(result, bytes, first); TclAppendBytesToByteArray(result, iBytes, newBytes); TclAppendBytesToByteArray(result, bytes + first + count, numBytes - count - first); return result; } /* Flow through to try other approaches below */ } /* * TODO: Figure out how not to generate a Tcl_UniChar array rep * when it can be determined objPtr->bytes points to a string of * all single-byte characters so we can index it directly. */ /* The traditional implementation... */ { int numChars; Tcl_UniChar *ustring = Tcl_GetUnicodeFromObj(objPtr, &numChars); /* TODO: Is there an in-place option worth pursuing here? */ result = Tcl_NewUnicodeObj(ustring, first); if (insertPtr) { Tcl_AppendObjToObj(result, insertPtr); } if (first + count < numChars) { Tcl_AppendUnicodeToObj(result, ustring + first + count, numChars - first - count); } return result; } } /* *--------------------------------------------------------------------------- * * FillUnicodeRep -- * * Populate the Unicode internal rep with the Unicode form of its string |
︙ | ︙ |