diff options
-rw-r--r--[-rwxr-xr-x] | compat/zlib/win32/zlib1.dll | bin | 107520 -> 107520 bytes | |||
-rw-r--r--[-rwxr-xr-x] | compat/zlib/win64/zlib1.dll | bin | 112640 -> 112640 bytes | |||
-rwxr-xr-x[-rw-r--r--] | doc/GetCwd.3 | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | doc/GetVersion.3 | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | doc/lset.n | 0 | ||||
-rw-r--r-- | generic/tclAssembly.c | 18 | ||||
-rw-r--r-- | generic/tclBasic.c | 4 | ||||
-rw-r--r-- | generic/tclCmdMZ.c | 47 | ||||
-rw-r--r-- | generic/tclCompCmds.c | 91 | ||||
-rw-r--r-- | generic/tclCompCmdsGR.c | 469 | ||||
-rw-r--r-- | generic/tclCompCmdsSZ.c | 391 | ||||
-rw-r--r-- | generic/tclCompile.c | 82 | ||||
-rw-r--r-- | generic/tclCompile.h | 19 | ||||
-rw-r--r-- | generic/tclExecute.c | 314 | ||||
-rw-r--r-- | generic/tclInt.h | 30 | ||||
-rw-r--r-- | generic/tclNamesp.c | 2 | ||||
-rw-r--r-- | generic/tclOptimize.c | 6 | ||||
-rwxr-xr-x[-rw-r--r--] | generic/tclStrToD.c | 0 | ||||
-rw-r--r-- | generic/tclStringTrim.h | 68 | ||||
-rw-r--r-- | generic/tclStubLibTbl.c | 58 | ||||
-rw-r--r-- | generic/tclUtil.c | 16 | ||||
-rwxr-xr-x[-rw-r--r--] | library/encoding/tis-620.enc | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/af.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/af_za.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ar.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ar_in.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ar_jo.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ar_lb.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ar_sy.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/be.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/bg.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/bn.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/bn_in.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ca.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/cs.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/da.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/de.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/de_at.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/de_be.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/el.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/en_au.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/en_be.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/en_bw.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/en_ca.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/en_gb.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/en_hk.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/en_ie.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/en_in.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/en_nz.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/en_ph.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/en_sg.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/en_za.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/en_zw.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/eo.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_ar.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_bo.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_cl.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_co.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_cr.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_do.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_ec.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_gt.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_hn.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_mx.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_ni.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_pa.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_pe.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_pr.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_py.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_sv.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_uy.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/es_ve.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/et.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/eu.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/eu_es.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/fa.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/fa_in.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/fa_ir.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/fi.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/fo.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/fo_fo.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/fr.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/fr_be.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/fr_ca.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/fr_ch.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ga.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ga_ie.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/gl.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/gl_es.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/gv.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/gv_gb.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/he.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/hi.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/hi_in.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/hr.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/hu.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/id.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/id_id.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/is.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/it.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/it_ch.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ja.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/kl.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/kl_gl.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ko.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ko_kr.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/kok.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/kok_in.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/kw.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/kw_gb.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/lt.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/lv.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/mk.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/mr.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/mr_in.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ms.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ms_my.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/mt.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/nb.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/nl.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/nl_be.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/nn.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/pl.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/pt.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/pt_br.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ro.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ru.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ru_ua.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/sh.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/sk.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/sl.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/sq.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/sr.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/sv.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/sw.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ta.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/ta_in.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/te.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/te_in.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/th.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/tr.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/uk.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/vi.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/zh.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/zh_cn.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/zh_hk.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/zh_sg.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/msgs/zh_tw.msg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/Africa/Asmara | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/America/Atikokan | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/America/Blanc-Sablon | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/America/Indiana/Petersburg | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/America/Indiana/Tell_City | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/America/Indiana/Vincennes | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/America/Indiana/Winamac | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/America/Moncton | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/America/North_Dakota/New_Salem | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/America/Resolute | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/Atlantic/Faroe | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/Australia/Eucla | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/Europe/Guernsey | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/Europe/Isle_of_Man | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/Europe/Jersey | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/Europe/Podgorica | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | library/tzdata/Europe/Volgograd | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | tests/lsetComp.test | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | tests/notify.test | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | tests/tcltest.test | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | tools/encoding/ebcdic.txt | 0 | ||||
-rwxr-xr-x[-rw-r--r--] | tools/encoding/tis-620.txt | 0 | ||||
-rw-r--r-- | unix/Makefile.in | 7 | ||||
-rwxr-xr-x[-rw-r--r--] | win/buildall.vc.bat | 0 |
173 files changed, 1295 insertions, 327 deletions
diff --git a/compat/zlib/win32/zlib1.dll b/compat/zlib/win32/zlib1.dll Binary files differindex 9ea38d5..9ea38d5 100755..100644 --- a/compat/zlib/win32/zlib1.dll +++ b/compat/zlib/win32/zlib1.dll diff --git a/compat/zlib/win64/zlib1.dll b/compat/zlib/win64/zlib1.dll Binary files differindex bd1dbc6..bd1dbc6 100755..100644 --- a/compat/zlib/win64/zlib1.dll +++ b/compat/zlib/win64/zlib1.dll diff --git a/doc/GetCwd.3 b/doc/GetCwd.3 index 58abcde..58abcde 100644..100755 --- a/doc/GetCwd.3 +++ b/doc/GetCwd.3 diff --git a/doc/GetVersion.3 b/doc/GetVersion.3 index 89f63d5..89f63d5 100644..100755 --- a/doc/GetVersion.3 +++ b/doc/GetVersion.3 diff --git a/doc/lset.n b/doc/lset.n index 954bd30..954bd30 100644..100755 --- a/doc/lset.n +++ b/doc/lset.n diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c index 03177b9..89c286a 100644 --- a/generic/tclAssembly.c +++ b/generic/tclAssembly.c @@ -349,7 +349,8 @@ static const TalInstDesc TalInstructionTable[] = { {"bitnot", ASSEM_1BYTE, INST_BITNOT, 1, 1}, {"bitor", ASSEM_1BYTE, INST_BITOR, 2, 1}, {"bitxor", ASSEM_1BYTE, INST_BITXOR, 2, 1}, - {"concat", ASSEM_CONCAT1, INST_CONCAT1, INT_MIN,1}, + {"concat", ASSEM_CONCAT1, INST_STR_CONCAT1, INT_MIN,1}, + {"concatStk", ASSEM_LIST, INST_CONCAT_STK, INT_MIN,1}, {"coroName", ASSEM_1BYTE, INST_COROUTINE_NAME, 0, 1}, {"currentNamespace",ASSEM_1BYTE, INST_NS_CURRENT, 0, 1}, {"dictAppend", ASSEM_LVT4, INST_DICT_APPEND, 2, 1}, @@ -436,6 +437,7 @@ static const TalInstDesc TalInstructionTable[] = { {"nop", ASSEM_1BYTE, INST_NOP, 0, 0}, {"not", ASSEM_1BYTE, INST_LNOT, 1, 1}, {"nsupvar", ASSEM_LVT4, INST_NSUPVAR, 2, 1}, + {"originCmd", ASSEM_1BYTE, INST_ORIGIN_COMMAND, 1, 1}, {"over", ASSEM_OVER, INST_OVER, INT_MIN,-1-1}, {"pop", ASSEM_1BYTE, INST_POP, 1, 0}, {"pushReturnCode", ASSEM_1BYTE, INST_PUSH_RETURN_CODE, 0, 1}, @@ -452,7 +454,11 @@ static const TalInstDesc TalInstructionTable[] = { | INST_STORE_ARRAY4), 2, 1}, {"storeArrayStk", ASSEM_1BYTE, INST_STORE_ARRAY_STK, 3, 1}, {"storeStk", ASSEM_1BYTE, INST_STORE_STK, 2, 1}, + {"strcaseLower", ASSEM_1BYTE, INST_STR_LOWER, 1, 1}, + {"strcaseTitle", ASSEM_1BYTE, INST_STR_TITLE, 1, 1}, + {"strcaseUpper", ASSEM_1BYTE, INST_STR_UPPER, 1, 1}, {"strcmp", ASSEM_1BYTE, INST_STR_CMP, 2, 1}, + {"strcat", ASSEM_CONCAT1, INST_STR_CONCAT1, INT_MIN,1}, {"streq", ASSEM_1BYTE, INST_STR_EQ, 2, 1}, {"strfind", ASSEM_1BYTE, INST_STR_FIND, 2, 1}, {"strindex", ASSEM_1BYTE, INST_STR_INDEX, 2, 1}, @@ -461,7 +467,11 @@ static const TalInstDesc TalInstructionTable[] = { {"strmatch", ASSEM_BOOL, INST_STR_MATCH, 2, 1}, {"strneq", ASSEM_1BYTE, INST_STR_NEQ, 2, 1}, {"strrange", ASSEM_1BYTE, INST_STR_RANGE, 3, 1}, + {"strreplace", ASSEM_1BYTE, INST_STR_REPLACE, 4, 1}, {"strrfind", ASSEM_1BYTE, INST_STR_FIND_LAST, 2, 1}, + {"strtrim", ASSEM_1BYTE, INST_STR_TRIM, 2, 1}, + {"strtrimLeft", ASSEM_1BYTE, INST_STR_TRIM_LEFT, 2, 1}, + {"strtrimRight", ASSEM_1BYTE, INST_STR_TRIM_RIGHT, 2, 1}, {"sub", ASSEM_1BYTE, INST_SUB, 2, 1}, {"tclooClass", ASSEM_1BYTE, INST_TCLOO_CLASS, 1, 1}, {"tclooIsObject", ASSEM_1BYTE, INST_TCLOO_IS_OBJECT, 1, 1}, @@ -493,6 +503,7 @@ static const unsigned char NonThrowingByteCodes[] = { INST_PUSH1, INST_PUSH4, INST_POP, INST_DUP, /* 1-4 */ INST_JUMP1, INST_JUMP4, /* 34-35 */ INST_END_CATCH, INST_PUSH_RESULT, INST_PUSH_RETURN_CODE, /* 70-72 */ + INST_LIST, /* 79 */ INST_OVER, /* 95 */ INST_PUSH_RETURN_OPTIONS, /* 108 */ INST_REVERSE, /* 126 */ @@ -502,7 +513,10 @@ static const unsigned char NonThrowingByteCodes[] = { INST_COROUTINE_NAME, /* 149 */ INST_NS_CURRENT, /* 151 */ INST_INFO_LEVEL_NUM, /* 152 */ - INST_RESOLVE_COMMAND /* 154 */ + INST_RESOLVE_COMMAND, /* 154 */ + INST_STR_TRIM, INST_STR_TRIM_LEFT, INST_STR_TRIM_RIGHT, /* 166-168 */ + INST_CONCAT_STK, /* 169 */ + INST_STR_UPPER, INST_STR_LOWER, INST_STR_TITLE /* 170-172 */ }; /* diff --git a/generic/tclBasic.c b/generic/tclBasic.c index 8ec94ca..7c02706 100644 --- a/generic/tclBasic.c +++ b/generic/tclBasic.c @@ -211,7 +211,7 @@ static const CmdInfo builtInCmds[] = { {"case", Tcl_CaseObjCmd, NULL, NULL, CMD_IS_SAFE}, #endif {"catch", Tcl_CatchObjCmd, TclCompileCatchCmd, TclNRCatchObjCmd, CMD_IS_SAFE}, - {"concat", Tcl_ConcatObjCmd, NULL, NULL, CMD_IS_SAFE}, + {"concat", Tcl_ConcatObjCmd, TclCompileConcatCmd, NULL, CMD_IS_SAFE}, {"continue", Tcl_ContinueObjCmd, TclCompileContinueCmd, NULL, CMD_IS_SAFE}, {"coroutine", NULL, NULL, TclNRCoroutineObjCmd, CMD_IS_SAFE}, {"error", Tcl_ErrorObjCmd, TclCompileErrorCmd, NULL, CMD_IS_SAFE}, @@ -227,7 +227,7 @@ static const CmdInfo builtInCmds[] = { {"lappend", Tcl_LappendObjCmd, TclCompileLappendCmd, NULL, CMD_IS_SAFE}, {"lassign", Tcl_LassignObjCmd, TclCompileLassignCmd, NULL, CMD_IS_SAFE}, {"lindex", Tcl_LindexObjCmd, TclCompileLindexCmd, NULL, CMD_IS_SAFE}, - {"linsert", Tcl_LinsertObjCmd, NULL, NULL, CMD_IS_SAFE}, + {"linsert", Tcl_LinsertObjCmd, TclCompileLinsertCmd, NULL, CMD_IS_SAFE}, {"list", Tcl_ListObjCmd, TclCompileListCmd, NULL, CMD_IS_SAFE|CMD_COMPILES_EXPANDED}, {"llength", Tcl_LlengthObjCmd, TclCompileLlengthCmd, NULL, CMD_IS_SAFE}, {"lmap", Tcl_LmapObjCmd, TclCompileLmapCmd, TclNRLmapCmd, CMD_IS_SAFE}, diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c index 5087fbb..d477216 100644 --- a/generic/tclCmdMZ.c +++ b/generic/tclCmdMZ.c @@ -18,6 +18,7 @@ #include "tclInt.h" #include "tclRegexp.h" +#include "tclStringTrim.h" static inline Tcl_Obj * During(Tcl_Interp *interp, int resultCode, Tcl_Obj *oldOptions, Tcl_Obj *errorInfo); @@ -31,38 +32,6 @@ static int TryPostHandler(ClientData data[], Tcl_Interp *interp, int result); static int UniCharIsAscii(int character); static int UniCharIsHexDigit(int character); - -/* - * Default set of characters to trim in [string trim] and friends. This is a - * UTF-8 literal string containing all Unicode space characters [TIP #413] - */ - -#define DEFAULT_TRIM_SET \ - "\x09\x0a\x0b\x0c\x0d " /* ASCII */\ - "\xc0\x80" /* nul (U+0000) */\ - "\xc2\x85" /* next line (U+0085) */\ - "\xc2\xa0" /* non-breaking space (U+00a0) */\ - "\xe1\x9a\x80" /* ogham space mark (U+1680) */ \ - "\xe1\xa0\x8e" /* mongolian vowel separator (U+180e) */\ - "\xe2\x80\x80" /* en quad (U+2000) */\ - "\xe2\x80\x81" /* em quad (U+2001) */\ - "\xe2\x80\x82" /* en space (U+2002) */\ - "\xe2\x80\x83" /* em space (U+2003) */\ - "\xe2\x80\x84" /* three-per-em space (U+2004) */\ - "\xe2\x80\x85" /* four-per-em space (U+2005) */\ - "\xe2\x80\x86" /* six-per-em space (U+2006) */\ - "\xe2\x80\x87" /* figure space (U+2007) */\ - "\xe2\x80\x88" /* punctuation space (U+2008) */\ - "\xe2\x80\x89" /* thin space (U+2009) */\ - "\xe2\x80\x8a" /* hair space (U+200a) */\ - "\xe2\x80\x8b" /* zero width space (U+200b) */\ - "\xe2\x80\xa8" /* line separator (U+2028) */\ - "\xe2\x80\xa9" /* paragraph separator (U+2029) */\ - "\xe2\x80\xaf" /* narrow no-break space (U+202f) */\ - "\xe2\x81\x9f" /* medium mathematical space (U+205f) */\ - "\xe2\x81\xa0" /* word joiner (U+2060) */\ - "\xe3\x80\x80" /* ideographic space (U+3000) */\ - "\xef\xbb\xbf" /* zero width no-break space (U+feff) */ /* *---------------------------------------------------------------------- @@ -3337,14 +3306,14 @@ TclInitStringCmd( {"match", StringMatchCmd, TclCompileStringMatchCmd, NULL, NULL, 0}, {"range", StringRangeCmd, TclCompileStringRangeCmd, NULL, NULL, 0}, {"repeat", StringReptCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, - {"replace", StringRplcCmd, NULL, NULL, NULL, 0}, + {"replace", StringRplcCmd, TclCompileStringReplaceCmd, NULL, NULL, 0}, {"reverse", StringRevCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, - {"tolower", StringLowerCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0}, - {"toupper", StringUpperCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0}, - {"totitle", StringTitleCmd, TclCompileBasic1To3ArgCmd, NULL, NULL, 0}, - {"trim", StringTrimCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, - {"trimleft", StringTrimLCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, - {"trimright", StringTrimRCmd, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0}, + {"tolower", StringLowerCmd, TclCompileStringToLowerCmd, NULL, NULL, 0}, + {"toupper", StringUpperCmd, TclCompileStringToUpperCmd, NULL, NULL, 0}, + {"totitle", StringTitleCmd, TclCompileStringToTitleCmd, NULL, NULL, 0}, + {"trim", StringTrimCmd, TclCompileStringTrimCmd, NULL, NULL, 0}, + {"trimleft", StringTrimLCmd, TclCompileStringTrimLCmd, NULL, NULL, 0}, + {"trimright", StringTrimRCmd, TclCompileStringTrimRCmd, NULL, NULL, 0}, {"wordend", StringEndCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, {"wordstart", StringStartCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0}, {NULL, NULL, NULL, NULL, NULL, 0} diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c index 323aa87..05b6d07 100644 --- a/generic/tclCompCmds.c +++ b/generic/tclCompCmds.c @@ -690,6 +690,93 @@ TclCompileCatchCmd( /* *---------------------------------------------------------------------- * + * TclCompileConcatCmd -- + * + * Procedure called to compile the "concat" command. + * + * Results: + * Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer + * evaluation to runtime. + * + * Side effects: + * Instructions are added to envPtr to execute the "concat" command at + * runtime. + * + *---------------------------------------------------------------------- + */ + +int +TclCompileConcatCmd( + Tcl_Interp *interp, /* Used for error reporting. */ + Tcl_Parse *parsePtr, /* Points to a parse structure for the command + * created by Tcl_ParseCommand. */ + Command *cmdPtr, /* Points to defintion of command being + * compiled. */ + CompileEnv *envPtr) /* Holds resulting instructions. */ +{ + DefineLineInformation; /* TIP #280 */ + Tcl_Obj *objPtr, *listObj; + Tcl_Token *tokenPtr; + int i; + + /* TODO: Consider compiling expansion case. */ + if (parsePtr->numWords == 1) { + /* + * [concat] without arguments just pushes an empty object. + */ + + PushStringLiteral(envPtr, ""); + return TCL_OK; + } + + /* + * Test if all arguments are compile-time known. If they are, we can + * implement with a simple push. + */ + + listObj = Tcl_NewObj(); + for (i = 1, tokenPtr = parsePtr->tokenPtr; i < parsePtr->numWords; i++) { + tokenPtr = TokenAfter(tokenPtr); + objPtr = Tcl_NewObj(); + if (!TclWordKnownAtCompileTime(tokenPtr, objPtr)) { + Tcl_DecrRefCount(objPtr); + Tcl_DecrRefCount(listObj); + listObj = NULL; + break; + } + (void) Tcl_ListObjAppendElement(NULL, listObj, objPtr); + } + if (listObj != NULL) { + Tcl_Obj **objs; + const char *bytes; + int len; + + Tcl_ListObjGetElements(NULL, listObj, &len, &objs); + objPtr = Tcl_ConcatObj(len, objs); + Tcl_DecrRefCount(listObj); + bytes = Tcl_GetStringFromObj(objPtr, &len); + PushLiteral(envPtr, bytes, len); + Tcl_DecrRefCount(objPtr); + return TCL_OK; + } + + /* + * General case: runtime concat. + */ + + for (i = 1, tokenPtr = parsePtr->tokenPtr; i < parsePtr->numWords; i++) { + tokenPtr = TokenAfter(tokenPtr); + CompileWord(envPtr, tokenPtr, interp, i); + } + + TclEmitInstInt4( INST_CONCAT_STK, i-1, envPtr); + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * * TclCompileContinueCmd -- * * Procedure called to compile the "continue" command. @@ -1678,7 +1765,7 @@ TclCompileDictAppendCmd( tokenPtr = TokenAfter(tokenPtr); } if (parsePtr->numWords > 4) { - TclEmitInstInt1(INST_CONCAT1, parsePtr->numWords-3, envPtr); + TclEmitInstInt1(INST_STR_CONCAT1, parsePtr->numWords-3, envPtr); } /* @@ -3011,7 +3098,7 @@ TclCompileFormatCmd( * Do the concatenation, which produces the result. */ - TclEmitInstInt1(INST_CONCAT1, i, envPtr); + TclEmitInstInt1(INST_STR_CONCAT1, i, envPtr); } else { /* * EVIL HACK! Force there to be a string representation in the case diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c index b7c89df..df8895f 100644 --- a/generic/tclCompCmdsGR.c +++ b/generic/tclCompCmdsGR.c @@ -28,6 +28,58 @@ static void CompileReturnInternal(CompileEnv *envPtr, static int IndexTailVarIfKnown(Tcl_Interp *interp, Tcl_Token *varTokenPtr, CompileEnv *envPtr); +#define INDEX_END (-2) + +/* + *---------------------------------------------------------------------- + * + * GetIndexFromToken -- + * + * Parse a token and get the encoded version of the index (as understood + * by TEBC), assuming it is at all knowable at compile time. Only handles + * indices that are integers or 'end' or 'end-integer'. + * + * Returns: + * TCL_OK if parsing succeeded, and TCL_ERROR if it failed. + * + * Side effects: + * Sets *index to the index value if successful. + * + *---------------------------------------------------------------------- + */ + +static inline int +GetIndexFromToken( + Tcl_Token *tokenPtr, + int *index) +{ + Tcl_Obj *tmpObj = Tcl_NewObj(); + int result, idx; + + if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) { + Tcl_DecrRefCount(tmpObj); + return TCL_ERROR; + } + + result = TclGetIntFromObj(NULL, tmpObj, &idx); + if (result == TCL_OK) { + if (idx < 0) { + result = TCL_ERROR; + } + } else { + result = TclGetIntForIndexM(NULL, tmpObj, INDEX_END, &idx); + if (result == TCL_OK && idx > INDEX_END) { + result = TCL_ERROR; + } + } + Tcl_DecrRefCount(tmpObj); + + if (result == TCL_OK) { + *index = idx; + } + + return result; +} /* *---------------------------------------------------------------------- @@ -1029,7 +1081,7 @@ TclCompileLassignCmd( */ TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr); - TclEmitInt4( -2 /* == "end" */, envPtr); + TclEmitInt4( INDEX_END, envPtr); return TCL_OK; } @@ -1062,7 +1114,7 @@ TclCompileLindexCmd( CompileEnv *envPtr) /* Holds resulting instructions. */ { Tcl_Token *idxTokenPtr, *valTokenPtr; - int i, numWords = parsePtr->numWords; + int i, idx, numWords = parsePtr->numWords; DefineLineInformation; /* TIP #280 */ /* @@ -1080,46 +1132,28 @@ TclCompileLindexCmd( } idxTokenPtr = TokenAfter(valTokenPtr); - if (idxTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) { - Tcl_Obj *tmpObj; - int idx, result; - - tmpObj = Tcl_NewStringObj(idxTokenPtr[1].start, idxTokenPtr[1].size); - result = TclGetIntFromObj(NULL, tmpObj, &idx); - if (result == TCL_OK) { - if (idx < 0) { - result = TCL_ERROR; - } - } else { - result = TclGetIntForIndexM(NULL, tmpObj, -2, &idx); - if (result == TCL_OK && idx > -2) { - result = TCL_ERROR; - } - } - TclDecrRefCount(tmpObj); - - if (result == TCL_OK) { - /* - * All checks have been completed, and we have exactly one of - * these constructs: - * lindex <arbitraryValue> <posInt> - * lindex <arbitraryValue> end-<posInt> - * This is best compiled as a push of the arbitrary value followed - * by an "immediate lindex" which is the most efficient variety. - */ - - CompileWord(envPtr, valTokenPtr, interp, 1); - TclEmitInstInt4( INST_LIST_INDEX_IMM, idx, envPtr); - return TCL_OK; - } - + if (GetIndexFromToken(idxTokenPtr, &idx) == TCL_OK) { /* - * If the conversion failed or the value was negative, we just keep on - * going with the more complex compilation. + * All checks have been completed, and we have exactly one of these + * constructs: + * lindex <arbitraryValue> <posInt> + * lindex <arbitraryValue> end-<posInt> + * This is best compiled as a push of the arbitrary value followed by + * an "immediate lindex" which is the most efficient variety. */ + + CompileWord(envPtr, valTokenPtr, interp, 1); + TclEmitInstInt4( INST_LIST_INDEX_IMM, idx, envPtr); + return TCL_OK; } /* + * If the value was not known at compile time, the conversion failed or + * the value was negative, we just keep on going with the more complex + * compilation. + */ + + /* * Push the operands onto the stack. */ @@ -1265,7 +1299,7 @@ TclCompileListCmd( if (concat && numWords == 2) { TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); - TclEmitInt4( -2, envPtr); + TclEmitInt4( INDEX_END, envPtr); } return TCL_OK; } @@ -1332,8 +1366,7 @@ TclCompileLrangeCmd( { Tcl_Token *tokenPtr, *listTokenPtr; DefineLineInformation; /* TIP #280 */ - Tcl_Obj *tmpObj; - int idx1, idx2, result; + int idx1, idx2; if (parsePtr->numWords != 4) { return TCL_ERROR; @@ -1341,56 +1374,18 @@ TclCompileLrangeCmd( listTokenPtr = TokenAfter(parsePtr->tokenPtr); /* - * Parse the first index. Will only compile if it is constant and not an + * Parse the indices. Will only compile if both are constants and not an * _integer_ less than zero (since we reserve negative indices here for - * end-relative indexing). + * end-relative indexing) or an end-based index greater than 'end' itself. */ tokenPtr = TokenAfter(listTokenPtr); - if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; - } - tmpObj = Tcl_NewStringObj(tokenPtr[1].start, tokenPtr[1].size); - result = TclGetIntFromObj(NULL, tmpObj, &idx1); - if (result == TCL_OK) { - if (idx1 < 0) { - result = TCL_ERROR; - } - } else { - result = TclGetIntForIndexM(NULL, tmpObj, -2, &idx1); - if (result == TCL_OK && idx1 > -2) { - result = TCL_ERROR; - } - } - TclDecrRefCount(tmpObj); - if (result != TCL_OK) { + if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) { return TCL_ERROR; } - /* - * Parse the second index. Will only compile if it is constant and not an - * _integer_ less than zero (since we reserve negative indices here for - * end-relative indexing). - */ - tokenPtr = TokenAfter(tokenPtr); - if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { - return TCL_ERROR; - } - tmpObj = Tcl_NewStringObj(tokenPtr[1].start, tokenPtr[1].size); - result = TclGetIntFromObj(NULL, tmpObj, &idx2); - if (result == TCL_OK) { - if (idx2 < 0) { - result = TCL_ERROR; - } - } else { - result = TclGetIntForIndexM(NULL, tmpObj, -2, &idx2); - if (result == TCL_OK && idx2 > -2) { - result = TCL_ERROR; - } - } - TclDecrRefCount(tmpObj); - if (result != TCL_OK) { + if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) { return TCL_ERROR; } @@ -1409,19 +1404,16 @@ TclCompileLrangeCmd( /* *---------------------------------------------------------------------- * - * TclCompileLreplaceCmd -- + * TclCompileLinsertCmd -- * - * How to compile the "lreplace" command. We only bother with the case - * where there are no elements to insert and where both the 'first' and - * 'last' arguments are constant and one can be deterined to be at the - * end of the list. (This is the case that could also be written with - * "lrange".) + * How to compile the "linsert" command. We only bother with the case + * where the index is constant. * *---------------------------------------------------------------------- */ int -TclCompileLreplaceCmd( +TclCompileLinsertCmd( Tcl_Interp *interp, /* Tcl interpreter for context. */ Tcl_Parse *parsePtr, /* Points to a parse structure for the * command. */ @@ -1431,101 +1423,272 @@ TclCompileLreplaceCmd( { Tcl_Token *tokenPtr, *listTokenPtr; DefineLineInformation; /* TIP #280 */ - Tcl_Obj *tmpObj; - int idx1, idx2, result, guaranteedDropAll = 0; + int idx, i; - if (parsePtr->numWords != 4) { + if (parsePtr->numWords < 3) { return TCL_ERROR; } listTokenPtr = TokenAfter(parsePtr->tokenPtr); /* - * Parse the first index. Will only compile if it is constant and not an + * Parse the index. Will only compile if it is constant and not an * _integer_ less than zero (since we reserve negative indices here for - * end-relative indexing). + * end-relative indexing) or an end-based index greater than 'end' itself. */ tokenPtr = TokenAfter(listTokenPtr); - if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { + if (GetIndexFromToken(tokenPtr, &idx) != TCL_OK) { return TCL_ERROR; } - tmpObj = Tcl_NewStringObj(tokenPtr[1].start, tokenPtr[1].size); - result = TclGetIntFromObj(NULL, tmpObj, &idx1); - if (result == TCL_OK) { - if (idx1 < 0) { - result = TCL_ERROR; - } + + /* + * There are four main cases. If there are no values to insert, this is + * just a confirm-listiness check. If the index is '0', this is a prepend. + * If the index is 'end' (== INDEX_END), this is an append. Otherwise, + * this is a splice (== split, insert values as list, concat-3). + */ + + CompileWord(envPtr, listTokenPtr, interp, 1); + if (parsePtr->numWords == 3) { + TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); + TclEmitInt4( INDEX_END, envPtr); + return TCL_OK; + } + + for (i=3 ; i<parsePtr->numWords ; i++) { + tokenPtr = TokenAfter(tokenPtr); + CompileWord(envPtr, tokenPtr, interp, i); + } + TclEmitInstInt4( INST_LIST, i-3, envPtr); + + if (idx == 0 /*start*/) { + TclEmitInstInt4( INST_REVERSE, 2, envPtr); + TclEmitOpcode( INST_LIST_CONCAT, envPtr); + } else if (idx == INDEX_END /*end*/) { + TclEmitOpcode( INST_LIST_CONCAT, envPtr); } else { - result = TclGetIntForIndexM(NULL, tmpObj, -2, &idx1); - if (result == TCL_OK && idx1 > -2) { - result = TCL_ERROR; + if (idx < 0) { + idx++; } + TclEmitInstInt4( INST_OVER, 1, envPtr); + TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); + TclEmitInt4( idx-1, envPtr); + TclEmitInstInt4( INST_REVERSE, 3, envPtr); + TclEmitInstInt4( INST_LIST_RANGE_IMM, idx, envPtr); + TclEmitInt4( INDEX_END, envPtr); + TclEmitOpcode( INST_LIST_CONCAT, envPtr); + TclEmitOpcode( INST_LIST_CONCAT, envPtr); } - TclDecrRefCount(tmpObj); - if (result != TCL_OK) { + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TclCompileLreplaceCmd -- + * + * How to compile the "lreplace" command. We only bother with the case + * where the indices are constant. + * + *---------------------------------------------------------------------- + */ + +int +TclCompileLreplaceCmd( + Tcl_Interp *interp, /* Tcl interpreter for context. */ + Tcl_Parse *parsePtr, /* Points to a parse structure for the + * command. */ + Command *cmdPtr, /* Points to defintion of command being + * compiled. */ + CompileEnv *envPtr) /* Holds the resulting instructions. */ +{ + Tcl_Token *tokenPtr, *listTokenPtr; + DefineLineInformation; /* TIP #280 */ + Tcl_Obj *tmpObj; + int idx1, idx2, i, offset; + + if (parsePtr->numWords < 4) { return TCL_ERROR; } + listTokenPtr = TokenAfter(parsePtr->tokenPtr); /* - * Parse the second index. Will only compile if it is constant and not an + * Parse the indices. Will only compile if both are constants and not an * _integer_ less than zero (since we reserve negative indices here for - * end-relative indexing). + * end-relative indexing) or an end-based index greater than 'end' itself. */ - tokenPtr = TokenAfter(tokenPtr); - if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { + tokenPtr = TokenAfter(listTokenPtr); + if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) { return TCL_ERROR; } - tmpObj = Tcl_NewStringObj(tokenPtr[1].start, tokenPtr[1].size); - result = TclGetIntFromObj(NULL, tmpObj, &idx2); - if (result == TCL_OK) { - if (idx2 < 0) { - result = TCL_ERROR; - } - } else { - result = TclGetIntForIndexM(NULL, tmpObj, -2, &idx2); - if (result == TCL_OK && idx2 > -2) { - result = TCL_ERROR; - } - } - TclDecrRefCount(tmpObj); - if (result != TCL_OK) { + + tokenPtr = TokenAfter(tokenPtr); + if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) { return TCL_ERROR; } /* - * Sanity check: can only issue when we're removing a range at one or - * other end of the list. If we're at one end or the other, convert the - * indices into the equivalent for an [lrange]. + * Work out what this [lreplace] is actually doing. */ + tmpObj = NULL; + CompileWord(envPtr, listTokenPtr, interp, 1); + if (parsePtr->numWords == 4) { + if (idx1 == 0) { + if (idx2 == INDEX_END) { + goto dropAll; + } + idx1 = idx2 + 1; + idx2 = INDEX_END; + goto dropEnd; + } else if (idx2 == INDEX_END) { + idx2 = idx1 - 1; + idx1 = 0; + goto dropEnd; + } else { + if (idx1 > 0) { + tmpObj = Tcl_NewIntObj(idx1); + Tcl_IncrRefCount(tmpObj); + } + goto dropRange; + } + } + + tokenPtr = TokenAfter(tokenPtr); + for (i=4 ; i<parsePtr->numWords ; i++) { + CompileWord(envPtr, tokenPtr, interp, i); + tokenPtr = TokenAfter(tokenPtr); + } + TclEmitInstInt4( INST_LIST, i - 4, envPtr); + TclEmitInstInt4( INST_REVERSE, 2, envPtr); if (idx1 == 0) { - if (idx2 == -2) { - guaranteedDropAll = 1; + if (idx2 == INDEX_END) { + goto replaceAll; } idx1 = idx2 + 1; - idx2 = -2; - } else if (idx2 == -2) { + idx2 = INDEX_END; + goto replaceHead; + } else if (idx2 == INDEX_END) { idx2 = idx1 - 1; idx1 = 0; + goto replaceTail; } else { - return TCL_ERROR; + if (idx1 > 0 && idx2 > 0 && idx2 < idx1) { + idx2 = idx1 - 1; + } else if (idx1 < 0 && idx2 < 0 && idx2 < idx1) { + idx2 = idx1 - 1; + } + if (idx1 > 0) { + tmpObj = Tcl_NewIntObj(idx1); + Tcl_IncrRefCount(tmpObj); + } + goto replaceRange; } /* - * Issue instructions. It's not safe to skip doing the LIST_RANGE, as - * we've not proved that the 'list' argument is really a list. Not that it - * is worth trying to do that given current knowledge. + * Issue instructions to perform the operations relating to configurations + * that just drop. The only argument pushed on the stack is the list to + * operate on. */ - CompileWord(envPtr, listTokenPtr, interp, 1); - if (guaranteedDropAll) { + dropAll: + TclEmitOpcode( INST_LIST_LENGTH, envPtr); + TclEmitOpcode( INST_POP, envPtr); + PushStringLiteral(envPtr, ""); + goto done; + + dropEnd: + TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr); + TclEmitInt4( idx2, envPtr); + goto done; + + dropRange: + if (tmpObj != NULL) { + TclEmitOpcode( INST_DUP, envPtr); TclEmitOpcode( INST_LIST_LENGTH, envPtr); - TclEmitOpcode( INST_POP, envPtr); - PushStringLiteral(envPtr, ""); - } else { - TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr); - TclEmitInt4( idx2, envPtr); + TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL), envPtr); + TclEmitOpcode( INST_GT, envPtr); + offset = CurrentOffset(envPtr); + TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr); + TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf( + "list doesn't contain element %d", idx1), NULL), envPtr); + CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0, + Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}")); + TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset, + envPtr->codeStart + offset + 1); + TclAdjustStackDepth(-1, envPtr); + } + TclEmitOpcode( INST_DUP, envPtr); + TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); + TclEmitInt4( idx1 - 1, envPtr); + TclEmitInstInt4( INST_REVERSE, 2, envPtr); + TclEmitInstInt4( INST_LIST_RANGE_IMM, idx2 + 1, envPtr); + TclEmitInt4( INDEX_END, envPtr); + TclEmitOpcode( INST_LIST_CONCAT, envPtr); + goto done; + + /* + * Issue instructions to perform the operations relating to configurations + * that do real replacement. All arguments are pushed and assembled into a + * pair: the list of values to replace with, and the list to do the + * surgery on. + */ + + replaceAll: + TclEmitOpcode( INST_LIST_LENGTH, envPtr); + TclEmitOpcode( INST_POP, envPtr); + goto done; + + replaceHead: + TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr); + TclEmitInt4( idx2, envPtr); + TclEmitOpcode( INST_LIST_CONCAT, envPtr); + goto done; + + replaceTail: + TclEmitInstInt4( INST_LIST_RANGE_IMM, idx1, envPtr); + TclEmitInt4( idx2, envPtr); + TclEmitInstInt4( INST_REVERSE, 2, envPtr); + TclEmitOpcode( INST_LIST_CONCAT, envPtr); + goto done; + + replaceRange: + if (tmpObj != NULL) { + TclEmitOpcode( INST_DUP, envPtr); + TclEmitOpcode( INST_LIST_LENGTH, envPtr); + TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL), envPtr); + TclEmitOpcode( INST_GT, envPtr); + offset = CurrentOffset(envPtr); + TclEmitInstInt1( INST_JUMP_TRUE1, 0, envPtr); + TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf( + "list doesn't contain element %d", idx1), NULL), envPtr); + CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0, + Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}")); + TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset, + envPtr->codeStart + offset + 1); + TclAdjustStackDepth(-1, envPtr); + } + TclEmitOpcode( INST_DUP, envPtr); + TclEmitInstInt4( INST_LIST_RANGE_IMM, 0, envPtr); + TclEmitInt4( idx1 - 1, envPtr); + TclEmitInstInt4( INST_REVERSE, 2, envPtr); + TclEmitInstInt4( INST_LIST_RANGE_IMM, idx2 + 1, envPtr); + TclEmitInt4( INDEX_END, envPtr); + TclEmitInstInt4( INST_REVERSE, 3, envPtr); + TclEmitOpcode( INST_LIST_CONCAT, envPtr); + TclEmitInstInt4( INST_REVERSE, 2, envPtr); + TclEmitOpcode( INST_LIST_CONCAT, envPtr); + goto done; + + /* + * Clean up the allocated memory. + */ + + done: + if (tmpObj != NULL) { + Tcl_DecrRefCount(tmpObj); } return TCL_OK; } @@ -1793,6 +1956,28 @@ TclCompileNamespaceCodeCmd( } int +TclCompileNamespaceOriginCmd( + Tcl_Interp *interp, /* Used for error reporting. */ + Tcl_Parse *parsePtr, /* Points to a parse structure for the command + * created by Tcl_ParseCommand. */ + Command *cmdPtr, /* Points to defintion of command being + * compiled. */ + CompileEnv *envPtr) /* Holds resulting instructions. */ +{ + Tcl_Token *tokenPtr; + DefineLineInformation; /* TIP #280 */ + + if (parsePtr->numWords != 2) { + return TCL_ERROR; + } + tokenPtr = TokenAfter(parsePtr->tokenPtr); + + CompileWord(envPtr, tokenPtr, interp, 1); + TclEmitOpcode( INST_ORIGIN_COMMAND, envPtr); + return TCL_OK; +} + +int TclCompileNamespaceQualifiersCmd( Tcl_Interp *interp, /* Used for error reporting. */ Tcl_Parse *parsePtr, /* Points to a parse structure for the command diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c index 3e4a55a..0f2790f 100644 --- a/generic/tclCompCmdsSZ.c +++ b/generic/tclCompCmdsSZ.c @@ -17,6 +17,7 @@ #include "tclInt.h" #include "tclCompile.h" +#include "tclStringTrim.h" /* * Prototypes for procedures defined later in this file: @@ -101,6 +102,59 @@ const AuxDataType tclJumptableInfoType = { if ((idx)<256) {OP1(STORE_SCALAR1,(idx));} else {OP4(STORE_SCALAR4,(idx));} #define INVOKE(name) \ TclEmitInvoke(envPtr,INST_##name) + +#define INDEX_END (-2) + +/* + *---------------------------------------------------------------------- + * + * GetIndexFromToken -- + * + * Parse a token and get the encoded version of the index (as understood + * by TEBC), assuming it is at all knowable at compile time. Only handles + * indices that are integers or 'end' or 'end-integer'. + * + * Returns: + * TCL_OK if parsing succeeded, and TCL_ERROR if it failed. + * + * Side effects: + * Sets *index to the index value if successful. + * + *---------------------------------------------------------------------- + */ + +static inline int +GetIndexFromToken( + Tcl_Token *tokenPtr, + int *index) +{ + Tcl_Obj *tmpObj = Tcl_NewObj(); + int result, idx; + + if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) { + Tcl_DecrRefCount(tmpObj); + return TCL_ERROR; + } + + result = TclGetIntFromObj(NULL, tmpObj, &idx); + if (result == TCL_OK) { + if (idx < 0) { + result = TCL_ERROR; + } + } else { + result = TclGetIntForIndexM(NULL, tmpObj, INDEX_END, &idx); + if (result == TCL_OK && idx > INDEX_END) { + result = TCL_ERROR; + } + } + Tcl_DecrRefCount(tmpObj); + + if (result == TCL_OK) { + *index = idx; + } + + return result; +} /* *---------------------------------------------------------------------- @@ -565,8 +619,7 @@ TclCompileStringRangeCmd( { DefineLineInformation; /* TIP #280 */ Tcl_Token *stringTokenPtr, *fromTokenPtr, *toTokenPtr; - Tcl_Obj *tmpObj; - int idx1, idx2, result; + int idx1, idx2; if (parsePtr->numWords != 4) { return TCL_ERROR; @@ -576,50 +629,13 @@ TclCompileStringRangeCmd( toTokenPtr = TokenAfter(fromTokenPtr); /* - * Parse the first index. Will only compile if it is constant and not an - * _integer_ less than zero (since we reserve negative indices here for - * end-relative indexing). + * Parse the two indices. */ - tmpObj = Tcl_NewObj(); - result = TCL_ERROR; - if (TclWordKnownAtCompileTime(fromTokenPtr, tmpObj)) { - if (TclGetIntFromObj(NULL, tmpObj, &idx1) == TCL_OK) { - if (idx1 >= 0) { - result = TCL_OK; - } - } else if (TclGetIntForIndexM(NULL, tmpObj, -2, &idx1) == TCL_OK) { - if (idx1 <= -2) { - result = TCL_OK; - } - } - } - TclDecrRefCount(tmpObj); - if (result != TCL_OK) { + if (GetIndexFromToken(fromTokenPtr, &idx1) != TCL_OK) { goto nonConstantIndices; } - - /* - * Parse the second index. Will only compile if it is constant and not an - * _integer_ less than zero (since we reserve negative indices here for - * end-relative indexing). - */ - - tmpObj = Tcl_NewObj(); - result = TCL_ERROR; - if (TclWordKnownAtCompileTime(toTokenPtr, tmpObj)) { - if (TclGetIntFromObj(NULL, tmpObj, &idx2) == TCL_OK) { - if (idx2 >= 0) { - result = TCL_OK; - } - } else if (TclGetIntForIndexM(NULL, tmpObj, -2, &idx2) == TCL_OK) { - if (idx2 <= -2) { - result = TCL_OK; - } - } - } - TclDecrRefCount(tmpObj); - if (result != TCL_OK) { + if (GetIndexFromToken(toTokenPtr, &idx2) != TCL_OK) { goto nonConstantIndices; } @@ -642,6 +658,285 @@ TclCompileStringRangeCmd( OP( STR_RANGE); return TCL_OK; } + +int +TclCompileStringReplaceCmd( + Tcl_Interp *interp, /* Tcl interpreter for context. */ + Tcl_Parse *parsePtr, /* Points to a parse structure for the + * command. */ + Command *cmdPtr, /* Points to defintion of command being + * compiled. */ + CompileEnv *envPtr) /* Holds the resulting instructions. */ +{ + Tcl_Token *tokenPtr, *valueTokenPtr, *replacementTokenPtr = NULL; + DefineLineInformation; /* TIP #280 */ + int idx1, idx2; + + if (parsePtr->numWords < 4 || parsePtr->numWords > 5) { + return TCL_ERROR; + } + valueTokenPtr = TokenAfter(parsePtr->tokenPtr); + if (parsePtr->numWords == 5) { + tokenPtr = TokenAfter(valueTokenPtr); + tokenPtr = TokenAfter(tokenPtr); + replacementTokenPtr = TokenAfter(tokenPtr); + } + + /* + * Parse the indices. Will only compile special cases if both are + * constants and not an _integer_ less than zero (since we reserve + * negative indices here for end-relative indexing) or an end-based index + * greater than 'end' itself. + */ + + tokenPtr = TokenAfter(valueTokenPtr); + if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) { + goto genericReplace; + } + + tokenPtr = TokenAfter(tokenPtr); + if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) { + goto genericReplace; + } + + /* + * We handle these replacements specially: first character (where + * idx1=idx2=0) and last character (where idx1=idx2=INDEX_END). Anything + * else and the semantics get rather screwy. + */ + + if (idx1 == 0 && idx2 == 0) { + int notEq, end; + + /* + * Just working with the first character. + */ + + CompileWord(envPtr, valueTokenPtr, interp, 1); + if (replacementTokenPtr == NULL) { + /* Drop first */ + OP44( STR_RANGE_IMM, 1, INDEX_END); + return TCL_OK; + } + /* Replace first */ + CompileWord(envPtr, replacementTokenPtr, interp, 4); + OP4( OVER, 1); + PUSH( ""); + OP( STR_EQ); + JUMP1( JUMP_FALSE, notEq); + OP( POP); + JUMP1( JUMP, end); + FIXJUMP1(notEq); + TclAdjustStackDepth(1, envPtr); + OP4( REVERSE, 2); + OP44( STR_RANGE_IMM, 1, INDEX_END); + OP1( STR_CONCAT1, 2); + FIXJUMP1(end); + return TCL_OK; + + } else if (idx1 == INDEX_END && idx2 == INDEX_END) { + int notEq, end; + + /* + * Just working with the last character. + */ + + CompileWord(envPtr, valueTokenPtr, interp, 1); + if (replacementTokenPtr == NULL) { + /* Drop last */ + OP44( STR_RANGE_IMM, 0, INDEX_END-1); + return TCL_OK; + } + /* Replace last */ + CompileWord(envPtr, replacementTokenPtr, interp, 4); + OP4( OVER, 1); + PUSH( ""); + OP( STR_EQ); + JUMP1( JUMP_FALSE, notEq); + OP( POP); + JUMP1( JUMP, end); + FIXJUMP1(notEq); + TclAdjustStackDepth(1, envPtr); + OP4( REVERSE, 2); + OP44( STR_RANGE_IMM, 0, INDEX_END-1); + OP4( REVERSE, 2); + OP1( STR_CONCAT1, 2); + FIXJUMP1(end); + return TCL_OK; + + } else { + /* + * Need to process indices at runtime. This could be because the + * indices are not constants, or because we need to resolve them to + * absolute indices to work out if a replacement is going to happen. + * In any case, to runtime it is. + */ + + genericReplace: + CompileWord(envPtr, valueTokenPtr, interp, 1); + tokenPtr = TokenAfter(valueTokenPtr); + CompileWord(envPtr, tokenPtr, interp, 2); + tokenPtr = TokenAfter(tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 3); + if (replacementTokenPtr != NULL) { + CompileWord(envPtr, replacementTokenPtr, interp, 4); + } else { + PUSH( ""); + } + OP( STR_REPLACE); + return TCL_OK; + } +} + +int +TclCompileStringTrimLCmd( + Tcl_Interp *interp, /* Used for error reporting. */ + Tcl_Parse *parsePtr, /* Points to a parse structure for the command + * created by Tcl_ParseCommand. */ + Command *cmdPtr, /* Points to defintion of command being + * compiled. */ + CompileEnv *envPtr) /* Holds resulting instructions. */ +{ + DefineLineInformation; /* TIP #280 */ + Tcl_Token *tokenPtr; + + if (parsePtr->numWords != 2 && parsePtr->numWords != 3) { + return TCL_ERROR; + } + + tokenPtr = TokenAfter(parsePtr->tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 1); + if (parsePtr->numWords == 3) { + tokenPtr = TokenAfter(tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 2); + } else { + PushLiteral(envPtr, DEFAULT_TRIM_SET, strlen(DEFAULT_TRIM_SET)); + } + OP( STR_TRIM_LEFT); + return TCL_OK; +} + +int +TclCompileStringTrimRCmd( + Tcl_Interp *interp, /* Used for error reporting. */ + Tcl_Parse *parsePtr, /* Points to a parse structure for the command + * created by Tcl_ParseCommand. */ + Command *cmdPtr, /* Points to defintion of command being + * compiled. */ + CompileEnv *envPtr) /* Holds resulting instructions. */ +{ + DefineLineInformation; /* TIP #280 */ + Tcl_Token *tokenPtr; + + if (parsePtr->numWords != 2 && parsePtr->numWords != 3) { + return TCL_ERROR; + } + + tokenPtr = TokenAfter(parsePtr->tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 1); + if (parsePtr->numWords == 3) { + tokenPtr = TokenAfter(tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 2); + } else { + PushLiteral(envPtr, DEFAULT_TRIM_SET, strlen(DEFAULT_TRIM_SET)); + } + OP( STR_TRIM_RIGHT); + return TCL_OK; +} + +int +TclCompileStringTrimCmd( + Tcl_Interp *interp, /* Used for error reporting. */ + Tcl_Parse *parsePtr, /* Points to a parse structure for the command + * created by Tcl_ParseCommand. */ + Command *cmdPtr, /* Points to defintion of command being + * compiled. */ + CompileEnv *envPtr) /* Holds resulting instructions. */ +{ + DefineLineInformation; /* TIP #280 */ + Tcl_Token *tokenPtr; + + if (parsePtr->numWords != 2 && parsePtr->numWords != 3) { + return TCL_ERROR; + } + + tokenPtr = TokenAfter(parsePtr->tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 1); + if (parsePtr->numWords == 3) { + tokenPtr = TokenAfter(tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 2); + } else { + PushLiteral(envPtr, DEFAULT_TRIM_SET, strlen(DEFAULT_TRIM_SET)); + } + OP( STR_TRIM); + return TCL_OK; +} + +int +TclCompileStringToUpperCmd( + Tcl_Interp *interp, /* Used for error reporting. */ + Tcl_Parse *parsePtr, /* Points to a parse structure for the command + * created by Tcl_ParseCommand. */ + Command *cmdPtr, /* Points to defintion of command being + * compiled. */ + CompileEnv *envPtr) /* Holds resulting instructions. */ +{ + DefineLineInformation; /* TIP #280 */ + Tcl_Token *tokenPtr; + + if (parsePtr->numWords != 2) { + return TclCompileBasic1To3ArgCmd(interp, parsePtr, cmdPtr, envPtr); + } + + tokenPtr = TokenAfter(parsePtr->tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 1); + OP( STR_UPPER); + return TCL_OK; +} + +int +TclCompileStringToLowerCmd( + Tcl_Interp *interp, /* Used for error reporting. */ + Tcl_Parse *parsePtr, /* Points to a parse structure for the command + * created by Tcl_ParseCommand. */ + Command *cmdPtr, /* Points to defintion of command being + * compiled. */ + CompileEnv *envPtr) /* Holds resulting instructions. */ +{ + DefineLineInformation; /* TIP #280 */ + Tcl_Token *tokenPtr; + + if (parsePtr->numWords != 2) { + return TclCompileBasic1To3ArgCmd(interp, parsePtr, cmdPtr, envPtr); + } + + tokenPtr = TokenAfter(parsePtr->tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 1); + OP( STR_LOWER); + return TCL_OK; +} + +int +TclCompileStringToTitleCmd( + Tcl_Interp *interp, /* Used for error reporting. */ + Tcl_Parse *parsePtr, /* Points to a parse structure for the command + * created by Tcl_ParseCommand. */ + Command *cmdPtr, /* Points to defintion of command being + * compiled. */ + CompileEnv *envPtr) /* Holds resulting instructions. */ +{ + DefineLineInformation; /* TIP #280 */ + Tcl_Token *tokenPtr; + + if (parsePtr->numWords != 2) { + return TclCompileBasic1To3ArgCmd(interp, parsePtr, cmdPtr, envPtr); + } + + tokenPtr = TokenAfter(parsePtr->tokenPtr); + CompileWord(envPtr, tokenPtr, interp, 1); + OP( STR_TITLE); + return TCL_OK; +} /* *---------------------------------------------------------------------- @@ -752,7 +1047,7 @@ TclSubstCompile( /* * Tricky point! If the first token does not result in a *guaranteed* push * of a Tcl_Obj on the stack, we must push an empty object. Otherwise it - * is possible to get to an INST_CONCAT1 or INST_DONE without enough + * is possible to get to an INST_STR_CONCAT1 or INST_DONE without enough * values on the stack, resulting in a crash. Thanks to Joe Mistachkin for * identifying a script that could trigger this case. */ @@ -817,11 +1112,11 @@ TclSubstCompile( } while (count > 255) { - OP1( CONCAT1, 255); + OP1( STR_CONCAT1, 255); count -= 254; } if (count > 1) { - OP1( CONCAT1, count); + OP1( STR_CONCAT1, count); count = 1; } @@ -941,7 +1236,7 @@ TclSubstCompile( (int) (CurrentOffset(envPtr) - okFixup.codeOffset)); } if (count > 1) { - OP1(CONCAT1, count); + OP1(STR_CONCAT1, count); count = 1; } @@ -954,11 +1249,11 @@ TclSubstCompile( } while (count > 255) { - OP1( CONCAT1, 255); + OP1( STR_CONCAT1, 255); count -= 254; } if (count > 1) { - OP1( CONCAT1, count); + OP1( STR_CONCAT1, count); } Tcl_FreeParse(&parse); diff --git a/generic/tclCompile.c b/generic/tclCompile.c index f3e9db3..0732fe5 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -63,7 +63,7 @@ InstructionDesc const tclInstructionTable[] = { /* Pop the topmost stack object */ {"dup", 1, +1, 0, {OPERAND_NONE}}, /* Duplicate the topmost stack object and push the result */ - {"concat1", 2, INT_MIN, 1, {OPERAND_UINT1}}, + {"strcat", 2, INT_MIN, 1, {OPERAND_UINT1}}, /* Concatenate the top op1 items and push result */ {"invokeStk1", 2, INT_MIN, 1, {OPERAND_UINT1}}, /* Invoke command named objv[0]; <objc,objv> = <op1,top op1> */ @@ -546,15 +546,75 @@ InstructionDesc const tclInstructionTable[] = { * until the matching stack depth is reached. */ /* New foreach implementation */ - {"foreach_start", 5, +2, 1, {OPERAND_AUX4}}, + {"foreach_start", 5, +2, 1, {OPERAND_AUX4}}, /* Initialize execution of a foreach loop. Operand is aux data index * of the ForeachInfo structure for the foreach command. It pushes 2 * elements which hold runtime params for foreach_step, they are later - * dropped by foreach_end together with the value lists. */ - {"foreach_step", 1, 0, 0, {OPERAND_NONE}}, - /* "Step" or begin next iteration of foreach loop. */ - {"foreach_end", 1, 0, 0, {OPERAND_NONE}}, - {"lmap_collect", 1, -1, 0, {OPERAND_NONE}}, + * dropped by foreach_end together with the value lists. NOTE that the + * iterator-tracker and info reference must not be passed to bytecodes + * that handle normal Tcl values. NOTE that this instruction jumps to + * the foreach_step instruction paired with it; the stack info below + * is only nominal. + * Stack: ... listObjs... => ... listObjs... iterTracker info */ + {"foreach_step", 1, 0, 0, {OPERAND_NONE}}, + /* "Step" or begin next iteration of foreach loop. Assigns to foreach + * iteration variables. May jump to straight after the foreach_start + * that pushed the iterTracker and info values. MUST be followed + * immediately by a foreach_end. + * Stack: ... listObjs... iterTracker info => + * ... listObjs... iterTracker info */ + {"foreach_end", 1, 0, 0, {OPERAND_NONE}}, + /* Clean up a foreach loop by dropping the info value, the tracker + * value and the lists that were being iterated over. + * Stack: ... listObjs... iterTracker info => ... */ + {"lmap_collect", 1, -1, 0, {OPERAND_NONE}}, + /* Appends the value at the top of the stack to the list located on + * the stack the "other side" of the foreach-related values. + * Stack: ... collector listObjs... iterTracker info value => + * ... collector listObjs... iterTracker info */ + + {"strtrim", 1, -1, 0, {OPERAND_NONE}}, + /* [string trim] core: removes the characters (designated by the value + * at the top of the stack) from both ends of the string and pushes + * the resulting string. + * Stack: ... string charset => ... trimmedString */ + {"strtrimLeft", 1, -1, 0, {OPERAND_NONE}}, + /* [string trimleft] core: removes the characters (designated by the + * value at the top of the stack) from the left of the string and + * pushes the resulting string. + * Stack: ... string charset => ... trimmedString */ + {"strtrimRight", 1, -1, 0, {OPERAND_NONE}}, + /* [string trimright] core: removes the characters (designated by the + * value at the top of the stack) from the right of the string and + * pushes the resulting string. + * Stack: ... string charset => ... trimmedString */ + + {"concatStk", 5, INT_MIN, 1, {OPERAND_UINT4}}, + /* Wrapper round Tcl_ConcatObj(), used for [concat] and [eval]. opnd + * is number of values to concatenate. + * Operation: push concat(stk1 stk2 ... stktop) */ + + {"strcaseUpper", 1, 0, 0, {OPERAND_NONE}}, + /* [string toupper] core: converts whole string to upper case using + * the default (extended "C" locale) rules. + * Stack: ... string => ... newString */ + {"strcaseLower", 1, 0, 0, {OPERAND_NONE}}, + /* [string tolower] core: converts whole string to upper case using + * the default (extended "C" locale) rules. + * Stack: ... string => ... newString */ + {"strcaseTitle", 1, 0, 0, {OPERAND_NONE}}, + /* [string totitle] core: converts whole string to upper case using + * the default (extended "C" locale) rules. + * Stack: ... string => ... newString */ + {"strreplace", 1, -3, 0, {OPERAND_NONE}}, + /* [string replace] core: replaces a non-empty range of one string + * with the contents of another. + * Stack: ... string fromIdx toIdx replacement => ... newString */ + + {"originCmd", 1, 0, 0, {OPERAND_NONE}}, + /* Reports which command was the origin (via namespace import chain) + * of the command named on the top of the stack. + * Stack: ... cmdName => ... fullOriginalCmdName */ {NULL, 0, 0, 0, {OPERAND_NONE}} }; @@ -2407,11 +2467,11 @@ TclCompileTokens( */ while (numObjsToConcat > 255) { - TclEmitInstInt1(INST_CONCAT1, 255, envPtr); + TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr); numObjsToConcat -= 254; /* concat pushes 1 obj, the result */ } if (numObjsToConcat > 1) { - TclEmitInstInt1(INST_CONCAT1, numObjsToConcat, envPtr); + TclEmitInstInt1(INST_STR_CONCAT1, numObjsToConcat, envPtr); } /* @@ -2543,11 +2603,11 @@ TclCompileExprWords( } concatItems = 2*numWords - 1; while (concatItems > 255) { - TclEmitInstInt1(INST_CONCAT1, 255, envPtr); + TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr); concatItems -= 254; } if (concatItems > 1) { - TclEmitInstInt1(INST_CONCAT1, concatItems, envPtr); + TclEmitInstInt1(INST_STR_CONCAT1, concatItems, envPtr); } TclEmitOpcode(INST_EXPR_STK, envPtr); } diff --git a/generic/tclCompile.h b/generic/tclCompile.h index b3c8442..fb66e90 100644 --- a/generic/tclCompile.h +++ b/generic/tclCompile.h @@ -512,7 +512,7 @@ typedef struct ByteCode { #define INST_PUSH4 2 #define INST_POP 3 #define INST_DUP 4 -#define INST_CONCAT1 5 +#define INST_STR_CONCAT1 5 #define INST_INVOKE_STK1 6 #define INST_INVOKE_STK4 7 #define INST_EVAL_STK 8 @@ -769,14 +769,27 @@ typedef struct ByteCode { #define INST_EXPAND_DROP 165 /* New foreach implementation */ - #define INST_FOREACH_START 166 #define INST_FOREACH_STEP 167 #define INST_FOREACH_END 168 #define INST_LMAP_COLLECT 169 +/* For compilation of [string trim] and related */ +#define INST_STR_TRIM 170 +#define INST_STR_TRIM_LEFT 171 +#define INST_STR_TRIM_RIGHT 172 + +#define INST_CONCAT_STK 173 + +#define INST_STR_UPPER 174 +#define INST_STR_LOWER 175 +#define INST_STR_TITLE 176 +#define INST_STR_REPLACE 177 + +#define INST_ORIGIN_COMMAND 178 + /* The last opcode */ -#define LAST_INST_OPCODE 169 +#define LAST_INST_OPCODE 178 /* * Table describing the Tcl bytecode instructions: their name (for displaying diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 37a7397..78e09c3 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -2621,7 +2621,7 @@ TEBCresume( NEXT_INST_F(5, 0, 0); } - case INST_CONCAT1: { + case INST_STR_CONCAT1: { int appendLen = 0; char *bytes, *p; Tcl_Obj **currPtr; @@ -2770,6 +2770,17 @@ TEBCresume( NEXT_INST_V(2, opnd, 1); } + case INST_CONCAT_STK: + /* + * Pop the opnd (objc) top stack elements, run through Tcl_ConcatObj, + * and then decrement their ref counts. + */ + + opnd = TclGetUInt4AtPtr(pc+1); + objResultPtr = Tcl_ConcatObj(opnd, &OBJ_AT_DEPTH(opnd-1)); + TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr); + NEXT_INST_V(5, opnd, 1); + case INST_EXPAND_START: /* * Push an element to the auxObjList. This records the current @@ -4442,12 +4453,11 @@ TEBCresume( register CallFrame *framePtr = iPtr->varFramePtr; register CallFrame *rootFramePtr = iPtr->rootFramePtr; + TRACE(("\"%.30s\" => ", O2S(OBJ_AT_TOS))); if (TclGetIntFromObj(interp, OBJ_AT_TOS, &level) != TCL_OK) { - TRACE_WITH_OBJ(("\"%.30s\" => ERROR: ", O2S(OBJ_AT_TOS)), - Tcl_GetObjResult(interp)); + TRACE_ERROR(interp); goto gotError; } - TRACE(("%d => ", level)); if (level <= 0) { level += framePtr->level; } @@ -4469,15 +4479,39 @@ TEBCresume( TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); NEXT_INST_F(1, 1, 1); } - case INST_RESOLVE_COMMAND: { - Tcl_Command cmd = Tcl_GetCommandFromObj(interp, OBJ_AT_TOS); + { + Tcl_Command cmd, origCmd; + case INST_RESOLVE_COMMAND: + cmd = Tcl_GetCommandFromObj(interp, OBJ_AT_TOS); TclNewObj(objResultPtr); if (cmd != NULL) { Tcl_GetCommandFullName(interp, cmd, objResultPtr); } TRACE_WITH_OBJ(("\"%.20s\" => ", O2S(OBJ_AT_TOS)), objResultPtr); NEXT_INST_F(1, 1, 1); + + case INST_ORIGIN_COMMAND: + TRACE(("\"%.30s\" => ", O2S(OBJ_AT_TOS))); + cmd = Tcl_GetCommandFromObj(interp, OBJ_AT_TOS); + if (cmd == NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "invalid command name \"%s\"", TclGetString(OBJ_AT_TOS))); + DECACHE_STACK_INFO(); + Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", + TclGetString(OBJ_AT_TOS), NULL); + CACHE_STACK_INFO(); + TRACE_APPEND(("ERROR: not command\n")); + goto gotError; + } + origCmd = TclGetOriginalCommand(cmd); + if (origCmd == NULL) { + origCmd = cmd; + } + TclNewObj(objResultPtr); + Tcl_GetCommandFullName(interp, origCmd, objResultPtr); + TRACE_APPEND(("\"%.30s\"", O2S(OBJ_AT_TOS))); + NEXT_INST_F(1, 1, 1); } case INST_TCLOO_SELF: { CallFrame *framePtr = iPtr->varFramePtr; @@ -5051,6 +5085,55 @@ TEBCresume( TRACE(("\"%.20s\" => %d\n", O2S(valuePtr), length)); NEXT_INST_F(1, 1, 1); + case INST_STR_UPPER: + valuePtr = OBJ_AT_TOS; + TRACE(("\"%.20s\" => ", O2S(valuePtr))); + if (Tcl_IsShared(valuePtr)) { + s1 = TclGetStringFromObj(valuePtr, &length); + TclNewStringObj(objResultPtr, s1, length); + length = Tcl_UtfToUpper(TclGetString(objResultPtr)); + Tcl_SetObjLength(objResultPtr, length); + TRACE_APPEND(("\"%.20s\"\n", O2S(objResultPtr))); + NEXT_INST_F(1, 1, 1); + } else { + length = Tcl_UtfToUpper(TclGetString(valuePtr)); + Tcl_SetObjLength(valuePtr, length); + TRACE_APPEND(("\"%.20s\"\n", O2S(valuePtr))); + NEXT_INST_F(1, 0, 0); + } + case INST_STR_LOWER: + valuePtr = OBJ_AT_TOS; + TRACE(("\"%.20s\" => ", O2S(valuePtr))); + if (Tcl_IsShared(valuePtr)) { + s1 = TclGetStringFromObj(valuePtr, &length); + TclNewStringObj(objResultPtr, s1, length); + length = Tcl_UtfToLower(TclGetString(objResultPtr)); + Tcl_SetObjLength(objResultPtr, length); + TRACE_APPEND(("\"%.20s\"\n", O2S(objResultPtr))); + NEXT_INST_F(1, 1, 1); + } else { + length = Tcl_UtfToLower(TclGetString(valuePtr)); + Tcl_SetObjLength(valuePtr, length); + TRACE_APPEND(("\"%.20s\"\n", O2S(valuePtr))); + NEXT_INST_F(1, 0, 0); + } + case INST_STR_TITLE: + valuePtr = OBJ_AT_TOS; + TRACE(("\"%.20s\" => ", O2S(valuePtr))); + if (Tcl_IsShared(valuePtr)) { + s1 = TclGetStringFromObj(valuePtr, &length); + TclNewStringObj(objResultPtr, s1, length); + length = Tcl_UtfToTitle(TclGetString(objResultPtr)); + Tcl_SetObjLength(objResultPtr, length); + TRACE_APPEND(("\"%.20s\"\n", O2S(objResultPtr))); + NEXT_INST_F(1, 1, 1); + } else { + length = Tcl_UtfToTitle(TclGetString(valuePtr)); + Tcl_SetObjLength(valuePtr, length); + TRACE_APPEND(("\"%.20s\"\n", O2S(valuePtr))); + NEXT_INST_F(1, 0, 0); + } + case INST_STR_INDEX: value2Ptr = OBJ_AT_TOS; valuePtr = OBJ_UNDER_TOS; @@ -5159,6 +5242,179 @@ TEBCresume( int length3; Tcl_Obj *value3Ptr; + case INST_STR_REPLACE: + value3Ptr = POP_OBJECT(); + valuePtr = OBJ_AT_DEPTH(2); + length = Tcl_GetCharLength(valuePtr) - 1; + TRACE(("\"%.20s\" %s %s \"%.20s\" => ", O2S(valuePtr), + O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), O2S(value3Ptr))); + if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, length, + &fromIdx) != TCL_OK + || TclGetIntForIndexM(interp, OBJ_AT_TOS, length, + &toIdx) != TCL_OK) { + TclDecrRefCount(value3Ptr); + TRACE_ERROR(interp); + goto gotError; + } + TclDecrRefCount(OBJ_AT_TOS); + (void) POP_OBJECT(); + TclDecrRefCount(OBJ_AT_TOS); + (void) POP_OBJECT(); + if (fromIdx < 0) { + fromIdx = 0; + } + + if (fromIdx > toIdx || fromIdx > length) { + TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr))); + TclDecrRefCount(value3Ptr); + NEXT_INST_F(1, 0, 0); + } + + if (toIdx > length) { + toIdx = length; + } + + if (fromIdx == 0 && toIdx == length) { + TclDecrRefCount(OBJ_AT_TOS); + OBJ_AT_TOS = value3Ptr; + TRACE_APPEND(("\"%.30s\"\n", O2S(value3Ptr))); + NEXT_INST_F(1, 0, 0); + } + + length3 = Tcl_GetCharLength(value3Ptr); + + /* + * Remove substring. In-place. + */ + + if (length3 == 0 && !Tcl_IsShared(valuePtr) && toIdx == length) { + TclDecrRefCount(value3Ptr); + Tcl_SetObjLength(valuePtr, fromIdx); + TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr))); + NEXT_INST_F(1, 0, 0); + } + + /* + * See if we can splice in place. This happens when the number of + * characters being replaced is the same as the number of characters + * in the string to be inserted. + */ + + if (length3 - 1 == toIdx - fromIdx) { + unsigned char *bytes1, *bytes2; + + if (Tcl_IsShared(valuePtr)) { + objResultPtr = Tcl_DuplicateObj(valuePtr); + if (TclIsPureByteArray(objResultPtr) + && TclIsPureByteArray(value3Ptr)) { + bytes1 = Tcl_GetByteArrayFromObj(objResultPtr, NULL); + bytes2 = Tcl_GetByteArrayFromObj(value3Ptr, NULL); + memcpy(bytes1 + fromIdx, bytes2, length3); + } else { + ustring1 = Tcl_GetUnicodeFromObj(objResultPtr, NULL); + ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL); + memcpy(ustring1 + fromIdx, ustring2, + length3 * sizeof(Tcl_UniChar)); + + /* + * Magic! Flush the info in the string internal rep that + * refers to the about-to-be-invalidated UTF-8 rep. This + * sets the 'allocated' field of the String structure to 0 + * to indicate that a new buffer needs to be allocated. + * This is safe; we know we've got a tclStringTypePtr set + * at this point (post Tcl_GetUnicodeFromObj). + */ + + ((int *) objResultPtr->internalRep.otherValuePtr)[1] = 0; + } + Tcl_InvalidateStringRep(objResultPtr); + TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr))); + NEXT_INST_F(1, 1, 1); + } else { + if (TclIsPureByteArray(valuePtr) + && TclIsPureByteArray(value3Ptr)) { + bytes1 = Tcl_GetByteArrayFromObj(valuePtr, NULL); + bytes2 = Tcl_GetByteArrayFromObj(value3Ptr, NULL); + memcpy(bytes1 + fromIdx, bytes2, length3); + } else { + ustring1 = Tcl_GetUnicodeFromObj(valuePtr, NULL); + ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL); + memcpy(ustring1 + fromIdx, ustring2, + length3 * sizeof(Tcl_UniChar)); + + /* + * Magic! Flush the info in the string internal rep that + * refers to the about-to-be-invalidated UTF-8 rep. This + * sets the 'allocated' field of the String structure to 0 + * to indicate that a new buffer needs to be allocated. + * This is safe; we know we've got a tclStringTypePtr set + * at this point (post Tcl_GetUnicodeFromObj). + */ + + ((int *) objResultPtr->internalRep.otherValuePtr)[1] = 0; + } + Tcl_InvalidateStringRep(valuePtr); + TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr))); + NEXT_INST_F(1, 0, 0); + } + } + + /* + * Get the unicode representation; this is where we guarantee to lose + * bytearrays. + */ + + ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length); + length--; + + /* + * Remove substring using copying. + */ + + if (length3 == 0) { + if (fromIdx > 0) { + objResultPtr = Tcl_NewUnicodeObj(ustring1, fromIdx); + if (toIdx < length) { + Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1, + length - toIdx); + } + } else { + objResultPtr = Tcl_NewUnicodeObj(ustring1 + toIdx + 1, + length - toIdx); + } + TclDecrRefCount(value3Ptr); + TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr))); + NEXT_INST_F(1, 1, 1); + } + + /* + * Splice string pieces by full copying. + */ + + if (fromIdx > 0) { + objResultPtr = Tcl_NewUnicodeObj(ustring1, fromIdx); + Tcl_AppendObjToObj(objResultPtr, value3Ptr); + if (toIdx < length) { + Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1, + length - toIdx); + } + } else if (Tcl_IsShared(value3Ptr)) { + objResultPtr = Tcl_DuplicateObj(value3Ptr); + if (toIdx < length) { + Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1, + length - toIdx); + } + } else { + objResultPtr = value3Ptr; + if (toIdx < length) { + Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1, + length - toIdx); + } + } + TclDecrRefCount(value3Ptr); + TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr))); + NEXT_INST_F(1, 1, 1); + case INST_STR_MAP: valuePtr = OBJ_AT_TOS; /* "Main" string. */ value3Ptr = OBJ_UNDER_TOS; /* "Target" string. */ @@ -5304,11 +5560,55 @@ TEBCresume( JUMP_PEEPHOLE_F(match, 2, 2); + { + const char *string1, *string2; + int trim1, trim2; + + case INST_STR_TRIM_LEFT: + valuePtr = OBJ_UNDER_TOS; /* String */ + value2Ptr = OBJ_AT_TOS; /* TrimSet */ + string2 = TclGetStringFromObj(value2Ptr, &length2); + string1 = TclGetStringFromObj(valuePtr, &length); + trim1 = TclTrimLeft(string1, length, string2, length2); + trim2 = 0; + goto createTrimmedString; + case INST_STR_TRIM_RIGHT: + valuePtr = OBJ_UNDER_TOS; /* String */ + value2Ptr = OBJ_AT_TOS; /* TrimSet */ + string2 = TclGetStringFromObj(value2Ptr, &length2); + string1 = TclGetStringFromObj(valuePtr, &length); + trim2 = TclTrimRight(string1, length, string2, length2); + trim1 = 0; + goto createTrimmedString; + case INST_STR_TRIM: + valuePtr = OBJ_UNDER_TOS; /* String */ + value2Ptr = OBJ_AT_TOS; /* TrimSet */ + string2 = TclGetStringFromObj(value2Ptr, &length2); + string1 = TclGetStringFromObj(valuePtr, &length); + trim1 = TclTrimLeft(string1, length, string2, length2); + if (trim1 < length) { + trim2 = TclTrimRight(string1, length, string2, length2); + } else { + trim2 = 0; + } + createTrimmedString: + if (trim1 == 0 && trim2 == 0) { + TRACE_WITH_OBJ(("\"%.30s\" \"%.30s\" => ", + O2S(valuePtr), O2S(value2Ptr)), valuePtr); + NEXT_INST_F(1, 1, 0); + } else { + objResultPtr = Tcl_NewStringObj(string1+trim1, length-trim1-trim2); + TRACE_WITH_OBJ(("\"%.30s\" \"%.30s\" => ", + O2S(valuePtr), O2S(value2Ptr)), objResultPtr); + NEXT_INST_F(1, 2, 1); + } + } + case INST_REGEXP: cflags = TclGetInt1AtPtr(pc+1); /* RE compile flages like NOCASE */ valuePtr = OBJ_AT_TOS; /* String */ value2Ptr = OBJ_UNDER_TOS; /* Pattern */ - TRACE(("%.20s %.20s => ", O2S(valuePtr), O2S(value2Ptr))); + TRACE(("\"%.30s\" \"%.30s\" => ", O2S(valuePtr), O2S(value2Ptr))); /* * Compile and match the regular expression. diff --git a/generic/tclInt.h b/generic/tclInt.h index 8ccfadb..94ee836 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -3442,6 +3442,9 @@ MODULE_SCOPE int TclCompileBreakCmd(Tcl_Interp *interp, MODULE_SCOPE int TclCompileCatchCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileConcatCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileContinueCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); @@ -3541,6 +3544,9 @@ MODULE_SCOPE int TclCompileLassignCmd(Tcl_Interp *interp, MODULE_SCOPE int TclCompileLindexCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileLinsertCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileListCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); @@ -3565,6 +3571,9 @@ MODULE_SCOPE int TclCompileNamespaceCodeCmd(Tcl_Interp *interp, MODULE_SCOPE int TclCompileNamespaceCurrentCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileNamespaceOriginCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileNamespaceQualifiersCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); @@ -3622,6 +3631,27 @@ MODULE_SCOPE int TclCompileStringMatchCmd(Tcl_Interp *interp, MODULE_SCOPE int TclCompileStringRangeCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileStringReplaceCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileStringToLowerCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileStringToTitleCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileStringToUpperCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileStringTrimCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileStringTrimLCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); +MODULE_SCOPE int TclCompileStringTrimRCmd(Tcl_Interp *interp, + Tcl_Parse *parsePtr, Command *cmdPtr, + struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileSubstCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c index cd44455..8f2f10e 100644 --- a/generic/tclNamesp.c +++ b/generic/tclNamesp.c @@ -171,7 +171,7 @@ static const EnsembleImplMap defaultNamespaceMap[] = { {"forget", NamespaceForgetCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0}, {"import", NamespaceImportCmd, TclCompileBasicMin0ArgCmd, NULL, NULL, 0}, {"inscope", NamespaceInscopeCmd, NULL, NRNamespaceInscopeCmd, NULL, 0}, - {"origin", NamespaceOriginCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0}, + {"origin", NamespaceOriginCmd, TclCompileNamespaceOriginCmd, NULL, NULL, 0}, {"parent", NamespaceParentCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"path", NamespacePathCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0}, {"qualifiers", NamespaceQualifiersCmd, TclCompileNamespaceQualifiersCmd, NULL, NULL, 0}, diff --git a/generic/tclOptimize.c b/generic/tclOptimize.c index 74de7a3..827d89d 100644 --- a/generic/tclOptimize.c +++ b/generic/tclOptimize.c @@ -191,7 +191,7 @@ TrimUnreachable( * ConvertZeroEffectToNOP -- * * Replace PUSH/POP sequences (when non-hazardous) with NOPs. Also - * replace PUSH empty/CONCAT and TRY_CVT_NUMERIC (when followed by an + * replace PUSH empty/STR_CONCAT and TRY_CVT_NUMERIC (when followed by an * operation that guarantees the check for arithmeticity) and eliminate * LNOT when we can invert the following JUMP condition. * @@ -227,7 +227,7 @@ ConvertZeroEffectToNOP( case INST_PUSH1: if (nextInst == INST_POP) { blank = size + InstLength(nextInst); - } else if (nextInst == INST_CONCAT1 + } else if (nextInst == INST_STR_CONCAT1 && TclGetUInt1AtPtr(currentInstPtr + size + 1) == 2) { Tcl_Obj *litPtr = TclFetchLiteral(envPtr, TclGetUInt1AtPtr(currentInstPtr + 1)); @@ -242,7 +242,7 @@ ConvertZeroEffectToNOP( case INST_PUSH4: if (nextInst == INST_POP) { blank = size + 1; - } else if (nextInst == INST_CONCAT1 + } else if (nextInst == INST_STR_CONCAT1 && TclGetUInt1AtPtr(currentInstPtr + size + 1) == 2) { Tcl_Obj *litPtr = TclFetchLiteral(envPtr, TclGetUInt4AtPtr(currentInstPtr + 1)); diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c index 883e2ea..883e2ea 100644..100755 --- a/generic/tclStrToD.c +++ b/generic/tclStrToD.c diff --git a/generic/tclStringTrim.h b/generic/tclStringTrim.h new file mode 100644 index 0000000..669f10b --- /dev/null +++ b/generic/tclStringTrim.h @@ -0,0 +1,68 @@ +/* + * tclStringTrim.h -- + * + * This file contains the definition of what characters are to be trimmed + * from a string by [string trim] by default. It's only needed by Tcl's + * implementation; it does not form a public or private API at all. + * + * Copyright (c) 1987-1993 The Regents of the University of California. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 1998-2000 Scriptics Corporation. + * Copyright (c) 2002 ActiveState Corporation. + * Copyright (c) 2003-2013 Donal K. Fellows. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef TCL_STRING_TRIM_H +#define TCL_STRING_TRIM_H + +/* + * Default set of characters to trim in [string trim] and friends. This is a + * UTF-8 literal string containing all Unicode space characters. [TIP #413] + */ + +#define DEFAULT_TRIM_SET \ + "\x09\x0a\x0b\x0c\x0d " /* ASCII */\ + "\xc0\x80" /* nul (U+0000) */\ + "\xc2\x85" /* next line (U+0085) */\ + "\xc2\xa0" /* non-breaking space (U+00a0) */\ + "\xe1\x9a\x80" /* ogham space mark (U+1680) */ \ + "\xe1\xa0\x8e" /* mongolian vowel separator (U+180e) */\ + "\xe2\x80\x80" /* en quad (U+2000) */\ + "\xe2\x80\x81" /* em quad (U+2001) */\ + "\xe2\x80\x82" /* en space (U+2002) */\ + "\xe2\x80\x83" /* em space (U+2003) */\ + "\xe2\x80\x84" /* three-per-em space (U+2004) */\ + "\xe2\x80\x85" /* four-per-em space (U+2005) */\ + "\xe2\x80\x86" /* six-per-em space (U+2006) */\ + "\xe2\x80\x87" /* figure space (U+2007) */\ + "\xe2\x80\x88" /* punctuation space (U+2008) */\ + "\xe2\x80\x89" /* thin space (U+2009) */\ + "\xe2\x80\x8a" /* hair space (U+200a) */\ + "\xe2\x80\x8b" /* zero width space (U+200b) */\ + "\xe2\x80\xa8" /* line separator (U+2028) */\ + "\xe2\x80\xa9" /* paragraph separator (U+2029) */\ + "\xe2\x80\xaf" /* narrow no-break space (U+202f) */\ + "\xe2\x81\x9f" /* medium mathematical space (U+205f) */\ + "\xe2\x81\xa0" /* word joiner (U+2060) */\ + "\xe3\x80\x80" /* ideographic space (U+3000) */\ + "\xef\xbb\xbf" /* zero width no-break space (U+feff) */ + +/* + * The whitespace trimming set used when [concat]enating. This is a subset of + * the above, and deliberately so. + */ + +#define CONCAT_TRIM_SET " \f\v\r\t\n" + +#endif /* TCL_STRING_TRIM_H */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tclStubLibTbl.c b/generic/tclStubLibTbl.c deleted file mode 100644 index 0391502..0000000 --- a/generic/tclStubLibTbl.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * tclStubLibTbl.c -- - * - * Stub object that will be statically linked into extensions that want - * to access Tcl. - * - * Copyright (c) 1998-1999 by Scriptics Corporation. - * Copyright (c) 1998 Paul Duffin. - * - * See the file "license.terms" for information on usage and redistribution of - * this file, and for a DISCLAIMER OF ALL WARRANTIES. - */ - -#include "tclInt.h" - -/* - *---------------------------------------------------------------------- - * - * TclInitStubTable -- - * - * Initialize the stub table, using the structure pointed at - * by the "version" argument. - * - * Results: - * Outputs the value of the "version" argument. - * - * Side effects: - * Sets the stub table pointers. - * - *---------------------------------------------------------------------- - */ -MODULE_SCOPE const char * -TclInitStubTable( - const char *version) /* points to the version field of a - TclStubInfoType structure variable. */ -{ - tclStubsPtr = ((const TclStubInfoType *) version)->stubs; - - if (tclStubsPtr->hooks) { - tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs; - tclIntStubsPtr = tclStubsPtr->hooks->tclIntStubs; - tclIntPlatStubsPtr = tclStubsPtr->hooks->tclIntPlatStubs; - } else { - tclPlatStubsPtr = NULL; - tclIntStubsPtr = NULL; - tclIntPlatStubsPtr = NULL; - } - - return version; -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ diff --git a/generic/tclUtil.c b/generic/tclUtil.c index b089132..2d00adf 100644 --- a/generic/tclUtil.c +++ b/generic/tclUtil.c @@ -14,6 +14,7 @@ #include "tclInt.h" #include "tclParse.h" +#include "tclStringTrim.h" #include <math.h> /* @@ -1768,8 +1769,7 @@ TclTrimLeft( */ /* The whitespace characters trimmed during [concat] operations */ -#define CONCAT_WS " \f\v\r\t\n" -#define CONCAT_WS_SIZE (int) (sizeof(CONCAT_WS "") - 1) +#define CONCAT_WS_SIZE (int) (sizeof(CONCAT_TRIM_SET "") - 1) char * Tcl_Concat( @@ -1825,7 +1825,8 @@ Tcl_Concat( * Trim away the leading whitespace. */ - trim = TclTrimLeft(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE); + trim = TclTrimLeft(element, elemLength, CONCAT_TRIM_SET, + CONCAT_WS_SIZE); element += trim; elemLength -= trim; @@ -1834,7 +1835,8 @@ Tcl_Concat( * a final backslash character. */ - trim = TclTrimRight(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE); + trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET, + CONCAT_WS_SIZE); trim -= trim && (element[elemLength - trim - 1] == '\\'); elemLength -= trim; @@ -1959,7 +1961,8 @@ Tcl_ConcatObj( * Trim away the leading whitespace. */ - trim = TclTrimLeft(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE); + trim = TclTrimLeft(element, elemLength, CONCAT_TRIM_SET, + CONCAT_WS_SIZE); element += trim; elemLength -= trim; @@ -1968,7 +1971,8 @@ Tcl_ConcatObj( * a final backslash character. */ - trim = TclTrimRight(element, elemLength, CONCAT_WS, CONCAT_WS_SIZE); + trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET, + CONCAT_WS_SIZE); trim -= trim && (element[elemLength - trim - 1] == '\\'); elemLength -= trim; diff --git a/library/encoding/tis-620.enc b/library/encoding/tis-620.enc index c233be5..c233be5 100644..100755 --- a/library/encoding/tis-620.enc +++ b/library/encoding/tis-620.enc diff --git a/library/msgs/af.msg b/library/msgs/af.msg index 0892615..0892615 100644..100755 --- a/library/msgs/af.msg +++ b/library/msgs/af.msg diff --git a/library/msgs/af_za.msg b/library/msgs/af_za.msg index fef48ad..fef48ad 100644..100755 --- a/library/msgs/af_za.msg +++ b/library/msgs/af_za.msg diff --git a/library/msgs/ar.msg b/library/msgs/ar.msg index 257157f..257157f 100644..100755 --- a/library/msgs/ar.msg +++ b/library/msgs/ar.msg diff --git a/library/msgs/ar_in.msg b/library/msgs/ar_in.msg index 185e49c..185e49c 100644..100755 --- a/library/msgs/ar_in.msg +++ b/library/msgs/ar_in.msg diff --git a/library/msgs/ar_jo.msg b/library/msgs/ar_jo.msg index 0f5e269..0f5e269 100644..100755 --- a/library/msgs/ar_jo.msg +++ b/library/msgs/ar_jo.msg diff --git a/library/msgs/ar_lb.msg b/library/msgs/ar_lb.msg index e62acd3..e62acd3 100644..100755 --- a/library/msgs/ar_lb.msg +++ b/library/msgs/ar_lb.msg diff --git a/library/msgs/ar_sy.msg b/library/msgs/ar_sy.msg index d5e1c87..d5e1c87 100644..100755 --- a/library/msgs/ar_sy.msg +++ b/library/msgs/ar_sy.msg diff --git a/library/msgs/be.msg b/library/msgs/be.msg index 379a1d7..379a1d7 100644..100755 --- a/library/msgs/be.msg +++ b/library/msgs/be.msg diff --git a/library/msgs/bg.msg b/library/msgs/bg.msg index ff17759..ff17759 100644..100755 --- a/library/msgs/bg.msg +++ b/library/msgs/bg.msg diff --git a/library/msgs/bn.msg b/library/msgs/bn.msg index 664b9d8..664b9d8 100644..100755 --- a/library/msgs/bn.msg +++ b/library/msgs/bn.msg diff --git a/library/msgs/bn_in.msg b/library/msgs/bn_in.msg index 28c000f..28c000f 100644..100755 --- a/library/msgs/bn_in.msg +++ b/library/msgs/bn_in.msg diff --git a/library/msgs/ca.msg b/library/msgs/ca.msg index 36c9772..36c9772 100644..100755 --- a/library/msgs/ca.msg +++ b/library/msgs/ca.msg diff --git a/library/msgs/cs.msg b/library/msgs/cs.msg index 8db8bdd..8db8bdd 100644..100755 --- a/library/msgs/cs.msg +++ b/library/msgs/cs.msg diff --git a/library/msgs/da.msg b/library/msgs/da.msg index e4fec7f..e4fec7f 100644..100755 --- a/library/msgs/da.msg +++ b/library/msgs/da.msg diff --git a/library/msgs/de.msg b/library/msgs/de.msg index 9eb3145..9eb3145 100644..100755 --- a/library/msgs/de.msg +++ b/library/msgs/de.msg diff --git a/library/msgs/de_at.msg b/library/msgs/de_at.msg index 61bc266..61bc266 100644..100755 --- a/library/msgs/de_at.msg +++ b/library/msgs/de_at.msg diff --git a/library/msgs/de_be.msg b/library/msgs/de_be.msg index 3614763..3614763 100644..100755 --- a/library/msgs/de_be.msg +++ b/library/msgs/de_be.msg diff --git a/library/msgs/el.msg b/library/msgs/el.msg index ac19f62..ac19f62 100644..100755 --- a/library/msgs/el.msg +++ b/library/msgs/el.msg diff --git a/library/msgs/en_au.msg b/library/msgs/en_au.msg index 7f9870c..7f9870c 100644..100755 --- a/library/msgs/en_au.msg +++ b/library/msgs/en_au.msg diff --git a/library/msgs/en_be.msg b/library/msgs/en_be.msg index 5072986..5072986 100644..100755 --- a/library/msgs/en_be.msg +++ b/library/msgs/en_be.msg diff --git a/library/msgs/en_bw.msg b/library/msgs/en_bw.msg index 8fd20c7..8fd20c7 100644..100755 --- a/library/msgs/en_bw.msg +++ b/library/msgs/en_bw.msg diff --git a/library/msgs/en_ca.msg b/library/msgs/en_ca.msg index 278efe7..278efe7 100644..100755 --- a/library/msgs/en_ca.msg +++ b/library/msgs/en_ca.msg diff --git a/library/msgs/en_gb.msg b/library/msgs/en_gb.msg index 5c61c43..5c61c43 100644..100755 --- a/library/msgs/en_gb.msg +++ b/library/msgs/en_gb.msg diff --git a/library/msgs/en_hk.msg b/library/msgs/en_hk.msg index 8b33bc0..8b33bc0 100644..100755 --- a/library/msgs/en_hk.msg +++ b/library/msgs/en_hk.msg diff --git a/library/msgs/en_ie.msg b/library/msgs/en_ie.msg index ba621cf..ba621cf 100644..100755 --- a/library/msgs/en_ie.msg +++ b/library/msgs/en_ie.msg diff --git a/library/msgs/en_in.msg b/library/msgs/en_in.msg index a1f155d..a1f155d 100644..100755 --- a/library/msgs/en_in.msg +++ b/library/msgs/en_in.msg diff --git a/library/msgs/en_nz.msg b/library/msgs/en_nz.msg index b419017..b419017 100644..100755 --- a/library/msgs/en_nz.msg +++ b/library/msgs/en_nz.msg diff --git a/library/msgs/en_ph.msg b/library/msgs/en_ph.msg index 682666d..682666d 100644..100755 --- a/library/msgs/en_ph.msg +++ b/library/msgs/en_ph.msg diff --git a/library/msgs/en_sg.msg b/library/msgs/en_sg.msg index 4dc5b1d..4dc5b1d 100644..100755 --- a/library/msgs/en_sg.msg +++ b/library/msgs/en_sg.msg diff --git a/library/msgs/en_za.msg b/library/msgs/en_za.msg index fe43797..fe43797 100644..100755 --- a/library/msgs/en_za.msg +++ b/library/msgs/en_za.msg diff --git a/library/msgs/en_zw.msg b/library/msgs/en_zw.msg index 2a5804f..2a5804f 100644..100755 --- a/library/msgs/en_zw.msg +++ b/library/msgs/en_zw.msg diff --git a/library/msgs/eo.msg b/library/msgs/eo.msg index 1d2a24f..1d2a24f 100644..100755 --- a/library/msgs/eo.msg +++ b/library/msgs/eo.msg diff --git a/library/msgs/es.msg b/library/msgs/es.msg index a24f0a1..a24f0a1 100644..100755 --- a/library/msgs/es.msg +++ b/library/msgs/es.msg diff --git a/library/msgs/es_ar.msg b/library/msgs/es_ar.msg index 7d35027..7d35027 100644..100755 --- a/library/msgs/es_ar.msg +++ b/library/msgs/es_ar.msg diff --git a/library/msgs/es_bo.msg b/library/msgs/es_bo.msg index 498ad0d..498ad0d 100644..100755 --- a/library/msgs/es_bo.msg +++ b/library/msgs/es_bo.msg diff --git a/library/msgs/es_cl.msg b/library/msgs/es_cl.msg index 31d465c..31d465c 100644..100755 --- a/library/msgs/es_cl.msg +++ b/library/msgs/es_cl.msg diff --git a/library/msgs/es_co.msg b/library/msgs/es_co.msg index 77e57f0..77e57f0 100644..100755 --- a/library/msgs/es_co.msg +++ b/library/msgs/es_co.msg diff --git a/library/msgs/es_cr.msg b/library/msgs/es_cr.msg index 7a652fa..7a652fa 100644..100755 --- a/library/msgs/es_cr.msg +++ b/library/msgs/es_cr.msg diff --git a/library/msgs/es_do.msg b/library/msgs/es_do.msg index 0e283da..0e283da 100644..100755 --- a/library/msgs/es_do.msg +++ b/library/msgs/es_do.msg diff --git a/library/msgs/es_ec.msg b/library/msgs/es_ec.msg index 9e921e0..9e921e0 100644..100755 --- a/library/msgs/es_ec.msg +++ b/library/msgs/es_ec.msg diff --git a/library/msgs/es_gt.msg b/library/msgs/es_gt.msg index ecd6faf..ecd6faf 100644..100755 --- a/library/msgs/es_gt.msg +++ b/library/msgs/es_gt.msg diff --git a/library/msgs/es_hn.msg b/library/msgs/es_hn.msg index a758ca2..a758ca2 100644..100755 --- a/library/msgs/es_hn.msg +++ b/library/msgs/es_hn.msg diff --git a/library/msgs/es_mx.msg b/library/msgs/es_mx.msg index 7cfb545..7cfb545 100644..100755 --- a/library/msgs/es_mx.msg +++ b/library/msgs/es_mx.msg diff --git a/library/msgs/es_ni.msg b/library/msgs/es_ni.msg index 7c39495..7c39495 100644..100755 --- a/library/msgs/es_ni.msg +++ b/library/msgs/es_ni.msg diff --git a/library/msgs/es_pa.msg b/library/msgs/es_pa.msg index cecacdc..cecacdc 100644..100755 --- a/library/msgs/es_pa.msg +++ b/library/msgs/es_pa.msg diff --git a/library/msgs/es_pe.msg b/library/msgs/es_pe.msg index 9f90595..9f90595 100644..100755 --- a/library/msgs/es_pe.msg +++ b/library/msgs/es_pe.msg diff --git a/library/msgs/es_pr.msg b/library/msgs/es_pr.msg index 8511b12..8511b12 100644..100755 --- a/library/msgs/es_pr.msg +++ b/library/msgs/es_pr.msg diff --git a/library/msgs/es_py.msg b/library/msgs/es_py.msg index aa93d36..aa93d36 100644..100755 --- a/library/msgs/es_py.msg +++ b/library/msgs/es_py.msg diff --git a/library/msgs/es_sv.msg b/library/msgs/es_sv.msg index fc7954d..fc7954d 100644..100755 --- a/library/msgs/es_sv.msg +++ b/library/msgs/es_sv.msg diff --git a/library/msgs/es_uy.msg b/library/msgs/es_uy.msg index b33525c..b33525c 100644..100755 --- a/library/msgs/es_uy.msg +++ b/library/msgs/es_uy.msg diff --git a/library/msgs/es_ve.msg b/library/msgs/es_ve.msg index 7c2a7b0..7c2a7b0 100644..100755 --- a/library/msgs/es_ve.msg +++ b/library/msgs/es_ve.msg diff --git a/library/msgs/et.msg b/library/msgs/et.msg index 8d32e9e..8d32e9e 100644..100755 --- a/library/msgs/et.msg +++ b/library/msgs/et.msg diff --git a/library/msgs/eu.msg b/library/msgs/eu.msg index cf708b6..cf708b6 100644..100755 --- a/library/msgs/eu.msg +++ b/library/msgs/eu.msg diff --git a/library/msgs/eu_es.msg b/library/msgs/eu_es.msg index 2694418..2694418 100644..100755 --- a/library/msgs/eu_es.msg +++ b/library/msgs/eu_es.msg diff --git a/library/msgs/fa.msg b/library/msgs/fa.msg index 89b2f90..89b2f90 100644..100755 --- a/library/msgs/fa.msg +++ b/library/msgs/fa.msg diff --git a/library/msgs/fa_in.msg b/library/msgs/fa_in.msg index adc9e91..adc9e91 100644..100755 --- a/library/msgs/fa_in.msg +++ b/library/msgs/fa_in.msg diff --git a/library/msgs/fa_ir.msg b/library/msgs/fa_ir.msg index 597ce9d..597ce9d 100644..100755 --- a/library/msgs/fa_ir.msg +++ b/library/msgs/fa_ir.msg diff --git a/library/msgs/fi.msg b/library/msgs/fi.msg index acabba0..acabba0 100644..100755 --- a/library/msgs/fi.msg +++ b/library/msgs/fi.msg diff --git a/library/msgs/fo.msg b/library/msgs/fo.msg index 4696e62..4696e62 100644..100755 --- a/library/msgs/fo.msg +++ b/library/msgs/fo.msg diff --git a/library/msgs/fo_fo.msg b/library/msgs/fo_fo.msg index 2392b8e..2392b8e 100644..100755 --- a/library/msgs/fo_fo.msg +++ b/library/msgs/fo_fo.msg diff --git a/library/msgs/fr.msg b/library/msgs/fr.msg index 55b19bf..55b19bf 100644..100755 --- a/library/msgs/fr.msg +++ b/library/msgs/fr.msg diff --git a/library/msgs/fr_be.msg b/library/msgs/fr_be.msg index cdb13bd..cdb13bd 100644..100755 --- a/library/msgs/fr_be.msg +++ b/library/msgs/fr_be.msg diff --git a/library/msgs/fr_ca.msg b/library/msgs/fr_ca.msg index 00ccfff..00ccfff 100644..100755 --- a/library/msgs/fr_ca.msg +++ b/library/msgs/fr_ca.msg diff --git a/library/msgs/fr_ch.msg b/library/msgs/fr_ch.msg index 7e2bac7..7e2bac7 100644..100755 --- a/library/msgs/fr_ch.msg +++ b/library/msgs/fr_ch.msg diff --git a/library/msgs/ga.msg b/library/msgs/ga.msg index 6edf13a..6edf13a 100644..100755 --- a/library/msgs/ga.msg +++ b/library/msgs/ga.msg diff --git a/library/msgs/ga_ie.msg b/library/msgs/ga_ie.msg index b6acbbc..b6acbbc 100644..100755 --- a/library/msgs/ga_ie.msg +++ b/library/msgs/ga_ie.msg diff --git a/library/msgs/gl.msg b/library/msgs/gl.msg index 4b869e8..4b869e8 100644..100755 --- a/library/msgs/gl.msg +++ b/library/msgs/gl.msg diff --git a/library/msgs/gl_es.msg b/library/msgs/gl_es.msg index d4ed270..d4ed270 100644..100755 --- a/library/msgs/gl_es.msg +++ b/library/msgs/gl_es.msg diff --git a/library/msgs/gv.msg b/library/msgs/gv.msg index 7d332ad..7d332ad 100644..100755 --- a/library/msgs/gv.msg +++ b/library/msgs/gv.msg diff --git a/library/msgs/gv_gb.msg b/library/msgs/gv_gb.msg index 5e96e6f..5e96e6f 100644..100755 --- a/library/msgs/gv_gb.msg +++ b/library/msgs/gv_gb.msg diff --git a/library/msgs/he.msg b/library/msgs/he.msg index 4fd921d..4fd921d 100644..100755 --- a/library/msgs/he.msg +++ b/library/msgs/he.msg diff --git a/library/msgs/hi.msg b/library/msgs/hi.msg index 50c9fb8..50c9fb8 100644..100755 --- a/library/msgs/hi.msg +++ b/library/msgs/hi.msg diff --git a/library/msgs/hi_in.msg b/library/msgs/hi_in.msg index 239793f..239793f 100644..100755 --- a/library/msgs/hi_in.msg +++ b/library/msgs/hi_in.msg diff --git a/library/msgs/hr.msg b/library/msgs/hr.msg index cec145b..cec145b 100644..100755 --- a/library/msgs/hr.msg +++ b/library/msgs/hr.msg diff --git a/library/msgs/hu.msg b/library/msgs/hu.msg index e5e68d9..e5e68d9 100644..100755 --- a/library/msgs/hu.msg +++ b/library/msgs/hu.msg diff --git a/library/msgs/id.msg b/library/msgs/id.msg index 17c6bb5..17c6bb5 100644..100755 --- a/library/msgs/id.msg +++ b/library/msgs/id.msg diff --git a/library/msgs/id_id.msg b/library/msgs/id_id.msg index bb672c1..bb672c1 100644..100755 --- a/library/msgs/id_id.msg +++ b/library/msgs/id_id.msg diff --git a/library/msgs/is.msg b/library/msgs/is.msg index adc2d2a..adc2d2a 100644..100755 --- a/library/msgs/is.msg +++ b/library/msgs/is.msg diff --git a/library/msgs/it.msg b/library/msgs/it.msg index b641cde..b641cde 100644..100755 --- a/library/msgs/it.msg +++ b/library/msgs/it.msg diff --git a/library/msgs/it_ch.msg b/library/msgs/it_ch.msg index b36ed36..b36ed36 100644..100755 --- a/library/msgs/it_ch.msg +++ b/library/msgs/it_ch.msg diff --git a/library/msgs/ja.msg b/library/msgs/ja.msg index 2767665..2767665 100644..100755 --- a/library/msgs/ja.msg +++ b/library/msgs/ja.msg diff --git a/library/msgs/kl.msg b/library/msgs/kl.msg index d877bfe..d877bfe 100644..100755 --- a/library/msgs/kl.msg +++ b/library/msgs/kl.msg diff --git a/library/msgs/kl_gl.msg b/library/msgs/kl_gl.msg index 403aa10..403aa10 100644..100755 --- a/library/msgs/kl_gl.msg +++ b/library/msgs/kl_gl.msg diff --git a/library/msgs/ko.msg b/library/msgs/ko.msg index 0cd17a1..0cd17a1 100644..100755 --- a/library/msgs/ko.msg +++ b/library/msgs/ko.msg diff --git a/library/msgs/ko_kr.msg b/library/msgs/ko_kr.msg index ea5bbd7..ea5bbd7 100644..100755 --- a/library/msgs/ko_kr.msg +++ b/library/msgs/ko_kr.msg diff --git a/library/msgs/kok.msg b/library/msgs/kok.msg index 0869f20..0869f20 100644..100755 --- a/library/msgs/kok.msg +++ b/library/msgs/kok.msg diff --git a/library/msgs/kok_in.msg b/library/msgs/kok_in.msg index abcb1ff..abcb1ff 100644..100755 --- a/library/msgs/kok_in.msg +++ b/library/msgs/kok_in.msg diff --git a/library/msgs/kw.msg b/library/msgs/kw.msg index aaf79b3..aaf79b3 100644..100755 --- a/library/msgs/kw.msg +++ b/library/msgs/kw.msg diff --git a/library/msgs/kw_gb.msg b/library/msgs/kw_gb.msg index 2967680..2967680 100644..100755 --- a/library/msgs/kw_gb.msg +++ b/library/msgs/kw_gb.msg diff --git a/library/msgs/lt.msg b/library/msgs/lt.msg index 27b0985..27b0985 100644..100755 --- a/library/msgs/lt.msg +++ b/library/msgs/lt.msg diff --git a/library/msgs/lv.msg b/library/msgs/lv.msg index a037b15..a037b15 100644..100755 --- a/library/msgs/lv.msg +++ b/library/msgs/lv.msg diff --git a/library/msgs/mk.msg b/library/msgs/mk.msg index 41cf60d..41cf60d 100644..100755 --- a/library/msgs/mk.msg +++ b/library/msgs/mk.msg diff --git a/library/msgs/mr.msg b/library/msgs/mr.msg index cea427a..cea427a 100644..100755 --- a/library/msgs/mr.msg +++ b/library/msgs/mr.msg diff --git a/library/msgs/mr_in.msg b/library/msgs/mr_in.msg index 1889da5..1889da5 100644..100755 --- a/library/msgs/mr_in.msg +++ b/library/msgs/mr_in.msg diff --git a/library/msgs/ms.msg b/library/msgs/ms.msg index e954431..e954431 100644..100755 --- a/library/msgs/ms.msg +++ b/library/msgs/ms.msg diff --git a/library/msgs/ms_my.msg b/library/msgs/ms_my.msg index c1f93d4..c1f93d4 100644..100755 --- a/library/msgs/ms_my.msg +++ b/library/msgs/ms_my.msg diff --git a/library/msgs/mt.msg b/library/msgs/mt.msg index ddd5446..ddd5446 100644..100755 --- a/library/msgs/mt.msg +++ b/library/msgs/mt.msg diff --git a/library/msgs/nb.msg b/library/msgs/nb.msg index 90d49a3..90d49a3 100644..100755 --- a/library/msgs/nb.msg +++ b/library/msgs/nb.msg diff --git a/library/msgs/nl.msg b/library/msgs/nl.msg index 4c5c675..4c5c675 100644..100755 --- a/library/msgs/nl.msg +++ b/library/msgs/nl.msg diff --git a/library/msgs/nl_be.msg b/library/msgs/nl_be.msg index 4b19670..4b19670 100644..100755 --- a/library/msgs/nl_be.msg +++ b/library/msgs/nl_be.msg diff --git a/library/msgs/nn.msg b/library/msgs/nn.msg index bd61ac9..bd61ac9 100644..100755 --- a/library/msgs/nn.msg +++ b/library/msgs/nn.msg diff --git a/library/msgs/pl.msg b/library/msgs/pl.msg index d206f4b..d206f4b 100644..100755 --- a/library/msgs/pl.msg +++ b/library/msgs/pl.msg diff --git a/library/msgs/pt.msg b/library/msgs/pt.msg index 96fdb35..96fdb35 100644..100755 --- a/library/msgs/pt.msg +++ b/library/msgs/pt.msg diff --git a/library/msgs/pt_br.msg b/library/msgs/pt_br.msg index 8684327..8684327 100644..100755 --- a/library/msgs/pt_br.msg +++ b/library/msgs/pt_br.msg diff --git a/library/msgs/ro.msg b/library/msgs/ro.msg index bdd7c61..bdd7c61 100644..100755 --- a/library/msgs/ro.msg +++ b/library/msgs/ro.msg diff --git a/library/msgs/ru.msg b/library/msgs/ru.msg index 65b075d..65b075d 100644..100755 --- a/library/msgs/ru.msg +++ b/library/msgs/ru.msg diff --git a/library/msgs/ru_ua.msg b/library/msgs/ru_ua.msg index 6e1f8a8..6e1f8a8 100644..100755 --- a/library/msgs/ru_ua.msg +++ b/library/msgs/ru_ua.msg diff --git a/library/msgs/sh.msg b/library/msgs/sh.msg index 6ee0fc7..6ee0fc7 100644..100755 --- a/library/msgs/sh.msg +++ b/library/msgs/sh.msg diff --git a/library/msgs/sk.msg b/library/msgs/sk.msg index 9b2f0aa..9b2f0aa 100644..100755 --- a/library/msgs/sk.msg +++ b/library/msgs/sk.msg diff --git a/library/msgs/sl.msg b/library/msgs/sl.msg index 42bc509..42bc509 100644..100755 --- a/library/msgs/sl.msg +++ b/library/msgs/sl.msg diff --git a/library/msgs/sq.msg b/library/msgs/sq.msg index 8fb1fce..8fb1fce 100644..100755 --- a/library/msgs/sq.msg +++ b/library/msgs/sq.msg diff --git a/library/msgs/sr.msg b/library/msgs/sr.msg index 7576668..7576668 100644..100755 --- a/library/msgs/sr.msg +++ b/library/msgs/sr.msg diff --git a/library/msgs/sv.msg b/library/msgs/sv.msg index f7a67c6..f7a67c6 100644..100755 --- a/library/msgs/sv.msg +++ b/library/msgs/sv.msg diff --git a/library/msgs/sw.msg b/library/msgs/sw.msg index b888b43..b888b43 100644..100755 --- a/library/msgs/sw.msg +++ b/library/msgs/sw.msg diff --git a/library/msgs/ta.msg b/library/msgs/ta.msg index 4abb90c..4abb90c 100644..100755 --- a/library/msgs/ta.msg +++ b/library/msgs/ta.msg diff --git a/library/msgs/ta_in.msg b/library/msgs/ta_in.msg index 24590ac..24590ac 100644..100755 --- a/library/msgs/ta_in.msg +++ b/library/msgs/ta_in.msg diff --git a/library/msgs/te.msg b/library/msgs/te.msg index 6111473..6111473 100644..100755 --- a/library/msgs/te.msg +++ b/library/msgs/te.msg diff --git a/library/msgs/te_in.msg b/library/msgs/te_in.msg index 61638b5..61638b5 100644..100755 --- a/library/msgs/te_in.msg +++ b/library/msgs/te_in.msg diff --git a/library/msgs/th.msg b/library/msgs/th.msg index 7486c35..7486c35 100644..100755 --- a/library/msgs/th.msg +++ b/library/msgs/th.msg diff --git a/library/msgs/tr.msg b/library/msgs/tr.msg index 7b2ecf9..7b2ecf9 100644..100755 --- a/library/msgs/tr.msg +++ b/library/msgs/tr.msg diff --git a/library/msgs/uk.msg b/library/msgs/uk.msg index 7d4c64a..7d4c64a 100644..100755 --- a/library/msgs/uk.msg +++ b/library/msgs/uk.msg diff --git a/library/msgs/vi.msg b/library/msgs/vi.msg index c98b2a6..c98b2a6 100644..100755 --- a/library/msgs/vi.msg +++ b/library/msgs/vi.msg diff --git a/library/msgs/zh.msg b/library/msgs/zh.msg index b799a32..b799a32 100644..100755 --- a/library/msgs/zh.msg +++ b/library/msgs/zh.msg diff --git a/library/msgs/zh_cn.msg b/library/msgs/zh_cn.msg index d62ce77..d62ce77 100644..100755 --- a/library/msgs/zh_cn.msg +++ b/library/msgs/zh_cn.msg diff --git a/library/msgs/zh_hk.msg b/library/msgs/zh_hk.msg index badb1dd..badb1dd 100644..100755 --- a/library/msgs/zh_hk.msg +++ b/library/msgs/zh_hk.msg diff --git a/library/msgs/zh_sg.msg b/library/msgs/zh_sg.msg index a2f3e39..a2f3e39 100644..100755 --- a/library/msgs/zh_sg.msg +++ b/library/msgs/zh_sg.msg diff --git a/library/msgs/zh_tw.msg b/library/msgs/zh_tw.msg index e0796b1..e0796b1 100644..100755 --- a/library/msgs/zh_tw.msg +++ b/library/msgs/zh_tw.msg diff --git a/library/tzdata/Africa/Asmara b/library/tzdata/Africa/Asmara index 1f0f13e..1f0f13e 100644..100755 --- a/library/tzdata/Africa/Asmara +++ b/library/tzdata/Africa/Asmara diff --git a/library/tzdata/America/Atikokan b/library/tzdata/America/Atikokan index e72b04f..e72b04f 100644..100755 --- a/library/tzdata/America/Atikokan +++ b/library/tzdata/America/Atikokan diff --git a/library/tzdata/America/Blanc-Sablon b/library/tzdata/America/Blanc-Sablon index d5485e8..d5485e8 100644..100755 --- a/library/tzdata/America/Blanc-Sablon +++ b/library/tzdata/America/Blanc-Sablon diff --git a/library/tzdata/America/Indiana/Petersburg b/library/tzdata/America/Indiana/Petersburg index 6992bfc..6992bfc 100644..100755 --- a/library/tzdata/America/Indiana/Petersburg +++ b/library/tzdata/America/Indiana/Petersburg diff --git a/library/tzdata/America/Indiana/Tell_City b/library/tzdata/America/Indiana/Tell_City index 9eebcf7..9eebcf7 100644..100755 --- a/library/tzdata/America/Indiana/Tell_City +++ b/library/tzdata/America/Indiana/Tell_City diff --git a/library/tzdata/America/Indiana/Vincennes b/library/tzdata/America/Indiana/Vincennes index 1af7fc9..1af7fc9 100644..100755 --- a/library/tzdata/America/Indiana/Vincennes +++ b/library/tzdata/America/Indiana/Vincennes diff --git a/library/tzdata/America/Indiana/Winamac b/library/tzdata/America/Indiana/Winamac index fb6cd37..fb6cd37 100644..100755 --- a/library/tzdata/America/Indiana/Winamac +++ b/library/tzdata/America/Indiana/Winamac diff --git a/library/tzdata/America/Moncton b/library/tzdata/America/Moncton index d286c88..d286c88 100644..100755 --- a/library/tzdata/America/Moncton +++ b/library/tzdata/America/Moncton diff --git a/library/tzdata/America/North_Dakota/New_Salem b/library/tzdata/America/North_Dakota/New_Salem index 5a9d229..5a9d229 100644..100755 --- a/library/tzdata/America/North_Dakota/New_Salem +++ b/library/tzdata/America/North_Dakota/New_Salem diff --git a/library/tzdata/America/Resolute b/library/tzdata/America/Resolute index b4c0bab..b4c0bab 100644..100755 --- a/library/tzdata/America/Resolute +++ b/library/tzdata/America/Resolute diff --git a/library/tzdata/Atlantic/Faroe b/library/tzdata/Atlantic/Faroe index d2c314a..d2c314a 100644..100755 --- a/library/tzdata/Atlantic/Faroe +++ b/library/tzdata/Atlantic/Faroe diff --git a/library/tzdata/Australia/Eucla b/library/tzdata/Australia/Eucla index 0f8ed4d..0f8ed4d 100644..100755 --- a/library/tzdata/Australia/Eucla +++ b/library/tzdata/Australia/Eucla diff --git a/library/tzdata/Europe/Guernsey b/library/tzdata/Europe/Guernsey index 4372c64..4372c64 100644..100755 --- a/library/tzdata/Europe/Guernsey +++ b/library/tzdata/Europe/Guernsey diff --git a/library/tzdata/Europe/Isle_of_Man b/library/tzdata/Europe/Isle_of_Man index 870ac45..870ac45 100644..100755 --- a/library/tzdata/Europe/Isle_of_Man +++ b/library/tzdata/Europe/Isle_of_Man diff --git a/library/tzdata/Europe/Jersey b/library/tzdata/Europe/Jersey index e4da512..e4da512 100644..100755 --- a/library/tzdata/Europe/Jersey +++ b/library/tzdata/Europe/Jersey diff --git a/library/tzdata/Europe/Podgorica b/library/tzdata/Europe/Podgorica index f4f9066..f4f9066 100644..100755 --- a/library/tzdata/Europe/Podgorica +++ b/library/tzdata/Europe/Podgorica diff --git a/library/tzdata/Europe/Volgograd b/library/tzdata/Europe/Volgograd index c3f148f..c3f148f 100644..100755 --- a/library/tzdata/Europe/Volgograd +++ b/library/tzdata/Europe/Volgograd diff --git a/tests/lsetComp.test b/tests/lsetComp.test index 6846cbf..6846cbf 100644..100755 --- a/tests/lsetComp.test +++ b/tests/lsetComp.test diff --git a/tests/notify.test b/tests/notify.test index d2b9123..d2b9123 100644..100755 --- a/tests/notify.test +++ b/tests/notify.test diff --git a/tests/tcltest.test b/tests/tcltest.test index ce8d617..ce8d617 100644..100755 --- a/tests/tcltest.test +++ b/tests/tcltest.test diff --git a/tools/encoding/ebcdic.txt b/tools/encoding/ebcdic.txt index d9fa42e..d9fa42e 100644..100755 --- a/tools/encoding/ebcdic.txt +++ b/tools/encoding/ebcdic.txt diff --git a/tools/encoding/tis-620.txt b/tools/encoding/tis-620.txt index d3656c5..d3656c5 100644..100755 --- a/tools/encoding/tis-620.txt +++ b/tools/encoding/tis-620.txt diff --git a/unix/Makefile.in b/unix/Makefile.in index f74d516..69dd14f 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -1035,6 +1035,7 @@ IOHDR=$(GENERIC_DIR)/tclIO.h MATHHDRS=$(GENERIC_DIR)/tommath.h $(GENERIC_DIR)/tclTomMath.h PARSEHDR=$(GENERIC_DIR)/tclParse.h NREHDR=$(GENERIC_DIR)/tclInt.h +TRIMHDR=$(GENERIC_DIR)/tclStringTrim.h regcomp.o: $(REGHDRS) $(GENERIC_DIR)/regcomp.c $(GENERIC_DIR)/regc_lex.c \ $(GENERIC_DIR)/regc_color.c $(GENERIC_DIR)/regc_locale.c \ @@ -1080,7 +1081,7 @@ tclCmdAH.o: $(GENERIC_DIR)/tclCmdAH.c tclCmdIL.o: $(GENERIC_DIR)/tclCmdIL.c $(TCLREHDRS) $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdIL.c -tclCmdMZ.o: $(GENERIC_DIR)/tclCmdMZ.c $(TCLREHDRS) +tclCmdMZ.o: $(GENERIC_DIR)/tclCmdMZ.c $(TCLREHDRS) $(TRIMHDR) $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCmdMZ.c tclDate.o: $(GENERIC_DIR)/tclDate.c @@ -1092,7 +1093,7 @@ tclCompCmds.o: $(GENERIC_DIR)/tclCompCmds.c $(COMPILEHDR) tclCompCmdsGR.o: $(GENERIC_DIR)/tclCompCmdsGR.c $(COMPILEHDR) $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompCmdsGR.c -tclCompCmdsSZ.o: $(GENERIC_DIR)/tclCompCmdsSZ.c $(COMPILEHDR) +tclCompCmdsSZ.o: $(GENERIC_DIR)/tclCompCmdsSZ.c $(COMPILEHDR) $(TRIMHDR) $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclCompCmdsSZ.c tclCompExpr.o: $(GENERIC_DIR)/tclCompExpr.c $(COMPILEHDR) @@ -1309,7 +1310,7 @@ tclStubInit.o: $(GENERIC_DIR)/tclStubInit.c tclTrace.o: $(GENERIC_DIR)/tclTrace.c $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTrace.c -tclUtil.o: $(GENERIC_DIR)/tclUtil.c $(PARSEHDR) +tclUtil.o: $(GENERIC_DIR)/tclUtil.c $(PARSEHDR) $(TRIMHDR) $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclUtil.c tclUtf.o: $(GENERIC_DIR)/tclUtf.c $(GENERIC_DIR)/tclUniData.c diff --git a/win/buildall.vc.bat b/win/buildall.vc.bat index e4f0a30..e4f0a30 100644..100755 --- a/win/buildall.vc.bat +++ b/win/buildall.vc.bat |