Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Comment: | merge trunk |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | dkf-utf16-branch |
Files: | files | file ages | folders |
SHA1: |
3dcfeb9b276ab633d44f3b7c500ef592 |
User & Date: | dkf 2011-10-07 14:49:36 |
2011-10-13
| ||
21:10 | merge trunk check-in: e7017fcc72 user: dkf tags: dkf-utf16-branch | |
2011-10-07
| ||
14:49 | merge trunk check-in: 3dcfeb9b27 user: dkf tags: dkf-utf16-branch | |
12:01 | Fix gcc warnings (discovered with latest mingw, based on gcc 4.6.1) check-in: 91a0a93dad user: jan.nijtmans tags: trunk | |
2011-09-20
| ||
08:24 | Merge to feature branch check-in: 4bb08079e6 user: dkf tags: dkf-utf16-branch | |
Changes to ChangeLog.
|
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | 2011-10-07 Jan Nijtmans <[email protected]> * generic/tcl.h: Fix gcc warnings (discovered with * generic/tclIORChan.c: latest mingw, based on gcc 4.6.1) 2011-10-06 Donal K. Fellows <[email protected]> * generic/tclDictObj.c (TclDictWithInit, TclDictWithFinish): * generic/tclCompCmds.c (TclCompileDictWithCmd): Experimental compilation for the [dict with] subcommand, using parts factored out from the interpreted version of the command. 2011-10-05 Jan Nijtmans <[email protected]> * win/tclWinInt.h: Remove tclWinProcs, as it is no longer * win/tclWin32Dll.c: being used. 2011-10-03 Venkat Iyer <[email protected]> * library/tzdata/Africa/Dar_es_Salaam: Update to Olson's tzdata2011k * library/tzdata/Africa/Kampala * library/tzdata/Africa/Nairobi * library/tzdata/Asia/Gaza * library/tzdata/Europe/Kaliningrad * library/tzdata/Europe/Kiev * library/tzdata/Europe/Minsk * library/tzdata/Europe/Simferopol * library/tzdata/Europe/Uzhgorod * library/tzdata/Europe/Zaporozhye * library/tzdata/Pacific/Apia 2011-09-29 Donal K. Fellows <[email protected]> * tools/tcltk-man2html.tcl, tools/tcltk-man2html-utils.tcl: More refactoring so that more of the utility code is decently out of the way. Adjusted the header-material generator so that version numbers are only included in locations where there is room. 2011-09-28 Jan Nijtmans <[email protected]> * generic/tclOO.h: [RFE 3010352]: make all TclOO API functions * generic/tclOODecls.h: MODULE_SCOPE * generic/tclOOIntDecls.h: 2011-09-27 Donal K. Fellows <[email protected]> * generic/tclIndexObj.c (Tcl_ParseArgsObjv): [Bug 3413857]: Corrected the memory management for the code parsing arguments when returning "large" numbers of arguments. Also unbroke the TCL_ARGV_AUTO_REST macro in passing. 2011-09-26 Donal K. Fellows <[email protected]> * generic/tclCmdAH.c (TclMakeFileCommandSafe): [Bug 3211758]: Also make the main [file] command hidden by default in safe interpreters, because that's what existing code expects. This will reduce the amount which the code breaks, but not necessarily eliminate it... 2011-09-23 Don Porter <[email protected]> * generic/tclIORTrans.c: More revisions to get finalization of ReflectedTransforms correct, including adopting a "dead" field as was done in tclIORChan.c. * tests/thread.test: Stop using the deprecated thread management commands of the tcltest package. The test suite ought to provide these tools for itself. They do not belong in a testing harness. 2011-09-22 Don Porter <[email protected]> * generic/tclCmdIL.c: Revise [info frame] so that it stops creating cycles in the iPtr->cmdFramePtr stack. 2011-09-22 Donal K. Fellows <[email protected]> * doc/re_syntax.n: [Bug 2903743]: Add more magic so that we can do at least something sane on Solaris. * tools/tcltk-man2html-utils.tcl (process-text): Teach the HTML generator how to handle this magic. 2011-09-21 Don Porter <[email protected]> * generic/tclThreadTest.c: Revise the thread exit handling of the [testthread] command so that it properly maintains the per-process data structures even when the thread exits for reasons other than the [testthread exit] command. 2011-09-21 Alexandre Ferrieux <[email protected]> * unix/tclIO.c: [Bug 3412487]: Now short reads are allowed in synchronous fcopy, avoid mistaking them as nonblocking ones. 2011-09-21 Andreas Kupries <[email protected]> * generic/tclIORTrans.c (ForwardOpToOwnerThread): Fixed the missing initialization of the 'dsti' field. Reported by Don Porter, on chat. 2011-09-20 Don Porter <[email protected]> * generic/tclIORChan.c: Re-using the "interp" field to signal a dead channel (via NULL value) interfered with conditional cleanup tasks testing for "the right interp". Added a new field "dead" to perform the dead channel signalling task so the corrupted logic is avoided. * generic/tclIORTrans.c: Revised ReflectClose() and FreeReflectedTransform() so that we stop leaking ReflectedTransforms, yet free all Tcl_Obj values in the same thread that alloced them. 2011-09-19 Don Porter <[email protected]> * tests/ioTrans.test: Conversion from [testthread] to Thread package stops most memory leaks. * tests/thread.test: Plug most memory leaks in thread.test. Constrain the rest to be skipped during `make valgrind'. Tests using the [testthread cancel] testing command are leaky. Corrections wait for either addition of [thread::cancel] to the Thread package, or improvements to the [testthread] testing command to make leak-free versions of these tests possible. * generic/tclIORChan.c: Plug all memory leaks in ioCmd.test exposed * tests/ioCmd.test: by `make valgrind'. * unix/Makefile.in: 2011-09-16 Jan Nijtmans <[email protected]> IMPLEMENTATION OF TIP #388 * doc/Tcl.n * doc/re_syntax.n * generic/regc_lex.c * generic/regcomp.c * generic/regcustom.h * generic/tcl.h * generic/tclParse.c * tests/reg.test * tests/utf.test 2011-09-16 Donal K. Fellows <[email protected]> * generic/tclProc.c (ProcWrongNumArgs): [Bugs 3400658,3408830]: Corrected the handling of procedure error messages (found by TclOO). 2011-09-16 Jan Nijtmans <[email protected]> * generic/tcl.h: Don't change Tcl_UniChar type when * generic/regcustom.h: TCL_UTF_MAX == 4 (not supported anyway) 2011-09-16 Donal K. Fellows <[email protected]> |
︙ | ︙ | |||
2193 2194 2195 2196 2197 2198 2199 | * generic/tclResult.c (TclMergeReturnOptions): Use memcmp where applicable as possible speedup on some libc variants. 2010-09-21 Kevin B. Kenny <[email protected]> [BRANCH: dogeen-assembler-branch] | | | 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 | * generic/tclResult.c (TclMergeReturnOptions): Use memcmp where applicable as possible speedup on some libc variants. 2010-09-21 Kevin B. Kenny <[email protected]> [BRANCH: dogeen-assembler-branch] * generic/tclAssembly.c (new file): * generic/tclAssembly.h: * generic/tclBasic.c (builtInCmds, Tcl_CreateInterp): * generic/tclInt.h: * tests/assemble.test (new file): * tests/assemble1.bench (new file): * unix/Makefile.in: * win/Makefile.in: |
︙ | ︙ |
Changes to doc/re_syntax.n.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | '\" '\" Copyright (c) 1998 Sun Microsystems, Inc. '\" Copyright (c) 1999 Scriptics Corporation '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" .so man.macros .TH re_syntax n "8.1" Tcl "Tcl Built-In Commands" .BS .SH NAME re_syntax \- Syntax of Tcl regular expressions .BE .SH DESCRIPTION .PP | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | '\" '\" Copyright (c) 1998 Sun Microsystems, Inc. '\" Copyright (c) 1999 Scriptics Corporation '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" .so man.macros .ie '\w'o''\w'\C'^o''' .ds qo \C'^o' .el .ds qo u .TH re_syntax n "8.1" Tcl "Tcl Built-In Commands" .BS .SH NAME re_syntax \- Syntax of Tcl regular expressions .BE .SH DESCRIPTION .PP |
︙ | ︙ | |||
286 287 288 289 290 291 292 | and \fB=]\fR is an equivalence class, standing for the sequences of characters of all collating elements equivalent to that one, including itself. (If there are no other equivalent collating elements, the treatment is as if the enclosing delimiters were .QW \fB[.\fR \& and .QW \fB.]\fR .) | | | | | 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 | and \fB=]\fR is an equivalence class, standing for the sequences of characters of all collating elements equivalent to that one, including itself. (If there are no other equivalent collating elements, the treatment is as if the enclosing delimiters were .QW \fB[.\fR \& and .QW \fB.]\fR .) For example, if \fBo\fR and \fB\*(qo\fR are the members of an equivalence class, then .QW \fB[[=o=]]\fR , .QW \fB[[=\*(qo=]]\fR , and .QW \fB[o\*(qo]\fR \& are all synonymous. An equivalence class may not be an endpoint of a range. .RS .PP (\fINote:\fR Tcl implements only the Unicode locale. It does not define any equivalence classes. The examples above are just illustrations.) .RE .SH ESCAPES |
︙ | ︙ |
Changes to generic/tcl.h.
︙ | ︙ | |||
2272 2273 2274 2275 2276 2277 2278 | /* * Shorthand for commonly used argTable entries. */ #define TCL_ARGV_AUTO_HELP \ {TCL_ARGV_HELP, "-help", NULL, NULL, \ | | | | | 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 | /* * Shorthand for commonly used argTable entries. */ #define TCL_ARGV_AUTO_HELP \ {TCL_ARGV_HELP, "-help", NULL, NULL, \ "Print summary of command-line options and abort", NULL} #define TCL_ARGV_AUTO_REST \ {TCL_ARGV_REST, "--", NULL, NULL, \ "Marks the end of the options", NULL} #define TCL_ARGV_TABLE_END \ {TCL_ARGV_END, NULL, NULL, NULL, NULL, NULL} /* *---------------------------------------------------------------------------- * Definitions needed for Tcl_Zlib routines. [TIP #234] * * Constants for the format flags describing what sort of data format is * desired/expected for the Tcl_ZlibDeflate, Tcl_ZlibInflate and |
︙ | ︙ |
Changes to generic/tclAssembly.c.
︙ | ︙ | |||
366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 | INST_BEGIN_CATCH4, 0, 0}, {"bitand", ASSEM_1BYTE, INST_BITAND, 2, 1}, {"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}, {"dictAppend", ASSEM_LVT4, INST_DICT_APPEND, 2, 1}, {"dictGet", ASSEM_DICT_GET, INST_DICT_GET, INT_MIN,1}, {"dictIncrImm", ASSEM_SINT4_LVT4, INST_DICT_INCR_IMM, 1, 1}, {"dictLappend", ASSEM_LVT4, INST_DICT_LAPPEND, 2, 1}, {"dictSet", ASSEM_DICT_SET, INST_DICT_SET, INT_MIN,1}, {"dictUnset", ASSEM_DICT_UNSET, INST_DICT_UNSET, INT_MIN,1}, {"div", ASSEM_1BYTE, INST_DIV, 2, 1}, {"dup", ASSEM_1BYTE, INST_DUP, 1, 2}, {"endCatch", ASSEM_END_CATCH,INST_END_CATCH, 0, 0}, {"eq", ASSEM_1BYTE, INST_EQ, 2, 1}, | > > > | 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 | INST_BEGIN_CATCH4, 0, 0}, {"bitand", ASSEM_1BYTE, INST_BITAND, 2, 1}, {"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}, {"dictAppend", ASSEM_LVT4, INST_DICT_APPEND, 2, 1}, {"dictExpand", ASSEM_1BYTE, INST_DICT_EXPAND, 3, 1}, {"dictGet", ASSEM_DICT_GET, INST_DICT_GET, INT_MIN,1}, {"dictIncrImm", ASSEM_SINT4_LVT4, INST_DICT_INCR_IMM, 1, 1}, {"dictLappend", ASSEM_LVT4, INST_DICT_LAPPEND, 2, 1}, {"dictRecombineStk",ASSEM_1BYTE, INST_DICT_RECOMBINE_STK,3, 0}, {"dictRecombineImm",ASSEM_LVT4, INST_DICT_RECOMBINE_IMM,2, 0}, {"dictSet", ASSEM_DICT_SET, INST_DICT_SET, INT_MIN,1}, {"dictUnset", ASSEM_DICT_UNSET, INST_DICT_UNSET, INT_MIN,1}, {"div", ASSEM_1BYTE, INST_DIV, 2, 1}, {"dup", ASSEM_1BYTE, INST_DUP, 1, 2}, {"endCatch", ASSEM_END_CATCH,INST_END_CATCH, 0, 0}, {"eq", ASSEM_1BYTE, INST_EQ, 2, 1}, |
︙ | ︙ |
Changes to generic/tclCmdAH.c.
︙ | ︙ | |||
1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 | unsafeInfo[i].cmdName, Tcl_GetString(Tcl_GetObjResult(interp))); } } } Tcl_DStringFree(&oldBuf); Tcl_DStringFree(&newBuf); return TCL_OK; } /* *---------------------------------------------------------------------- * * FileAttrAccessTimeCmd -- | > > > > > > > > > > > | 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 | unsafeInfo[i].cmdName, Tcl_GetString(Tcl_GetObjResult(interp))); } } } Tcl_DStringFree(&oldBuf); Tcl_DStringFree(&newBuf); /* * Ugh. The [file] command is now actually safe, but it is assumed by * scripts that it is not, which messes up security policies. [Bug * 3211758] */ if (Tcl_HideCommand(interp, "file", "file") != TCL_OK) { Tcl_Panic("problem making 'file' safe: %s", Tcl_GetString(Tcl_GetObjResult(interp))); } return TCL_OK; } /* *---------------------------------------------------------------------- * * FileAttrAccessTimeCmd -- |
︙ | ︙ |
Changes to generic/tclCmdIL.c.
︙ | ︙ | |||
1136 1137 1138 1139 1140 1141 1142 | InfoFrameCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; | | | > > > > > > < | > < | < > > | | | | | | > > | | < < < | > | > > > > > > > > > > > > > > > > > > | | 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 | InfoFrameCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Interp *iPtr = (Interp *) interp; int level, topLevel, code = TCL_OK; CmdFrame *runPtr, *framePtr; CoroutineData *corPtr = iPtr->execEnvPtr->corPtr; if (objc > 2) { Tcl_WrongNumArgs(interp, 1, objv, "?number?"); return TCL_ERROR; } topLevel = ((iPtr->cmdFramePtr == NULL) ? 0 : iPtr->cmdFramePtr->level); if (corPtr) { /* * A coroutine: must fix the level computations AND the cmdFrame chain, * which is interrupted at the base. */ CmdFrame *lastPtr = NULL; runPtr = iPtr->cmdFramePtr; /* TODO - deal with overflow */ topLevel += corPtr->caller.cmdFramePtr->level; while (runPtr) { runPtr->level += corPtr->caller.cmdFramePtr->level; lastPtr = runPtr; runPtr = runPtr->nextPtr; } if (lastPtr) { lastPtr->nextPtr = corPtr->caller.cmdFramePtr; } else { iPtr->cmdFramePtr = corPtr->caller.cmdFramePtr; } } if (objc == 1) { /* * Just "info frame". */ Tcl_SetObjResult(interp, Tcl_NewIntObj(topLevel)); goto done; } /* * We've got "info frame level" and must parse the level first. */ if (TclGetIntFromObj(interp, objv[1], &level) != TCL_OK) { code = TCL_ERROR; goto done; } if ((level > topLevel) || (level <= - topLevel)) { levelError: Tcl_AppendResult(interp, "bad level \"", TclGetString(objv[1]), "\"", NULL); Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_FRAME", TclGetString(objv[1]), NULL); code = TCL_ERROR; goto done; } /* * Let us convert to relative so that we know how many levels to go back */ if (level > 0) { level -= topLevel; } framePtr = iPtr->cmdFramePtr; while (++level <= 0) { framePtr = framePtr->nextPtr; if (!framePtr) { goto levelError; } } Tcl_SetObjResult(interp, TclInfoFrame(interp, framePtr)); done: if (corPtr) { if (iPtr->cmdFramePtr == corPtr->caller.cmdFramePtr) { iPtr->cmdFramePtr = NULL; } else { runPtr = iPtr->cmdFramePtr; while (runPtr->nextPtr != corPtr->caller.cmdFramePtr) { runPtr->level -= corPtr->caller.cmdFramePtr->level; runPtr = runPtr->nextPtr; } runPtr->level = 1; runPtr->nextPtr = NULL; } } return code; } /* *---------------------------------------------------------------------- * * TclInfoFrame -- * |
︙ | ︙ |
Changes to generic/tclCompCmds.c.
︙ | ︙ | |||
1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 | return TCL_ERROR; } CompileWord(envPtr, keyTokenPtr, interp, 3); CompileWord(envPtr, valueTokenPtr, interp, 4); TclEmitInstInt4( INST_DICT_LAPPEND, dictVarIndex, envPtr); return TCL_OK; } /* *---------------------------------------------------------------------- * * DupDictUpdateInfo, FreeDictUpdateInfo -- * * Functions to duplicate, release and print the aux data created for use | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 | return TCL_ERROR; } CompileWord(envPtr, keyTokenPtr, interp, 3); CompileWord(envPtr, valueTokenPtr, interp, 4); TclEmitInstInt4( INST_DICT_LAPPEND, dictVarIndex, envPtr); return TCL_OK; } int TclCompileDictWithCmd( Tcl_Interp *interp, /* Used for looking up stuff. */ 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 */ int i, range, varNameTmp, pathTmp, keysTmp, gotPath, dictVar = -1; Tcl_Token *dictVarTokenPtr, *tokenPtr; int savedStackDepth = envPtr->currStackDepth; JumpFixup jumpFixup; /* * There must be at least one argument after the command and we must be in * a procedure so we can have local temporaries. */ if (envPtr->procPtr == NULL) { return TCL_ERROR; } if (parsePtr->numWords < 3) { return TCL_ERROR; } /* * Parse the command (trivially). Expect the following: * dict with <any (varName)> ?<any> ...? <literal> */ dictVarTokenPtr = TokenAfter(parsePtr->tokenPtr); tokenPtr = TokenAfter(dictVarTokenPtr); for (i=3 ; i<parsePtr->numWords ; i++) { tokenPtr = TokenAfter(tokenPtr); } if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) { return TCL_ERROR; } /* * Allocate local (unnamed, untraced) working variables. */ gotPath = (parsePtr->numWords > 3); if (dictVarTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) { const char *ptr = dictVarTokenPtr[1].start; const char *end = ptr + dictVarTokenPtr[1].size; int notArray = 1; /* * A conservative check for if we're working with an array since we * have a reasonable fallback if things are tricky. */ for (; ptr<end ; ptr++) { if (*ptr == '(' || *ptr == ')') { notArray = 0; break; } } if (notArray) { dictVar = TclFindCompiledLocal(dictVarTokenPtr[1].start, dictVarTokenPtr[1].size, 1, envPtr); } } if (dictVar == -1) { varNameTmp = TclFindCompiledLocal(NULL, 0, 1, envPtr); } else { varNameTmp = -1; } if (gotPath) { pathTmp = TclFindCompiledLocal(NULL, 0, 1, envPtr); } else { pathTmp = -1; } keysTmp = TclFindCompiledLocal(NULL, 0, 1, envPtr); /* * Issue instructions. First, the part to expand the dictionary. */ tokenPtr = dictVarTokenPtr; if (varNameTmp > -1) { CompileWord(envPtr, tokenPtr, interp, 0); if (varNameTmp <= 255) { TclEmitInstInt1( INST_STORE_SCALAR1, varNameTmp, envPtr); } else { TclEmitInstInt4( INST_STORE_SCALAR4, varNameTmp, envPtr); } } tokenPtr = TokenAfter(tokenPtr); if (gotPath) { for (i=2 ; i<parsePtr->numWords-1 ; i++) { CompileWord(envPtr, tokenPtr, interp, i-1); tokenPtr = TokenAfter(tokenPtr); } TclEmitInstInt4( INST_LIST, parsePtr->numWords-3,envPtr); if (pathTmp <= 255) { TclEmitInstInt1( INST_STORE_SCALAR1, pathTmp, envPtr); } else { TclEmitInstInt4( INST_STORE_SCALAR4, pathTmp, envPtr); } TclEmitOpcode( INST_POP, envPtr); } if (dictVar == -1) { TclEmitOpcode( INST_LOAD_STK, envPtr); } else if (dictVar <= 255) { TclEmitInstInt1( INST_LOAD_SCALAR1, dictVar, envPtr); } else { TclEmitInstInt4( INST_LOAD_SCALAR4, dictVar, envPtr); } if (gotPath) { if (pathTmp <= 255) { TclEmitInstInt1( INST_LOAD_SCALAR1, pathTmp, envPtr); } else { TclEmitInstInt4( INST_LOAD_SCALAR4, pathTmp, envPtr); } } else { PushLiteral(envPtr, "", 0); } TclEmitOpcode( INST_DICT_EXPAND, envPtr); if (keysTmp <= 255) { TclEmitInstInt1( INST_STORE_SCALAR1, keysTmp, envPtr); } else { TclEmitInstInt4( INST_STORE_SCALAR4, keysTmp, envPtr); } TclEmitOpcode( INST_POP, envPtr); /* * Now the body of the [dict with]. */ range = DeclareExceptionRange(envPtr, CATCH_EXCEPTION_RANGE); TclEmitInstInt4( INST_BEGIN_CATCH4, range, envPtr); ExceptionRangeStarts(envPtr, range); envPtr->currStackDepth++; SetLineInformation(parsePtr->numWords-1); CompileBody(envPtr, tokenPtr, interp); envPtr->currStackDepth = savedStackDepth; ExceptionRangeEnds(envPtr, range); /* * Now fold the results back into the dictionary in the OK case. */ TclEmitOpcode( INST_END_CATCH, envPtr); if (varNameTmp > -1 && varNameTmp <= 255) { TclEmitInstInt1( INST_LOAD_SCALAR1, varNameTmp, envPtr); } else if (varNameTmp > -1) { TclEmitInstInt4( INST_LOAD_SCALAR4, varNameTmp, envPtr); } if (gotPath) { if (pathTmp <= 255) { TclEmitInstInt1( INST_LOAD_SCALAR1, pathTmp, envPtr); } else { TclEmitInstInt4( INST_LOAD_SCALAR4, pathTmp, envPtr); } } else { PushLiteral(envPtr, "", 0); } if (keysTmp <= 255) { TclEmitInstInt1( INST_LOAD_SCALAR1, keysTmp, envPtr); } else { TclEmitInstInt4( INST_LOAD_SCALAR4, keysTmp, envPtr); } if (dictVar == -1) { TclEmitOpcode( INST_DICT_RECOMBINE_STK, envPtr); } else { TclEmitInstInt4( INST_DICT_RECOMBINE_IMM, dictVar, envPtr); } TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup); /* * Now fold the results back into the dictionary in the exception case. */ ExceptionRangeTarget(envPtr, range, catchOffset); TclEmitOpcode( INST_PUSH_RETURN_OPTIONS, envPtr); TclEmitOpcode( INST_PUSH_RESULT, envPtr); TclEmitOpcode( INST_END_CATCH, envPtr); if (varNameTmp > -1 && varNameTmp <= 255) { TclEmitInstInt1( INST_LOAD_SCALAR1, varNameTmp, envPtr); } else if (varNameTmp > -1) { TclEmitInstInt4( INST_LOAD_SCALAR4, varNameTmp, envPtr); } if (parsePtr->numWords > 3) { if (pathTmp <= 255) { TclEmitInstInt1( INST_LOAD_SCALAR1, pathTmp, envPtr); } else { TclEmitInstInt4( INST_LOAD_SCALAR4, pathTmp, envPtr); } } else { PushLiteral(envPtr, "", 0); } if (keysTmp <= 255) { TclEmitInstInt1( INST_LOAD_SCALAR1, keysTmp, envPtr); } else { TclEmitInstInt4( INST_LOAD_SCALAR4, keysTmp, envPtr); } if (dictVar == -1) { TclEmitOpcode( INST_DICT_RECOMBINE_STK, envPtr); } else { TclEmitInstInt4( INST_DICT_RECOMBINE_IMM, dictVar, envPtr); } TclEmitOpcode( INST_RETURN_STK, envPtr); /* * Prepare for the start of the next command. */ if (TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127)) { Tcl_Panic("TclCompileDictCmd(update): bad jump distance %d", (int) (CurrentOffset(envPtr) - jumpFixup.codeOffset)); } return TCL_OK; } /* *---------------------------------------------------------------------- * * DupDictUpdateInfo, FreeDictUpdateInfo -- * * Functions to duplicate, release and print the aux data created for use |
︙ | ︙ |
Changes to generic/tclCompExpr.c.
︙ | ︙ | |||
163 164 165 166 167 168 169 | #define INCOMPLETE 4 /* A parse error. Used only when the single * "=" is encountered. */ #define INVALID 5 /* A parse error. Used when any punctuation * appears that's not a supported operator. */ /* Leaf lexemes */ | | > > | > | > | > | > | > | | < | | | | | | | | | | < | | | | | | < | | | > | | < | | | < | | | | | | | | | | | | | | | < | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | > | | < | | | | | | | | | | | < | | | < | | | | < | > | | | < | | | > | | | | < | 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 | #define INCOMPLETE 4 /* A parse error. Used only when the single * "=" is encountered. */ #define INVALID 5 /* A parse error. Used when any punctuation * appears that's not a supported operator. */ /* Leaf lexemes */ #define NUMBER (LEAF | 1) /* For literal numbers */ #define SCRIPT (LEAF | 2) /* Script substitution; [foo] */ #define BOOLEAN (LEAF | BAREWORD) /* For literal booleans */ #define BRACED (LEAF | 4) /* Braced string; {foo bar} */ #define VARIABLE (LEAF | 5) /* Variable substitution; $x */ #define QUOTED (LEAF | 6) /* Quoted string; "foo $bar [soom]" */ #define EMPTY (LEAF | 7) /* Used only for an empty argument list to a * function. Represents the empty string * within parens in the expression: rand() */ /* Unary operator lexemes */ #define UNARY_PLUS (UNARY | PLUS) #define UNARY_MINUS (UNARY | MINUS) #define FUNCTION (UNARY | BAREWORD) /* This is a bit of "creative interpretation" * on the part of the parser. A function call * is parsed into the parse tree according to * the perspective that the function name is a * unary operator and its argument list, * enclosed in parens, is its operand. The * additional requirements not implied * generally by treatment as a unary operator * -- for example, the requirement that the * operand be enclosed in parens -- are hard * coded in the relevant portions of * ParseExpr(). We trade off the need to * include such exceptional handling in the * code against the need we would otherwise * have for more lexeme categories. */ #define START (UNARY | 4) /* This lexeme isn't parsed from the * expression text at all. It represents the * start of the expression and sits at the * root of the parse tree where it serves as * the start/end point of traversals. */ #define OPEN_PAREN (UNARY | 5) /* Another bit of creative interpretation, * where we treat "(" as a unary operator with * the sub-expression between it and its * matching ")" as its operand. See * CLOSE_PAREN below. */ #define NOT (UNARY | 6) #define BIT_NOT (UNARY | 7) /* Binary operator lexemes */ #define BINARY_PLUS (BINARY | PLUS) #define BINARY_MINUS (BINARY | MINUS) #define COMMA (BINARY | 3) /* The "," operator is a low precedence binary * operator that separates the arguments in a * function call. The additional constraint * that this operator can only legally appear * at the right places within a function call * argument list are hard coded within * ParseExpr(). */ #define MULT (BINARY | 4) #define DIVIDE (BINARY | 5) #define MOD (BINARY | 6) #define LESS (BINARY | 7) #define GREATER (BINARY | 8) #define BIT_AND (BINARY | 9) #define BIT_XOR (BINARY | 10) #define BIT_OR (BINARY | 11) #define QUESTION (BINARY | 12) /* These two lexemes make up the */ #define COLON (BINARY | 13) /* ternary conditional operator, $x ? $y : $z. * We treat them as two binary operators to * avoid another lexeme category, and code the * additional constraints directly in * ParseExpr(). For instance, the right * operand of a "?" operator must be a ":" * operator. */ #define LEFT_SHIFT (BINARY | 14) #define RIGHT_SHIFT (BINARY | 15) #define LEQ (BINARY | 16) #define GEQ (BINARY | 17) #define EQUAL (BINARY | 18) #define NEQ (BINARY | 19) #define AND (BINARY | 20) #define OR (BINARY | 21) #define STREQ (BINARY | 22) #define STRNEQ (BINARY | 23) #define EXPON (BINARY | 24) /* Unlike the other binary operators, EXPON is * right associative and this distinction is * coded directly in ParseExpr(). */ #define IN_LIST (BINARY | 25) #define NOT_IN_LIST (BINARY | 26) #define CLOSE_PAREN (BINARY | 27) /* By categorizing the CLOSE_PAREN lexeme as a * BINARY operator, the normal parsing rules * for binary operators assure that a close * paren will not directly follow another * operator, and the machinery already in * place to connect operands to operators * according to precedence performs most of * the work of matching open and close parens * for us. In the end though, a close paren is * not really a binary operator, and some * special coding in ParseExpr() make sure we * never put an actual CLOSE_PAREN node in the * parse tree. The sub-expression between * parens becomes the single argument of the * matching OPEN_PAREN unary operator. */ #define END (BINARY | 28) /* This lexeme represents the end of the * string being parsed. Treating it as a * binary operator follows the same logic as * the CLOSE_PAREN lexeme and END pairs with * START, in the same way that CLOSE_PAREN * pairs with OPEN_PAREN. */ /* * When ParseExpr() builds the parse tree it must choose which operands to * connect to which operators. This is done according to operator precedence. * The greater an operator's precedence the greater claim it has to link to an * available operand. The Precedence enumeration lists the precedence values * used by Tcl expression operators, from lowest to highest claim. Each * precedence level is commented with the operators that hold that precedence. */ enum Precedence { PREC_END = 1, /* END */ PREC_START, /* START */ PREC_CLOSE_PAREN, /* ")" */ PREC_OPEN_PAREN, /* "(" */ |
︙ | ︙ | |||
316 317 318 319 320 321 322 | PREC_ADD, /* "+", "-" */ PREC_MULT, /* "*", "/", "%" */ PREC_EXPON, /* "**" */ PREC_UNARY /* "+", "-", FUNCTION, "!", "~" */ }; /* | | | | | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | PREC_ADD, /* "+", "-" */ PREC_MULT, /* "*", "/", "%" */ PREC_EXPON, /* "**" */ PREC_UNARY /* "+", "-", FUNCTION, "!", "~" */ }; /* * Here the same information contained in the comments above is stored in * inverted form, so that given a lexeme, one can quickly look up its * precedence value. */ static const unsigned char prec[] = { /* Non-operator lexemes */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
︙ | ︙ | |||
595 596 597 598 599 600 601 | * moment. OT_EMPTY is a nonsense value used * only to silence compiler warnings. During a * parse, complete will always hold an index * or an OperandTypes value pointing to an * actual leaf at the time the complete tree * is needed. */ | > | > > | 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 | * moment. OT_EMPTY is a nonsense value used * only to silence compiler warnings. During a * parse, complete will always hold an index * or an OperandTypes value pointing to an * actual leaf at the time the complete tree * is needed. */ /* * These variables control generation of the error message. */ Tcl_Obj *msg = NULL; /* The error message. */ Tcl_Obj *post = NULL; /* In a few cases, an additional postscript * for the error message, supplying more * information after the error msg and * location have been reported. */ const char *errCode = NULL; /* The detail word of the errorCode list, or * NULL to indicate that no changes to the |
︙ | ︙ | |||
797 798 799 800 801 802 803 | lexeme |= UNARY; } else { lexeme |= BINARY; } } } /* Uncategorized lexemes */ | > | > > | | | | | | | < > | > > | 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 | lexeme |= UNARY; } else { lexeme |= BINARY; } } } /* Uncategorized lexemes */ /* * Handle lexeme based on its category. */ switch (NODE_TYPE & lexeme) { case LEAF: { /* * Each LEAF results in either a literal getting appended to the * litList, or a sequence of Tcl_Tokens representing a Tcl word * getting appended to the parsePtr->tokens. No OpNode is filled * for this lexeme. */ Tcl_Token *tokenPtr; const char *end = start; int wordIndex; int code = TCL_OK; /* * A leaf operand appearing just after something that's not an * operator is a syntax error. */ if (NotOperator(lastParsed)) { msg = Tcl_ObjPrintf("missing operator at %s", mark); errCode = "MISSING"; scanned = 0; insertMark = 1; /* * Free any literal to avoid a memleak. */ if ((lexeme == NUMBER) || (lexeme == BOOLEAN)) { Tcl_DecrRefCount(literal); } goto error; } switch (lexeme) { |
︙ | ︙ | |||
1023 1024 1025 1026 1027 1028 1029 | msg = Tcl_ObjPrintf("missing operator at %s", mark); scanned = 0; insertMark = 1; errCode = "MISSING"; goto error; } | > | > > | 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 | msg = Tcl_ObjPrintf("missing operator at %s", mark); scanned = 0; insertMark = 1; errCode = "MISSING"; goto error; } /* * Create an OpNode for the unary operator. */ nodePtr->lexeme = lexeme; nodePtr->precedence = prec[lexeme]; nodePtr->mark = MARK_RIGHT; /* * A FUNCTION cannot be a constant expression, because Tcl allows * functions to return variable results with the same arguments; |
︙ | ︙ | |||
1494 1495 1496 1497 1498 1499 1500 | case OT_EMPTY: /* No tokens and no characters for the OT_EMPTY leaf. */ break; case OT_LITERAL: | > | > > | 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 | case OT_EMPTY: /* No tokens and no characters for the OT_EMPTY leaf. */ break; case OT_LITERAL: /* * Skip any white space that comes before the literal. */ scanned = TclParseAllWhiteSpace(start, numBytes); start += scanned; numBytes -= scanned; /* * Reparse the literal to get pointers into source string. */ |
︙ | ︙ | |||
1577 1578 1579 1580 1581 1582 1583 | numBytes -= scanned; tokenPtr += toCopy; break; } default: | > | > > | 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 | numBytes -= scanned; tokenPtr += toCopy; break; } default: /* * Advance to the child node, which is an operator. */ nodePtr = nodes + next; /* * Skip any white space that comes before the subexpression. */ scanned = TclParseAllWhiteSpace(start, numBytes); |
︙ | ︙ | |||
1658 1659 1660 1661 1662 1663 1664 | case MARK_LEFT: next = nodePtr->left; break; case MARK_RIGHT: next = nodePtr->right; | > | > > > | > > | 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 | case MARK_LEFT: next = nodePtr->left; break; case MARK_RIGHT: next = nodePtr->right; /* * Skip any white space that comes before the operator. */ scanned = TclParseAllWhiteSpace(start, numBytes); start += scanned; numBytes -= scanned; /* * Here we scan from the string the operator corresponding to * nodePtr->lexeme. */ scanned = ParseLexeme(start, numBytes, &lexeme, NULL); switch(nodePtr->lexeme) { case OPEN_PAREN: case COMMA: case COLON: /* * No tokens for these lexemes -> nothing to do. */ break; default: /* * Record in the TCL_TOKEN_OPERATOR token the pointers into * the string marking where the operator is. |
︙ | ︙ | |||
1710 1711 1712 1713 1714 1715 1716 | case COLON: /* No tokens for these lexemes -> nothing to do. */ break; case OPEN_PAREN: | > | > > | | 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 | case COLON: /* No tokens for these lexemes -> nothing to do. */ break; case OPEN_PAREN: /* * Skip past matching close paren. */ scanned = TclParseAllWhiteSpace(start, numBytes); start += scanned; numBytes -= scanned; scanned = ParseLexeme(start, numBytes, &lexeme, NULL); start += scanned; numBytes -= scanned; break; default: /* * Before we leave this node/operator/subexpression for the * last time, finish up its tokens.... * * Our current position scanning the string is where the * substring for the subexpression ends. |
︙ | ︙ | |||
1752 1753 1754 1755 1756 1757 1758 | * fill in the zero numComponents for the operator Tcl_Token. */ parentIdx = subExprTokenPtr[1].numComponents; subExprTokenPtr[1].numComponents = 0; subExprTokenIdx = parentIdx; break; | < | 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 | * fill in the zero numComponents for the operator Tcl_Token. */ parentIdx = subExprTokenPtr[1].numComponents; subExprTokenPtr[1].numComponents = 0; subExprTokenIdx = parentIdx; break; } /* * Since we're returning to parent, skip child handling code. */ nodePtr = nodes + nodePtr->p.parent; |
︙ | ︙ | |||
2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 | * (alpha, digit, underscore). Is this a number followed by * bareword syntax error? Or should we join into one bareword? * Example: Inf + luence + () becomes a valid function call. * [Bug 3401704] */ if (literal->typePtr == &tclDoubleType) { const char *p = start; while (p < end) { if (!isalnum(UCHAR(*p++))) { /* * The number has non-bareword characters, so we * must treat it as a number. */ goto number; } } } ParseLexeme(end, numBytes-(end-start), &lexeme, NULL); if ((NODE_TYPE & lexeme) == BINARY) { /* * The bareword characters following the number take the * form of an operator (eq, ne, in, ni, ...) so we treat * as number + operator. */ goto number; } /* * Otherwise, fall through and parse the whole as a bareword. */ } } if (Tcl_UtfCharComplete(start, numBytes)) { | > > | 2030 2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 | * (alpha, digit, underscore). Is this a number followed by * bareword syntax error? Or should we join into one bareword? * Example: Inf + luence + () becomes a valid function call. * [Bug 3401704] */ if (literal->typePtr == &tclDoubleType) { const char *p = start; while (p < end) { if (!isalnum(UCHAR(*p++))) { /* * The number has non-bareword characters, so we * must treat it as a number. */ goto number; } } } ParseLexeme(end, numBytes-(end-start), &lexeme, NULL); if ((NODE_TYPE & lexeme) == BINARY) { /* * The bareword characters following the number take the * form of an operator (eq, ne, in, ni, ...) so we treat * as number + operator. */ goto number; } /* * Otherwise, fall through and parse the whole as a bareword. */ } } if (Tcl_UtfCharComplete(start, numBytes)) { |
︙ | ︙ | |||
2286 2287 2288 2289 2290 2291 2292 | */ nodePtr->left = numWords; numWords = 2; /* Command plus one argument */ break; } case QUESTION: | | | | | | 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 | */ nodePtr->left = numWords; numWords = 2; /* Command plus one argument */ break; } case QUESTION: TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpPtr->jump); break; case COLON: CLANG_ASSERT(jumpPtr); TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpPtr->next->jump); envPtr->currStackDepth = jumpPtr->depth; jumpPtr->offset = (envPtr->codeNext - envPtr->codeStart); jumpPtr->convert = convert; convert = 1; break; case AND: TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpPtr->jump); break; case OR: TclEmitForwardJump(envPtr, TCL_TRUE_JUMP, &jumpPtr->jump); break; } } else { switch (nodePtr->lexeme) { case START: case QUESTION: if (convert && (nodePtr == rootPtr)) { |
︙ | ︙ | |||
2344 2345 2346 2347 2348 2349 2350 | * Each comma implies another function argument. */ numWords++; break; case COLON: CLANG_ASSERT(jumpPtr); | | | | | | | | < > | 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 | * Each comma implies another function argument. */ numWords++; break; case COLON: CLANG_ASSERT(jumpPtr); if (TclFixupForwardJump(envPtr, &jumpPtr->next->jump, (envPtr->codeNext - envPtr->codeStart) - jumpPtr->next->jump.codeOffset, 127)) { jumpPtr->offset += 3; } TclFixupForwardJump(envPtr, &jumpPtr->jump, jumpPtr->offset - jumpPtr->jump.codeOffset, 127); convert |= jumpPtr->convert; envPtr->currStackDepth = jumpPtr->depth + 1; freePtr = jumpPtr; jumpPtr = jumpPtr->next; TclStackFree(interp, freePtr); freePtr = jumpPtr; jumpPtr = jumpPtr->next; TclStackFree(interp, freePtr); break; case AND: case OR: CLANG_ASSERT(jumpPtr); TclEmitForwardJump(envPtr, (nodePtr->lexeme == AND) ? TCL_FALSE_JUMP : TCL_TRUE_JUMP, &jumpPtr->next->jump); TclEmitPush(TclRegisterNewLiteral(envPtr, (nodePtr->lexeme == AND) ? "1" : "0", 1), envPtr); TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpPtr->next->next->jump); TclFixupForwardJumpToHere(envPtr, &jumpPtr->next->jump, 127); if (TclFixupForwardJumpToHere(envPtr, &jumpPtr->jump, 127)) { jumpPtr->next->next->jump.codeOffset += 3; } TclEmitPush(TclRegisterNewLiteral(envPtr, (nodePtr->lexeme == AND) ? "0" : "1", 1), envPtr); TclFixupForwardJumpToHere(envPtr, &jumpPtr->next->next->jump, 127); convert = 0; envPtr->currStackDepth = jumpPtr->depth + 1; freePtr = jumpPtr; jumpPtr = jumpPtr->next; TclStackFree(interp, freePtr); freePtr = jumpPtr; jumpPtr = jumpPtr->next; TclStackFree(interp, freePtr); freePtr = jumpPtr; jumpPtr = jumpPtr->next; TclStackFree(interp, freePtr); break; default: TclEmitOpcode(instruction[nodePtr->lexeme], envPtr); convert = 0; break; } if (nodePtr == rootPtr) { /* We're done */ return; } nodePtr = nodes + nodePtr->p.parent; continue; } nodePtr->mark++; |
︙ | ︙ | |||
2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 | int index; Tcl_Obj *objPtr = Tcl_GetObjResult(interp); /* * Don't generate a string rep, but if we have one * already, then use it to share via the literal table. */ if (objPtr->bytes) { Tcl_Obj *tableValue; index = TclRegisterNewLiteral(envPtr, objPtr->bytes, objPtr->length); tableValue = envPtr->literalArrayPtr[index].objPtr; if ((tableValue->typePtr == NULL) && (objPtr->typePtr != NULL)) { | > > | > > | 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 | int index; Tcl_Obj *objPtr = Tcl_GetObjResult(interp); /* * Don't generate a string rep, but if we have one * already, then use it to share via the literal table. */ if (objPtr->bytes) { Tcl_Obj *tableValue; index = TclRegisterNewLiteral(envPtr, objPtr->bytes, objPtr->length); tableValue = envPtr->literalArrayPtr[index].objPtr; if ((tableValue->typePtr == NULL) && (objPtr->typePtr != NULL)) { /* * Same intrep surgery as for OT_LITERAL. */ tableValue->typePtr = objPtr->typePtr; tableValue->internalRep = objPtr->internalRep; objPtr->typePtr = NULL; } } else { index = TclAddLiteralObj(envPtr, objPtr, NULL); } |
︙ | ︙ | |||
2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 | } } /* *---------------------------------------------------------------------- * * TclSingleOpCmd -- * Implements the commands: ~, !, <<, >>, %, !=, ne, in, ni * in the ::tcl::mathop namespace. These commands have no * extension to arbitrary arguments; they accept only exactly one * or exactly two arguments as suitable for the operator. * * Results: * A standard Tcl return code and result left in interp. | > | 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 | } } /* *---------------------------------------------------------------------- * * TclSingleOpCmd -- * * Implements the commands: ~, !, <<, >>, %, !=, ne, in, ni * in the ::tcl::mathop namespace. These commands have no * extension to arbitrary arguments; they accept only exactly one * or exactly two arguments as suitable for the operator. * * Results: * A standard Tcl return code and result left in interp. |
︙ | ︙ | |||
2533 2534 2535 2536 2537 2538 2539 | Tcl_Obj *const objv[]) { TclOpCmdClientData *occdPtr = clientData; unsigned char lexeme; OpNode nodes[2]; Tcl_Obj *const *litObjv = objv + 1; | | | 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 | Tcl_Obj *const objv[]) { TclOpCmdClientData *occdPtr = clientData; unsigned char lexeme; OpNode nodes[2]; Tcl_Obj *const *litObjv = objv + 1; if (objc != 1 + occdPtr->i.numArgs) { Tcl_WrongNumArgs(interp, 1, objv, occdPtr->expected); return TCL_ERROR; } ParseLexeme(occdPtr->op, strlen(occdPtr->op), &lexeme, NULL); nodes[0].lexeme = START; nodes[0].mark = MARK_RIGHT; |
︙ | ︙ |
Changes to generic/tclCompile.c.
︙ | ︙ | |||
416 417 418 419 420 421 422 423 424 425 426 427 428 429 | * stktop; op1 is 1 for errors on problems, 0 otherwise */ {"unsetArrayStk", 2, -2, 1, {OPERAND_UINT1}}, /* Make array element cease to exist; element is stktop, array name is * stknext; op1 is 1 for errors on problems, 0 otherwise */ {"unsetStk", 2, -1, 1, {OPERAND_UINT1}}, /* Make general variable cease to exist; unparsed variable name is * stktop; op1 is 1 for errors on problems, 0 otherwise */ {NULL, 0, 0, 0, {OPERAND_NONE}} }; /* * Prototypes for procedures defined later in this file: */ | > > > > > > > > > > > > > > | 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | * stktop; op1 is 1 for errors on problems, 0 otherwise */ {"unsetArrayStk", 2, -2, 1, {OPERAND_UINT1}}, /* Make array element cease to exist; element is stktop, array name is * stknext; op1 is 1 for errors on problems, 0 otherwise */ {"unsetStk", 2, -1, 1, {OPERAND_UINT1}}, /* Make general variable cease to exist; unparsed variable name is * stktop; op1 is 1 for errors on problems, 0 otherwise */ {"dictExpand", 1, -1, 0, {OPERAND_NONE}}, /* Probe into a dict and extract it (or a subdict of it) into * variables with matched names. Produces list of keys bound as * result. Part of [dict with]. * Stack: ... dict path => ... keyList */ {"dictRecombineStk", 1, -3, 0, {OPERAND_NONE}}, /* Map variable contents back into a dictionary in a variable. Part of * [dict with]. * Stack: ... dictVarName path keyList => ... */ {"dictRecombineImm", 1, -2, 1, {OPERAND_LVT4}}, /* Map variable contents back into a dictionary in the local variable * indicated by the LVT index. Part of [dict with]. * Stack: ... path keyList => ... */ {NULL, 0, 0, 0, {OPERAND_NONE}} }; /* * Prototypes for procedures defined later in this file: */ |
︙ | ︙ |
Changes to generic/tclCompile.h.
︙ | ︙ | |||
672 673 674 675 676 677 678 679 | /* For [unset] compilation */ #define INST_UNSET_SCALAR 134 #define INST_UNSET_ARRAY 135 #define INST_UNSET_ARRAY_STK 136 #define INST_UNSET_STK 137 /* The last opcode */ | > > > > | | 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 | /* For [unset] compilation */ #define INST_UNSET_SCALAR 134 #define INST_UNSET_ARRAY 135 #define INST_UNSET_ARRAY_STK 136 #define INST_UNSET_STK 137 #define INST_DICT_EXPAND 138 #define INST_DICT_RECOMBINE_STK 139 #define INST_DICT_RECOMBINE_IMM 140 /* The last opcode */ #define LAST_INST_OPCODE 140 /* * Table describing the Tcl bytecode instructions: their name (for displaying * code), total number of code bytes required (including operand bytes), and a * description of the type of each operand. These operand types include signed * and unsigned integers of length one and four bytes. The unsigned integers * are used for indexes or for, e.g., the count of objects to push in a "push" |
︙ | ︙ |
Changes to generic/tclDictObj.c.
︙ | ︙ | |||
99 100 101 102 103 104 105 | {"remove", DictRemoveCmd, NULL, NULL, NULL, 0 }, {"replace", DictReplaceCmd, NULL, NULL, NULL, 0 }, {"set", DictSetCmd, TclCompileDictSetCmd, NULL, NULL, 0 }, {"size", DictSizeCmd, NULL, NULL, NULL, 0 }, {"unset", DictUnsetCmd, NULL, NULL, NULL, 0 }, {"update", DictUpdateCmd, TclCompileDictUpdateCmd, NULL, NULL, 0 }, {"values", DictValuesCmd, NULL, NULL, NULL, 0 }, | | | 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 | {"remove", DictRemoveCmd, NULL, NULL, NULL, 0 }, {"replace", DictReplaceCmd, NULL, NULL, NULL, 0 }, {"set", DictSetCmd, TclCompileDictSetCmd, NULL, NULL, 0 }, {"size", DictSizeCmd, NULL, NULL, NULL, 0 }, {"unset", DictUnsetCmd, NULL, NULL, NULL, 0 }, {"update", DictUpdateCmd, TclCompileDictUpdateCmd, NULL, NULL, 0 }, {"values", DictValuesCmd, NULL, NULL, NULL, 0 }, {"with", DictWithCmd, TclCompileDictWithCmd, NULL, NULL, 0 }, {NULL, NULL, NULL, NULL, NULL, 0} }; /* * Internal representation of the entries in the hash table that backs a * dictionary. */ |
︙ | ︙ | |||
3106 3107 3108 3109 3110 3111 3112 | DictWithCmd( ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Interp *iPtr = (Interp *) interp; | | < < < < < < < | < | < < < < < < | < < < < < < < < < < < < < < | 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 | DictWithCmd( ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv) { Interp *iPtr = (Interp *) interp; Tcl_Obj *dictPtr, *keysPtr, *pathPtr; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "dictVar ?key ...? script"); return TCL_ERROR; } /* * Get the dictionary to open out. */ dictPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG); if (dictPtr == NULL) { return TCL_ERROR; } keysPtr = TclDictWithInit(interp, dictPtr, objc-3, objv+2); if (keysPtr == NULL) { return TCL_ERROR; } Tcl_IncrRefCount(keysPtr); /* * Execute the body, while making the invoking context available to the * loop body (TIP#280) and postponing the cleanup until later (NRE). */ pathPtr = NULL; |
︙ | ︙ | |||
3179 3180 3181 3182 3183 3184 3185 | static int FinalizeDictWith( ClientData data[], Tcl_Interp *interp, int result) { | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > < < < < < | < < < < < < < > > | < < < < < > | > | > > < | < < < < < < < < | 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 | static int FinalizeDictWith( ClientData data[], Tcl_Interp *interp, int result) { Tcl_Obj **pathv; int pathc; Tcl_InterpState state; Tcl_Obj *varName = data[0]; Tcl_Obj *keysPtr = data[1]; Tcl_Obj *pathPtr = data[2]; Var *varPtr, *arrayPtr; if (result == TCL_ERROR) { Tcl_AddErrorInfo(interp, "\n (body of \"dict with\")"); } /* * Save the result state; TDWF doesn't guarantee to not modify that on * TCL_OK result. */ state = Tcl_SaveInterpState(interp, result); if (pathPtr != NULL) { Tcl_ListObjGetElements(NULL, pathPtr, &pathc, &pathv); } else { pathc = 0; pathv = NULL; } /* * Pack from local variables back into the dictionary. */ varPtr = TclObjLookupVarEx(interp, varName, NULL, TCL_LEAVE_ERR_MSG, "set", /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr); if (varPtr == NULL) { result = TCL_ERROR; } else { result = TclDictWithFinish(interp, varPtr, arrayPtr, varName, NULL, -1, pathc, pathv, keysPtr); } /* * Tidy up and return the real result (unless we had an error). */ TclDecrRefCount(varName); TclDecrRefCount(keysPtr); if (pathPtr != NULL) { TclDecrRefCount(pathPtr); } if (result != TCL_OK) { Tcl_DiscardInterpState(state); return TCL_ERROR; } return Tcl_RestoreInterpState(interp, state); } /* *---------------------------------------------------------------------- * * TclDictWithInit -- * * Part of the core of [dict with]. Pokes into a dictionary and converts * the mappings there into assignments to (presumably) local variables. * Returns a list of all the names that were mapped so that removal of * either the variable or the dictionary entry won't surprise us when we * come to stuffing everything back. * * Result: * List of mapped names, or NULL if there was an error. * * Side effects: * Assigns to variables, so potentially legion due to traces. * *---------------------------------------------------------------------- */ Tcl_Obj * TclDictWithInit( Tcl_Interp *interp, Tcl_Obj *dictPtr, int pathc, Tcl_Obj *const pathv[]) { Tcl_DictSearch s; Tcl_Obj *keyPtr, *valPtr, *keysPtr; int done; if (pathc > 0) { dictPtr = TclTraceDictPath(interp, dictPtr, pathc, pathv, DICT_PATH_READ); if (dictPtr == NULL) { return NULL; } } /* * Go over the list of keys and write each corresponding value to a * variable in the current context with the same name. Also keep a copy of * the keys so we can write back properly later on even if the dictionary * has been structurally modified. */ if (Tcl_DictObjFirst(interp, dictPtr, &s, &keyPtr, &valPtr, &done) != TCL_OK) { return NULL; } TclNewObj(keysPtr); for (; !done ; Tcl_DictObjNext(&s, &keyPtr, &valPtr, &done)) { Tcl_ListObjAppendElement(NULL, keysPtr, keyPtr); if (Tcl_ObjSetVar2(interp, keyPtr, NULL, valPtr, TCL_LEAVE_ERR_MSG) == NULL) { TclDecrRefCount(keysPtr); Tcl_DictObjDone(&s); return NULL; } } return keysPtr; } /* *---------------------------------------------------------------------- * * TclDictWithFinish -- * * Part of the core of [dict with]. Reassembles the piece of the dict (in * varName, location given by pathc/pathv) from the variables named in * the keysPtr argument. NB, does not try to preserve errors or manage * argument lifetimes. * * Result: * TCL_OK if we succeeded, or TCL_ERROR if we failed. * * Side effects: * Assigns to a variable, so potentially legion due to traces. Updates * the dictionary in the named variable. * *---------------------------------------------------------------------- */ int TclDictWithFinish( Tcl_Interp *interp, /* Command interpreter in which variable * exists. Used for state management, traces * and error reporting. */ Var *varPtr, /* Reference to the variable holding the * dictionary. */ Var *arrayPtr, /* Reference to the array containing the * variable, or NULL if the variable is a * scalar. */ Tcl_Obj *part1Ptr, /* Name of an array (if part2 is non-NULL) or * the name of a variable. NULL if the 'index' * parameter is >= 0 */ Tcl_Obj *part2Ptr, /* If non-NULL, gives the name of an element * in the array part1. */ int index, /* Index into the local variable table of the * variable, or -1. Only used when part1Ptr is * NULL. */ int pathc, /* The number of elements in the path into the * dictionary. */ Tcl_Obj *const pathv[], /* The elements of the path to the subdict. */ Tcl_Obj *keysPtr) /* List of keys to be synchronized. This is * the result value from TclDictWithInit. */ { Tcl_Obj *dictPtr, *leafPtr, *valPtr; int i, allocdict, keyc; Tcl_Obj **keyv; /* * If the dictionary variable doesn't exist, drop everything silently. */ dictPtr = TclPtrGetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr, TCL_LEAVE_ERR_MSG, index); if (dictPtr == NULL) { return TCL_OK; } /* * Double-check that it is still a dictionary. */ if (Tcl_DictObjSize(interp, dictPtr, &i) != TCL_OK) { return TCL_ERROR; } if (Tcl_IsShared(dictPtr)) { dictPtr = Tcl_DuplicateObj(dictPtr); allocdict = 1; } else { allocdict = 0; } if (pathc > 0) { /* * Want to get to the dictionary which we will update; need to do * prepare-for-update de-sharing along the path *but* avoid generating * an error on a non-existant path (we'll treat that the same as a * non-existant variable. Luckily, the de-sharing operation isn't * deeply damaging if we don't go on to update; it's just less than * perfectly efficient (but no memory should be leaked). */ leafPtr = TclTraceDictPath(interp, dictPtr, pathc, pathv, DICT_PATH_EXISTS | DICT_PATH_UPDATE); if (leafPtr == NULL) { if (allocdict) { TclDecrRefCount(dictPtr); } return TCL_ERROR; } if (leafPtr == DICT_PATH_NON_EXISTENT) { if (allocdict) { TclDecrRefCount(dictPtr); } return TCL_OK; } } else { leafPtr = dictPtr; } /* * Now process our updates on the leaf dictionary. |
︙ | ︙ | |||
3282 3283 3284 3285 3286 3287 3288 | */ Tcl_DictObjPut(NULL, leafPtr, keyv[i], Tcl_DuplicateObj(valPtr)); } else { Tcl_DictObjPut(NULL, leafPtr, keyv[i], valPtr); } } | < | | | > | > < | | 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 | */ Tcl_DictObjPut(NULL, leafPtr, keyv[i], Tcl_DuplicateObj(valPtr)); } else { Tcl_DictObjPut(NULL, leafPtr, keyv[i], valPtr); } } /* * Ensure that none of the dictionaries in the chain still have a string * rep. */ if (pathc > 0) { InvalidateDictChain(leafPtr); } /* * Write back the outermost dictionary to the variable. */ if (TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr, dictPtr, TCL_LEAVE_ERR_MSG, index) == NULL) { if (allocdict) { TclDecrRefCount(dictPtr); } return TCL_ERROR; } return TCL_OK; } /* *---------------------------------------------------------------------- * * TclInitDictCmd -- * |
︙ | ︙ |
Changes to generic/tclExecute.c.
︙ | ︙ | |||
1988 1989 1990 1991 1992 1993 1994 | iPtr->stats.numExecutions++; #endif /* * Push the callback for bytecode execution */ | | | < | 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 | iPtr->stats.numExecutions++; #endif /* * Push the callback for bytecode execution */ TclNRAddCallback(interp, TEBCresume, TD, /*resume*/ INT2PTR(0), NULL, NULL); return TCL_OK; } static int TEBCresume( ClientData data[], Tcl_Interp *interp, |
︙ | ︙ | |||
5621 5622 5623 5624 5625 5626 5627 | /* * ----------------------------------------------------------------- * Start of dictionary-related instructions. */ { int opnd2, allocateDict, done, i, allocdict; | | | 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 | /* * ----------------------------------------------------------------- * Start of dictionary-related instructions. */ { int opnd2, allocateDict, done, i, allocdict; Tcl_Obj *dictPtr, *statePtr, *keyPtr, *listPtr, *varNamePtr, *keysPtr; Tcl_Obj *emptyPtr, **keyPtrPtr; Tcl_DictSearch *searchPtr; DictUpdateInfo *duiPtr; case INST_DICT_GET: opnd = TclGetUInt4AtPtr(pc+1); TRACE(("%u => ", opnd)); |
︙ | ︙ | |||
6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 | if (allocdict) { TclDecrRefCount(dictPtr); } goto gotError; } } NEXT_INST_F(9, 1, 0); } /* * End of dictionary-related instructions. * ----------------------------------------------------------------- */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 6118 6119 6120 6121 6122 6123 6124 6125 6126 6127 6128 6129 6130 6131 6132 6133 6134 6135 6136 6137 6138 6139 6140 6141 6142 6143 6144 6145 6146 6147 6148 6149 6150 6151 6152 6153 6154 6155 6156 6157 6158 6159 6160 6161 6162 6163 6164 6165 6166 6167 6168 6169 6170 6171 6172 6173 6174 6175 6176 6177 6178 6179 6180 6181 6182 6183 6184 6185 | if (allocdict) { TclDecrRefCount(dictPtr); } goto gotError; } } NEXT_INST_F(9, 1, 0); case INST_DICT_EXPAND: dictPtr = OBJ_UNDER_TOS; listPtr = OBJ_AT_TOS; if (TclListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) { TRACE_WITH_OBJ(("%.30s %.30s => ERROR: ", O2S(dictPtr), O2S(listPtr)), Tcl_GetObjResult(interp)); goto gotError; } objResultPtr = TclDictWithInit(interp, dictPtr, objc, objv); if (objResultPtr == NULL) { TRACE_WITH_OBJ(("%.30s %.30s => ERROR: ", O2S(dictPtr), O2S(listPtr)), Tcl_GetObjResult(interp)); goto gotError; } TRACE_APPEND(("%.30s\n", O2S(objResultPtr))); NEXT_INST_F(1, 2, 1); case INST_DICT_RECOMBINE_STK: keysPtr = POP_OBJECT(); varNamePtr = OBJ_UNDER_TOS; listPtr = OBJ_AT_TOS; TRACE(("\"%.30s\" \"%.30s\" \"%.30s\" => ", O2S(varNamePtr), O2S(valuePtr), O2S(keysPtr))); if (TclListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) { TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp)))); TclDecrRefCount(keysPtr); goto gotError; } varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL, TCL_LEAVE_ERR_MSG, "set", 1, 1, &arrayPtr); if (varPtr == NULL) { TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp)))); TclDecrRefCount(keysPtr); goto gotError; } DECACHE_STACK_INFO(); result = TclDictWithFinish(interp, varPtr,arrayPtr,varNamePtr,NULL,-1, objc, objv, keysPtr); CACHE_STACK_INFO(); TclDecrRefCount(keysPtr); if (result != TCL_OK) { TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp)))); goto gotError; } TRACE_APPEND(("OK\n")); NEXT_INST_F(1, 2, 0); case INST_DICT_RECOMBINE_IMM: opnd = TclGetUInt4AtPtr(pc+1); listPtr = OBJ_UNDER_TOS; keysPtr = OBJ_AT_TOS; varPtr = LOCAL(opnd); TRACE(("%u <- \"%.30s\" \"%.30s\" => ", opnd, O2S(valuePtr), O2S(keysPtr))); if (TclListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) { TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp)))); goto gotError; } while (TclIsVarLink(varPtr)) { varPtr = varPtr->value.linkPtr; } DECACHE_STACK_INFO(); result = TclDictWithFinish(interp, varPtr, NULL, NULL, NULL, opnd, objc, objv, keysPtr); CACHE_STACK_INFO(); if (result != TCL_OK) { TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp)))); goto gotError; } TRACE_APPEND(("OK\n")); NEXT_INST_F(5, 2, 0); } /* * End of dictionary-related instructions. * ----------------------------------------------------------------- */ |
︙ | ︙ |
Changes to generic/tclIO.c.
︙ | ︙ | |||
9211 9212 9213 9214 9215 9216 9217 | * copying is done, otherwise set up a channel handler to detect * when the channel becomes readable again. */ if ((size == 0) && Tcl_Eof(inChan) && !(cmdPtr && (mask == 0))) { break; } | | | | 9211 9212 9213 9214 9215 9216 9217 9218 9219 9220 9221 9222 9223 9224 9225 9226 | * copying is done, otherwise set up a channel handler to detect * when the channel becomes readable again. */ if ((size == 0) && Tcl_Eof(inChan) && !(cmdPtr && (mask == 0))) { break; } if (cmdPtr && (!Tcl_Eof(inChan) || (mask == 0)) && !(mask & TCL_READABLE)) { if (mask & TCL_WRITABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, csPtr); } Tcl_CreateChannelHandler(inChan, TCL_READABLE, CopyEventProc, csPtr); } if (size == 0) { |
︙ | ︙ |
Changes to generic/tclIORChan.c.
︙ | ︙ | |||
117 118 119 120 121 122 123 124 125 126 127 128 129 130 | * names? */ int mode; /* Mask of R/W mode */ int interest; /* Mask of events the channel is interested * in. */ /* * Note regarding the usage of timers. * * Most channel implementations need a timer in the C level to ensure that * data in buffers is flushed out through the generation of fake file * events. * | > > > | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | * names? */ int mode; /* Mask of R/W mode */ int interest; /* Mask of events the channel is interested * in. */ int dead; /* Boolean signal that some operations * should no longer be attempted. */ /* * Note regarding the usage of timers. * * Most channel implementations need a timer in the C level to ensure that * data in buffers is flushed out through the generation of fake file * events. * |
︙ | ︙ | |||
1124 1125 1126 1127 1128 1129 1130 | * when the channel was created in a different interpreter and/or * thread and then was moved here. * * NOTE: The channel may have been removed from the map already via * the per-interp DeleteReflectedChannelMap exit-handler. */ | | | 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 | * when the channel was created in a different interpreter and/or * thread and then was moved here. * * NOTE: The channel may have been removed from the map already via * the per-interp DeleteReflectedChannelMap exit-handler. */ if (!rcPtr->dead) { rcmPtr = GetReflectedChannelMap(rcPtr->interp); hPtr = Tcl_FindHashEntry(&rcmPtr->map, Tcl_GetChannelName(rcPtr->chan)); if (hPtr) { Tcl_DeleteHashEntry(hPtr); } } |
︙ | ︙ | |||
2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 | /* rcPtr->chan: Assigned by caller. Dummy data here. */ /* rcPtr->methods: Assigned by caller. Dummy data here. */ rcPtr->chan = NULL; rcPtr->methods = 0; rcPtr->interp = interp; #ifdef TCL_THREADS rcPtr->thread = Tcl_GetCurrentThread(); #endif rcPtr->mode = mode; rcPtr->interest = 0; /* Initially no interest registered */ /* | > | 2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 | /* rcPtr->chan: Assigned by caller. Dummy data here. */ /* rcPtr->methods: Assigned by caller. Dummy data here. */ rcPtr->chan = NULL; rcPtr->methods = 0; rcPtr->interp = interp; rcPtr->dead = 0; #ifdef TCL_THREADS rcPtr->thread = Tcl_GetCurrentThread(); #endif rcPtr->mode = mode; rcPtr->interest = 0; /* Initially no interest registered */ /* |
︙ | ︙ | |||
2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 | if (chanPtr->typePtr != &tclRChannelType) { /* * Delete a cloned ChannelType structure. */ ckfree(chanPtr->typePtr); } FreeReflectedChannelArgs(rcPtr); ckfree(rcPtr->argv); ckfree(rcPtr); } | > | 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 | if (chanPtr->typePtr != &tclRChannelType) { /* * Delete a cloned ChannelType structure. */ ckfree(chanPtr->typePtr); chanPtr->typePtr = NULL; } FreeReflectedChannelArgs(rcPtr); ckfree(rcPtr->argv); ckfree(rcPtr); } |
︙ | ︙ | |||
2197 2198 2199 2200 2201 2202 2203 | { int cmdc; /* #words in constructed command */ Tcl_Obj *methObj = NULL; /* Method name in object form */ Tcl_InterpState sr; /* State of handler interp */ int result; /* Result code of method invokation */ Tcl_Obj *resObj = NULL; /* Result of method invokation. */ | | | 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 | { int cmdc; /* #words in constructed command */ Tcl_Obj *methObj = NULL; /* Method name in object form */ Tcl_InterpState sr; /* State of handler interp */ int result; /* Result code of method invokation */ Tcl_Obj *resObj = NULL; /* Result of method invokation. */ if (rcPtr->dead) { /* * The channel is marked as dead. Bail out immediately, with an * appropriate error. */ if (resultObjPtr != NULL) { resObj = Tcl_NewStringObj(msg_dstlost,-1); |
︙ | ︙ | |||
2361 2362 2363 2364 2365 2366 2367 | ErrnoReturn( ReflectedChannel *rcPtr, Tcl_Obj *resObj) { int code; Tcl_InterpState sr; /* State of handler interp */ | | | 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 | ErrnoReturn( ReflectedChannel *rcPtr, Tcl_Obj *resObj) { int code; Tcl_InterpState sr; /* State of handler interp */ if (rcPtr->dead) { return 0; } sr = Tcl_SaveInterpState(rcPtr->interp, 0 /* Dummy */); UnmarshallErrorResult(rcPtr->interp, resObj); resObj = Tcl_GetObjResult(rcPtr->interp); |
︙ | ︙ | |||
2470 2471 2472 2473 2474 2475 2476 | for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch); hPtr != NULL; hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) { chan = Tcl_GetHashValue(hPtr); rcPtr = Tcl_GetChannelInstanceData(chan); | | | 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 | for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch); hPtr != NULL; hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) { chan = Tcl_GetHashValue(hPtr); rcPtr = Tcl_GetChannelInstanceData(chan); rcPtr->dead = 1; Tcl_DeleteHashEntry(hPtr); } Tcl_DeleteHashTable(&rcmPtr->map); ckfree(&rcmPtr->map); #ifdef TCL_THREADS /* |
︙ | ︙ | |||
2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 | /* * Ignore entries for other interpreters. */ continue; } Tcl_DeleteHashEntry(hPtr); } #endif } #ifdef TCL_THREADS /* | > > | 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 | /* * Ignore entries for other interpreters. */ continue; } rcPtr->dead = 1; FreeReflectedChannelArgs(rcPtr); Tcl_DeleteHashEntry(hPtr); } #endif } #ifdef TCL_THREADS /* |
︙ | ︙ | |||
2674 2675 2676 2677 2678 2679 2680 | rcmPtr = GetThreadReflectedChannelMap(); for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch); hPtr != NULL; hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) { Tcl_Channel chan = Tcl_GetHashValue(hPtr); ReflectedChannel *rcPtr = Tcl_GetChannelInstanceData(chan); | | | 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 | rcmPtr = GetThreadReflectedChannelMap(); for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch); hPtr != NULL; hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) { Tcl_Channel chan = Tcl_GetHashValue(hPtr); ReflectedChannel *rcPtr = Tcl_GetChannelInstanceData(chan); rcPtr->dead = 1; FreeReflectedChannelArgs(rcPtr); Tcl_DeleteHashEntry(hPtr); } ckfree(rcmPtr); } static void |
︙ | ︙ | |||
2698 2699 2700 2701 2702 2703 2704 | /* * We gather the lock early. This allows us to check the liveness of the * channel without interference from DeleteThreadReflectedChannelMap(). */ Tcl_MutexLock(&rcForwardMutex); | | | 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 | /* * We gather the lock early. This allows us to check the liveness of the * channel without interference from DeleteThreadReflectedChannelMap(). */ Tcl_MutexLock(&rcForwardMutex); if (rcPtr->dead) { /* * The channel is marked as dead. Bail out immediately, with an * appropriate error. Do not forget to unlock the mutex on this path. */ ForwardSetStaticError((ForwardParam *) param, msg_send_dstlost); Tcl_MutexUnlock(&rcForwardMutex); |
︙ | ︙ |
Changes to generic/tclIORTrans.c.
︙ | ︙ | |||
157 158 159 160 161 162 163 164 165 166 167 168 169 170 | * NOTE (9): Should we have predefined shared literals for the method * names? */ int mode; /* Mask of R/W mode */ int nonblocking; /* Flag: Channel is blocking or not. */ int readIsDrained; /* Flag: Read buffers are flushed. */ ResultBuffer result; } ReflectedTransform; /* * Structure of the table mapping from transform handles to reflected * transform (channels). Each interpreter which has the handler command for * one or more reflected transforms records them in such a table, so that we | > > | 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | * NOTE (9): Should we have predefined shared literals for the method * names? */ int mode; /* Mask of R/W mode */ int nonblocking; /* Flag: Channel is blocking or not. */ int readIsDrained; /* Flag: Read buffers are flushed. */ int dead; /* Boolean signal that some operations * should no longer be attempted. */ ResultBuffer result; } ReflectedTransform; /* * Structure of the table mapping from transform handles to reflected * transform (channels). Each interpreter which has the handler command for * one or more reflected transforms records them in such a table, so that we |
︙ | ︙ | |||
403 404 405 406 407 408 409 410 411 412 413 414 415 416 | static Tcl_Obj * DecodeEventMask(int mask); static ReflectedTransform * NewReflectedTransform(Tcl_Interp *interp, Tcl_Obj *cmdpfxObj, int mode, Tcl_Obj *handleObj, Tcl_Channel parentChan); static Tcl_Obj * NextHandle(void); static void FreeReflectedTransform(ReflectedTransform *rtPtr); static int InvokeTclMethod(ReflectedTransform *rtPtr, const char *method, Tcl_Obj *argOneObj, Tcl_Obj *argTwoObj, Tcl_Obj **resultObjPtr); static ReflectedTransformMap * GetReflectedTransformMap(Tcl_Interp *interp); static void DeleteReflectedTransformMap(ClientData clientData, Tcl_Interp *interp); | > | 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 | static Tcl_Obj * DecodeEventMask(int mask); static ReflectedTransform * NewReflectedTransform(Tcl_Interp *interp, Tcl_Obj *cmdpfxObj, int mode, Tcl_Obj *handleObj, Tcl_Channel parentChan); static Tcl_Obj * NextHandle(void); static void FreeReflectedTransform(ReflectedTransform *rtPtr); static void FreeReflectedTransformArgs(ReflectedTransform *rtPtr); static int InvokeTclMethod(ReflectedTransform *rtPtr, const char *method, Tcl_Obj *argOneObj, Tcl_Obj *argTwoObj, Tcl_Obj **resultObjPtr); static ReflectedTransformMap * GetReflectedTransformMap(Tcl_Interp *interp); static void DeleteReflectedTransformMap(ClientData clientData, Tcl_Interp *interp); |
︙ | ︙ | |||
877 878 879 880 881 882 883 | static int ReflectClose( ClientData clientData, Tcl_Interp *interp) { ReflectedTransform *rtPtr = clientData; | > | | 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 | static int ReflectClose( ClientData clientData, Tcl_Interp *interp) { ReflectedTransform *rtPtr = clientData; int errorCode, errorCodeSet = 0; int result = TCL_OK; /* Result code for 'close' */ Tcl_Obj *resObj; /* Result data for 'close' */ ReflectedTransformMap *rtmPtr; /* Map of reflected transforms with handlers * in this interp. */ Tcl_HashEntry *hPtr; /* Entry in the above map */ if (TclInThreadExit()) { |
︙ | ︙ | |||
908 909 910 911 912 913 914 | #ifdef TCL_THREADS if (rtPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; ForwardOpToOwnerThread(rtPtr, ForwardedClose, &p); result = p.base.code; | < < < < < < < < > > | > | > > > > < < > > | > | > > > > < | < < | 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 | #ifdef TCL_THREADS if (rtPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; ForwardOpToOwnerThread(rtPtr, ForwardedClose, &p); result = p.base.code; if (result != TCL_OK) { FreeReceivedError(&p); } } #endif Tcl_EventuallyFree (rtPtr, (Tcl_FreeProc *) FreeReflectedTransform); return EOK; } /* * In the reflected channel implementation a cleaned method mask here * implies that the channel creation was aborted, and "finalize" must not * be called. for transformations however we are not going through here on * such an abort, but directly through FreeReflectedTransform. So for us * that check is not necessary. We always go through 'finalize'. */ if (HAS(rtPtr->methods, METH_DRAIN) && !rtPtr->readIsDrained) { if (!TransformDrain(rtPtr, &errorCode)) { #ifdef TCL_THREADS if (rtPtr->thread != Tcl_GetCurrentThread()) { Tcl_EventuallyFree (rtPtr, (Tcl_FreeProc *) FreeReflectedTransform); return errorCode; } #endif errorCodeSet = 1; goto cleanup; } } if (HAS(rtPtr->methods, METH_FLUSH)) { if (!TransformFlush(rtPtr, &errorCode, FLUSH_WRITE)) { #ifdef TCL_THREADS if (rtPtr->thread != Tcl_GetCurrentThread()) { Tcl_EventuallyFree (rtPtr, (Tcl_FreeProc *) FreeReflectedTransform); return errorCode; } #endif errorCodeSet = 1; goto cleanup; } } /* * Are we in the correct thread? */ #ifdef TCL_THREADS if (rtPtr->thread != Tcl_GetCurrentThread()) { ForwardParam p; ForwardOpToOwnerThread(rtPtr, ForwardedClose, &p); result = p.base.code; Tcl_EventuallyFree (rtPtr, (Tcl_FreeProc *) FreeReflectedTransform); if (result != TCL_OK) { PassReceivedErrorInterp(interp, &p); return EINVAL; } return EOK; } |
︙ | ︙ | |||
986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 | if ((result != TCL_OK) && (interp != NULL)) { Tcl_SetChannelErrorInterp(interp, resObj); } Tcl_DecrRefCount(resObj); /* Remove reference we held from the * invoke. */ /* * Remove the transform from the map before releasing the memory, to * prevent future accesses from finding and dereferencing a dangling * pointer. * * NOTE: The transform may not be in the map. This is ok, that happens * when the transform was created in a different interpreter and/or thread * and then was moved here. * * NOTE: The channel may have been removed from the map already via * the per-interp DeleteReflectedTransformMap exit-handler. */ | > > | | < | | | | | | | | | | | > | | 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 | if ((result != TCL_OK) && (interp != NULL)) { Tcl_SetChannelErrorInterp(interp, resObj); } Tcl_DecrRefCount(resObj); /* Remove reference we held from the * invoke. */ cleanup: /* * Remove the transform from the map before releasing the memory, to * prevent future accesses from finding and dereferencing a dangling * pointer. * * NOTE: The transform may not be in the map. This is ok, that happens * when the transform was created in a different interpreter and/or thread * and then was moved here. * * NOTE: The channel may have been removed from the map already via * the per-interp DeleteReflectedTransformMap exit-handler. */ if (!rtPtr->dead) { rtmPtr = GetReflectedTransformMap(rtPtr->interp); hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle)); if (hPtr) { Tcl_DeleteHashEntry(hPtr); } /* * In a threaded interpreter we manage a per-thread map as well, * to allow us to survive if the script level pulls the rug out * under a channel by deleting the owning thread. */ #ifdef TCL_THREADS rtmPtr = GetThreadReflectedTransformMap(); hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle)); if (hPtr) { Tcl_DeleteHashEntry(hPtr); } #endif } Tcl_EventuallyFree (rtPtr, (Tcl_FreeProc *) FreeReflectedTransform); return errorCodeSet ? errorCode : ((result == TCL_OK) ? EOK : EINVAL); } /* *---------------------------------------------------------------------- * * ReflectInput -- * |
︙ | ︙ | |||
1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 | rtPtr->handle = handleObj; Tcl_IncrRefCount(handleObj); rtPtr->timer = NULL; rtPtr->mode = 0; rtPtr->readIsDrained = 0; rtPtr->nonblocking = (((Channel *) parentChan)->state->flags & CHANNEL_NONBLOCKING); /* * Query parent for current blocking mode. */ ResultInit(&rtPtr->result); | > | 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 | rtPtr->handle = handleObj; Tcl_IncrRefCount(handleObj); rtPtr->timer = NULL; rtPtr->mode = 0; rtPtr->readIsDrained = 0; rtPtr->nonblocking = (((Channel *) parentChan)->state->flags & CHANNEL_NONBLOCKING); rtPtr->dead = 0; /* * Query parent for current blocking mode. */ ResultInit(&rtPtr->result); |
︙ | ︙ | |||
1862 1863 1864 1865 1866 1867 1868 | rtCounter++; Tcl_MutexUnlock(&rtCounterMutex); return resObj; } static void | | | | | > < > > > > > > > > > > > > | 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 | rtCounter++; Tcl_MutexUnlock(&rtCounterMutex); return resObj; } static void FreeReflectedTransformArgs( ReflectedTransform *rtPtr) { int i, n = rtPtr->argc - 2; if (n < 0) { return; } Tcl_DecrRefCount(rtPtr->handle); rtPtr->handle = NULL; for (i=0; i<n; i++) { Tcl_DecrRefCount(rtPtr->argv[i]); } /* * See [x] in NewReflectedTransform for lock * n+1 = argc-1. */ Tcl_DecrRefCount(rtPtr->argv[n+1]); rtPtr->argc = 1; } static void FreeReflectedTransform( ReflectedTransform *rtPtr) { TimerKill(rtPtr); ResultClear(&rtPtr->result); FreeReflectedTransformArgs(rtPtr); ckfree(rtPtr->argv); ckfree(rtPtr); } /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
1929 1930 1931 1932 1933 1934 1935 | { int cmdc; /* #words in constructed command */ Tcl_Obj *methObj = NULL; /* Method name in object form */ Tcl_InterpState sr; /* State of handler interp */ int result; /* Result code of method invokation */ Tcl_Obj *resObj = NULL; /* Result of method invokation. */ | | | 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 | { int cmdc; /* #words in constructed command */ Tcl_Obj *methObj = NULL; /* Method name in object form */ Tcl_InterpState sr; /* State of handler interp */ int result; /* Result code of method invokation */ Tcl_Obj *resObj = NULL; /* Result of method invokation. */ if (rtPtr->dead) { /* * The transform is marked as dead. Bail out immediately, with an * appropriate error. */ if (resultObjPtr != NULL) { resObj = Tcl_NewStringObj(msg_dstlost,-1); |
︙ | ︙ | |||
2142 2143 2144 2145 2146 2147 2148 | */ rtmPtr = clientData; for (hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch); hPtr != NULL; hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch)) { rtPtr = Tcl_GetHashValue(hPtr); | > | > > > > > > > > > > > > > > > > > > > > > > > > > > | 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 | */ rtmPtr = clientData; for (hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch); hPtr != NULL; hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch)) { rtPtr = Tcl_GetHashValue(hPtr); rtPtr->dead = 1; Tcl_DeleteHashEntry(hPtr); } Tcl_DeleteHashTable(&rtmPtr->map); ckfree(&rtmPtr->map); #ifdef TCL_THREADS /* * The origin interpreter for one or more reflected channels is gone. */ /* * Get the map of all channels handled by the current thread. This is a * ReflectedTransformMap, but on a per-thread basis, not per-interp. Go * through the channels and remove all which were handled by this * interpreter. They have already been marked as dead. */ rtmPtr = GetThreadReflectedTransformMap(); for (hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch); hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) { rtPtr = Tcl_GetHashValue(hPtr); if (rtPtr->interp != interp) { /* * Ignore entries for other interpreters. */ continue; } rtPtr->dead = 1; FreeReflectedTransformArgs(rtPtr); Tcl_DeleteHashEntry(hPtr); } /* * Go through the list of pending results and cancel all whose events were * destined for this interpreter. While this is in progress we block any * other access to the list of pending results. */ |
︙ | ︙ | |||
2189 2190 2191 2192 2193 2194 2195 | ForwardSetStaticError(paramPtr, msg_send_dstlost); Tcl_ConditionNotify(&resultPtr->done); } Tcl_MutexUnlock(&rtForwardMutex); | < < < < < < < < < < < < < < < < < < < < < < < | 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 | ForwardSetStaticError(paramPtr, msg_send_dstlost); Tcl_ConditionNotify(&resultPtr->done); } Tcl_MutexUnlock(&rtForwardMutex); #endif } #ifdef TCL_THREADS /* *---------------------------------------------------------------------- * |
︙ | ︙ | |||
2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 | /* * The origin thread for one or more reflected channels is gone. * NOTE: If this function is called due to a thread getting killed the * per-interp DeleteReflectedTransformMap is apparently not called. */ /* * Go through the list of pending results and cancel all whose events were * destined for this thread. While this is in progress we block any * other access to the list of pending results. */ Tcl_MutexLock(&rtForwardMutex); | > > > > > > > > > > > > > > > > > > | 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 | /* * The origin thread for one or more reflected channels is gone. * NOTE: If this function is called due to a thread getting killed the * per-interp DeleteReflectedTransformMap is apparently not called. */ /* * Get the map of all channels handled by the current thread. This is a * ReflectedTransformMap, but on a per-thread basis, not per-interp. Go * through the channels, remove all, mark them as dead. */ rtmPtr = GetThreadReflectedTransformMap(); for (hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch); hPtr != NULL; hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch)) { ReflectedTransform *rtPtr = Tcl_GetHashValue(hPtr); rtPtr->dead = 1; FreeReflectedTransformArgs(rtPtr); Tcl_DeleteHashEntry(hPtr); } ckfree(rtmPtr); /* * Go through the list of pending results and cancel all whose events were * destined for this thread. While this is in progress we block any * other access to the list of pending results. */ Tcl_MutexLock(&rtForwardMutex); |
︙ | ︙ | |||
2319 2320 2321 2322 2323 2324 2325 | resultPtr->result = TCL_ERROR; ForwardSetStaticError(paramPtr, msg_send_dstlost); Tcl_ConditionNotify(&resultPtr->done); } Tcl_MutexUnlock(&rtForwardMutex); | < < < < < < < < < < < < < < < < < | | 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 | resultPtr->result = TCL_ERROR; ForwardSetStaticError(paramPtr, msg_send_dstlost); Tcl_ConditionNotify(&resultPtr->done); } Tcl_MutexUnlock(&rtForwardMutex); } static void ForwardOpToOwnerThread( ReflectedTransform *rtPtr, /* Channel instance */ ForwardedOperation op, /* Forwarded driver operation */ const void *param) /* Arguments */ { Tcl_ThreadId dst = rtPtr->thread; ForwardingEvent *evPtr; ForwardingResult *resultPtr; /* * We gather the lock early. This allows us to check the liveness of the * channel without interference from DeleteThreadReflectedTransformMap(). */ Tcl_MutexLock(&rtForwardMutex); if (rtPtr->dead) { /* * The channel is marked as dead. Bail out immediately, with an * appropriate error. Do not forget to unlock the mutex on this path. */ ForwardSetStaticError((ForwardParam *) param, msg_send_dstlost); Tcl_MutexUnlock(&rtForwardMutex); |
︙ | ︙ | |||
2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 | evPtr->resultPtr = resultPtr; evPtr->op = op; evPtr->rtPtr = rtPtr; evPtr->param = (ForwardParam *) param; resultPtr->src = Tcl_GetCurrentThread(); resultPtr->dst = dst; resultPtr->done = NULL; resultPtr->result = -1; resultPtr->evPtr = evPtr; /* * Now execute the forward. */ | > | 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 | evPtr->resultPtr = resultPtr; evPtr->op = op; evPtr->rtPtr = rtPtr; evPtr->param = (ForwardParam *) param; resultPtr->src = Tcl_GetCurrentThread(); resultPtr->dst = dst; resultPtr->dsti = rtPtr->interp; resultPtr->done = NULL; resultPtr->result = -1; resultPtr->evPtr = evPtr; /* * Now execute the forward. */ |
︙ | ︙ | |||
2537 2538 2539 2540 2541 2542 2543 | * channel by deleting the owning thread. */ rtmPtr = GetThreadReflectedTransformMap(); hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle)); Tcl_DeleteHashEntry(hPtr); | | | 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 | * channel by deleting the owning thread. */ rtmPtr = GetThreadReflectedTransformMap(); hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle)); Tcl_DeleteHashEntry(hPtr); FreeReflectedTransformArgs(rtPtr); break; case ForwardedInput: { Tcl_Obj *bufObj = Tcl_NewByteArrayObj((unsigned char *) paramPtr->transform.buf, paramPtr->transform.size); Tcl_IncrRefCount(bufObj); |
︙ | ︙ |
Changes to generic/tclIndexObj.c.
︙ | ︙ | |||
1109 1110 1111 1112 1113 1114 1115 | * being processed, primarily for error * reporting. */ int objc; /* # arguments in objv still to process. */ int length; /* Number of characters in current argument */ if (remObjv != NULL) { /* | | > > > | | < | 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 | * being processed, primarily for error * reporting. */ int objc; /* # arguments in objv still to process. */ int length; /* Number of characters in current argument */ if (remObjv != NULL) { /* * Then we should copy the name of the command (0th argument). The * upper bound on the number of elements is known, and (undocumented, * but historically true) there should be a NULL argument after the * last result. [Bug 3413857] */ nrem = 1; leftovers = ckalloc((1 + *objcPtr) * sizeof(Tcl_Obj *)); leftovers[0] = objv[0]; } else { nrem = 0; leftovers = NULL; } /* * OK, now start processing from the second element (1st argument). |
︙ | ︙ | |||
1178 1179 1180 1181 1182 1183 1184 | if (remObjv == NULL) { Tcl_AppendResult(interp, "unrecognized argument \"", str, "\"", NULL); goto error; } dstIndex++; /* This argument is now handled */ | < < < < < < < | | 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 | if (remObjv == NULL) { Tcl_AppendResult(interp, "unrecognized argument \"", str, "\"", NULL); goto error; } dstIndex++; /* This argument is now handled */ leftovers[nrem++] = curArg; continue; } /* * Take the appropriate action based on the option type */ |
︙ | ︙ | |||
1223 1224 1225 1226 1227 1228 1229 | } *((const char **) infoPtr->dstPtr) = Tcl_GetString(objv[srcIndex]); srcIndex++; objc--; break; case TCL_ARGV_REST: | > > > > > > | > | 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 | } *((const char **) infoPtr->dstPtr) = Tcl_GetString(objv[srcIndex]); srcIndex++; objc--; break; case TCL_ARGV_REST: /* * Only store the point where we got to if it's not to be written * to NULL, so that TCL_ARGV_AUTO_REST works. */ if (infoPtr->dstPtr != NULL) { *((int *) infoPtr->dstPtr) = dstIndex; } goto argsDone; case TCL_ARGV_FLOAT: if (objc == 0) { goto missingArg; } if (Tcl_GetDoubleFromObj(interp, objv[srcIndex], (double *) infoPtr->dstPtr) == TCL_ERROR) { |
︙ | ︙ | |||
1278 1279 1280 1281 1282 1283 1284 | "bad argument type %d in Tcl_ArgvInfo", infoPtr->type)); goto error; } } /* * If we broke out of the loop because of an OPT_REST argument, copy the | | > > | < < | < < | < < < | | | 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 | "bad argument type %d in Tcl_ArgvInfo", infoPtr->type)); goto error; } } /* * If we broke out of the loop because of an OPT_REST argument, copy the * remaining arguments down. Note that there is always at least one * argument left over - the command name - so we always have a result if * our caller is willing to receive it. [Bug 3413857] */ argsDone: if (remObjv == NULL) { /* * Nothing to do. */ return TCL_OK; } if (objc > 0) { memcpy(leftovers+nrem, objv+srcIndex, objc*sizeof(Tcl_Obj *)); nrem += objc; } leftovers[nrem] = NULL; *objcPtr = nrem++; *remObjv = ckrealloc(leftovers, nrem * sizeof(Tcl_Obj *)); return TCL_OK; /* * Make sure to handle freeing any temporary space we've allocated on the * way to an error. */ |
︙ | ︙ |
Changes to generic/tclInt.h.
︙ | ︙ | |||
3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 | MODULE_SCOPE Tcl_TimerToken TclCreateAbsoluteTimerHandler( Tcl_Time *timePtr, Tcl_TimerProc *proc, ClientData clientData); MODULE_SCOPE int TclDefaultBgErrorHandlerObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE Tcl_Command TclInitDictCmd(Tcl_Interp *interp); MODULE_SCOPE int Tcl_DisassembleObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* Assemble command function */ MODULE_SCOPE int Tcl_AssembleObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, | > > > > > > | 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 | MODULE_SCOPE Tcl_TimerToken TclCreateAbsoluteTimerHandler( Tcl_Time *timePtr, Tcl_TimerProc *proc, ClientData clientData); MODULE_SCOPE int TclDefaultBgErrorHandlerObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); MODULE_SCOPE Tcl_Command TclInitDictCmd(Tcl_Interp *interp); MODULE_SCOPE int TclDictWithFinish(Tcl_Interp *interp, Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int index, int pathc, Tcl_Obj *const pathv[], Tcl_Obj *keysPtr); MODULE_SCOPE Tcl_Obj * TclDictWithInit(Tcl_Interp *interp, Tcl_Obj *dictPtr, int pathc, Tcl_Obj *const pathv[]); MODULE_SCOPE int Tcl_DisassembleObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* Assemble command function */ MODULE_SCOPE int Tcl_AssembleObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, |
︙ | ︙ | |||
3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 | Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileDictSetCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileDictUpdateCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileEnsemble(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileErrorCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); | > > > | 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 | Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileDictSetCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileDictUpdateCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileDictWithCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileEnsemble(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); MODULE_SCOPE int TclCompileErrorCmd(Tcl_Interp *interp, Tcl_Parse *parsePtr, Command *cmdPtr, struct CompileEnv *envPtr); |
︙ | ︙ |
Changes to generic/tclOO.decls.
1 2 3 4 5 6 7 8 | library tclOO ###################################################################### # public API # interface tclOO hooks tclOOInt | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | library tclOO ###################################################################### # public API # interface tclOO hooks tclOOInt scspec TCLOOAPI declare 0 { Tcl_Object Tcl_CopyObjectInstance(Tcl_Interp *interp, Tcl_Object sourceObject, const char *targetName, const char *targetNamespaceName) } declare 1 { |
︙ | ︙ |
Changes to generic/tclOO.h.
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #ifndef TCLOO_H_INCLUDED #define TCLOO_H_INCLUDED #include "tcl.h" /* * Be careful when it comes to versioning; need to make sure that the * standalone TclOO version matches. Also make sure that this matches the * version in the files: * * tests/oo.test * unix/tclooConfig.sh | > > > > > > > > > > > > > > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #ifndef TCLOO_H_INCLUDED #define TCLOO_H_INCLUDED #include "tcl.h" #ifndef TCLOOAPI # if defined(BUILD_tcl) || defined(BUILD_TclOO) # define TCLOOAPI MODULE_SCOPE # else # define TCLOOAPI extern # undef USE_TCLOO_STUBS # define USE_TCLOO_STUBS 1 # endif #endif extern const char *TclOOInitializeStubs( Tcl_Interp *, const char *version); #define Tcl_OOInitStubs(interp) TclOOInitializeStubs((interp), TCLOO_VERSION) /* * Be careful when it comes to versioning; need to make sure that the * standalone TclOO version matches. Also make sure that this matches the * version in the files: * * tests/oo.test * unix/tclooConfig.sh |
︙ | ︙ |
Changes to generic/tclOODecls.h.
1 2 3 4 5 6 7 | /* * This file is (mostly) automatically generated from tclOO.decls. */ #ifndef _TCLOODECLS #define _TCLOODECLS | < < < < < < < < < < < < < < < < < < < < < < < < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | /* * This file is (mostly) automatically generated from tclOO.decls. */ #ifndef _TCLOODECLS #define _TCLOODECLS /* !BEGIN!: Do not edit below this line. */ /* * Exported function declarations: */ /* 0 */ TCLOOAPI Tcl_Object Tcl_CopyObjectInstance(Tcl_Interp *interp, Tcl_Object sourceObject, const char *targetName, const char *targetNamespaceName); /* 1 */ TCLOOAPI Tcl_Object Tcl_GetClassAsObject(Tcl_Class clazz); /* 2 */ TCLOOAPI Tcl_Class Tcl_GetObjectAsClass(Tcl_Object object); /* 3 */ TCLOOAPI Tcl_Command Tcl_GetObjectCommand(Tcl_Object object); /* 4 */ TCLOOAPI Tcl_Object Tcl_GetObjectFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr); /* 5 */ TCLOOAPI Tcl_Namespace * Tcl_GetObjectNamespace(Tcl_Object object); /* 6 */ TCLOOAPI Tcl_Class Tcl_MethodDeclarerClass(Tcl_Method method); /* 7 */ TCLOOAPI Tcl_Object Tcl_MethodDeclarerObject(Tcl_Method method); /* 8 */ TCLOOAPI int Tcl_MethodIsPublic(Tcl_Method method); /* 9 */ TCLOOAPI int Tcl_MethodIsType(Tcl_Method method, const Tcl_MethodType *typePtr, ClientData *clientDataPtr); /* 10 */ TCLOOAPI Tcl_Obj * Tcl_MethodName(Tcl_Method method); /* 11 */ TCLOOAPI Tcl_Method Tcl_NewInstanceMethod(Tcl_Interp *interp, Tcl_Object object, Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr, ClientData clientData); /* 12 */ TCLOOAPI Tcl_Method Tcl_NewMethod(Tcl_Interp *interp, Tcl_Class cls, Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr, ClientData clientData); /* 13 */ TCLOOAPI Tcl_Object Tcl_NewObjectInstance(Tcl_Interp *interp, Tcl_Class cls, const char *nameStr, const char *nsNameStr, int objc, Tcl_Obj *const *objv, int skip); /* 14 */ TCLOOAPI int Tcl_ObjectDeleted(Tcl_Object object); /* 15 */ TCLOOAPI int Tcl_ObjectContextIsFiltering( Tcl_ObjectContext context); /* 16 */ TCLOOAPI Tcl_Method Tcl_ObjectContextMethod(Tcl_ObjectContext context); /* 17 */ TCLOOAPI Tcl_Object Tcl_ObjectContextObject(Tcl_ObjectContext context); /* 18 */ TCLOOAPI int Tcl_ObjectContextSkippedArgs( Tcl_ObjectContext context); /* 19 */ TCLOOAPI ClientData Tcl_ClassGetMetadata(Tcl_Class clazz, const Tcl_ObjectMetadataType *typePtr); /* 20 */ TCLOOAPI void Tcl_ClassSetMetadata(Tcl_Class clazz, const Tcl_ObjectMetadataType *typePtr, ClientData metadata); /* 21 */ TCLOOAPI ClientData Tcl_ObjectGetMetadata(Tcl_Object object, const Tcl_ObjectMetadataType *typePtr); /* 22 */ TCLOOAPI void Tcl_ObjectSetMetadata(Tcl_Object object, const Tcl_ObjectMetadataType *typePtr, ClientData metadata); /* 23 */ TCLOOAPI int Tcl_ObjectContextInvokeNext(Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv, int skip); /* 24 */ TCLOOAPI Tcl_ObjectMapMethodNameProc * Tcl_ObjectGetMethodNameMapper( Tcl_Object object); /* 25 */ TCLOOAPI void Tcl_ObjectSetMethodNameMapper(Tcl_Object object, Tcl_ObjectMapMethodNameProc *mapMethodNameProc); /* 26 */ TCLOOAPI void Tcl_ClassSetConstructor(Tcl_Interp *interp, Tcl_Class clazz, Tcl_Method method); /* 27 */ TCLOOAPI void Tcl_ClassSetDestructor(Tcl_Interp *interp, Tcl_Class clazz, Tcl_Method method); /* 28 */ TCLOOAPI Tcl_Obj * Tcl_GetObjectName(Tcl_Interp *interp, Tcl_Object object); typedef struct TclOOStubHooks { const struct TclOOIntStubs *tclOOIntStubs; } TclOOStubHooks; typedef struct TclOOStubs { |
︙ | ︙ | |||
236 237 238 239 240 241 242 | (tclOOStubsPtr->tcl_ClassSetDestructor) /* 27 */ #define Tcl_GetObjectName \ (tclOOStubsPtr->tcl_GetObjectName) /* 28 */ #endif /* defined(USE_TCLOO_STUBS) */ /* !END!: Do not edit above this line. */ | < < < < | 211 212 213 214 215 216 217 218 | (tclOOStubsPtr->tcl_ClassSetDestructor) /* 27 */ #define Tcl_GetObjectName \ (tclOOStubsPtr->tcl_GetObjectName) /* 28 */ #endif /* defined(USE_TCLOO_STUBS) */ /* !END!: Do not edit above this line. */ #endif /* _TCLOODECLS */ |
Changes to generic/tclOOIntDecls.h.
1 2 3 4 5 6 7 | /* * This file is (mostly) automatically generated from tclOO.decls. */ #ifndef _TCLOOINTDECLS #define _TCLOOINTDECLS | < < < < < < < < < < < < < < < < < | | | | | | | | | | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | /* * This file is (mostly) automatically generated from tclOO.decls. */ #ifndef _TCLOOINTDECLS #define _TCLOOINTDECLS /* !BEGIN!: Do not edit below this line. */ /* * Exported function declarations: */ /* 0 */ TCLOOAPI Tcl_Object TclOOGetDefineCmdContext(Tcl_Interp *interp); /* 1 */ TCLOOAPI Tcl_Method TclOOMakeProcInstanceMethod(Tcl_Interp *interp, Object *oPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType *typePtr, ClientData clientData, Proc **procPtrPtr); /* 2 */ TCLOOAPI Tcl_Method TclOOMakeProcMethod(Tcl_Interp *interp, Class *clsPtr, int flags, Tcl_Obj *nameObj, const char *namePtr, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType *typePtr, ClientData clientData, Proc **procPtrPtr); /* 3 */ TCLOOAPI Method * TclOONewProcInstanceMethod(Tcl_Interp *interp, Object *oPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, ProcedureMethod **pmPtrPtr); /* 4 */ TCLOOAPI Method * TclOONewProcMethod(Tcl_Interp *interp, Class *clsPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, ProcedureMethod **pmPtrPtr); /* 5 */ TCLOOAPI int TclOOObjectCmdCore(Object *oPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, int publicOnly, Class *startCls); /* 6 */ TCLOOAPI int TclOOIsReachable(Class *targetPtr, Class *startPtr); /* 7 */ TCLOOAPI Method * TclOONewForwardMethod(Tcl_Interp *interp, Class *clsPtr, int isPublic, Tcl_Obj *nameObj, Tcl_Obj *prefixObj); /* 8 */ TCLOOAPI Method * TclOONewForwardInstanceMethod(Tcl_Interp *interp, Object *oPtr, int isPublic, Tcl_Obj *nameObj, Tcl_Obj *prefixObj); /* 9 */ TCLOOAPI Tcl_Method TclOONewProcInstanceMethodEx(Tcl_Interp *interp, Tcl_Object oPtr, TclOO_PreCallProc *preCallPtr, TclOO_PostCallProc *postCallPtr, ProcErrorProc *errProc, ClientData clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr); /* 10 */ TCLOOAPI Tcl_Method TclOONewProcMethodEx(Tcl_Interp *interp, Tcl_Class clsPtr, TclOO_PreCallProc *preCallPtr, TclOO_PostCallProc *postCallPtr, ProcErrorProc *errProc, ClientData clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr); /* 11 */ TCLOOAPI int TclOOInvokeObject(Tcl_Interp *interp, Tcl_Object object, Tcl_Class startCls, int publicPrivate, int objc, Tcl_Obj *const *objv); /* 12 */ TCLOOAPI void TclOOObjectSetFilters(Object *oPtr, int numFilters, Tcl_Obj *const *filters); /* 13 */ TCLOOAPI void TclOOClassSetFilters(Tcl_Interp *interp, Class *classPtr, int numFilters, Tcl_Obj *const *filters); /* 14 */ TCLOOAPI void TclOOObjectSetMixins(Object *oPtr, int numMixins, Class *const *mixins); /* 15 */ TCLOOAPI void TclOOClassSetMixins(Tcl_Interp *interp, Class *classPtr, int numMixins, Class *const *mixins); typedef struct TclOOIntStubs { int magic; const struct TclOOIntStubHooks *hooks; |
︙ | ︙ | |||
173 174 175 176 177 178 179 | (tclOOIntStubsPtr->tclOOObjectSetMixins) /* 14 */ #define TclOOClassSetMixins \ (tclOOIntStubsPtr->tclOOClassSetMixins) /* 15 */ #endif /* defined(USE_TCLOO_STUBS) */ /* !END!: Do not edit above this line. */ | < < < < | 156 157 158 159 160 161 162 163 | (tclOOIntStubsPtr->tclOOObjectSetMixins) /* 14 */ #define TclOOClassSetMixins \ (tclOOIntStubsPtr->tclOOClassSetMixins) /* 15 */ #endif /* defined(USE_TCLOO_STUBS) */ /* !END!: Do not edit above this line. */ #endif /* _TCLOOINTDECLS */ |
Changes to generic/tclTest.c.
︙ | ︙ | |||
307 308 309 310 311 312 313 314 315 316 317 318 319 320 | static int TestexitmainloopCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestpanicCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestfinexitObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestparserObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestparsevarObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestparsevarnameObjCmd(ClientData dummy, | > > | 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 | static int TestexitmainloopCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestpanicCmd(ClientData dummy, Tcl_Interp *interp, int argc, const char **argv); static int TestfinexitObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestparseargsCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestparserObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestparsevarObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); static int TestparsevarnameObjCmd(ClientData dummy, |
︙ | ︙ | |||
620 621 622 623 624 625 626 627 628 629 630 631 632 633 | Tcl_CreateCommand(interp, "testinterpdelete", TestinterpdeleteCmd, NULL, NULL); Tcl_CreateCommand(interp, "testlink", TestlinkCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testlocale", TestlocaleCmd, NULL, NULL); Tcl_CreateCommand(interp, "testpanic", TestpanicCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testfinexit", TestfinexitObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testparser", TestparserObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testparsevar", TestparsevarObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testparsevarname", TestparsevarnameObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testregexp", TestregexpObjCmd, | > | 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 | Tcl_CreateCommand(interp, "testinterpdelete", TestinterpdeleteCmd, NULL, NULL); Tcl_CreateCommand(interp, "testlink", TestlinkCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testlocale", TestlocaleCmd, NULL, NULL); Tcl_CreateCommand(interp, "testpanic", TestpanicCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testfinexit", TestfinexitObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testparseargs", TestparseargsCmd,NULL,NULL); Tcl_CreateObjCommand(interp, "testparser", TestparserObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testparsevar", TestparsevarObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testparsevarname", TestparsevarnameObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testregexp", TestregexpObjCmd, |
︙ | ︙ | |||
7076 7077 7078 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 | Tcl_DecrRefCount(tmpPtr); if (result == TCL_OK) { Tcl_ResetResult(interp); } return result; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * tab-width: 8 * indent-tabs-mode: nil * End: */ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 7079 7080 7081 7082 7083 7084 7085 7086 7087 7088 7089 7090 7091 7092 7093 7094 7095 7096 7097 7098 7099 7100 7101 7102 7103 7104 7105 7106 7107 7108 7109 7110 7111 7112 7113 7114 7115 7116 7117 7118 7119 7120 7121 7122 7123 7124 7125 7126 7127 7128 7129 7130 7131 7132 7133 7134 7135 7136 7137 7138 | Tcl_DecrRefCount(tmpPtr); if (result == TCL_OK) { Tcl_ResetResult(interp); } return result; } /* *---------------------------------------------------------------------- * * TestparseargsCmd -- * * This procedure implements the "testparseargs" command. It is used to * test that Tcl_ParseArgsObjv does indeed return the right number of * arguments. In other words, that [Bug 3413857] was fixed properly. * * Results: * A standard Tcl result. * * Side effects: * None. * *---------------------------------------------------------------------- */ static int TestparseargsCmd( ClientData dummy, /* Not used. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Arguments. */ { int count = objc, foo = 0; Tcl_Obj **remObjv, *result[3]; Tcl_ArgvInfo argTable[] = { {TCL_ARGV_CONSTANT, "-bool", INT2PTR(1), &foo, "booltest", NULL}, TCL_ARGV_AUTO_REST, TCL_ARGV_AUTO_HELP, TCL_ARGV_TABLE_END }; if (Tcl_ParseArgsObjv(interp, argTable, &count, objv, &remObjv)!=TCL_OK) { return TCL_ERROR; } result[0] = Tcl_NewIntObj(foo); result[1] = Tcl_NewIntObj(count); result[2] = Tcl_NewListObj(count, remObjv); Tcl_SetObjResult(interp, Tcl_NewListObj(3, result)); ckfree(remObjv); return TCL_OK; } /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * tab-width: 8 * indent-tabs-mode: nil * End: */ |
Changes to generic/tclThreadTest.c.
︙ | ︙ | |||
42 43 44 45 46 47 48 | static Tcl_ThreadDataKey dataKey; /* * This list is used to list all threads that have interpreters. This is * protected by threadMutex. */ | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | static Tcl_ThreadDataKey dataKey; /* * This list is used to list all threads that have interpreters. This is * protected by threadMutex. */ static ThreadSpecificData *threadList = NULL; /* * The following bit-values are legal for the "flags" field of the * ThreadSpecificData structure. */ #define TP_Dying 0x001 /* This thread is being canceled */ |
︙ | ︙ | |||
619 620 621 622 623 624 625 | ThreadErrorProc(tsdPtr->interp); } /* * Clean up. */ | | | | 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 | ThreadErrorProc(tsdPtr->interp); } /* * Clean up. */ Tcl_DeleteInterp(tsdPtr->interp); Tcl_Release(tsdPtr->interp); ListRemove(tsdPtr); Tcl_ExitThread(result); TCL_THREAD_CREATE_RETURN; } /* *------------------------------------------------------------------------ |
︙ | ︙ | |||
740 741 742 743 744 745 746 747 748 749 750 751 752 753 | } else { threadList = tsdPtr->nextPtr; } if (tsdPtr->nextPtr) { tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr; } tsdPtr->nextPtr = tsdPtr->prevPtr = 0; Tcl_MutexUnlock(&threadMutex); } /* *------------------------------------------------------------------------ * * ThreadList -- | > | 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 | } else { threadList = tsdPtr->nextPtr; } if (tsdPtr->nextPtr) { tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr; } tsdPtr->nextPtr = tsdPtr->prevPtr = 0; tsdPtr->interp = NULL; Tcl_MutexUnlock(&threadMutex); } /* *------------------------------------------------------------------------ * * ThreadList -- |
︙ | ︙ | |||
1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 | static void ThreadExitProc( ClientData clientData) { char *threadEvalScript = clientData; ThreadEventResult *resultPtr, *nextPtr; Tcl_ThreadId self = Tcl_GetCurrentThread(); Tcl_MutexLock(&threadMutex); if (threadEvalScript) { ckfree(threadEvalScript); threadEvalScript = NULL; } | > > > > > | 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 | static void ThreadExitProc( ClientData clientData) { char *threadEvalScript = clientData; ThreadEventResult *resultPtr, *nextPtr; Tcl_ThreadId self = Tcl_GetCurrentThread(); ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); if (tsdPtr->interp != NULL) { ListRemove(tsdPtr); } Tcl_MutexLock(&threadMutex); if (threadEvalScript) { ckfree(threadEvalScript); threadEvalScript = NULL; } |
︙ | ︙ |
Changes to library/tzdata/Africa/Dar_es_Salaam.
1 2 3 4 5 | # created by tools/tclZIC.tcl - do not edit set TZData(:Africa/Dar_es_Salaam) { {-9223372036854775808 9428 0 LMT} {-1230777428 10800 0 EAT} | | | | 1 2 3 4 5 6 7 8 | # created by tools/tclZIC.tcl - do not edit set TZData(:Africa/Dar_es_Salaam) { {-9223372036854775808 9428 0 LMT} {-1230777428 10800 0 EAT} {-694321200 9900 0 BEAUT} {-284006700 10800 0 EAT} } |
Changes to library/tzdata/Africa/Kampala.
1 2 3 4 5 6 | # created by tools/tclZIC.tcl - do not edit set TZData(:Africa/Kampala) { {-9223372036854775808 7780 0 LMT} {-1309745380 10800 0 EAT} {-1262314800 9000 0 BEAT} | | | | 1 2 3 4 5 6 7 8 9 | # created by tools/tclZIC.tcl - do not edit set TZData(:Africa/Kampala) { {-9223372036854775808 7780 0 LMT} {-1309745380 10800 0 EAT} {-1262314800 9000 0 BEAT} {-694319400 9900 0 BEAUT} {-410237100 10800 0 EAT} } |
Changes to library/tzdata/Africa/Nairobi.
1 2 3 4 5 6 | # created by tools/tclZIC.tcl - do not edit set TZData(:Africa/Nairobi) { {-9223372036854775808 8836 0 LMT} {-1309746436 10800 0 EAT} {-1262314800 9000 0 BEAT} | | | | 1 2 3 4 5 6 7 8 9 | # created by tools/tclZIC.tcl - do not edit set TZData(:Africa/Nairobi) { {-9223372036854775808 8836 0 LMT} {-1309746436 10800 0 EAT} {-1262314800 9000 0 BEAT} {-946780200 9900 0 BEAUT} {-315629100 10800 0 EAT} } |
Changes to library/tzdata/Asia/Gaza.
︙ | ︙ | |||
85 86 87 88 89 90 91 | {1113516000 10800 1 EEST} {1128380400 7200 0 EET} {1143842400 10800 1 EEST} {1158872400 7200 0 EET} {1175378400 10800 1 EEST} {1189638000 7200 0 EET} {1207000800 10800 1 EEST} | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | {1113516000 10800 1 EEST} {1128380400 7200 0 EET} {1143842400 10800 1 EEST} {1158872400 7200 0 EET} {1175378400 10800 1 EEST} {1189638000 7200 0 EET} {1207000800 10800 1 EEST} {1219957200 7200 0 EET} {1238104800 10800 1 EEST} {1252018800 7200 0 EET} {1269640860 10800 1 EEST} {1281474000 7200 0 EET} {1301738460 10800 1 EEST} {1312146000 7200 0 EET} } |
Changes to library/tzdata/Europe/Kaliningrad.
︙ | ︙ | |||
76 77 78 79 80 81 82 | {1193529600 7200 0 EET} {1206835200 10800 1 EEST} {1224979200 7200 0 EET} {1238284800 10800 1 EEST} {1256428800 7200 0 EET} {1269734400 10800 1 EEST} {1288483200 7200 0 EET} | | | 76 77 78 79 80 81 82 83 84 | {1193529600 7200 0 EET} {1206835200 10800 1 EEST} {1224979200 7200 0 EET} {1238284800 10800 1 EEST} {1256428800 7200 0 EET} {1269734400 10800 1 EEST} {1288483200 7200 0 EET} {1301184000 10800 0 FET} } |
Changes to library/tzdata/Europe/Kiev.
︙ | ︙ | |||
66 67 68 69 70 71 72 | {1193533200 7200 0 EET} {1206838800 10800 1 EEST} {1224982800 7200 0 EET} {1238288400 10800 1 EEST} {1256432400 7200 0 EET} {1269738000 10800 1 EEST} {1288486800 7200 0 EET} | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 66 67 68 69 70 71 72 73 74 | {1193533200 7200 0 EET} {1206838800 10800 1 EEST} {1224982800 7200 0 EET} {1238288400 10800 1 EEST} {1256432400 7200 0 EET} {1269738000 10800 1 EEST} {1288486800 7200 0 EET} {1301187600 10800 0 FET} } |
Changes to library/tzdata/Europe/Minsk.
︙ | ︙ | |||
66 67 68 69 70 71 72 | {1193529600 7200 0 EET} {1206835200 10800 1 EEST} {1224979200 7200 0 EET} {1238284800 10800 1 EEST} {1256428800 7200 0 EET} {1269734400 10800 1 EEST} {1288483200 7200 0 EET} | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 66 67 68 69 70 71 72 73 74 | {1193529600 7200 0 EET} {1206835200 10800 1 EEST} {1224979200 7200 0 EET} {1238284800 10800 1 EEST} {1256428800 7200 0 EET} {1269734400 10800 1 EEST} {1288483200 7200 0 EET} {1301184000 10800 0 FET} } |
Changes to library/tzdata/Europe/Simferopol.
︙ | ︙ | |||
68 69 70 71 72 73 74 | {1193533200 7200 0 EET} {1206838800 10800 1 EEST} {1224982800 7200 0 EET} {1238288400 10800 1 EEST} {1256432400 7200 0 EET} {1269738000 10800 1 EEST} {1288486800 7200 0 EET} | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 68 69 70 71 72 73 74 75 76 | {1193533200 7200 0 EET} {1206838800 10800 1 EEST} {1224982800 7200 0 EET} {1238288400 10800 1 EEST} {1256432400 7200 0 EET} {1269738000 10800 1 EEST} {1288486800 7200 0 EET} {1301187600 10800 0 FET} } |
Changes to library/tzdata/Europe/Uzhgorod.
︙ | ︙ | |||
69 70 71 72 73 74 75 | {1193533200 7200 0 EET} {1206838800 10800 1 EEST} {1224982800 7200 0 EET} {1238288400 10800 1 EEST} {1256432400 7200 0 EET} {1269738000 10800 1 EEST} {1288486800 7200 0 EET} | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 69 70 71 72 73 74 75 76 77 | {1193533200 7200 0 EET} {1206838800 10800 1 EEST} {1224982800 7200 0 EET} {1238288400 10800 1 EEST} {1256432400 7200 0 EET} {1269738000 10800 1 EEST} {1288486800 7200 0 EET} {1301187600 10800 0 FET} } |
Changes to library/tzdata/Europe/Zaporozhye.
︙ | ︙ | |||
67 68 69 70 71 72 73 | {1193533200 7200 0 EET} {1206838800 10800 1 EEST} {1224982800 7200 0 EET} {1238288400 10800 1 EEST} {1256432400 7200 0 EET} {1269738000 10800 1 EEST} {1288486800 7200 0 EET} | | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 67 68 69 70 71 72 73 74 75 | {1193533200 7200 0 EET} {1206838800 10800 1 EEST} {1224982800 7200 0 EET} {1238288400 10800 1 EEST} {1256432400 7200 0 EET} {1269738000 10800 1 EEST} {1288486800 7200 0 EET} {1301187600 10800 0 FET} } |
Changes to library/tzdata/Pacific/Apia.
1 2 3 4 5 6 7 8 9 | # created by tools/tclZIC.tcl - do not edit set TZData(:Pacific/Apia) { {-9223372036854775808 45184 0 LMT} {-2855737984 -41216 0 LMT} {-1861878784 -41400 0 SAMT} {-631110600 -39600 0 WST} {1285498800 -36000 1 WSDT} {1301752800 -39600 0 WST} | > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 | # created by tools/tclZIC.tcl - do not edit set TZData(:Pacific/Apia) { {-9223372036854775808 45184 0 LMT} {-2855737984 -41216 0 LMT} {-1861878784 -41400 0 SAMT} {-631110600 -39600 0 WST} {1285498800 -36000 1 WSDT} {1301752800 -39600 0 WST} {1316872800 -36000 1 WSDT} {1325239200 50400 1 WSDT} {1333202400 46800 0 WST} } |
Changes to tests/dict.test.
︙ | ︙ | |||
1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 | } } } string range [append foo OK] end-1 end } -cleanup { unset foo t inner } -result OK # cleanup ::tcltest::cleanupTests return # Local Variables: # mode: tcl | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 | } } } string range [append foo OK] end-1 end } -cleanup { unset foo t inner } -result OK test dict-22.12 {dict with: compiled} { apply {{} { set d {a 1 b 2} list [dict with d { set a $b unset b dict set d c 3 list ok }] $d }} } {ok {a 2 c 3}} test dict-22.13 {dict with: compiled} { apply {i { set d($i) {a 1 b 2} list [dict with d($i) { set a $b unset b dict set d($i) c 3 list ok }] [array get d] }} e } {ok {e {a 2 c 3}}} test dict-22.14 {dict with: compiled} { apply {{} { set d {a 1 b 2} foreach x {1 2 3} { dict with d { incr a $b if {$x == 2} break } unset a b } list $a $b $x $d }} } {5 2 2 {a 5 b 2}} test dict-22.15 {dict with: compiled} { apply {i { set d($i) {a 1 b 2} foreach x {1 2 3} { dict with d($i) { incr a $b if {$x == 2} break } unset a b } list $a $b $x [array get d] }} e } {5 2 2 {e {a 5 b 2}}} test dict-22.16 {dict with: compiled} { apply {{} { set d {p {q {a 1 b 2}}} dict with d p q { set a $b.$a } return $d }} } {p {q {a 2.1 b 2}}} test dict-22.17 {dict with: compiled} { apply {i { set d($i) {p {q {a 1 b 2}}} dict with d($i) p q { set a $b.$a } array get d }} e } {e {p {q {a 2.1 b 2}}}} # cleanup ::tcltest::cleanupTests return # Local Variables: # mode: tcl |
︙ | ︙ |
Changes to tests/indexObj.test.
1 | # This file is a Tcl script to test out the the procedures in file | | | | | | > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | # This file is a Tcl script to test out the the procedures in file # tkIndexObj.c, which implement indexed table lookups. The tests here are # organized in the standard fashion for Tcl tests. # # Copyright (c) 1997 Sun Microsystems, Inc. # Copyright (c) 1998-1999 by Scriptics Corporation. # # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 namespace import -force ::tcltest::* } testConstraint testindexobj [llength [info commands testindexobj]] testConstraint testparseargs [llength [info commands testparseargs]] test indexObj-1.1 {exact match} testindexobj { testindexobj 1 1 xyz abc def xyz alm } {2} test indexObj-1.2 {exact match} testindexobj { testindexobj 1 1 abc abc def xyz alm } {0} test indexObj-1.3 {exact match} testindexobj { |
︙ | ︙ | |||
124 125 126 127 128 129 130 131 132 133 134 135 136 137 | } "wrong # args: should be \"testgetindexfromobjstruct c 1\"" test indexObj-6.4 {Tcl_GetIndexFromObjStruct} testindexobj { set x c testgetindexfromobjstruct $x 1 testgetindexfromobjstruct $x 1 } "wrong # args: should be \"testgetindexfromobjstruct c 1\"" # cleanup ::tcltest::cleanupTests return # Local Variables: # mode: tcl # End: | > > > > > > > > > > > > > > > > > > > > > > > > > | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | } "wrong # args: should be \"testgetindexfromobjstruct c 1\"" test indexObj-6.4 {Tcl_GetIndexFromObjStruct} testindexobj { set x c testgetindexfromobjstruct $x 1 testgetindexfromobjstruct $x 1 } "wrong # args: should be \"testgetindexfromobjstruct c 1\"" test indexObj-7.1 {Tcl_ParseArgsObjv} testparseargs { testparseargs } {0 1 testparseargs} test indexObj-7.2 {Tcl_ParseArgsObjv} testparseargs { testparseargs -bool } {1 1 testparseargs} test indexObj-7.3 {Tcl_ParseArgsObjv} testparseargs { testparseargs -bool bar } {1 2 {testparseargs bar}} test indexObj-7.4 {Tcl_ParseArgsObjv} testparseargs { testparseargs bar } {0 2 {testparseargs bar}} test indexObj-7.5 {Tcl_ParseArgsObjv} -constraints testparseargs -body { testparseargs -help } -returnCodes error -result {Command-specific options: -bool: booltest --: Marks the end of the options -help: Print summary of command-line options and abort} test indexObj-7.6 {Tcl_ParseArgsObjv} testparseargs { testparseargs -- -bool -help } {0 3 {testparseargs -bool -help}} test indexObj-7.7 {Tcl_ParseArgsObjv memory management} testparseargs { testparseargs 1 2 3 4 5 6 7 8 9 0 -bool 1 2 3 4 5 6 7 8 9 0 } {1 21 {testparseargs 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0}} # cleanup ::tcltest::cleanupTests return # Local Variables: # mode: tcl # End: |
Changes to tests/interp.test.
︙ | ︙ | |||
13 14 15 16 17 18 19 | if {"::tcltest" ni [namespace children]} { package require tcltest 2.1 namespace import -force ::tcltest::* } testConstraint testinterpdelete [llength [info commands testinterpdelete]] | | | 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | if {"::tcltest" ni [namespace children]} { package require tcltest 2.1 namespace import -force ::tcltest::* } testConstraint testinterpdelete [llength [info commands testinterpdelete]] set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable unload} foreach i [interp slaves] { interp delete $i } # Part 0: Check out options for interp command test interp-1.1 {options for interp command} -returnCodes error -body { |
︙ | ︙ |
Changes to tests/namespace.test.
︙ | ︙ | |||
2476 2477 2478 2479 2480 2481 2482 | interp create slave slave eval namespace eval demo namespace path :: interp delete slave } {} test namespace-51.17 {resolution epoch handling: Bug 2898722} -setup { set result {} catch {namespace delete ::a} | | | 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 | interp create slave slave eval namespace eval demo namespace path :: interp delete slave } {} test namespace-51.17 {resolution epoch handling: Bug 2898722} -setup { set result {} catch {namespace delete ::a} } -body { namespace eval ::a { proc c {} {lappend ::result A} c namespace eval b { variable d c lappend ::result [catch { $d }] } |
︙ | ︙ |
Changes to tests/safe.test.
︙ | ︙ | |||
537 538 539 540 541 542 543 544 545 546 547 548 549 550 | test safe-12.7 {glob is restricted} -setup { set i [safe::interpCreate] } -body { $i eval glob * } -cleanup { safe::interpDelete $i } -match glob -result * set ::auto_path $saveAutoPath # cleanup ::tcltest::cleanupTests return # Local Variables: | > > > > > > > > > > > > > > > > | 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 | test safe-12.7 {glob is restricted} -setup { set i [safe::interpCreate] } -body { $i eval glob * } -cleanup { safe::interpDelete $i } -match glob -result * test safe-13.1 {safe file ensemble does not surprise code} -setup { set i [interp create -safe] } -body { set result [expr {"file" in [interp hidden $i]}] lappend result [interp eval $i {tcl::file::split a/b/c}] lappend result [catch {interp eval $i {tcl::file::isdirectory .}}] lappend result [interp invokehidden $i file split a/b/c] lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg lappend result [catch {interp invokehidden $i file isdirectory .}] interp expose $i file lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg lappend result [catch {interp eval $i {file isdirectory .}} msg] $msg } -cleanup { interp delete $i } -result {1 {a b c} 1 {a b c} 1 {invalid command name "file"} 1 0 {a b c} 1 {invalid command name "::tcl::file::isdirectory"}} set ::auto_path $saveAutoPath # cleanup ::tcltest::cleanupTests return # Local Variables: |
︙ | ︙ |
Changes to tests/thread.test.
︙ | ︙ | |||
19 20 21 22 23 24 25 | # Some tests require the testthread command testConstraint testthread [expr {[info commands testthread] != {}}] testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}] testConstraint notValgrind [expr {![testConstraint valgrind]}] | > | > | > > | < < < | > > > > > > > > > > > > > > > > > | 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | # Some tests require the testthread command testConstraint testthread [expr {[info commands testthread] != {}}] testConstraint thread [expr {0 == [catch {package require Thread 2.6}]}] testConstraint notValgrind [expr {![testConstraint valgrind]}] proc ThreadError {id info} { global threadId threadError set threadId $id set threadError $info } if {[testConstraint thread]} { thread::errorproc ThreadError } if {[testConstraint testthread]} { testthread errorproc ThreadError set mainThread [testthread id] proc ThreadNullError {id info} { # ignore } proc threadReap {} { testthread errorproc ThreadNullError while {[llength [testthread names]] > 1} { foreach tid [testthread names] { if {$tid != [testthread id]} { catch { testthread send -async $tid {testthread exit} } } } after 1 } testthread errorproc ThreadError return [llength [testthread names]] } } test thread-1.1 {Tcl_ThreadObjCmd: no args} {testthread} { list [catch {testthread} msg] $msg } {1 {wrong # args: should be "testthread option ?arg ...?"}} test thread-1.2 {Tcl_ThreadObjCmd: bad option} {testthread} { list [catch {testthread foo} msg] $msg } {1 {bad option "foo": must be cancel, create, event, exit, id, join, names, send, wait, or errorproc}} |
︙ | ︙ | |||
66 67 68 69 70 71 72 | if {$l == 1} { break } } set l } {1} test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} { | < | | | | 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | if {$l == 1} { break } } set l } {1} test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} { thread::create {{*}{}} update after 10 llength [thread::names] } {1} test thread-1.7 {Tcl_ThreadObjCmd: thread id args} {testthread} { set x [catch {testthread id x} msg] list $x $msg } {1 {wrong # args: should be "testthread id"}} test thread-1.8 {Tcl_ThreadObjCmd: thread id} {testthread} { string compare [testthread id] $mainThread } {0} test thread-1.9 {Tcl_ThreadObjCmd: thread names args} {testthread} { set x [catch {testthread names x} msg] list $x $msg } {1 {wrong # args: should be "testthread names"}} test thread-1.10 {Tcl_ThreadObjCmd: thread id} {testthread} { string compare [testthread names] $mainThread } {0} test thread-1.11 {Tcl_ThreadObjCmd: send args} {testthread} { set x [catch {testthread send} msg] list $x $msg } {1 {wrong # args: should be "testthread send ?-async? id script"}} test thread-1.12 {Tcl_ThreadObjCmd: send nonint} {testthread} { set x [catch {testthread send abc command} msg] list $x $msg } {1 {expected integer but got "abc"}} test thread-1.13 {Tcl_ThreadObjCmd: send args} {thread} { set serverthread [thread::create -preserved] set five [thread::send $serverthread {set x 5}] thread::release $serverthread set five } 5 test thread-1.14 {Tcl_ThreadObjCmd: send bad id} {testthread} { set tid [expr $mainThread + 10] set x [catch {testthread send $tid {set x 5}} msg] list $x $msg } {1 {invalid thread id}} test thread-1.15 {Tcl_ThreadObjCmd: wait} {thread} { set serverthread [thread::create -preserved {set z 5 ; thread::wait}] set five [thread::send $serverthread {set z}] thread::release $serverthread |
︙ | ︙ | |||
245 246 247 248 249 250 251 | list $x $msg } {1 {wrong # args: should be "testthread cancel ?-unwind? id ?result?"}} test thread-7.2 {cancel: nonint} {testthread} { set x [catch {testthread cancel abc} msg] list $x $msg } {1 {expected integer but got "abc"}} test thread-7.3 {cancel: bad id} {testthread} { | | | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | list $x $msg } {1 {wrong # args: should be "testthread cancel ?-unwind? id ?result?"}} test thread-7.2 {cancel: nonint} {testthread} { set x [catch {testthread cancel abc} msg] list $x $msg } {1 {expected integer but got "abc"}} test thread-7.3 {cancel: bad id} {testthread} { set tid [expr $mainThread + 10] set x [catch {testthread cancel $tid} msg] list $x $msg } {1 {invalid thread id}} test thread-7.4 {cancel: pure bytecode loop} {testthread} { threadReap unset -nocomplain ::threadError ::threadId ::threadIdStarted set serverthread [testthread create -joinable { |
︙ | ︙ |
Changes to tools/tcltk-man2html-utils.tcl.
︙ | ︙ | |||
31 32 33 34 35 36 37 | } proc fatal {msg} { global manual uplevel 1 [list manerror $msg] exit 1 } | | > > > > > | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 | } proc fatal {msg} { global manual uplevel 1 [list manerror $msg] exit 1 } ## ## templating ## proc indexfile {} { if {[info exists ::TARGET] && $::TARGET eq "devsite"} { return "index.tml" } else { return "contents.htm" } } proc copyright {copyright {level {}}} { # We don't actually generate a separate copyright page anymore #set page "${level}copyright.htm" #return "<A HREF=\"$page\">Copyright</A> © [htmlize-text [lrange $copyright 2 end]]" # obfuscate any email addresses that may appear in name set who [string map {@ (at)} [lrange $copyright 2 end]] return "Copyright © [htmlize-text $who]" } proc copyout {copyrights {level {}}} { set out "<div class=\"copy\">" foreach c $copyrights { append out "[copyright $c $level]\n" } append out "</div>" return $out } proc CSS {{level ""}} { return "<link rel=\"stylesheet\" href=\"${level}$::CSSFILE\" type=\"text/css\" media=\"all\">\n" } proc DOCTYPE {} { return "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">" } proc htmlhead {title header args} { set level "" if {[lindex $args end] eq "../[indexfile]"} { # XXX hack - assume same level for CSS file set level "../" } set out "[DOCTYPE]\n<HTML>\n<HEAD><TITLE>$title</TITLE>\n[CSS $level]</HEAD>\n" |
︙ | ︙ | |||
89 90 91 92 93 94 95 | lappend subs "<A HREF=\"${level}$subdir/[indexfile]\">$name</A>" } } append out "\n<H3>[join $subs { | }]</H3>" } return $out } | | > | 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | lappend subs "<A HREF=\"${level}$subdir/[indexfile]\">$name</A>" } } append out "\n<H3>[join $subs { | }]</H3>" } return $out } ## ## parsing ## proc unquote arg { return [string map [list \" {}] $arg] } proc parse-directive {line codename restname} { upvar 1 $codename code $restname rest return [regexp {^(\.[.a-zA-Z0-9]*) *(.*)} $line all code rest] } proc htmlize-text {text {charmap {}}} { # contains some extras for use in nroff->html processing # build on the list passed in, if any lappend charmap \ "–" "–" \ {&} {&} \ {\\} "\" \ {\e} "\" \ {\ } { } \ {\|} { } \ {\0} { } \ \" {"} \ |
︙ | ︙ | |||
139 140 141 142 143 144 145 146 | {\(fm} "′" \ {\(mu} "×" \ {\(mi} "−" \ {\(->} "<font size=\"+1\">→</font>" \ {\fP} {\fR} \ {\.} . \ {\(bu} "•" \ ] | > < | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | {\(fm} "′" \ {\(mu} "×" \ {\(mi} "−" \ {\(->} "<font size=\"+1\">→</font>" \ {\fP} {\fR} \ {\.} . \ {\(bu} "•" \ {\*(qo} "ô" \ ] lappend charmap {\-\|\-} -- ; # two hyphens lappend charmap {\-} - ; # a hyphen set text [htmlize-text $text $charmap] # General quoted entity regsub -all {\\N'(\d+)'} $text "\\&#\\1;" text while {[string first "\\" $text] >= 0} { |
︙ | ︙ | |||
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | } # unrecognized manerror "uncaught backslash: $text" set text [string map [list "\\" "\"] $text] } return $text } ## ## pass 2 text input and matching ## proc open-text {} { global manual set manual(text-length) [llength $manual(text)] set manual(text-pointer) 0 } proc more-text {} { global manual return [expr {$manual(text-pointer) < $manual(text-length)}] } proc next-text {} { global manual if {[more-text]} { set text [lindex $manual(text) $manual(text-pointer)] incr manual(text-pointer) return $text } manerror "read past end of text" error "fatal" } proc is-a-directive {line} { return [string match .* $line] } proc split-directive {line opname restname} { upvar 1 $opname op $restname rest set op [string range $line 0 2] set rest [string trim [string range $line 3 end]] } proc next-op-is {op restname} { global manual upvar 1 $restname rest if {[more-text]} { set text [lindex $manual(text) $manual(text-pointer)] if {[string equal -length 3 $text $op]} { set rest [string range $text 4 end] incr manual(text-pointer) return 1 } } return 0 } proc backup-text {n} { global manual if {$manual(text-pointer)-$n >= 0} { incr manual(text-pointer) -$n } } proc match-text args { global manual set nargs [llength $args] if {$manual(text-pointer) + $nargs > $manual(text-length)} { return 0 } set nback 0 | > > > > > > > > | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 | } # unrecognized manerror "uncaught backslash: $text" set text [string map [list "\\" "\"] $text] } return $text } ## ## pass 2 text input and matching ## proc open-text {} { global manual set manual(text-length) [llength $manual(text)] set manual(text-pointer) 0 } proc more-text {} { global manual return [expr {$manual(text-pointer) < $manual(text-length)}] } proc next-text {} { global manual if {[more-text]} { set text [lindex $manual(text) $manual(text-pointer)] incr manual(text-pointer) return $text } manerror "read past end of text" error "fatal" } proc is-a-directive {line} { return [string match .* $line] } proc split-directive {line opname restname} { upvar 1 $opname op $restname rest set op [string range $line 0 2] set rest [string trim [string range $line 3 end]] } proc next-op-is {op restname} { global manual upvar 1 $restname rest if {[more-text]} { set text [lindex $manual(text) $manual(text-pointer)] if {[string equal -length 3 $text $op]} { set rest [string range $text 4 end] incr manual(text-pointer) return 1 } } return 0 } proc backup-text {n} { global manual if {$manual(text-pointer)-$n >= 0} { incr manual(text-pointer) -$n } } proc match-text args { global manual set nargs [llength $args] if {$manual(text-pointer) + $nargs > $manual(text-length)} { return 0 } set nback 0 |
︙ | ︙ | |||
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | continue } backup-text $nback return 0 } return 1 } proc expand-next-text {n} { global manual return [join [lrange $manual(text) $manual(text-pointer) \ [expr {$manual(text-pointer)+$n-1}]] \n\n] } ## ## pass 2 output ## proc man-puts {text} { global manual lappend manual(output-$manual(wing-file)-$manual(name)) $text } | > > | > | 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | continue } backup-text $nback return 0 } return 1 } proc expand-next-text {n} { global manual return [join [lrange $manual(text) $manual(text-pointer) \ [expr {$manual(text-pointer)+$n-1}]] \n\n] } ## ## pass 2 output ## proc man-puts {text} { global manual lappend manual(output-$manual(wing-file)-$manual(name)) $text } ## ## build hypertext links to tables of contents ## proc long-toc {text} { global manual set here M[incr manual(section-toc-n)] set manual($manual(name)-id-$text) $here set there L[incr manual(long-toc-n)] lappend manual(section-toc) \ "<DD><A HREF=\"$manual(name).htm#$here\" NAME=\"$there\">$text</A>" return "<A NAME=\"$here\">$text</A>" } proc option-toc {name class switch} { global manual # Special case handling, oh we hate it but must do it if {[string match "*OPTIONS" $manual(section)]} { if {$manual(name) ne "ttk_widget" && ($manual(name) ne "ttk_entry" || ![string match validate* $name])} { # link the defined option into the long table of contents |
︙ | ︙ | |||
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 | set there L[incr manual(long-toc-n)] set manual(standard-option-$manual(name)-$first) \ "<A HREF=\"$manual(name).htm#$here\">$switch, $name, $class</A>" lappend manual(section-toc) \ "<DD><A HREF=\"$manual(name).htm#$here\" NAME=\"$there\">$switch, $name, $class</A>" return "<A NAME=\"$here\">$switch</A>" } proc std-option-toc {name page} { global manual if {[info exists manual(standard-option-$page-$name)]} { lappend manual(section-toc) <DD>$manual(standard-option-$page-$name) return $manual(standard-option-$page-$name) } manerror "missing reference to \"$name\" in $page.n" set here M[incr manual(section-toc-n)] set there L[incr manual(long-toc-n)] set other M$name lappend manual(section-toc) "<DD><A HREF=\"$page.htm#$other\">$name</A>" return "<A HREF=\"$page.htm#$other\">$name</A>" } ## ## process the widget option section ## in widget and options man pages ## proc output-widget-options {rest} { global manual man-puts <DL> | > > | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 | set there L[incr manual(long-toc-n)] set manual(standard-option-$manual(name)-$first) \ "<A HREF=\"$manual(name).htm#$here\">$switch, $name, $class</A>" lappend manual(section-toc) \ "<DD><A HREF=\"$manual(name).htm#$here\" NAME=\"$there\">$switch, $name, $class</A>" return "<A NAME=\"$here\">$switch</A>" } proc std-option-toc {name page} { global manual if {[info exists manual(standard-option-$page-$name)]} { lappend manual(section-toc) <DD>$manual(standard-option-$page-$name) return $manual(standard-option-$page-$name) } manerror "missing reference to \"$name\" in $page.n" set here M[incr manual(section-toc-n)] set there L[incr manual(long-toc-n)] set other M$name lappend manual(section-toc) "<DD><A HREF=\"$page.htm#$other\">$name</A>" return "<A HREF=\"$page.htm#$other\">$name</A>" } ## ## process the widget option section ## in widget and options man pages ## proc output-widget-options {rest} { global manual man-puts <DL> |
︙ | ︙ | |||
406 407 408 409 410 411 412 | } } } } man-puts </DL> lappend manual(section-toc) </DL> } | | | 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 | } } } } man-puts </DL> lappend manual(section-toc) </DL> } ## ## process .RS lists ## proc output-RS-list {} { global manual if {[next-op-is .IP rest]} { output-IP-list .RS .IP $rest |
︙ | ︙ | |||
450 451 452 453 454 455 456 | } } else { man-puts $line } } man-puts </DL> } | | | 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 | } } else { man-puts $line } } man-puts </DL> } ## ## process .IP lists which may be plain indents, ## numeric lists, or definition lists ## proc output-IP-list {context code rest} { global manual if {![string length $rest]} { |
︙ | ︙ | |||
589 590 591 592 593 594 595 596 597 598 599 600 601 602 | man-puts "$para$enddl" lappend manual(section-toc) $enddl if {$accept_RE} { manerror "missing .RE in output-IP-list" } } } ## ## handle the NAME section lines ## there's only one line in the NAME section, ## consisting of a comma separated list of names, ## followed by a hyphen and a short description. ## proc output-name {line} { | > | 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 | man-puts "$para$enddl" lappend manual(section-toc) $enddl if {$accept_RE} { manerror "missing .RE in output-IP-list" } } } ## ## handle the NAME section lines ## there's only one line in the NAME section, ## consisting of a comma separated list of names, ## followed by a hyphen and a short description. ## proc output-name {line} { |
︙ | ︙ | |||
613 614 615 616 617 618 619 620 621 622 623 624 625 626 | if {[llength $name] > 1} { manerror "name has a space: {$name}\nfrom: $line" } lappend manual(wing-toc) $name lappend manual(name-$name) $manual(wing-file)/$manual(name) } } ## ## build a cross-reference link if appropriate ## proc cross-reference {ref} { global manual remap_link_target global ensemble_commands exclude_refs_map exclude_when_followed_by_map set manname $manual(name) | > | 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 | if {[llength $name] > 1} { manerror "name has a space: {$name}\nfrom: $line" } lappend manual(wing-toc) $name lappend manual(name-$name) $manual(wing-file)/$manual(name) } } ## ## build a cross-reference link if appropriate ## proc cross-reference {ref} { global manual remap_link_target global ensemble_commands exclude_refs_map exclude_when_followed_by_map set manname $manual(name) |
︙ | ︙ | |||
721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 | return $ref } ## ## return the cross reference ## return "<A HREF=\"../$manref.htm\">$ref</A>" } ## ## reference generation errors ## proc reference-error {msg text} { global manual puts stderr "$manual(tail): $msg: {$text}" return $text } ## ## insert as many cross references into this text string as are appropriate ## proc insert-cross-references {text} { global manual set result "" | > > | 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 | return $ref } ## ## return the cross reference ## return "<A HREF=\"../$manref.htm\">$ref</A>" } ## ## reference generation errors ## proc reference-error {msg text} { global manual puts stderr "$manual(tail): $msg: {$text}" return $text } ## ## insert as many cross references into this text string as are appropriate ## proc insert-cross-references {text} { global manual set result "" |
︙ | ︙ | |||
883 884 885 886 887 888 889 890 891 892 893 894 895 896 | } end-anchor - end-bold - end-quote { return [reference-error "Out of place $invert([lindex $offsets 0])" $text] } } } } ## ## process formatting directives ## proc output-directive {line} { global manual # process format directive split-directive $line code rest | > | 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 | } end-anchor - end-bold - end-quote { return [reference-error "Out of place $invert([lindex $offsets 0])" $text] } } } } ## ## process formatting directives ## proc output-directive {line} { global manual # process format directive split-directive $line code rest |
︙ | ︙ | |||
1059 1060 1061 1062 1063 1064 1065 | output-widget-options $rest return } .IP { output-IP-list .IP .IP $rest return } | | < < < < < < < < | 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 | output-widget-options $rest return } .IP { output-IP-list .IP .IP $rest return } .PP - .sp { man-puts <P> } .RS { output-RS-list return } .br { man-puts <BR> return } .DS { if {[next-op-is .ta rest]} { # skip the leading .ta directive if it is there } if {[match-text @stuff .DE]} { set td "<td><p class=\"tablecell\">" set bodyText [string map [list \n <tr>$td \t $td] \n$stuff] |
︙ | ︙ | |||
1105 1106 1107 1108 1109 1110 1111 | if {[match-text @stuff .CE]} { man-puts <PRE>$stuff</PRE> } else { manerror "unexpected .CS format:\n[expand-next-text 2]" } return } | < < < < < < < < < < | 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 | if {[match-text @stuff .CE]} { man-puts <PRE>$stuff</PRE> } else { manerror "unexpected .CS format:\n[expand-next-text 2]" } return } .nf { if {[match-text @more .fi]} { foreach more [split $more \n] { man-puts $more<BR> } } elseif {[match-text .RS @more .RE .fi]} { man-puts <DL><DD> |
︙ | ︙ | |||
1170 1171 1172 1173 1174 1175 1176 | man-puts $more<BR> } man-puts </DL><P> } else { manerror "ignoring $line" } } | | | > | < < < > | 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 | man-puts $more<BR> } man-puts </DL><P> } else { manerror "ignoring $line" } } .RE - .DE - .CE { manerror "unexpected $code" return } .ta - .fi - .na - .ad - .UL - .ie - .el - .ne { manerror "ignoring $line" } default { manerror "unrecognized format directive: $line" } } } ## ## merge copyright listings ## proc merge-copyrights {l1 l2} { set merge {} set re1 {^Copyright +(?:\(c\)|\\\(co|©) +(\w.*?)(?:all rights reserved)?(?:\. )*$} set re2 {^(\d+) +(?:by +)?(\w.*)$} ;# date who |
︙ | ︙ | |||
1221 1222 1223 1224 1225 1226 1227 | lappend merge "Copyright © [lindex $list 0] $who" } else { lappend merge "Copyright © [lindex $list 0]-[lrange $list end end] $who" } } return [lsort -dictionary $merge] } | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 | lappend merge "Copyright © [lindex $list 0] $who" } else { lappend merge "Copyright © [lindex $list 0]-[lrange $list end end] $who" } } return [lsort -dictionary $merge] } ## ## foreach of the man pages in the section specified by ## sectionDescriptor, convert manpages into hypertext in ## the directory specified by outputDir. ## proc make-manpage-section {outputDir sectionDescriptor} { global manual overall_title tcltkdesc verbose global excluded_pages forced_index_pages process_first_patterns set LQ \u201c set RQ \u201d lassign $sectionDescriptor \ manual(wing-glob) \ manual(wing-name) \ manual(wing-file) \ manual(wing-description) set manual(wing-copyrights) {} makedirhier $outputDir/$manual(wing-file) set manual(wing-toc-fp) [open $outputDir/$manual(wing-file)/[indexfile] w] # whistle puts stderr "scanning section $manual(wing-name)" # put the entry for this section into the short table of contents puts $manual(short-toc-fp) "<DT><A HREF=\"$manual(wing-file)/[indexfile]\">$manual(wing-name)</A></DT><DD>$manual(wing-description)</DD>" # initialize the wing table of contents puts $manual(wing-toc-fp) [htmlhead $manual(wing-name) \ $manual(wing-name) $overall_title "../[indexfile]"] # initialize the short table of contents for this section set manual(wing-toc) {} # initialize the man directory for this section makedirhier $outputDir/$manual(wing-file) # initialize the long table of contents for this section set manual(long-toc-n) 1 # get the manual pages for this section set manual(pages) [lsort -dictionary [glob -nocomplain $manual(wing-glob)]] # Some pages have to go first so that their links override others foreach pat $process_first_patterns { set n [lsearch -glob $manual(pages) $pat] if {$n >= 0} { set f [lindex $manual(pages) $n] puts stderr "shuffling [file tail $f] to front of processing queue" set manual(pages) \ [linsert [lreplace $manual(pages) $n $n] 0 $f] } } # set manual(pages) [lrange $manual(pages) 0 5] foreach manual_page $manual(pages) { set manual(page) [file normalize $manual_page] # whistle if {$verbose} { puts stderr "scanning page $manual(page)" } else { puts -nonewline stderr . } set manual(tail) [file tail $manual(page)] set manual(name) [file root $manual(tail)] set manual(section) {} if {$manual(name) in $excluded_pages} { # obsolete if {!$verbose} { puts stderr "" } manerror "discarding $manual(name)" continue } set manual(infp) [open $manual(page)] set manual(text) {} set manual(partial-text) {} foreach p {.RS .DS .CS .SO} { set manual($p) 0 } set manual(stack) {} set manual(section) {} set manual(section-toc) {} set manual(section-toc-n) 1 set manual(copyrights) {} lappend manual(all-pages) $manual(wing-file)/$manual(tail) lappend manual(all-page-domains) $manual(wing-name) manreport 100 $manual(name) while {[gets $manual(infp) line] >= 0} { manreport 100 $line if {[regexp {^[`'][/\\]} $line]} { if {[regexp {Copyright (?:\(c\)|\\\(co).*$} $line copyright]} { lappend manual(copyrights) $copyright } # comment continue } if {"$line" eq {'}} { # comment continue } if {![parse-directive $line code rest]} { addbuffer $line continue } switch -exact -- $code { .if - .nr - .ti - .in - .ie - .el - .ad - .na - .so - .ne - .AS - .VE - .VS - . { # ignore continue } } switch -exact -- $code { .SH - .SS { flushbuffer if {[llength $rest] == 0} { gets $manual(infp) rest } lappend manual(text) "$code [unquote $rest]" } .TH { flushbuffer lappend manual(text) "$code [unquote $rest]" } .QW { lassign [regexp -all -inline {\"(?:[^""]+)\"|\S+} $rest] \ inQuote afterwards addbuffer $LQ [unquote $inQuote] $RQ [unquote $afterwards] } .PQ { lassign [regexp -all -inline {\"(?:[^""]+)\"|\S+} $rest] \ inQuote punctuation afterwards addbuffer ( $LQ [unquote $inQuote] $RQ \ [unquote $punctuation] ) [unquote $afterwards] } .QR { lassign [regexp -all -inline {\"(?:[^""]+)\"|\S+} $rest] \ rangeFrom rangeTo afterwards addbuffer $LQ [unquote $rangeFrom] "–" \ [unquote $rangeTo] $RQ [unquote $afterwards] } .MT { addbuffer $LQ$RQ } .HS - .UL - .ta { flushbuffer lappend manual(text) "$code [unquote $rest]" } .BS - .BE - .br - .fi - .sp - .nf { flushbuffer if {$rest ne ""} { if {!$verbose} { puts stderr "" } manerror "unexpected argument: $line" } lappend manual(text) $code } .AP { flushbuffer lappend manual(text) [concat .IP [process-text \ "[lindex $rest 0] \\fB[lindex $rest 1]\\fR ([lindex $rest 2])"]] } .IP { flushbuffer regexp {^(.*) +\d+$} $rest all rest lappend manual(text) ".IP [process-text \ [unquote [string trim $rest]]]" } .TP { flushbuffer while {[is-a-directive [set next [gets $manual(infp)]]]} { if {!$verbose} { puts stderr "" } manerror "ignoring $next after .TP" } if {"$next" ne {'}} { lappend manual(text) ".IP [process-text $next]" } } .OP { flushbuffer lassign $rest cmdName dbName dbClass lappend manual(text) [concat .OP [process-text \ "\\fB$cmdName\\fR \\fB$dbName\\fR \\fB$dbClass\\fR"]] } .PP - .LP { flushbuffer lappend manual(text) {.PP} } .RS { flushbuffer incr manual(.RS) lappend manual(text) $code } .RE { flushbuffer incr manual(.RS) -1 lappend manual(text) $code } .SO { flushbuffer incr manual(.SO) if {[llength $rest] == 0} { lappend manual(text) "$code options" } else { lappend manual(text) "$code [unquote $rest]" } } .SE { flushbuffer incr manual(.SO) -1 lappend manual(text) $code } .DS { flushbuffer incr manual(.DS) lappend manual(text) $code } .DE { flushbuffer incr manual(.DS) -1 lappend manual(text) $code } .CS { flushbuffer incr manual(.CS) lappend manual(text) $code } .CE { flushbuffer incr manual(.CS) -1 lappend manual(text) $code } .de { while {[gets $manual(infp) line] >= 0} { if {[string match "..*" $line]} { break } } } .. { if {!$verbose} { puts stderr "" } error "found .. outside of .de" } default { if {!$verbose} { puts stderr "" } flushbuffer manerror "unrecognized format directive: $line" } } } flushbuffer close $manual(infp) # fixups if {$manual(.RS) != 0} { if {!$verbose} { puts stderr "" } puts "unbalanced .RS .RE" } if {$manual(.DS) != 0} { if {!$verbose} { puts stderr "" } puts "unbalanced .DS .DE" } if {$manual(.CS) != 0} { if {!$verbose} { puts stderr "" } puts "unbalanced .CS .CE" } if {$manual(.SO) != 0} { if {!$verbose} { puts stderr "" } puts "unbalanced .SO .SE" } # output conversion open-text set haserror 0 if {[next-op-is .HS rest]} { set manual($manual(wing-file)-$manual(name)-title) \ "[join [lrange $rest 1 end] { }] [lindex $rest 0] manual page" } elseif {[next-op-is .TH rest]} { set manual($manual(wing-file)-$manual(name)-title) \ "[lindex $rest 0] manual page - [join [lrange $rest 4 end] { }]" } else { set haserror 1 if {!$verbose} { puts stderr "" } manerror "no .HS or .TH record found" } if {!$haserror} { while {[more-text]} { set line [next-text] if {[is-a-directive $line]} { output-directive $line } else { man-puts $line } } man-puts [copyout $manual(copyrights) "../"] set manual(wing-copyrights) [merge-copyrights \ $manual(wing-copyrights) $manual(copyrights)] } # # make the long table of contents for this page # set manual(toc-$manual(wing-file)-$manual(name)) \ [concat <DL> $manual(section-toc) </DL>] } if {!$verbose} { puts stderr "" } # # make the wing table of contents for the section # set width 0 foreach name $manual(wing-toc) { if {[string length $name] > $width} { set width [string length $name] } } set perline [expr {118 / $width}] set nrows [expr {([llength $manual(wing-toc)]+$perline)/$perline}] set n 0 catch {unset rows} foreach name [lsort -dictionary $manual(wing-toc)] { set tail $manual(name-$name) if {[llength $tail] > 1} { manerror "$name is defined in more than one file: $tail" set tail [lindex $tail [expr {[llength $tail]-1}]] } set tail [file tail $tail] append rows([expr {$n%$nrows}]) \ "<td> <a href=\"$tail.htm\">$name</a> </td>" incr n } puts $manual(wing-toc-fp) <table> foreach row [lsort -integer [array names rows]] { puts $manual(wing-toc-fp) <tr>$rows($row)</tr> } puts $manual(wing-toc-fp) </table> # # insert wing copyrights # puts $manual(wing-toc-fp) [copyout $manual(wing-copyrights) "../"] puts $manual(wing-toc-fp) "</BODY></HTML>" close $manual(wing-toc-fp) set manual(merge-copyrights) \ [merge-copyrights $manual(merge-copyrights) $manual(wing-copyrights)] } proc makedirhier {dir} { try { if {![file isdirectory $dir]} { file mkdir $dir } } on error msg { return -code error "cannot create directory $dir: $msg" |
︙ | ︙ |
Changes to tools/tcltk-man2html.tcl.
|
| | < < | 1 2 3 4 5 6 7 8 | #!/usr/bin/env tclsh package require Tcl 8.6 # Convert Ousterhout format man pages into highly crosslinked hypertext. # # Along the way detect many unmatched font changes and other odd things. # |
︙ | ︙ | |||
257 258 259 260 261 262 263 | close $cssfd set manual(short-toc-n) 1 set manual(short-toc-fp) [open $html/[indexfile] w] puts $manual(short-toc-fp) [htmlhead $overall_title $overall_title] puts $manual(short-toc-fp) "<DL class=\"keylist\">" set manual(merge-copyrights) {} | < < < > > | > | > > > > > > < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > > > | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 | close $cssfd set manual(short-toc-n) 1 set manual(short-toc-fp) [open $html/[indexfile] w] puts $manual(short-toc-fp) [htmlhead $overall_title $overall_title] puts $manual(short-toc-fp) "<DL class=\"keylist\">" set manual(merge-copyrights) {} foreach arg $args { # preprocess to set up subheader for the rest of the files if {![llength $arg]} { continue } lassign $arg -> name file if {[regexp {(.*)(?: Package)? Commands(?:, version .*)?} $name -> pkg]} { set name "$pkg Commands" } elseif {[regexp {(.*)(?: Package)? C API(?:, version .*)?} $name -> pkg]} { set name "$pkg C API" } lappend manual(subheader) $name $file } ## ## parse the manpages in a section of the docs (split by ## package) and construct formatted manpages ## foreach arg $args { if {[llength $arg]} { make-manpage-section $html $arg } } ## ## build the keyword index. ## if {!$verbose} { puts stderr "Assembling index" } file delete -force -- $html/Keywords makedirhier $html/Keywords set keyfp [open $html/Keywords/[indexfile] w] puts $keyfp [htmlhead "$tcltkdesc Keywords" "$tcltkdesc Keywords" \ $overall_title "../[indexfile]"] set letters {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} # Create header first |
︙ | ︙ | |||
682 683 684 685 686 687 688 | close $manual(short-toc-fp) ## ## output man pages ## unset manual(section) if {!$verbose} { | | | | 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 | close $manual(short-toc-fp) ## ## output man pages ## unset manual(section) if {!$verbose} { puts stderr "Rescanning [llength $manual(all-pages)] pages to build cross links and write out" } foreach path $manual(all-pages) wing_name $manual(all-page-domains) { set manual(wing-file) [file dirname $path] set manual(tail) [file tail $path] set manual(name) [file root $manual(tail)] try { set text $manual(output-$manual(wing-file)-$manual(name)) set ntext 0 foreach item $text { |
︙ | ︙ | |||
708 709 710 711 712 713 714 | if {$verbose} { puts stderr "rescanning page $manual(name) $ntoc/$ntext" } else { puts -nonewline stderr . } set outfd [open $html/$manual(wing-file)/$manual(name).htm w] puts $outfd [htmlhead "$manual($manual(wing-file)-$manual(name)-title)" \ | | | 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 | if {$verbose} { puts stderr "rescanning page $manual(name) $ntoc/$ntext" } else { puts -nonewline stderr . } set outfd [open $html/$manual(wing-file)/$manual(name).htm w] puts $outfd [htmlhead "$manual($manual(wing-file)-$manual(name)-title)" \ $manual(name) $wing_name "[indexfile]" \ $overall_title "../[indexfile]"] if {($ntext > 60) && ($ntoc > 32)} { foreach item $toc { puts $outfd $item } } elseif {$manual(name) in $forced_index_pages} { if {!$verbose} {puts stderr ""} |
︙ | ︙ | |||
783 784 785 786 787 788 789 | append title ", version $version" } set dir [string totitle $dir]Cmd set desc \ "The additional commands provided by the $name package." } 3 { | | | 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 | append title ", version $version" } set dir [string totitle $dir]Cmd set desc \ "The additional commands provided by the $name package." } 3 { set title "$name Package C API" if {$version ne ""} { append title ", version $version" } set dir [string totitle $dir]Lib set desc \ "The additional C functions provided by the $name package." } |
︙ | ︙ | |||
984 985 986 987 988 989 990 | [list $tcltkdir/{$appdir}/doc/*.1 "$tcltkdesc Applications" UserCmd \ "The interpreters which implement $cmdesc."] \ [plus-base $build_tcl $tcldir/doc/*.n {Tcl Commands} TclCmd \ "The commands which the <B>tclsh</B> interpreter implements."] \ [plus-base $build_tk $tkdir/doc/*.n {Tk Commands} TkCmd \ "The additional commands which the <B>wish</B> interpreter implements."] \ {*}[plus-pkgs n {*}$packageDirNameMap] \ | | | | | 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 | [list $tcltkdir/{$appdir}/doc/*.1 "$tcltkdesc Applications" UserCmd \ "The interpreters which implement $cmdesc."] \ [plus-base $build_tcl $tcldir/doc/*.n {Tcl Commands} TclCmd \ "The commands which the <B>tclsh</B> interpreter implements."] \ [plus-base $build_tk $tkdir/doc/*.n {Tk Commands} TkCmd \ "The additional commands which the <B>wish</B> interpreter implements."] \ {*}[plus-pkgs n {*}$packageDirNameMap] \ [plus-base $build_tcl $tcldir/doc/*.3 {Tcl C API} TclLib \ "The C functions which a Tcl extended C program may use."] \ [plus-base $build_tk $tkdir/doc/*.3 {Tk C API} TkLib \ "The additional C functions which a Tk extended C program may use."] \ {*}[plus-pkgs 3 {*}$packageDirNameMap] } on error {msg opts} { # On failure make sure we show what went wrong. We're not supposed # to get here though; it represents a bug in the script. puts $msg\n[dict get $opts -errorinfo] exit 1 } # Local-Variables: # mode: tcl # End: |
Changes to unix/Makefile.in.
︙ | ︙ | |||
464 465 466 467 468 469 470 | $(GENERIC_DIR)/tclOOInfo.c \ $(GENERIC_DIR)/tclOOMethod.c \ $(GENERIC_DIR)/tclOOStubInit.c STUB_SRCS = \ $(GENERIC_DIR)/tclStubLib.c \ $(GENERIC_DIR)/tclTomMathStubLib.c \ | | | 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 | $(GENERIC_DIR)/tclOOInfo.c \ $(GENERIC_DIR)/tclOOMethod.c \ $(GENERIC_DIR)/tclOOStubInit.c STUB_SRCS = \ $(GENERIC_DIR)/tclStubLib.c \ $(GENERIC_DIR)/tclTomMathStubLib.c \ $(GENERIC_DIR)/tclOOStubLib.c TOMMATH_SRCS = \ $(TOMMATH_DIR)/bncore.c \ $(TOMMATH_DIR)/bn_reverse.c \ $(TOMMATH_DIR)/bn_fast_s_mp_mul_digs.c \ $(TOMMATH_DIR)/bn_fast_s_mp_sqr.c \ $(TOMMATH_DIR)/bn_mp_add.c \ |
︙ | ︙ |
Changes to win/tclWin32Dll.c.
︙ | ︙ | |||
12 13 14 15 16 17 18 | */ #include "tclWinInt.h" #if defined(HAVE_INTRIN_H) # include <intrin.h> #endif | < < < < < < < < < < < < < < | 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | */ #include "tclWinInt.h" #if defined(HAVE_INTRIN_H) # include <intrin.h> #endif /* * The following variables keep track of information about this DLL on a * per-instance basis. Each time this DLL is loaded, it gets its own new data * segment with its own copy of all static and global information. */ static HINSTANCE hInstance; /* HINSTANCE of this DLL. */ |
︙ | ︙ | |||
62 63 64 65 66 67 68 | #if defined(_MSC_VER) && (_MSC_VER <= 1100) #define cpuid __asm __emit 0fh __asm __emit 0a2h #endif static Tcl_Encoding winTCharEncoding = NULL; | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | #if defined(_MSC_VER) && (_MSC_VER <= 1100) #define cpuid __asm __emit 0fh __asm __emit 0a2h #endif static Tcl_Encoding winTCharEncoding = NULL; /* * The following declaration is for the VC++ DLL entry point. */ BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserved); |
︙ | ︙ |
Changes to win/tclWinInt.h.
︙ | ︙ | |||
29 30 31 32 33 34 35 | #ifdef _WIN64 # define TCL_I_MODIFIER "I" #else # define TCL_I_MODIFIER "" #endif | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | #ifdef _WIN64 # define TCL_I_MODIFIER "I" #else # define TCL_I_MODIFIER "" #endif /* * Declarations of functions that are not accessible by way of the * stubs table. */ MODULE_SCOPE char TclWinDriveLetterForVolMountPoint( const TCHAR *mountPoint); |
︙ | ︙ |