Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Sync with trunk. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | standard-cli-colors |
| Files: | files | file ages | folders |
| SHA3-256: |
b81b4c6c3c099ad9afb04d75f3769c0f |
| User & Date: | florian 2025-11-26 14:12:00.000 |
Context
|
2025-11-26
| ||
| 14:16 | Change the `fossil system ls' command to work with the global `--color' option. Like this, colored output on Windows for `--color=auto' (the default if the option is omitted) is only enabled if the terminal supports VT100 escape codes. Additionally, the `NO_COLOR' environment variable allows turning off all colored output. ... (check-in: 07570b15b7 user: florian tags: standard-cli-colors) | |
| 14:12 | Sync with trunk. ... (check-in: b81b4c6c3c user: florian tags: standard-cli-colors) | |
| 11:27 | Patch the default ticket display TH1 script, as suggested by [forum:/forumpost/5e0a68ccc9|forum post 5e0a68ccc9]. ... (check-in: f0a30252d6 user: drh tags: trunk) | |
|
2025-09-26
| ||
| 12:58 | Sync with trunk. ... (check-in: c321b7e490 user: florian tags: standard-cli-colors) | |
Changes
Changes to VERSION.
|
| | | 1 | 2.28 |
Changes to auto.def.
| ︙ | ︙ | |||
93 94 95 96 97 98 99 100 101 |
# autosetup won't build jimsh0 at all if it can find tclsh itself.
# Ironically, this means we may right now be running under either jimsh0
# or a version of tclsh that we find unsuitable below!
cc-check-progs tclsh
set hbtd /usr/local/Cellar/tcl-tk
if {[string equal false [get-define TCLSH]]} {
msg-result "WARNING: 'make test' will not run here."
} else {
set v [exec sh -c "echo 'puts \$tcl_version' | tclsh"]
| > | | 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# autosetup won't build jimsh0 at all if it can find tclsh itself.
# Ironically, this means we may right now be running under either jimsh0
# or a version of tclsh that we find unsuitable below!
cc-check-progs tclsh
set hbtd /usr/local/Cellar/tcl-tk
if {[string equal false [get-define TCLSH]]} {
msg-result "WARNING: 'make test' will not run here."
set v 8.6
} else {
set v [exec sh -c "echo 'puts \$tcl_version' | tclsh"]
if {$v >= 8.6} {
msg-result "Found Tclsh version $v in the PATH."
define TCLSH tclsh
} elseif {[file isdirectory $hbtd]} {
# This is a macOS system with the Homebrew version of Tcl/Tk
# installed. Select the newest version. It won't normally be
# in the PATH to avoid shadowing /usr/bin/tclsh, and even if it
# were in the PATH, it's bad practice to put /usr/local/bin (the
|
| ︙ | ︙ | |||
624 625 626 627 628 629 630 631 632 633 634 635 636 637 |
handle-with-sqlite
define-append CFLAGS_INCLUDE {-I. -I$(SRCDIR) -I$(SRCDIR_extsrc)}; # must be after handle-with-sqlite
#
# Handle the --with-tcl flag.
#
proc handle-with-tcl {} {
set tclpath [opt-val with-tcl]
if {$tclpath eq ""} {
return
}
set tclprivatestubs [opt-bool with-tcl-private-stubs]
# Note parse-tclconfig-sh is in autosetup/local.tcl
if {$tclpath eq "1"} {
| > > > > | > | 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 |
handle-with-sqlite
define-append CFLAGS_INCLUDE {-I. -I$(SRCDIR) -I$(SRCDIR_extsrc)}; # must be after handle-with-sqlite
#
# Handle the --with-tcl flag.
#
proc handle-with-tcl {} {
global v
set tclpath [opt-val with-tcl]
if {$tclpath eq ""} {
return
}
set tclprivatestubs [opt-bool with-tcl-private-stubs]
# Note parse-tclconfig-sh is in autosetup/local.tcl
if {$tclpath eq "1"} {
if {$v >= 9.0} {
set tcldir [file dirname $::autosetup(dir)]/compat/tcl-9.0
} else {
set tcldir [file dirname $::autosetup(dir)]/compat/tcl-8.6
}
if {$tclprivatestubs} {
set tclconfig(TCL_INCLUDE_SPEC) -I$tcldir/generic
set tclconfig(TCL_VERSION) {Private Stubs}
set tclconfig(TCL_PATCH_LEVEL) {}
set tclconfig(TCL_PREFIX) $tcldir
set tclconfig(TCL_LD_FLAGS) { }
} else {
|
| ︙ | ︙ |
Added compat/tcl-9.0/generic/tcl.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 151 152 153 154 155 156 157 158 159 160 161 162 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 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 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 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 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 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 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 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 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 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 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 984 985 986 987 988 989 990 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 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 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 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 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 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 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 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 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 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 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 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 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 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 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 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 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 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 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 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 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 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 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 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 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 |
/*
* tcl.h --
*
* This header file describes the externally-visible facilities of the
* Tcl interpreter.
*
* Copyright (c) 1987-1994 The Regents of the University of California.
* Copyright (c) 1993-1996 Lucent Technologies.
* Copyright (c) 1994-1998 Sun Microsystems, Inc.
* Copyright (c) 1998-2000 by Scriptics Corporation.
* Copyright (c) 2002 by Kevin B. Kenny. All rights reserved.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*/
#ifndef _TCL
#define _TCL
/*
* For C++ compilers, use extern "C"
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* The following defines are used to indicate the various release levels.
*/
#define TCL_ALPHA_RELEASE 0
#define TCL_BETA_RELEASE 1
#define TCL_FINAL_RELEASE 2
/*
* When version numbers change here, must also go into the following files and
* update the version numbers:
*
* library/init.tcl (1 LOC patch)
* unix/configure.ac (2 LOC Major, 2 LOC minor, 1 LOC patch)
* win/configure.ac (as above)
* win/tcl.m4 (not patchlevel)
* README.md (sections 0 and 2, with and without separator)
* win/README (not patchlevel) (sections 0 and 2)
* unix/tcl.spec (1 LOC patch)
*/
#if !defined(TCL_MAJOR_VERSION)
# define TCL_MAJOR_VERSION 9
#endif
#if TCL_MAJOR_VERSION == 9
# define TCL_MINOR_VERSION 0
# define TCL_RELEASE_LEVEL TCL_FINAL_RELEASE
# define TCL_RELEASE_SERIAL 0
# define TCL_VERSION "9.0"
# define TCL_PATCH_LEVEL "9.0.0"
#endif /* TCL_MAJOR_VERSION */
#if defined(RC_INVOKED)
/*
* Utility macros: STRINGIFY takes an argument and wraps it in "" (double
* quotation marks), JOIN joins two arguments.
*/
#ifndef STRINGIFY
# define STRINGIFY(x) STRINGIFY1(x)
# define STRINGIFY1(x) #x
#endif
#ifndef JOIN
# define JOIN(a,b) JOIN1(a,b)
# define JOIN1(a,b) a##b
#endif
#endif /* RC_INVOKED */
/*
* A special definition used to allow this header file to be included from
* windows resource files so that they can obtain version information.
* RC_INVOKED is defined by default by the windows RC tool.
*
* Resource compilers don't like all the C stuff, like typedefs and function
* declarations, that occur below, so block them out.
*/
#ifndef RC_INVOKED
/*
* Special macro to define mutexes.
*/
#define TCL_DECLARE_MUTEX(name) \
static Tcl_Mutex name;
/*
* Tcl's public routine Tcl_FSSeek() uses the values SEEK_SET, SEEK_CUR, and
* SEEK_END, all #define'd by stdio.h .
*
* Also, many extensions need stdio.h, and they've grown accustomed to tcl.h
* providing it for them rather than #include-ing it themselves as they
* should, so also for their sake, we keep the #include to be consistent with
* prior Tcl releases.
*/
#include <stdio.h>
#include <stddef.h>
#if defined(__GNUC__) && (__GNUC__ > 2)
# if defined(_WIN32) && defined(__USE_MINGW_ANSI_STDIO) && __USE_MINGW_ANSI_STDIO
# define TCL_FORMAT_PRINTF(a,b) __attribute__ ((__format__ (__MINGW_PRINTF_FORMAT, a, b)))
# else
# define TCL_FORMAT_PRINTF(a,b) __attribute__ ((__format__ (__printf__, a, b)))
# endif
# define TCL_NORETURN __attribute__ ((__noreturn__))
# define TCL_NOINLINE __attribute__ ((__noinline__))
# define TCL_NORETURN1 __attribute__ ((__noreturn__))
#else
# define TCL_FORMAT_PRINTF(a,b)
# if defined(_MSC_VER)
# define TCL_NORETURN __declspec(noreturn)
# define TCL_NOINLINE __declspec(noinline)
# else
# define TCL_NORETURN /* nothing */
# define TCL_NOINLINE /* nothing */
# endif
# define TCL_NORETURN1 /* nothing */
#endif
/*
* Allow a part of Tcl's API to be explicitly marked as deprecated.
*
* Used to make TIP 330/336 generate moans even if people use the
* compatibility macros. Change your code, guys! We won't support you forever.
*/
#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
# if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5))
# define TCL_DEPRECATED_API(msg) __attribute__ ((__deprecated__ (msg)))
# else
# define TCL_DEPRECATED_API(msg) __attribute__ ((__deprecated__))
# endif
#else
# define TCL_DEPRECATED_API(msg) /* nothing portable */
#endif
/*
*----------------------------------------------------------------------------
* Macros used to declare a function to be exported by a DLL. Used by Windows,
* maps to no-op declarations on non-Windows systems. The default build on
* windows is for a DLL, which causes the DLLIMPORT and DLLEXPORT macros to be
* nonempty. To build a static library, the macro STATIC_BUILD should be
* defined.
*
* Note: when building static but linking dynamically to MSVCRT we must still
* correctly decorate the C library imported function. Use CRTIMPORT
* for this purpose. _DLL is defined by the compiler when linking to
* MSVCRT.
*/
#ifdef _WIN32
# ifdef STATIC_BUILD
# define DLLIMPORT
# define DLLEXPORT
# ifdef _DLL
# define CRTIMPORT __declspec(dllimport)
# else
# define CRTIMPORT
# endif
# else
# define DLLIMPORT __declspec(dllimport)
# define DLLEXPORT __declspec(dllexport)
# define CRTIMPORT __declspec(dllimport)
# endif
#else
# define DLLIMPORT
# if defined(__GNUC__) && __GNUC__ > 3
# define DLLEXPORT __attribute__ ((visibility("default")))
# else
# define DLLEXPORT
# endif
# define CRTIMPORT
#endif
/*
* These macros are used to control whether functions are being declared for
* import or export. If a function is being declared while it is being built
* to be included in a shared library, then it should have the DLLEXPORT
* storage class. If is being declared for use by a module that is going to
* link against the shared library, then it should have the DLLIMPORT storage
* class. If the symbol is being declared for a static build or for use from a
* stub library, then the storage class should be empty.
*
* The convention is that a macro called BUILD_xxxx, where xxxx is the name of
* a library we are building, is set on the compile line for sources that are
* to be placed in the library. When this macro is set, the storage class will
* be set to DLLEXPORT. At the end of the header file, the storage class will
* be reset to DLLIMPORT.
*/
#undef TCL_STORAGE_CLASS
#ifdef BUILD_tcl
# define TCL_STORAGE_CLASS DLLEXPORT
#else
# ifdef USE_TCL_STUBS
# define TCL_STORAGE_CLASS
# else
# define TCL_STORAGE_CLASS DLLIMPORT
# endif
#endif
#if !defined(CONST86) && !defined(TCL_NO_DEPRECATED)
# define CONST86 const
#endif
/*
* Make sure EXTERN isn't defined elsewhere.
*/
#ifdef EXTERN
# undef EXTERN
#endif /* EXTERN */
#ifdef __cplusplus
# define EXTERN extern "C" TCL_STORAGE_CLASS
#else
# define EXTERN extern TCL_STORAGE_CLASS
#endif
/*
* Miscellaneous declarations.
*/
typedef void *ClientData;
/*
* Darwin specific configure overrides (to support fat compiles, where
* configure runs only once for multiple architectures):
*/
#ifdef __APPLE__
# ifdef __LP64__
# define TCL_WIDE_INT_IS_LONG 1
# define TCL_CFG_DO64BIT 1
# else /* !__LP64__ */
# undef TCL_WIDE_INT_IS_LONG
# undef TCL_CFG_DO64BIT
# endif /* __LP64__ */
# undef HAVE_STRUCT_STAT64
#endif /* __APPLE__ */
/* Cross-compiling 32-bit on a 64-bit platform? Then our
* configure script does the wrong thing. Correct that here.
*/
#if defined(__GNUC__) && !defined(_WIN32) && !defined(__LP64__)
# undef TCL_WIDE_INT_IS_LONG
#endif
/*
* Define Tcl_WideInt to be a type that is (at least) 64-bits wide, and define
* Tcl_WideUInt to be the unsigned variant of that type (assuming that where
* we have one, we can have the other.)
*
* Also defines the following macros:
* TCL_WIDE_INT_IS_LONG - if wide ints are really longs (i.e. we're on a
* LP64 system such as modern Solaris or Linux ... not including Win64)
* Tcl_WideAsLong - forgetful converter from wideInt to long.
* Tcl_LongAsWide - sign-extending converter from long to wideInt.
* Tcl_WideAsDouble - converter from wideInt to double.
* Tcl_DoubleAsWide - converter from double to wideInt.
*
* The following invariant should hold for any long value 'longVal':
* longVal == Tcl_WideAsLong(Tcl_LongAsWide(longVal))
*/
#if !defined(TCL_WIDE_INT_TYPE) && !defined(TCL_WIDE_INT_IS_LONG) && !defined(_WIN32) && !defined(__GNUC__)
/*
* Don't know what platform it is and configure hasn't discovered what is
* going on for us. Try to guess...
*/
# include <limits.h>
# if defined(LLONG_MAX) && (LLONG_MAX == LONG_MAX)
# define TCL_WIDE_INT_IS_LONG 1
# endif
#endif
#ifndef TCL_WIDE_INT_TYPE
# define TCL_WIDE_INT_TYPE long long
#endif /* !TCL_WIDE_INT_TYPE */
typedef TCL_WIDE_INT_TYPE Tcl_WideInt;
typedef unsigned TCL_WIDE_INT_TYPE Tcl_WideUInt;
#ifndef TCL_LL_MODIFIER
# if defined(_WIN32) && (!defined(__USE_MINGW_ANSI_STDIO) || !__USE_MINGW_ANSI_STDIO)
# define TCL_LL_MODIFIER "I64"
# else
# define TCL_LL_MODIFIER "ll"
# endif
#endif /* !TCL_LL_MODIFIER */
#ifndef TCL_Z_MODIFIER
# if defined(__GNUC__) && !defined(_WIN32)
# define TCL_Z_MODIFIER "z"
# elif defined(_WIN64)
# define TCL_Z_MODIFIER TCL_LL_MODIFIER
# else
# define TCL_Z_MODIFIER ""
# endif
#endif /* !TCL_Z_MODIFIER */
#ifndef TCL_T_MODIFIER
# if defined(__GNUC__) && !defined(_WIN32)
# define TCL_T_MODIFIER "t"
# elif defined(_WIN64)
# define TCL_T_MODIFIER TCL_LL_MODIFIER
# else
# define TCL_T_MODIFIER TCL_Z_MODIFIER
# endif
#endif /* !TCL_T_MODIFIER */
#define Tcl_WideAsLong(val) ((long)((Tcl_WideInt)(val)))
#define Tcl_LongAsWide(val) ((Tcl_WideInt)((long)(val)))
#define Tcl_WideAsDouble(val) ((double)((Tcl_WideInt)(val)))
#define Tcl_DoubleAsWide(val) ((Tcl_WideInt)((double)(val)))
#if TCL_MAJOR_VERSION < 9
# ifndef Tcl_Size
typedef int Tcl_Size;
# endif
# ifndef TCL_SIZE_MAX
# define TCL_SIZE_MAX ((int)(((unsigned int)-1)>>1))
# endif
# ifndef TCL_SIZE_MODIFIER
# define TCL_SIZE_MODIFIER ""
#endif
#else
typedef ptrdiff_t Tcl_Size;
# define TCL_SIZE_MAX ((Tcl_Size)(((size_t)-1)>>1))
# define TCL_SIZE_MODIFIER TCL_T_MODIFIER
#endif /* TCL_MAJOR_VERSION */
#ifdef _WIN32
# if TCL_MAJOR_VERSION > 8 || defined(_WIN64) || defined(_USE_64BIT_TIME_T)
typedef struct __stat64 Tcl_StatBuf;
# elif defined(_USE_32BIT_TIME_T)
typedef struct _stati64 Tcl_StatBuf;
# else
typedef struct _stat32i64 Tcl_StatBuf;
# endif
#elif defined(__CYGWIN__)
typedef struct {
unsigned st_dev;
unsigned short st_ino;
unsigned short st_mode;
short st_nlink;
short st_uid;
short st_gid;
/* Here is a 2-byte gap */
unsigned st_rdev;
/* Here is a 4-byte gap */
long long st_size;
struct {long tv_sec;} st_atim;
struct {long tv_sec;} st_mtim;
struct {long tv_sec;} st_ctim;
} Tcl_StatBuf;
#else
typedef struct stat Tcl_StatBuf;
#endif
/*
*----------------------------------------------------------------------------
* Data structures defined opaquely in this module. The definitions below just
* provide dummy types.
*/
typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler;
typedef struct Tcl_Channel_ *Tcl_Channel;
typedef struct Tcl_ChannelTypeVersion_ *Tcl_ChannelTypeVersion;
typedef struct Tcl_Command_ *Tcl_Command;
typedef struct Tcl_Condition_ *Tcl_Condition;
typedef struct Tcl_Dict_ *Tcl_Dict;
typedef struct Tcl_EncodingState_ *Tcl_EncodingState;
typedef struct Tcl_Encoding_ *Tcl_Encoding;
typedef struct Tcl_Event Tcl_Event;
typedef struct Tcl_Interp Tcl_Interp;
typedef struct Tcl_InterpState_ *Tcl_InterpState;
typedef struct Tcl_LoadHandle_ *Tcl_LoadHandle;
typedef struct Tcl_Mutex_ *Tcl_Mutex;
typedef struct Tcl_Pid_ *Tcl_Pid;
typedef struct Tcl_RegExp_ *Tcl_RegExp;
typedef struct Tcl_ThreadDataKey_ *Tcl_ThreadDataKey;
typedef struct Tcl_ThreadId_ *Tcl_ThreadId;
typedef struct Tcl_TimerToken_ *Tcl_TimerToken;
typedef struct Tcl_Trace_ *Tcl_Trace;
typedef struct Tcl_Var_ *Tcl_Var;
typedef struct Tcl_ZLibStream_ *Tcl_ZlibStream;
/*
*----------------------------------------------------------------------------
* Definition of the interface to functions implementing threads. A function
* following this definition is given to each call of 'Tcl_CreateThread' and
* will be called as the main fuction of the new thread created by that call.
*/
#if defined _WIN32
typedef unsigned (__stdcall Tcl_ThreadCreateProc) (void *clientData);
#else
typedef void (Tcl_ThreadCreateProc) (void *clientData);
#endif
/*
* Threading function return types used for abstracting away platform
* differences when writing a Tcl_ThreadCreateProc. See the NewThread function
* in generic/tclThreadTest.c for it's usage.
*/
#if defined _WIN32
# define Tcl_ThreadCreateType unsigned __stdcall
# define TCL_THREAD_CREATE_RETURN return 0
#else
# define Tcl_ThreadCreateType void
# define TCL_THREAD_CREATE_RETURN
#endif
/*
* Definition of values for default stacksize and the possible flags to be
* given to Tcl_CreateThread.
*/
#define TCL_THREAD_STACK_DEFAULT (0) /* Use default size for stack. */
#define TCL_THREAD_NOFLAGS (0000) /* Standard flags, default
* behaviour. */
#define TCL_THREAD_JOINABLE (0001) /* Mark the thread as joinable. */
/*
* Flag values passed to Tcl_StringCaseMatch.
*/
#define TCL_MATCH_NOCASE (1<<0)
/*
* Flag values passed to Tcl_GetRegExpFromObj.
*/
#define TCL_REG_BASIC 000000 /* BREs (convenience). */
#define TCL_REG_EXTENDED 000001 /* EREs. */
#define TCL_REG_ADVF 000002 /* Advanced features in EREs. */
#define TCL_REG_ADVANCED 000003 /* AREs (which are also EREs). */
#define TCL_REG_QUOTE 000004 /* No special characters, none. */
#define TCL_REG_NOCASE 000010 /* Ignore case. */
#define TCL_REG_NOSUB 000020 /* Don't care about subexpressions. */
#define TCL_REG_EXPANDED 000040 /* Expanded format, white space &
* comments. */
#define TCL_REG_NLSTOP 000100 /* \n doesn't match . or [^ ] */
#define TCL_REG_NLANCH 000200 /* ^ matches after \n, $ before. */
#define TCL_REG_NEWLINE 000300 /* Newlines are line terminators. */
#define TCL_REG_CANMATCH 001000 /* Report details on partial/limited
* matches. */
/*
* Flags values passed to Tcl_RegExpExecObj.
*/
#define TCL_REG_NOTBOL 0001 /* Beginning of string does not match ^. */
#define TCL_REG_NOTEOL 0002 /* End of string does not match $. */
/*
* Structures filled in by Tcl_RegExpInfo. Note that all offset values are
* relative to the start of the match string, not the beginning of the entire
* string.
*/
typedef struct Tcl_RegExpIndices {
#if TCL_MAJOR_VERSION > 8
Tcl_Size start; /* Character offset of first character in
* match. */
Tcl_Size end; /* Character offset of first character after
* the match. */
#else
long start;
long end;
#endif
} Tcl_RegExpIndices;
typedef struct Tcl_RegExpInfo {
Tcl_Size nsubs; /* Number of subexpressions in the compiled
* expression. */
Tcl_RegExpIndices *matches; /* Array of nsubs match offset pairs. */
#if TCL_MAJOR_VERSION > 8
Tcl_Size extendStart; /* The offset at which a subsequent match
* might begin. */
#else
long extendStart;
long reserved; /* Reserved for later use. */
#endif
} Tcl_RegExpInfo;
/*
* Picky compilers complain if this typdef doesn't appear before the struct's
* reference in tclDecls.h.
*/
typedef Tcl_StatBuf *Tcl_Stat_;
typedef struct stat *Tcl_OldStat_;
/*
*----------------------------------------------------------------------------
* When a TCL command returns, the interpreter contains a result from the
* command. Programmers are strongly encouraged to use one of the functions
* Tcl_GetObjResult() or Tcl_GetStringResult() to read the interpreter's
* result. See the SetResult man page for details. Besides this result, the
* command function returns an integer code, which is one of the following:
*
* TCL_OK Command completed normally; the interpreter's result
* contains the command's result.
* TCL_ERROR The command couldn't be completed successfully; the
* interpreter's result describes what went wrong.
* TCL_RETURN The command requests that the current function return;
* the interpreter's result contains the function's
* return value.
* TCL_BREAK The command requests that the innermost loop be
* exited; the interpreter's result is meaningless.
* TCL_CONTINUE Go on to the next iteration of the current loop; the
* interpreter's result is meaningless.
* Integer return codes in the range TCL_CODE_USER_MIN to TCL_CODE_USER_MAX are
* reserved for the use of packages.
*/
#define TCL_OK 0
#define TCL_ERROR 1
#define TCL_RETURN 2
#define TCL_BREAK 3
#define TCL_CONTINUE 4
#define TCL_CODE_USER_MIN 5
#define TCL_CODE_USER_MAX 0x3fffffff /* 1073741823 */
/*
*----------------------------------------------------------------------------
* Flags to control what substitutions are performed by Tcl_SubstObj():
*/
#define TCL_SUBST_COMMANDS 001
#define TCL_SUBST_VARIABLES 002
#define TCL_SUBST_BACKSLASHES 004
#define TCL_SUBST_ALL 007
/*
* Forward declaration of Tcl_Obj to prevent an error when the forward
* reference to Tcl_Obj is encountered in the function types declared below.
*/
struct Tcl_Obj;
/*
*----------------------------------------------------------------------------
* Function types defined by Tcl:
*/
typedef int (Tcl_AppInitProc) (Tcl_Interp *interp);
typedef int (Tcl_AsyncProc) (void *clientData, Tcl_Interp *interp,
int code);
typedef void (Tcl_ChannelProc) (void *clientData, int mask);
typedef void (Tcl_CloseProc) (void *data);
typedef void (Tcl_CmdDeleteProc) (void *clientData);
typedef int (Tcl_CmdProc) (void *clientData, Tcl_Interp *interp,
int argc, const char *argv[]);
typedef void (Tcl_CmdTraceProc) (void *clientData, Tcl_Interp *interp,
int level, char *command, Tcl_CmdProc *proc,
void *cmdClientData, int argc, const char *argv[]);
typedef int (Tcl_CmdObjTraceProc) (void *clientData, Tcl_Interp *interp,
int level, const char *command, Tcl_Command commandInfo, int objc,
struct Tcl_Obj *const *objv);
typedef void (Tcl_CmdObjTraceDeleteProc) (void *clientData);
typedef void (Tcl_DupInternalRepProc) (struct Tcl_Obj *srcPtr,
struct Tcl_Obj *dupPtr);
typedef int (Tcl_EncodingConvertProc) (void *clientData, const char *src,
int srcLen, int flags, Tcl_EncodingState *statePtr, char *dst,
int dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr);
typedef void (Tcl_EncodingFreeProc) (void *clientData);
typedef int (Tcl_EventProc) (Tcl_Event *evPtr, int flags);
typedef void (Tcl_EventCheckProc) (void *clientData, int flags);
typedef int (Tcl_EventDeleteProc) (Tcl_Event *evPtr, void *clientData);
typedef void (Tcl_EventSetupProc) (void *clientData, int flags);
typedef void (Tcl_ExitProc) (void *clientData);
typedef void (Tcl_FileProc) (void *clientData, int mask);
typedef void (Tcl_FileFreeProc) (void *clientData);
typedef void (Tcl_FreeInternalRepProc) (struct Tcl_Obj *objPtr);
typedef void (Tcl_IdleProc) (void *clientData);
typedef void (Tcl_InterpDeleteProc) (void *clientData,
Tcl_Interp *interp);
typedef void (Tcl_NamespaceDeleteProc) (void *clientData);
typedef int (Tcl_ObjCmdProc) (void *clientData, Tcl_Interp *interp,
int objc, struct Tcl_Obj *const *objv);
#if TCL_MAJOR_VERSION > 8
typedef int (Tcl_ObjCmdProc2) (void *clientData, Tcl_Interp *interp,
Tcl_Size objc, struct Tcl_Obj *const *objv);
typedef int (Tcl_CmdObjTraceProc2) (void *clientData, Tcl_Interp *interp,
Tcl_Size level, const char *command, Tcl_Command commandInfo, Tcl_Size objc,
struct Tcl_Obj *const *objv);
typedef void (Tcl_FreeProc) (void *blockPtr);
#define Tcl_ExitProc Tcl_FreeProc
#define Tcl_FileFreeProc Tcl_FreeProc
#define Tcl_FileFreeProc Tcl_FreeProc
#define Tcl_EncodingFreeProc Tcl_FreeProc
#else
#define Tcl_ObjCmdProc2 Tcl_ObjCmdProc
#define Tcl_CmdObjTraceProc2 Tcl_CmdObjTraceProc
typedef void (Tcl_FreeProc) (char *blockPtr);
#endif
typedef int (Tcl_LibraryInitProc) (Tcl_Interp *interp);
typedef int (Tcl_LibraryUnloadProc) (Tcl_Interp *interp, int flags);
typedef void (Tcl_PanicProc) (const char *format, ...);
typedef void (Tcl_TcpAcceptProc) (void *callbackData, Tcl_Channel chan,
char *address, int port);
typedef void (Tcl_TimerProc) (void *clientData);
typedef int (Tcl_SetFromAnyProc) (Tcl_Interp *interp, struct Tcl_Obj *objPtr);
typedef void (Tcl_UpdateStringProc) (struct Tcl_Obj *objPtr);
typedef char * (Tcl_VarTraceProc) (void *clientData, Tcl_Interp *interp,
const char *part1, const char *part2, int flags);
typedef void (Tcl_CommandTraceProc) (void *clientData, Tcl_Interp *interp,
const char *oldName, const char *newName, int flags);
typedef void (Tcl_CreateFileHandlerProc) (int fd, int mask, Tcl_FileProc *proc,
void *clientData);
typedef void (Tcl_DeleteFileHandlerProc) (int fd);
typedef void (Tcl_AlertNotifierProc) (void *clientData);
typedef void (Tcl_ServiceModeHookProc) (int mode);
typedef void *(Tcl_InitNotifierProc) (void);
typedef void (Tcl_FinalizeNotifierProc) (void *clientData);
typedef void (Tcl_MainLoopProc) (void);
/* Abstract List functions */
typedef Tcl_Size (Tcl_ObjTypeLengthProc) (struct Tcl_Obj *listPtr);
typedef int (Tcl_ObjTypeIndexProc) (Tcl_Interp *interp, struct Tcl_Obj *listPtr,
Tcl_Size index, struct Tcl_Obj** elemObj);
typedef int (Tcl_ObjTypeSliceProc) (Tcl_Interp *interp, struct Tcl_Obj *listPtr,
Tcl_Size fromIdx, Tcl_Size toIdx, struct Tcl_Obj **newObjPtr);
typedef int (Tcl_ObjTypeReverseProc) (Tcl_Interp *interp,
struct Tcl_Obj *listPtr, struct Tcl_Obj **newObjPtr);
typedef int (Tcl_ObjTypeGetElements) (Tcl_Interp *interp,
struct Tcl_Obj *listPtr, Tcl_Size *objcptr, struct Tcl_Obj ***objvptr);
typedef struct Tcl_Obj *(Tcl_ObjTypeSetElement) (Tcl_Interp *interp,
struct Tcl_Obj *listPtr, Tcl_Size indexCount,
struct Tcl_Obj *const indexArray[], struct Tcl_Obj *valueObj);
typedef int (Tcl_ObjTypeReplaceProc) (Tcl_Interp *interp,
struct Tcl_Obj *listObj, Tcl_Size first, Tcl_Size numToDelete,
Tcl_Size numToInsert, struct Tcl_Obj *const insertObjs[]);
typedef int (Tcl_ObjTypeInOperatorProc) (Tcl_Interp *interp,
struct Tcl_Obj *valueObj, struct Tcl_Obj *listObj, int *boolResult);
#ifndef TCL_NO_DEPRECATED
# define Tcl_PackageInitProc Tcl_LibraryInitProc
# define Tcl_PackageUnloadProc Tcl_LibraryUnloadProc
#endif
/*
*----------------------------------------------------------------------------
* The following structure represents a type of object, which is a particular
* internal representation for an object plus a set of functions that provide
* standard operations on objects of that type.
*/
typedef struct Tcl_ObjType {
const char *name; /* Name of the type, e.g. "int". */
Tcl_FreeInternalRepProc *freeIntRepProc;
/* Called to free any storage for the type's
* internal rep. NULL if the internal rep does
* not need freeing. */
Tcl_DupInternalRepProc *dupIntRepProc;
/* Called to create a new object as a copy of
* an existing object. */
Tcl_UpdateStringProc *updateStringProc;
/* Called to update the string rep from the
* type's internal representation. */
Tcl_SetFromAnyProc *setFromAnyProc;
/* Called to convert the object's internal rep
* to this type. Frees the internal rep of the
* old type. Returns TCL_ERROR on failure. */
#if TCL_MAJOR_VERSION > 8
size_t version; /* Version field for future-proofing. */
/* List emulation functions - ObjType Version 1 */
Tcl_ObjTypeLengthProc *lengthProc;
/* Return the [llength] of the AbstractList */
Tcl_ObjTypeIndexProc *indexProc;
/* Return a value (Tcl_Obj) at a given index */
Tcl_ObjTypeSliceProc *sliceProc;
/* Return an AbstractList for
* [lrange $al $start $end] */
Tcl_ObjTypeReverseProc *reverseProc;
/* Return an AbstractList for [lreverse $al] */
Tcl_ObjTypeGetElements *getElementsProc;
/* Return an objv[] of all elements in the list */
Tcl_ObjTypeSetElement *setElementProc;
/* Replace the element at the indicies with the
* given valueObj. */
Tcl_ObjTypeReplaceProc *replaceProc;
/* Replace sublist with another sublist */
Tcl_ObjTypeInOperatorProc *inOperProc;
/* "in" and "ni" expr list operation.
* Determine if the given string value matches
* an element in the list. */
#endif
} Tcl_ObjType;
#if TCL_MAJOR_VERSION > 8
# define TCL_OBJTYPE_V0 0, \
0,0,0,0,0,0,0,0 /* Pre-Tcl 9 */
# define TCL_OBJTYPE_V1(a) offsetof(Tcl_ObjType, indexProc), \
a,0,0,0,0,0,0,0 /* Tcl 9 Version 1 */
# define TCL_OBJTYPE_V2(a,b,c,d,e,f,g,h) sizeof(Tcl_ObjType), \
a,b,c,d,e,f,g,h /* Tcl 9 - AbstractLists */
#else
# define TCL_OBJTYPE_V0 /* just empty */
# define TCL_OBJTYPE_V1(a) /* just empty */
# define TCL_OBJTYPE_V2(a,b,c,d,e,f,g,h) /* just empty */
#endif
/*
* The following structure stores an internal representation (internalrep) for
* a Tcl value. An internalrep is associated with an Tcl_ObjType when both
* are stored in the same Tcl_Obj. The routines of the Tcl_ObjType govern
* the handling of the internalrep.
*/
typedef union Tcl_ObjInternalRep { /* The internal representation: */
long longValue; /* - an long integer value. */
double doubleValue; /* - a double-precision floating value. */
void *otherValuePtr; /* - another, type-specific value, */
/* not used internally any more. */
Tcl_WideInt wideValue; /* - an integer value >= 64bits */
struct { /* - internal rep as two pointers. */
void *ptr1;
void *ptr2;
} twoPtrValue;
struct { /* - internal rep as a pointer and a long, */
void *ptr; /* not used internally any more. */
unsigned long value;
} ptrAndLongRep;
struct { /* - use for pointer and length reps */
void *ptr;
Tcl_Size size;
} ptrAndSize;
} Tcl_ObjInternalRep;
/*
* One of the following structures exists for each object in the Tcl system.
* An object stores a value as either a string, some internal representation,
* or both.
*/
typedef struct Tcl_Obj {
Tcl_Size refCount; /* When 0 the object will be freed. */
char *bytes; /* This points to the first byte of the
* object's string representation. The array
* must be followed by a null byte (i.e., at
* offset length) but may also contain
* embedded null characters. The array's
* storage is allocated by Tcl_Alloc. NULL means
* the string rep is invalid and must be
* regenerated from the internal rep. Clients
* should use Tcl_GetStringFromObj or
* Tcl_GetString to get a pointer to the byte
* array as a readonly value. */
Tcl_Size length; /* The number of bytes at *bytes, not
* including the terminating null. */
const Tcl_ObjType *typePtr; /* Denotes the object's type. Always
* corresponds to the type of the object's
* internal rep. NULL indicates the object has
* no internal rep (has no type). */
Tcl_ObjInternalRep internalRep;
/* The internal representation: */
} Tcl_Obj;
/*
*----------------------------------------------------------------------------
* The following definitions support Tcl's namespace facility. Note: the first
* five fields must match exactly the fields in a Namespace structure (see
* tclInt.h).
*/
typedef struct Tcl_Namespace {
char *name; /* The namespace's name within its parent
* namespace. This contains no ::'s. The name
* of the global namespace is "" although "::"
* is an synonym. */
char *fullName; /* The namespace's fully qualified name. This
* starts with ::. */
void *clientData; /* Arbitrary value associated with this
* namespace. */
Tcl_NamespaceDeleteProc *deleteProc;
/* Function invoked when deleting the
* namespace to, e.g., free clientData. */
struct Tcl_Namespace *parentPtr;
/* Points to the namespace that contains this
* one. NULL if this is the global
* namespace. */
} Tcl_Namespace;
/*
*----------------------------------------------------------------------------
* The following structure represents a call frame, or activation record. A
* call frame defines a naming context for a procedure call: its local scope
* (for local variables) and its namespace scope (used for non-local
* variables; often the global :: namespace). A call frame can also define the
* naming context for a namespace eval or namespace inscope command: the
* namespace in which the command's code should execute. The Tcl_CallFrame
* structures exist only while procedures or namespace eval/inscope's are
* being executed, and provide a Tcl call stack.
*
* A call frame is initialized and pushed using Tcl_PushCallFrame and popped
* using Tcl_PopCallFrame. Storage for a Tcl_CallFrame must be provided by the
* Tcl_PushCallFrame caller, and callers typically allocate them on the C call
* stack for efficiency. For this reason, Tcl_CallFrame is defined as a
* structure and not as an opaque token. However, most Tcl_CallFrame fields
* are hidden since applications should not access them directly; others are
* declared as "dummyX".
*
* WARNING!! The structure definition must be kept consistent with the
* CallFrame structure in tclInt.h. If you change one, change the other.
*/
typedef struct Tcl_CallFrame {
Tcl_Namespace *nsPtr; /* Current namespace for the call frame. */
int dummy1;
Tcl_Size dummy2;
void *dummy3;
void *dummy4;
void *dummy5;
Tcl_Size dummy6;
void *dummy7;
void *dummy8;
Tcl_Size dummy9;
void *dummy10;
void *dummy11;
void *dummy12;
void *dummy13;
} Tcl_CallFrame;
/*
*----------------------------------------------------------------------------
* Information about commands that is returned by Tcl_GetCommandInfo and
* passed to Tcl_SetCommandInfo. objProc is an objc/objv object-based command
* function while proc is a traditional Tcl argc/argv string-based function.
* Tcl_CreateObjCommand and Tcl_CreateCommand ensure that both objProc and
* proc are non-NULL and can be called to execute the command. However, it may
* be faster to call one instead of the other. The member isNativeObjectProc
* is set to 1 if an object-based function was registered by
* Tcl_CreateObjCommand, and to 0 if a string-based function was registered by
* Tcl_CreateCommand. The other function is typically set to a compatibility
* wrapper that does string-to-object or object-to-string argument conversions
* then calls the other function.
*/
typedef struct {
int isNativeObjectProc; /* 1 if objProc was registered by a call to
* Tcl_CreateObjCommand; 2 if objProc was registered by
* a call to Tcl_CreateObjCommand2; 0 otherwise.
* Tcl_SetCmdInfo does not modify this field. */
Tcl_ObjCmdProc *objProc; /* Command's object-based function. */
void *objClientData; /* ClientData for object proc. */
Tcl_CmdProc *proc; /* Command's string-based function. */
void *clientData; /* ClientData for string proc. */
Tcl_CmdDeleteProc *deleteProc;
/* Function to call when command is
* deleted. */
void *deleteData; /* Value to pass to deleteProc (usually the
* same as clientData). */
Tcl_Namespace *namespacePtr;/* Points to the namespace that contains this
* command. Note that Tcl_SetCmdInfo will not
* change a command's namespace; use
* TclRenameCommand or Tcl_Eval (of 'rename')
* to do that. */
Tcl_ObjCmdProc2 *objProc2; /* Command's object2-based function. */
void *objClientData2; /* ClientData for object2 proc. */
} Tcl_CmdInfo;
/*
*----------------------------------------------------------------------------
* The structure defined below is used to hold dynamic strings. The only
* fields that clients should use are string and length, accessible via the
* macros Tcl_DStringValue and Tcl_DStringLength.
*/
#define TCL_DSTRING_STATIC_SIZE 200
typedef struct Tcl_DString {
char *string; /* Points to beginning of string: either
* staticSpace below or a malloced array. */
Tcl_Size length; /* Number of bytes in string excluding
* terminating nul */
Tcl_Size spaceAvl; /* Total number of bytes available for the
* string and its terminating NULL char. */
char staticSpace[TCL_DSTRING_STATIC_SIZE];
/* Space to use in common case where string is
* small. */
} Tcl_DString;
#define Tcl_DStringLength(dsPtr) ((dsPtr)->length)
#define Tcl_DStringValue(dsPtr) ((dsPtr)->string)
/*
* Definitions for the maximum number of digits of precision that may be
* produced by Tcl_PrintDouble, and the number of bytes of buffer space
* required by Tcl_PrintDouble.
*/
#define TCL_MAX_PREC 17
#define TCL_DOUBLE_SPACE (TCL_MAX_PREC+10)
/*
* Definition for a number of bytes of buffer space sufficient to hold the
* string representation of an integer in base 10 (assuming the existence of
* 64-bit integers).
*/
#define TCL_INTEGER_SPACE (3*(int)sizeof(Tcl_WideInt))
/*
*----------------------------------------------------------------------------
* Type values returned by Tcl_GetNumberFromObj
* TCL_NUMBER_INT Representation is a Tcl_WideInt
* TCL_NUMBER_BIG Representation is an mp_int
* TCL_NUMBER_DOUBLE Representation is a double
* TCL_NUMBER_NAN Value is NaN.
*/
#define TCL_NUMBER_INT 2
#define TCL_NUMBER_BIG 3
#define TCL_NUMBER_DOUBLE 4
#define TCL_NUMBER_NAN 5
/*
* Flag values passed to Tcl_ConvertElement.
* TCL_DONT_USE_BRACES forces it not to enclose the element in braces, but to
* use backslash quoting instead.
* TCL_DONT_QUOTE_HASH disables the default quoting of the '#' character. It
* is safe to leave the hash unquoted when the element is not the first
* element of a list, and this flag can be used by the caller to indicate
* that condition.
*/
#define TCL_DONT_USE_BRACES 1
#define TCL_DONT_QUOTE_HASH 8
/*
* Flags that may be passed to Tcl_GetIndexFromObj.
* TCL_EXACT disallows abbreviated strings.
* TCL_NULL_OK allows the empty string or NULL to return TCL_OK.
* The returned value will be -1;
* TCL_INDEX_TEMP_TABLE disallows caching of lookups. A possible use case is
* a table that will not live long enough to make it worthwhile.
*/
#define TCL_EXACT 1
#define TCL_NULL_OK 32
#define TCL_INDEX_TEMP_TABLE 64
/*
* Flags that may be passed to Tcl_UniCharToUtf.
* TCL_COMBINE Combine surrogates
*/
#if TCL_MAJOR_VERSION > 8
# define TCL_COMBINE 0x1000000
#else
# define TCL_COMBINE 0
#endif
/*
*----------------------------------------------------------------------------
* Flag values passed to Tcl_RecordAndEval, Tcl_EvalObj, Tcl_EvalObjv.
* WARNING: these bit choices must not conflict with the bit choices for
* evalFlag bits in tclInt.h!
*
* Meanings:
* TCL_NO_EVAL: Just record this command
* TCL_EVAL_GLOBAL: Execute script in global namespace
* TCL_EVAL_DIRECT: Do not compile this script
* TCL_EVAL_INVOKE: Magical Tcl_EvalObjv mode for aliases/ensembles
* o Run in iPtr->lookupNsPtr or global namespace
* o Cut out of error traces
* o Don't reset the flags controlling ensemble
* error message rewriting.
* TCL_CANCEL_UNWIND: Magical Tcl_CancelEval mode that causes the
* stack for the script in progress to be
* completely unwound.
* TCL_EVAL_NOERR: Do no exception reporting at all, just return
* as the caller will report.
*/
#define TCL_NO_EVAL 0x010000
#define TCL_EVAL_GLOBAL 0x020000
#define TCL_EVAL_DIRECT 0x040000
#define TCL_EVAL_INVOKE 0x080000
#define TCL_CANCEL_UNWIND 0x100000
#define TCL_EVAL_NOERR 0x200000
/*
* Special freeProc values that may be passed to Tcl_SetResult (see the man
* page for details):
*/
#define TCL_VOLATILE ((Tcl_FreeProc *) 1)
#define TCL_STATIC ((Tcl_FreeProc *) 0)
#define TCL_DYNAMIC ((Tcl_FreeProc *) 3)
/*
* Flag values passed to variable-related functions.
* WARNING: these bit choices must not conflict with the bit choice for
* TCL_CANCEL_UNWIND, above.
*/
#define TCL_GLOBAL_ONLY 1
#define TCL_NAMESPACE_ONLY 2
#define TCL_APPEND_VALUE 4
#define TCL_LIST_ELEMENT 8
#define TCL_TRACE_READS 0x10
#define TCL_TRACE_WRITES 0x20
#define TCL_TRACE_UNSETS 0x40
#define TCL_TRACE_DESTROYED 0x80
#define TCL_LEAVE_ERR_MSG 0x200
#define TCL_TRACE_ARRAY 0x800
/* Indicate the semantics of the result of a trace. */
#define TCL_TRACE_RESULT_DYNAMIC 0x8000
#define TCL_TRACE_RESULT_OBJECT 0x10000
/*
* Flag values for ensemble commands.
*/
#define TCL_ENSEMBLE_PREFIX 0x02/* Flag value to say whether to allow
* unambiguous prefixes of commands or to
* require exact matches for command names. */
/*
* Flag values passed to command-related functions.
*/
#define TCL_TRACE_RENAME 0x2000
#define TCL_TRACE_DELETE 0x4000
#define TCL_ALLOW_INLINE_COMPILATION 0x20000
/*
* Types for linked variables:
*/
#define TCL_LINK_INT 1
#define TCL_LINK_DOUBLE 2
#define TCL_LINK_BOOLEAN 3
#define TCL_LINK_STRING 4
#define TCL_LINK_WIDE_INT 5
#define TCL_LINK_CHAR 6
#define TCL_LINK_UCHAR 7
#define TCL_LINK_SHORT 8
#define TCL_LINK_USHORT 9
#define TCL_LINK_UINT 10
#define TCL_LINK_LONG ((sizeof(long) != sizeof(int)) ? TCL_LINK_WIDE_INT : TCL_LINK_INT)
#define TCL_LINK_ULONG ((sizeof(long) != sizeof(int)) ? TCL_LINK_WIDE_UINT : TCL_LINK_UINT)
#define TCL_LINK_FLOAT 13
#define TCL_LINK_WIDE_UINT 14
#define TCL_LINK_CHARS 15
#define TCL_LINK_BINARY 16
#define TCL_LINK_READ_ONLY 0x80
/*
*----------------------------------------------------------------------------
* Forward declarations of Tcl_HashTable and related types.
*/
#ifndef TCL_HASH_TYPE
#if TCL_MAJOR_VERSION > 8
# define TCL_HASH_TYPE size_t
#else
# define TCL_HASH_TYPE unsigned
#endif
#endif
typedef struct Tcl_HashKeyType Tcl_HashKeyType;
typedef struct Tcl_HashTable Tcl_HashTable;
typedef struct Tcl_HashEntry Tcl_HashEntry;
typedef TCL_HASH_TYPE (Tcl_HashKeyProc) (Tcl_HashTable *tablePtr, void *keyPtr);
typedef int (Tcl_CompareHashKeysProc) (void *keyPtr, Tcl_HashEntry *hPtr);
typedef Tcl_HashEntry * (Tcl_AllocHashEntryProc) (Tcl_HashTable *tablePtr,
void *keyPtr);
typedef void (Tcl_FreeHashEntryProc) (Tcl_HashEntry *hPtr);
/*
* Structure definition for an entry in a hash table. No-one outside Tcl
* should access any of these fields directly; use the macros defined below.
*/
struct Tcl_HashEntry {
Tcl_HashEntry *nextPtr; /* Pointer to next entry in this hash bucket,
* or NULL for end of chain. */
Tcl_HashTable *tablePtr; /* Pointer to table containing entry. */
size_t hash; /* Hash value. */
void *clientData; /* Application stores something here with
* Tcl_SetHashValue. */
union { /* Key has one of these forms: */
char *oneWordValue; /* One-word value for key. */
Tcl_Obj *objPtr; /* Tcl_Obj * key value. */
int words[1]; /* Multiple integer words for key. The actual
* size will be as large as necessary for this
* table's keys. */
char string[1]; /* String for key. The actual size will be as
* large as needed to hold the key. */
} key; /* MUST BE LAST FIELD IN RECORD!! */
};
/*
* Flags used in Tcl_HashKeyType.
*
* TCL_HASH_KEY_RANDOMIZE_HASH -
* There are some things, pointers for example
* which don't hash well because they do not use
* the lower bits. If this flag is set then the
* hash table will attempt to rectify this by
* randomising the bits and then using the upper
* N bits as the index into the table.
* TCL_HASH_KEY_SYSTEM_HASH - If this flag is set then all memory internally
* allocated for the hash table that is not for an
* entry will use the system heap.
* TCL_HASH_KEY_DIRECT_COMPARE -
* Allows fast comparison for hash keys directly
* by compare of their key.oneWordValue values,
* before call of compareKeysProc (much slower
* than a direct compare, so it is speed-up only
* flag). Don't use it if keys contain values rather
* than pointers.
*/
#define TCL_HASH_KEY_RANDOMIZE_HASH 0x1
#define TCL_HASH_KEY_SYSTEM_HASH 0x2
#define TCL_HASH_KEY_DIRECT_COMPARE 0x4
/*
* Structure definition for the methods associated with a hash table key type.
*/
#define TCL_HASH_KEY_TYPE_VERSION 1
struct Tcl_HashKeyType {
int version; /* Version of the table. If this structure is
* extended in future then the version can be
* used to distinguish between different
* structures. */
int flags; /* Flags, see above for details. */
Tcl_HashKeyProc *hashKeyProc;
/* Calculates a hash value for the key. If
* this is NULL then the pointer itself is
* used as a hash value. */
Tcl_CompareHashKeysProc *compareKeysProc;
/* Compares two keys and returns zero if they
* do not match, and non-zero if they do. If
* this is NULL then the pointers are
* compared. */
Tcl_AllocHashEntryProc *allocEntryProc;
/* Called to allocate memory for a new entry,
* i.e. if the key is a string then this could
* allocate a single block which contains
* enough space for both the entry and the
* string. Only the key field of the allocated
* Tcl_HashEntry structure needs to be filled
* in. If something else needs to be done to
* the key, i.e. incrementing a reference
* count then that should be done by this
* function. If this is NULL then Tcl_Alloc is
* used to allocate enough space for a
* Tcl_HashEntry and the key pointer is
* assigned to key.oneWordValue. */
Tcl_FreeHashEntryProc *freeEntryProc;
/* Called to free memory associated with an
* entry. If something else needs to be done
* to the key, i.e. decrementing a reference
* count then that should be done by this
* function. If this is NULL then Tcl_Free is
* used to free the Tcl_HashEntry. */
};
/*
* Structure definition for a hash table. Must be in tcl.h so clients can
* allocate space for these structures, but clients should never access any
* fields in this structure.
*/
#define TCL_SMALL_HASH_TABLE 4
struct Tcl_HashTable {
Tcl_HashEntry **buckets; /* Pointer to bucket array. Each element
* points to first entry in bucket's hash
* chain, or NULL. */
Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE];
/* Bucket array used for small tables (to
* avoid mallocs and frees). */
Tcl_Size numBuckets; /* Total number of buckets allocated at
* **bucketPtr. */
Tcl_Size numEntries; /* Total number of entries present in
* table. */
Tcl_Size rebuildSize; /* Enlarge table when numEntries gets to be
* this large. */
#if TCL_MAJOR_VERSION > 8
size_t mask; /* Mask value used in hashing function. */
#endif
int downShift; /* Shift count used in hashing function.
* Designed to use high-order bits of
* randomized keys. */
#if TCL_MAJOR_VERSION < 9
int mask; /* Mask value used in hashing function. */
#endif
int keyType; /* Type of keys used in this table. It's
* either TCL_CUSTOM_KEYS, TCL_STRING_KEYS,
* TCL_ONE_WORD_KEYS, or an integer giving the
* number of ints that is the size of the
* key. */
Tcl_HashEntry *(*findProc) (Tcl_HashTable *tablePtr, const char *key);
Tcl_HashEntry *(*createProc) (Tcl_HashTable *tablePtr, const char *key,
int *newPtr);
const Tcl_HashKeyType *typePtr;
/* Type of the keys used in the
* Tcl_HashTable. */
};
/*
* Structure definition for information used to keep track of searches through
* hash tables:
*/
typedef struct Tcl_HashSearch {
Tcl_HashTable *tablePtr; /* Table being searched. */
Tcl_Size nextIndex; /* Index of next bucket to be enumerated after
* present one. */
Tcl_HashEntry *nextEntryPtr;/* Next entry to be enumerated in the current
* bucket. */
} Tcl_HashSearch;
/*
* Acceptable key types for hash tables:
*
* TCL_STRING_KEYS: The keys are strings, they are copied into the
* entry.
* TCL_ONE_WORD_KEYS: The keys are pointers, the pointer is stored
* in the entry.
* TCL_CUSTOM_TYPE_KEYS: The keys are arbitrary types which are copied
* into the entry.
* TCL_CUSTOM_PTR_KEYS: The keys are pointers to arbitrary types, the
* pointer is stored in the entry.
*
* While maintaining binary compatibility the above have to be distinct values
* as they are used to differentiate between old versions of the hash table
* which don't have a typePtr and new ones which do. Once binary compatibility
* is discarded in favour of making more wide spread changes TCL_STRING_KEYS
* can be the same as TCL_CUSTOM_TYPE_KEYS, and TCL_ONE_WORD_KEYS can be the
* same as TCL_CUSTOM_PTR_KEYS because they simply determine how the key is
* accessed from the entry and not the behaviour.
*/
#define TCL_STRING_KEYS (0)
#define TCL_ONE_WORD_KEYS (1)
#define TCL_CUSTOM_TYPE_KEYS (-2)
#define TCL_CUSTOM_PTR_KEYS (-1)
/*
* Structure definition for information used to keep track of searches through
* dictionaries. These fields should not be accessed by code outside
* tclDictObj.c
*/
typedef struct {
void *next; /* Search position for underlying hash
* table. */
TCL_HASH_TYPE epoch; /* Epoch marker for dictionary being searched,
* or 0 if search has terminated. */
Tcl_Dict dictionaryPtr; /* Reference to dictionary being searched. */
} Tcl_DictSearch;
/*
*----------------------------------------------------------------------------
* Flag values to pass to Tcl_DoOneEvent to disable searches for some kinds of
* events:
*/
#define TCL_DONT_WAIT (1<<1)
#define TCL_WINDOW_EVENTS (1<<2)
#define TCL_FILE_EVENTS (1<<3)
#define TCL_TIMER_EVENTS (1<<4)
#define TCL_IDLE_EVENTS (1<<5) /* WAS 0x10 ???? */
#define TCL_ALL_EVENTS (~TCL_DONT_WAIT)
/*
* The following structure defines a generic event for the Tcl event system.
* These are the things that are queued in calls to Tcl_QueueEvent and
* serviced later by Tcl_DoOneEvent. There can be many different kinds of
* events with different fields, corresponding to window events, timer events,
* etc. The structure for a particular event consists of a Tcl_Event header
* followed by additional information specific to that event.
*/
struct Tcl_Event {
Tcl_EventProc *proc; /* Function to call to service this event. */
struct Tcl_Event *nextPtr; /* Next in list of pending events, or NULL. */
};
/*
* Positions to pass to Tcl_QueueEvent/Tcl_ThreadQueueEvent:
*/
typedef enum {
TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, TCL_QUEUE_MARK,
TCL_QUEUE_ALERT_IF_EMPTY=4
} Tcl_QueuePosition;
/*
* Values to pass to Tcl_SetServiceMode to specify the behavior of notifier
* event routines.
*/
#define TCL_SERVICE_NONE 0
#define TCL_SERVICE_ALL 1
/*
* The following structure keeps is used to hold a time value, either as an
* absolute time (the number of seconds from the epoch) or as an elapsed time.
* On Unix systems the epoch is Midnight Jan 1, 1970 GMT.
*/
typedef struct Tcl_Time {
#if TCL_MAJOR_VERSION > 8
long long sec; /* Seconds. */
#else
long sec; /* Seconds. */
#endif
#if defined(_CYGWIN_) && TCL_MAJOR_VERSION > 8
int usec; /* Microseconds. */
#else
long usec; /* Microseconds. */
#endif
} Tcl_Time;
typedef void (Tcl_SetTimerProc) (const Tcl_Time *timePtr);
typedef int (Tcl_WaitForEventProc) (const Tcl_Time *timePtr);
/*
* TIP #233 (Virtualized Time)
*/
typedef void (Tcl_GetTimeProc) (Tcl_Time *timebuf, void *clientData);
typedef void (Tcl_ScaleTimeProc) (Tcl_Time *timebuf, void *clientData);
/*
*----------------------------------------------------------------------------
* Bits to pass to Tcl_CreateFileHandler and Tcl_CreateChannelHandler to
* indicate what sorts of events are of interest:
*/
#define TCL_READABLE (1<<1)
#define TCL_WRITABLE (1<<2)
#define TCL_EXCEPTION (1<<3)
/*
* Flag values to pass to Tcl_OpenCommandChannel to indicate the disposition
* of the stdio handles. TCL_STDIN, TCL_STDOUT, TCL_STDERR, are also used in
* Tcl_GetStdChannel.
*/
#define TCL_STDIN (1<<1)
#define TCL_STDOUT (1<<2)
#define TCL_STDERR (1<<3)
#define TCL_ENFORCE_MODE (1<<4)
/*
* Bits passed to Tcl_DriverClose2Proc to indicate which side of a channel
* should be closed.
*/
#define TCL_CLOSE_READ (1<<1)
#define TCL_CLOSE_WRITE (1<<2)
/*
* Value to use as the closeProc for a channel that supports the close2Proc
* interface.
*/
#if TCL_MAJOR_VERSION > 8
# define TCL_CLOSE2PROC NULL
#else
# define TCL_CLOSE2PROC ((void *) 1)
#endif
/*
* Channel version tag. This was introduced in 8.3.2/8.4.
*/
#define TCL_CHANNEL_VERSION_5 ((Tcl_ChannelTypeVersion) 0x5)
/*
* TIP #218: Channel Actions, Ids for Tcl_DriverThreadActionProc.
*/
#define TCL_CHANNEL_THREAD_INSERT (0)
#define TCL_CHANNEL_THREAD_REMOVE (1)
/*
* Typedefs for the various operations in a channel type:
*/
typedef int (Tcl_DriverBlockModeProc) (void *instanceData, int mode);
typedef void Tcl_DriverCloseProc;
typedef int (Tcl_DriverClose2Proc) (void *instanceData,
Tcl_Interp *interp, int flags);
typedef int (Tcl_DriverInputProc) (void *instanceData, char *buf,
int toRead, int *errorCodePtr);
typedef int (Tcl_DriverOutputProc) (void *instanceData,
const char *buf, int toWrite, int *errorCodePtr);
typedef void Tcl_DriverSeekProc;
typedef int (Tcl_DriverSetOptionProc) (void *instanceData,
Tcl_Interp *interp, const char *optionName,
const char *value);
typedef int (Tcl_DriverGetOptionProc) (void *instanceData,
Tcl_Interp *interp, const char *optionName,
Tcl_DString *dsPtr);
typedef void (Tcl_DriverWatchProc) (void *instanceData, int mask);
typedef int (Tcl_DriverGetHandleProc) (void *instanceData,
int direction, void **handlePtr);
typedef int (Tcl_DriverFlushProc) (void *instanceData);
typedef int (Tcl_DriverHandlerProc) (void *instanceData,
int interestMask);
typedef long long (Tcl_DriverWideSeekProc) (void *instanceData,
long long offset, int mode, int *errorCodePtr);
/*
* TIP #218, Channel Thread Actions
*/
typedef void (Tcl_DriverThreadActionProc) (void *instanceData,
int action);
/*
* TIP #208, File Truncation (etc.)
*/
typedef int (Tcl_DriverTruncateProc) (void *instanceData,
long long length);
/*
* struct Tcl_ChannelType:
*
* One such structure exists for each type (kind) of channel. It collects
* together in one place all the functions that are part of the specific
* channel type.
*
* It is recommend that the Tcl_Channel* functions are used to access elements
* of this structure, instead of direct accessing.
*/
typedef struct Tcl_ChannelType {
const char *typeName; /* The name of the channel type in Tcl
* commands. This storage is owned by channel
* type. */
Tcl_ChannelTypeVersion version;
/* Version of the channel type. */
void *closeProc; /* Not used any more. */
Tcl_DriverInputProc *inputProc;
/* Function to call for input on channel. */
Tcl_DriverOutputProc *outputProc;
/* Function to call for output on channel. */
void *seekProc; /* Not used any more. */
Tcl_DriverSetOptionProc *setOptionProc;
/* Set an option on a channel. */
Tcl_DriverGetOptionProc *getOptionProc;
/* Get an option from a channel. */
Tcl_DriverWatchProc *watchProc;
/* Set up the notifier to watch for events on
* this channel. */
Tcl_DriverGetHandleProc *getHandleProc;
/* Get an OS handle from the channel or NULL
* if not supported. */
Tcl_DriverClose2Proc *close2Proc;
/* Function to call to close the channel if
* the device supports closing the read &
* write sides independently. */
Tcl_DriverBlockModeProc *blockModeProc;
/* Set blocking mode for the raw channel. May
* be NULL. */
Tcl_DriverFlushProc *flushProc;
/* Function to call to flush a channel. May be
* NULL. */
Tcl_DriverHandlerProc *handlerProc;
/* Function to call to handle a channel event.
* This will be passed up the stacked channel
* chain. */
Tcl_DriverWideSeekProc *wideSeekProc;
/* Function to call to seek on the channel
* which can handle 64-bit offsets. May be
* NULL, and must be NULL if seekProc is
* NULL. */
Tcl_DriverThreadActionProc *threadActionProc;
/* Function to call to notify the driver of
* thread specific activity for a channel. May
* be NULL. */
Tcl_DriverTruncateProc *truncateProc;
/* Function to call to truncate the underlying
* file to a particular length. May be NULL if
* the channel does not support truncation. */
} Tcl_ChannelType;
/*
* The following flags determine whether the blockModeProc above should set
* the channel into blocking or nonblocking mode. They are passed as arguments
* to the blockModeProc function in the above structure.
*/
#define TCL_MODE_BLOCKING 0 /* Put channel into blocking mode. */
#define TCL_MODE_NONBLOCKING 1 /* Put channel into nonblocking
* mode. */
/*
*----------------------------------------------------------------------------
* Enum for different types of file paths.
*/
typedef enum Tcl_PathType {
TCL_PATH_ABSOLUTE,
TCL_PATH_RELATIVE,
TCL_PATH_VOLUME_RELATIVE
} Tcl_PathType;
/*
* The following structure is used to pass glob type data amongst the various
* glob routines and Tcl_FSMatchInDirectory.
*/
typedef struct Tcl_GlobTypeData {
int type; /* Corresponds to bcdpfls as in 'find -t'. */
int perm; /* Corresponds to file permissions. */
Tcl_Obj *macType; /* Acceptable Mac type. */
Tcl_Obj *macCreator; /* Acceptable Mac creator. */
} Tcl_GlobTypeData;
/*
* Type and permission definitions for glob command.
*/
#define TCL_GLOB_TYPE_BLOCK (1<<0)
#define TCL_GLOB_TYPE_CHAR (1<<1)
#define TCL_GLOB_TYPE_DIR (1<<2)
#define TCL_GLOB_TYPE_PIPE (1<<3)
#define TCL_GLOB_TYPE_FILE (1<<4)
#define TCL_GLOB_TYPE_LINK (1<<5)
#define TCL_GLOB_TYPE_SOCK (1<<6)
#define TCL_GLOB_TYPE_MOUNT (1<<7)
#define TCL_GLOB_PERM_RONLY (1<<0)
#define TCL_GLOB_PERM_HIDDEN (1<<1)
#define TCL_GLOB_PERM_R (1<<2)
#define TCL_GLOB_PERM_W (1<<3)
#define TCL_GLOB_PERM_X (1<<4)
/*
* Flags for the unload callback function.
*/
#define TCL_UNLOAD_DETACH_FROM_INTERPRETER (1<<0)
#define TCL_UNLOAD_DETACH_FROM_PROCESS (1<<1)
/*
* Typedefs for the various filesystem operations:
*/
typedef int (Tcl_FSStatProc) (Tcl_Obj *pathPtr, Tcl_StatBuf *buf);
typedef int (Tcl_FSAccessProc) (Tcl_Obj *pathPtr, int mode);
typedef Tcl_Channel (Tcl_FSOpenFileChannelProc) (Tcl_Interp *interp,
Tcl_Obj *pathPtr, int mode, int permissions);
typedef int (Tcl_FSMatchInDirectoryProc) (Tcl_Interp *interp, Tcl_Obj *result,
Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types);
typedef Tcl_Obj * (Tcl_FSGetCwdProc) (Tcl_Interp *interp);
typedef int (Tcl_FSChdirProc) (Tcl_Obj *pathPtr);
typedef int (Tcl_FSLstatProc) (Tcl_Obj *pathPtr, Tcl_StatBuf *buf);
typedef int (Tcl_FSCreateDirectoryProc) (Tcl_Obj *pathPtr);
typedef int (Tcl_FSDeleteFileProc) (Tcl_Obj *pathPtr);
typedef int (Tcl_FSCopyDirectoryProc) (Tcl_Obj *srcPathPtr,
Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr);
typedef int (Tcl_FSCopyFileProc) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr);
typedef int (Tcl_FSRemoveDirectoryProc) (Tcl_Obj *pathPtr, int recursive,
Tcl_Obj **errorPtr);
typedef int (Tcl_FSRenameFileProc) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr);
typedef void (Tcl_FSUnloadFileProc) (Tcl_LoadHandle loadHandle);
typedef Tcl_Obj * (Tcl_FSListVolumesProc) (void);
/* We have to declare the utime structure here. */
struct utimbuf;
typedef int (Tcl_FSUtimeProc) (Tcl_Obj *pathPtr, struct utimbuf *tval);
typedef int (Tcl_FSNormalizePathProc) (Tcl_Interp *interp, Tcl_Obj *pathPtr,
int nextCheckpoint);
typedef int (Tcl_FSFileAttrsGetProc) (Tcl_Interp *interp, int index,
Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef);
typedef const char *const * (Tcl_FSFileAttrStringsProc) (Tcl_Obj *pathPtr,
Tcl_Obj **objPtrRef);
typedef int (Tcl_FSFileAttrsSetProc) (Tcl_Interp *interp, int index,
Tcl_Obj *pathPtr, Tcl_Obj *objPtr);
typedef Tcl_Obj * (Tcl_FSLinkProc) (Tcl_Obj *pathPtr, Tcl_Obj *toPtr,
int linkType);
typedef int (Tcl_FSLoadFileProc) (Tcl_Interp *interp, Tcl_Obj *pathPtr,
Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr);
typedef int (Tcl_FSPathInFilesystemProc) (Tcl_Obj *pathPtr,
void **clientDataPtr);
typedef Tcl_Obj * (Tcl_FSFilesystemPathTypeProc) (Tcl_Obj *pathPtr);
typedef Tcl_Obj * (Tcl_FSFilesystemSeparatorProc) (Tcl_Obj *pathPtr);
#define Tcl_FSFreeInternalRepProc Tcl_FreeProc
typedef void *(Tcl_FSDupInternalRepProc) (void *clientData);
typedef Tcl_Obj * (Tcl_FSInternalToNormalizedProc) (void *clientData);
typedef void *(Tcl_FSCreateInternalRepProc) (Tcl_Obj *pathPtr);
typedef struct Tcl_FSVersion_ *Tcl_FSVersion;
/*
*----------------------------------------------------------------------------
* Data structures related to hooking into the filesystem
*/
/*
* Filesystem version tag. This was introduced in 8.4.
*/
#define TCL_FILESYSTEM_VERSION_1 ((Tcl_FSVersion) 0x1)
/*
* struct Tcl_Filesystem:
*
* One such structure exists for each type (kind) of filesystem. It collects
* together the functions that form the interface for a particulr the
* filesystem. Tcl always accesses the filesystem through one of these
* structures.
*
* Not all entries need be non-NULL; any which are NULL are simply ignored.
* However, a complete filesystem should provide all of these functions. The
* explanations in the structure show the importance of each function.
*/
typedef struct Tcl_Filesystem {
const char *typeName; /* The name of the filesystem. */
Tcl_Size structureLength; /* Length of this structure, so future binary
* compatibility can be assured. */
Tcl_FSVersion version; /* Version of the filesystem type. */
Tcl_FSPathInFilesystemProc *pathInFilesystemProc;
/* Determines whether the pathname is in this
* filesystem. This is the most important
* filesystem function. */
Tcl_FSDupInternalRepProc *dupInternalRepProc;
/* Duplicates the internal handle of the node.
* If it is NULL, the filesystem is less
* performant. */
Tcl_FSFreeInternalRepProc *freeInternalRepProc;
/* Frees the internal handle of the node. NULL
* only if there is no need to free resources
* used for the internal handle. */
Tcl_FSInternalToNormalizedProc *internalToNormalizedProc;
/* Converts the internal handle to a normalized
* path. NULL if the filesystem creates nodes
* having no pathname. */
Tcl_FSCreateInternalRepProc *createInternalRepProc;
/* Creates an internal handle for a pathname.
* May be NULL if pathnames have no internal
* handle or if pathInFilesystemProc always
* immediately creates an internal
* representation for pathnames in the
* filesystem. */
Tcl_FSNormalizePathProc *normalizePathProc;
/* Normalizes a path. Should be implemented if
* the filesystems supports multiple paths to
* the same node. */
Tcl_FSFilesystemPathTypeProc *filesystemPathTypeProc;
/* Determines the type of a path in this
* filesystem. May be NULL. */
Tcl_FSFilesystemSeparatorProc *filesystemSeparatorProc;
/* Produces the separator character(s) for this
* filesystem. Must not be NULL. */
Tcl_FSStatProc *statProc; /* Called by 'Tcl_FSStat()'. Provided by any
* reasonable filesystem. */
Tcl_FSAccessProc *accessProc;
/* Called by 'Tcl_FSAccess()'. Implemented by
* any reasonable filesystem. */
Tcl_FSOpenFileChannelProc *openFileChannelProc;
/* Called by 'Tcl_FSOpenFileChannel()'.
* Provided by any reasonable filesystem. */
Tcl_FSMatchInDirectoryProc *matchInDirectoryProc;
/* Called by 'Tcl_FSMatchInDirectory()'. NULL
* if the filesystem does not support glob or
* recursive copy. */
Tcl_FSUtimeProc *utimeProc; /* Called by 'Tcl_FSUtime()', by 'file
* mtime' to set (not read) times, 'file
* atime', and the open-r/open-w/fcopy variant
* of 'file copy'. */
Tcl_FSLinkProc *linkProc; /* Called by 'Tcl_FSLink()'. NULL if reading or
* creating links is not supported. */
Tcl_FSListVolumesProc *listVolumesProc;
/* Lists filesystem volumes added by this
* filesystem. NULL if the filesystem does not
* use volumes. */
Tcl_FSFileAttrStringsProc *fileAttrStringsProc;
/* List all valid attributes strings. NULL if
* the filesystem does not support the 'file
* attributes' command. Can be used to attach
* arbitrary additional data to files in a
* filesystem. */
Tcl_FSFileAttrsGetProc *fileAttrsGetProc;
/* Called by 'Tcl_FSFileAttrsGet()' and by
* 'file attributes'. */
Tcl_FSFileAttrsSetProc *fileAttrsSetProc;
/* Called by 'Tcl_FSFileAttrsSet()' and by
* 'file attributes'. */
Tcl_FSCreateDirectoryProc *createDirectoryProc;
/* Called by 'Tcl_FSCreateDirectory()'. May be
* NULL if the filesystem is read-only. */
Tcl_FSRemoveDirectoryProc *removeDirectoryProc;
/* Called by 'Tcl_FSRemoveDirectory()'. May be
* NULL if the filesystem is read-only. */
Tcl_FSDeleteFileProc *deleteFileProc;
/* Called by 'Tcl_FSDeleteFile()' May be NULL
* if the filesystem is is read-only. */
Tcl_FSCopyFileProc *copyFileProc;
/* Called by 'Tcl_FSCopyFile()'. If NULL, for
* a copy operation at the script level (not
* C) Tcl uses open-r, open-w and fcopy. */
Tcl_FSRenameFileProc *renameFileProc;
/* Called by 'Tcl_FSRenameFile()'. If NULL, for
* a rename operation at the script level (not
* C) Tcl performs a copy operation followed
* by a delete operation. */
Tcl_FSCopyDirectoryProc *copyDirectoryProc;
/* Called by 'Tcl_FSCopyDirectory()'. If NULL,
* for a copy operation at the script level
* (not C) Tcl recursively creates directories
* and copies files. */
Tcl_FSLstatProc *lstatProc; /* Called by 'Tcl_FSLstat()'. If NULL, Tcl
* attempts to use 'statProc' instead. */
Tcl_FSLoadFileProc *loadFileProc;
/* Called by 'Tcl_FSLoadFile()'. If NULL, Tcl
* performs a copy to a temporary file in the
* native filesystem and then calls
* Tcl_FSLoadFile() on that temporary copy. */
Tcl_FSGetCwdProc *getCwdProc;
/* Called by 'Tcl_FSGetCwd()'. Normally NULL.
* Usually only called once: If 'getcwd' is
* called before 'chdir' is ever called. */
Tcl_FSChdirProc *chdirProc; /* Called by 'Tcl_FSChdir()'. For a virtual
* filesystem, chdirProc just returns zero
* (success) if the pathname is a valid
* directory, and some other value otherwise.
* For A real filesystem, chdirProc performs
* the correct action, e.g. calls the system
* 'chdir' function. If not implemented, then
* 'cd' and 'pwd' fail for a pathname in this
* filesystem. On success Tcl stores the
* pathname for use by GetCwd. If NULL, Tcl
* performs records the pathname as the new
* current directory if it passes a series of
* directory access checks. */
} Tcl_Filesystem;
/*
* The following definitions are used as values for the 'linkAction' flag to
* Tcl_FSLink, or the linkProc of any filesystem. Any combination of flags can
* be given. For link creation, the linkProc should create a link which
* matches any of the types given.
*
* TCL_CREATE_SYMBOLIC_LINK - Create a symbolic or soft link.
* TCL_CREATE_HARD_LINK - Create a hard link.
*/
#define TCL_CREATE_SYMBOLIC_LINK 0x01
#define TCL_CREATE_HARD_LINK 0x02
/*
*----------------------------------------------------------------------------
* The following structure represents the Notifier functions that you can
* override with the Tcl_SetNotifier call.
*/
typedef struct Tcl_NotifierProcs {
Tcl_SetTimerProc *setTimerProc;
Tcl_WaitForEventProc *waitForEventProc;
Tcl_CreateFileHandlerProc *createFileHandlerProc;
Tcl_DeleteFileHandlerProc *deleteFileHandlerProc;
Tcl_InitNotifierProc *initNotifierProc;
Tcl_FinalizeNotifierProc *finalizeNotifierProc;
Tcl_AlertNotifierProc *alertNotifierProc;
Tcl_ServiceModeHookProc *serviceModeHookProc;
} Tcl_NotifierProcs;
/*
*----------------------------------------------------------------------------
* The following data structures and declarations are for the new Tcl parser.
*
* For each word of a command, and for each piece of a word such as a variable
* reference, one of the following structures is created to describe the
* token.
*/
typedef struct Tcl_Token {
int type; /* Type of token, such as TCL_TOKEN_WORD; see
* below for valid types. */
const char *start; /* First character in token. */
Tcl_Size size; /* Number of bytes in token. */
Tcl_Size numComponents; /* If this token is composed of other tokens,
* this field tells how many of them there are
* (including components of components, etc.).
* The component tokens immediately follow
* this one. */
} Tcl_Token;
/*
* Type values defined for Tcl_Token structures. These values are defined as
* mask bits so that it's easy to check for collections of types.
*
* TCL_TOKEN_WORD - The token describes one word of a command,
* from the first non-blank character of the word
* (which may be " or {) up to but not including
* the space, semicolon, or bracket that
* terminates the word. NumComponents counts the
* total number of sub-tokens that make up the
* word. This includes, for example, sub-tokens
* of TCL_TOKEN_VARIABLE tokens.
* TCL_TOKEN_SIMPLE_WORD - This token is just like TCL_TOKEN_WORD except
* that the word is guaranteed to consist of a
* single TCL_TOKEN_TEXT sub-token.
* TCL_TOKEN_TEXT - The token describes a range of literal text
* that is part of a word. NumComponents is
* always 0.
* TCL_TOKEN_BS - The token describes a backslash sequence that
* must be collapsed. NumComponents is always 0.
* TCL_TOKEN_COMMAND - The token describes a command whose result
* must be substituted into the word. The token
* includes the enclosing brackets. NumComponents
* is always 0.
* TCL_TOKEN_VARIABLE - The token describes a variable substitution,
* including the dollar sign, variable name, and
* array index (if there is one) up through the
* right parentheses. NumComponents tells how
* many additional tokens follow to represent the
* variable name. The first token will be a
* TCL_TOKEN_TEXT token that describes the
* variable name. If the variable is an array
* reference then there will be one or more
* additional tokens, of type TCL_TOKEN_TEXT,
* TCL_TOKEN_BS, TCL_TOKEN_COMMAND, and
* TCL_TOKEN_VARIABLE, that describe the array
* index; numComponents counts the total number
* of nested tokens that make up the variable
* reference, including sub-tokens of
* TCL_TOKEN_VARIABLE tokens.
* TCL_TOKEN_SUB_EXPR - The token describes one subexpression of an
* expression, from the first non-blank character
* of the subexpression up to but not including
* the space, brace, or bracket that terminates
* the subexpression. NumComponents counts the
* total number of following subtokens that make
* up the subexpression; this includes all
* subtokens for any nested TCL_TOKEN_SUB_EXPR
* tokens. For example, a numeric value used as a
* primitive operand is described by a
* TCL_TOKEN_SUB_EXPR token followed by a
* TCL_TOKEN_TEXT token. A binary subexpression
* is described by a TCL_TOKEN_SUB_EXPR token
* followed by the TCL_TOKEN_OPERATOR token for
* the operator, then TCL_TOKEN_SUB_EXPR tokens
* for the left then the right operands.
* TCL_TOKEN_OPERATOR - The token describes one expression operator.
* An operator might be the name of a math
* function such as "abs". A TCL_TOKEN_OPERATOR
* token is always preceded by one
* TCL_TOKEN_SUB_EXPR token for the operator's
* subexpression, and is followed by zero or more
* TCL_TOKEN_SUB_EXPR tokens for the operator's
* operands. NumComponents is always 0.
* TCL_TOKEN_EXPAND_WORD - This token is just like TCL_TOKEN_WORD except
* that it marks a word that began with the
* literal character prefix "{*}". This word is
* marked to be expanded - that is, broken into
* words after substitution is complete.
*/
#define TCL_TOKEN_WORD 1
#define TCL_TOKEN_SIMPLE_WORD 2
#define TCL_TOKEN_TEXT 4
#define TCL_TOKEN_BS 8
#define TCL_TOKEN_COMMAND 16
#define TCL_TOKEN_VARIABLE 32
#define TCL_TOKEN_SUB_EXPR 64
#define TCL_TOKEN_OPERATOR 128
#define TCL_TOKEN_EXPAND_WORD 256
/*
* Parsing error types. On any parsing error, one of these values will be
* stored in the error field of the Tcl_Parse structure defined below.
*/
#define TCL_PARSE_SUCCESS 0
#define TCL_PARSE_QUOTE_EXTRA 1
#define TCL_PARSE_BRACE_EXTRA 2
#define TCL_PARSE_MISSING_BRACE 3
#define TCL_PARSE_MISSING_BRACKET 4
#define TCL_PARSE_MISSING_PAREN 5
#define TCL_PARSE_MISSING_QUOTE 6
#define TCL_PARSE_MISSING_VAR_BRACE 7
#define TCL_PARSE_SYNTAX 8
#define TCL_PARSE_BAD_NUMBER 9
/*
* A structure of the following type is filled in by Tcl_ParseCommand. It
* describes a single command parsed from an input string.
*/
#define NUM_STATIC_TOKENS 20
typedef struct Tcl_Parse {
const char *commentStart; /* Pointer to # that begins the first of one
* or more comments preceding the command. */
Tcl_Size commentSize; /* Number of bytes in comments (up through
* newline character that terminates the last
* comment). If there were no comments, this
* field is 0. */
const char *commandStart; /* First character in first word of
* command. */
Tcl_Size commandSize; /* Number of bytes in command, including first
* character of first word, up through the
* terminating newline, close bracket, or
* semicolon. */
Tcl_Size numWords; /* Total number of words in command. May be
* 0. */
Tcl_Token *tokenPtr; /* Pointer to first token representing the
* words of the command. Initially points to
* staticTokens, but may change to point to
* malloc-ed space if command exceeds space in
* staticTokens. */
Tcl_Size numTokens; /* Total number of tokens in command. */
Tcl_Size tokensAvailable; /* Total number of tokens available at
* *tokenPtr. */
int errorType; /* One of the parsing error types defined
* above. */
#if TCL_MAJOR_VERSION > 8
int incomplete; /* This field is set to 1 by Tcl_ParseCommand
* if the command appears to be incomplete.
* This information is used by
* Tcl_CommandComplete. */
#endif
/*
* The fields below are intended only for the private use of the parser.
* They should not be used by functions that invoke Tcl_ParseCommand.
*/
const char *string; /* The original command string passed to
* Tcl_ParseCommand. */
const char *end; /* Points to the character just after the last
* one in the command string. */
Tcl_Interp *interp; /* Interpreter to use for error reporting, or
* NULL. */
const char *term; /* Points to character in string that
* terminated most recent token. Filled in by
* ParseTokens. If an error occurs, points to
* beginning of region where the error
* occurred (e.g. the open brace if the close
* brace is missing). */
#if TCL_MAJOR_VERSION < 9
int incomplete;
#endif
Tcl_Token staticTokens[NUM_STATIC_TOKENS];
/* Initial space for tokens for command. This
* space should be large enough to accommodate
* most commands; dynamic space is allocated
* for very large commands that don't fit
* here. */
} Tcl_Parse;
/*
*----------------------------------------------------------------------------
* The following structure represents a user-defined encoding. It collects
* together all the functions that are used by the specific encoding.
*/
typedef struct Tcl_EncodingType {
const char *encodingName; /* The name of the encoding, e.g. "euc-jp".
* This name is the unique key for this
* encoding type. */
Tcl_EncodingConvertProc *toUtfProc;
/* Function to convert from external encoding
* into UTF-8. */
Tcl_EncodingConvertProc *fromUtfProc;
/* Function to convert from UTF-8 into
* external encoding. */
Tcl_FreeProc *freeProc; /* If non-NULL, function to call when this
* encoding is deleted. */
void *clientData; /* Arbitrary value associated with encoding
* type. Passed to conversion functions. */
Tcl_Size nullSize; /* Number of zero bytes that signify
* end-of-string in this encoding. This number
* is used to determine the source string
* length when the srcLen argument is
* negative. Must be 1, 2, or 4. */
} Tcl_EncodingType;
/*
* The following definitions are used as values for the conversion control
* flags argument when converting text from one character set to another:
*
* TCL_ENCODING_START - Signifies that the source buffer is the first
* block in a (potentially multi-block) input
* stream. Tells the conversion function to reset
* to an initial state and perform any
* initialization that needs to occur before the
* first byte is converted. If the source buffer
* contains the entire input stream to be
* converted, this flag should be set.
* TCL_ENCODING_END - Signifies that the source buffer is the last
* block in a (potentially multi-block) input
* stream. Tells the conversion routine to
* perform any finalization that needs to occur
* after the last byte is converted and then to
* reset to an initial state. If the source
* buffer contains the entire input stream to be
* converted, this flag should be set.
* TCL_ENCODING_STOPONERROR - Not used any more.
* TCL_ENCODING_NO_TERMINATE - If set, Tcl_ExternalToUtf does not append a
* terminating NUL byte. Since it does not need
* an extra byte for a terminating NUL, it fills
* all dstLen bytes with encoded UTF-8 content if
* needed. If clear, a byte is reserved in the
* dst space for NUL termination, and a
* terminating NUL is appended.
* TCL_ENCODING_CHAR_LIMIT - If set and dstCharsPtr is not NULL, then
* Tcl_ExternalToUtf takes the initial value of
* *dstCharsPtr as a limit of the maximum number
* of chars to produce in the encoded UTF-8
* content. Otherwise, the number of chars
* produced is controlled only by other limiting
* factors.
* TCL_ENCODING_PROFILE_* - Mutually exclusive encoding profile ids. Note
* these are bit masks.
*
* NOTE: THESE BIT DEFINITIONS SHOULD NOT OVERLAP WITH INTERNAL USE BITS
* DEFINED IN tclEncoding.c (ENCODING_INPUT et al). Be cognizant of this
* when adding bits.
*/
#define TCL_ENCODING_START 0x01
#define TCL_ENCODING_END 0x02
#if TCL_MAJOR_VERSION > 8
# define TCL_ENCODING_STOPONERROR 0x0 /* Not used any more */
#else
# define TCL_ENCODING_STOPONERROR 0x04
#endif
#define TCL_ENCODING_NO_TERMINATE 0x08
#define TCL_ENCODING_CHAR_LIMIT 0x10
/* Internal use bits, do not define bits in this space. See above comment */
#define TCL_ENCODING_INTERNAL_USE_MASK 0xFF00
/*
* Reserve top byte for profile values (disjoint, not a mask). In case of
* changes, ensure ENCODING_PROFILE_* macros in tclInt.h are modified if
* necessary.
*/
#define TCL_ENCODING_PROFILE_STRICT TCL_ENCODING_STOPONERROR
#define TCL_ENCODING_PROFILE_TCL8 0x01000000
#define TCL_ENCODING_PROFILE_REPLACE 0x02000000
/*
* The following definitions are the error codes returned by the conversion
* routines:
*
* TCL_OK - All characters were converted.
* TCL_CONVERT_NOSPACE - The output buffer would not have been large
* enough for all of the converted data; as many
* characters as could fit were converted though.
* TCL_CONVERT_MULTIBYTE - The last few bytes in the source string were
* the beginning of a multibyte sequence, but
* more bytes were needed to complete this
* sequence. A subsequent call to the conversion
* routine should pass the beginning of this
* unconverted sequence plus additional bytes
* from the source stream to properly convert the
* formerly split-up multibyte sequence.
* TCL_CONVERT_SYNTAX - The source stream contained an invalid
* character sequence. This may occur if the
* input stream has been damaged or if the input
* encoding method was misidentified.
* TCL_CONVERT_UNKNOWN - The source string contained a character that
* could not be represented in the target
* encoding.
*/
#define TCL_CONVERT_MULTIBYTE (-1)
#define TCL_CONVERT_SYNTAX (-2)
#define TCL_CONVERT_UNKNOWN (-3)
#define TCL_CONVERT_NOSPACE (-4)
/*
* The maximum number of bytes that are necessary to represent a single
* Unicode character in UTF-8. The valid values are 3 and 4. If > 3,
* then Tcl_UniChar must be 4-bytes in size (UCS-4) (the default). If == 3,
* then Tcl_UniChar must be 2-bytes in size (UTF-16). Since Tcl 9.0, UCS-4
* mode is the default and recommended mode.
*/
#ifndef TCL_UTF_MAX
# if defined(BUILD_tcl) || TCL_MAJOR_VERSION > 8
# define TCL_UTF_MAX 4
# else
# define TCL_UTF_MAX 3
# endif
#endif
/*
* This represents a Unicode character. Any changes to this should also be
* reflected in regcustom.h.
*/
#if TCL_UTF_MAX == 4 && TCL_MAJOR_VERSION > 8
/*
* int isn't 100% accurate as it should be a strict 4-byte value
* (perhaps int32_t). ILP64/SILP64 systems may have troubles. The
* size of this value must be reflected correctly in regcustom.h.
*/
typedef int Tcl_UniChar;
#elif TCL_UTF_MAX == 3 && !defined(BUILD_tcl)
typedef unsigned short Tcl_UniChar;
#else
# error "This TCL_UTF_MAX value is not supported"
#endif
/*
*----------------------------------------------------------------------------
* TIP #59: The following structure is used in calls 'Tcl_RegisterConfig' to
* provide the system with the embedded configuration data.
*/
typedef struct Tcl_Config {
const char *key; /* Configuration key to register. ASCII
* encoded, thus UTF-8. */
const char *value; /* The value associated with the key. System
* encoding. */
} Tcl_Config;
/*
*----------------------------------------------------------------------------
* Flags for TIP#143 limits, detailing which limits are active in an
* interpreter. Used for Tcl_{Add,Remove}LimitHandler type argument.
*/
#define TCL_LIMIT_COMMANDS 0x01
#define TCL_LIMIT_TIME 0x02
/*
* Structure containing information about a limit handler to be called when a
* command- or time-limit is exceeded by an interpreter.
*/
typedef void (Tcl_LimitHandlerProc) (void *clientData, Tcl_Interp *interp);
#if TCL_MAJOR_VERSION > 8
#define Tcl_LimitHandlerDeleteProc Tcl_FreeProc
#else
typedef void (Tcl_LimitHandlerDeleteProc) (void *clientData);
#endif
#if 0
/*
*----------------------------------------------------------------------------
* We would like to provide an anonymous structure "mp_int" here, which is
* compatible with libtommath's "mp_int", but without duplicating anything
* from <tommath.h> or including <tommath.h> here. But the libtommath project
* didn't honor our request. See: <https://github.com/libtom/libtommath/pull/473>
*
* That's why this part is commented out, and we are using (void *) in
* various API's in stead of the more correct (mp_int *).
*/
#ifndef MP_INT_DECLARED
#define MP_INT_DECLARED
typedef struct mp_int mp_int;
#endif
#endif
/*
*----------------------------------------------------------------------------
* Definitions needed for Tcl_ParseArgvObj routines.
* Based on tkArgv.c.
* Modifications from the original are copyright (c) Sam Bromley 2006
*/
typedef struct {
int type; /* Indicates the option type; see below. */
const char *keyStr; /* The key string that flags the option in the
* argv array. */
void *srcPtr; /* Value to be used in setting dst; usage
* depends on type.*/
void *dstPtr; /* Address of value to be modified; usage
* depends on type.*/
const char *helpStr; /* Documentation message describing this
* option. */
void *clientData; /* Word to pass to function callbacks. */
} Tcl_ArgvInfo;
/*
* Legal values for the type field of a Tcl_ArgInfo: see the user
* documentation for details.
*/
#define TCL_ARGV_CONSTANT 15
#define TCL_ARGV_INT 16
#define TCL_ARGV_STRING 17
#define TCL_ARGV_REST 18
#define TCL_ARGV_FLOAT 19
#define TCL_ARGV_FUNC 20
#define TCL_ARGV_GENFUNC 21
#define TCL_ARGV_HELP 22
#define TCL_ARGV_END 23
/*
* Types of callback functions for the TCL_ARGV_FUNC and TCL_ARGV_GENFUNC
* argument types:
*/
typedef int (Tcl_ArgvFuncProc)(void *clientData, Tcl_Obj *objPtr,
void *dstPtr);
typedef Tcl_Size (Tcl_ArgvGenFuncProc)(void *clientData, Tcl_Interp *interp,
Tcl_Size objc, Tcl_Obj *const *objv, void *dstPtr);
/*
* 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
* Tcl_ZlibStreamInit functions.
*/
#define TCL_ZLIB_FORMAT_RAW 1
#define TCL_ZLIB_FORMAT_ZLIB 2
#define TCL_ZLIB_FORMAT_GZIP 4
#define TCL_ZLIB_FORMAT_AUTO 8
/*
* Constants that describe whether the stream is to operate in compressing or
* decompressing mode.
*/
#define TCL_ZLIB_STREAM_DEFLATE 16
#define TCL_ZLIB_STREAM_INFLATE 32
/*
* Constants giving compression levels. Use of TCL_ZLIB_COMPRESS_DEFAULT is
* recommended.
*/
#define TCL_ZLIB_COMPRESS_NONE 0
#define TCL_ZLIB_COMPRESS_FAST 1
#define TCL_ZLIB_COMPRESS_BEST 9
#define TCL_ZLIB_COMPRESS_DEFAULT (-1)
/*
* Constants for types of flushing, used with Tcl_ZlibFlush.
*/
#define TCL_ZLIB_NO_FLUSH 0
#define TCL_ZLIB_FLUSH 2
#define TCL_ZLIB_FULLFLUSH 3
#define TCL_ZLIB_FINALIZE 4
/*
*----------------------------------------------------------------------------
* Definitions needed for the Tcl_LoadFile function. [TIP #416]
*/
#define TCL_LOAD_GLOBAL 1
#define TCL_LOAD_LAZY 2
/*
*----------------------------------------------------------------------------
* Definitions needed for the Tcl_OpenTcpServerEx function. [TIP #456]
*/
#define TCL_TCPSERVER_REUSEADDR (1<<0)
#define TCL_TCPSERVER_REUSEPORT (1<<1)
/*
* Constants for special Tcl_Size-typed values, see TIP #494
*/
#define TCL_IO_FAILURE ((Tcl_Size)-1)
#define TCL_AUTO_LENGTH ((Tcl_Size)-1)
#define TCL_INDEX_NONE ((Tcl_Size)-1)
/*
*----------------------------------------------------------------------------
* Single public declaration for NRE.
*/
typedef int (Tcl_NRPostProc) (void *data[], Tcl_Interp *interp,
int result);
/*
*----------------------------------------------------------------------------
* The following constant is used to test for older versions of Tcl in the
* stubs tables.
*/
#if TCL_MAJOR_VERSION > 8
# define TCL_STUB_MAGIC ((int) 0xFCA3BACB + (int) sizeof(void *))
#else
# define TCL_STUB_MAGIC ((int) 0xFCA3BACF)
#endif
/*
* The following function is required to be defined in all stubs aware
* extensions. The function is actually implemented in the stub library, not
* the main Tcl library, although there is a trivial implementation in the
* main library in case an extension is statically linked into an application.
*/
const char * Tcl_InitStubs(Tcl_Interp *interp, const char *version,
int exact, int magic);
const char * TclTomMathInitializeStubs(Tcl_Interp *interp,
const char *version, int epoch, int revision);
const char * TclInitStubTable(const char *version);
void * TclStubCall(void *arg);
#if defined(_WIN32)
TCL_NORETURN void Tcl_ConsolePanic(const char *format, ...);
#else
# define Tcl_ConsolePanic ((Tcl_PanicProc *)NULL)
#endif
#ifdef USE_TCL_STUBS
#if TCL_MAJOR_VERSION < 9
# define Tcl_InitStubs(interp, version, exact) \
(Tcl_InitStubs)(interp, version, \
(exact)|(TCL_MAJOR_VERSION<<8)|(0xFF<<16), \
TCL_STUB_MAGIC)
#else
# define Tcl_InitStubs(interp, version, exact) \
(Tcl_InitStubs)(interp, version, \
(exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16), \
TCL_STUB_MAGIC)
#endif
#else
#if TCL_MAJOR_VERSION < 9
# define Tcl_InitStubs(interp, version, exact) \
Tcl_Panic(((void)interp, (void)version, \
(void)exact, "Please define -DUSE_TCL_STUBS"))
#else
# define Tcl_InitStubs(interp, version, exact) \
Tcl_PkgInitStubsCheck(interp, version, \
(exact)|(TCL_MAJOR_VERSION<<8)|(TCL_MINOR_VERSION<<16))
#endif
#endif
/*
* Public functions that are not accessible via the stubs table.
* Tcl_GetMemoryInfo is needed for AOLserver. [Bug 1868171]
*/
#define Tcl_Main(argc, argv, proc) Tcl_MainEx(argc, argv, proc, \
((Tcl_SetPanicProc(Tcl_ConsolePanic), Tcl_CreateInterp())))
EXTERN TCL_NORETURN void Tcl_MainEx(Tcl_Size argc, char **argv,
Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
EXTERN const char * Tcl_PkgInitStubsCheck(Tcl_Interp *interp,
const char *version, int exact);
EXTERN const char * Tcl_InitSubsystems(void);
EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
EXTERN const char * Tcl_FindExecutable(const char *argv0);
EXTERN const char * Tcl_SetPreInitScript(const char *string);
EXTERN const char * Tcl_SetPanicProc(
Tcl_PanicProc *panicProc);
EXTERN void Tcl_StaticLibrary(Tcl_Interp *interp,
const char *prefix,
Tcl_LibraryInitProc *initProc,
Tcl_LibraryInitProc *safeInitProc);
#ifndef TCL_NO_DEPRECATED
# define Tcl_StaticPackage Tcl_StaticLibrary
#endif
EXTERN Tcl_ExitProc * Tcl_SetExitProc(Tcl_ExitProc *proc);
#ifdef _WIN32
EXTERN const char *TclZipfs_AppHook(int *argc, unsigned short ***argv);
#else
EXTERN const char *TclZipfs_AppHook(int *argc, char ***argv);
#endif
#if defined(_WIN32) && defined(UNICODE)
#ifndef USE_TCL_STUBS
# define Tcl_FindExecutable(arg) ((Tcl_FindExecutable)((const char *)(arg)))
#endif
# define Tcl_MainEx Tcl_MainExW
EXTERN TCL_NORETURN void Tcl_MainExW(Tcl_Size argc, unsigned short **argv,
Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
#endif
#if defined(USE_TCL_STUBS) && (TCL_MAJOR_VERSION > 8)
#define Tcl_SetPanicProc(panicProc) \
TclInitStubTable(((const char *(*)(Tcl_PanicProc *))TclStubCall((void *)panicProc))(panicProc))
#define Tcl_InitSubsystems() \
TclInitStubTable(((const char *(*)(void))TclStubCall((void *)1))())
#define Tcl_FindExecutable(argv0) \
TclInitStubTable(((const char *(*)(const char *))TclStubCall((void *)2))(argv0))
#define TclZipfs_AppHook(argcp, argvp) \
TclInitStubTable(((const char *(*)(int *, void *))TclStubCall((void *)3))(argcp, argvp))
#define Tcl_MainExW(argc, argv, appInitProc, interp) \
(void)((const char *(*)(Tcl_Size, const void *, Tcl_AppInitProc *, Tcl_Interp *)) \
TclStubCall((void *)4))(argc, argv, appInitProc, interp)
#if !defined(_WIN32) || !defined(UNICODE)
#define Tcl_MainEx(argc, argv, appInitProc, interp) \
(void)((const char *(*)(Tcl_Size, const void *, Tcl_AppInitProc *, Tcl_Interp *)) \
TclStubCall((void *)5))(argc, argv, appInitProc, interp)
#endif
#define Tcl_StaticLibrary(interp, pkgName, initProc, safeInitProc) \
(void)((const char *(*)(Tcl_Interp *, const char *, Tcl_LibraryInitProc *, Tcl_LibraryInitProc *)) \
TclStubCall((void *)6))(interp, pkgName, initProc, safeInitProc)
#define Tcl_SetExitProc(proc) \
((Tcl_ExitProc *(*)(Tcl_ExitProc *))TclStubCall((void *)7))(proc)
#define Tcl_GetMemoryInfo(dsPtr) \
(void)((const char *(*)(Tcl_DString *))TclStubCall((void *)8))(dsPtr)
#define Tcl_SetPreInitScript(string) \
((const char *(*)(const char *))TclStubCall((void *)9))(string)
#endif
/*
*----------------------------------------------------------------------------
* Include the public function declarations that are accessible via the stubs
* table.
*/
#include "tclDecls.h"
/*
* Include platform specific public function declarations that are accessible
* via the stubs table. Make all TclOO symbols MODULE_SCOPE (which only
* has effect on building it as a shared library). See ticket [3010352].
*/
#if defined(BUILD_tcl)
# undef TCLAPI
# define TCLAPI MODULE_SCOPE
#endif
/*
*----------------------------------------------------------------------------
* The following declarations map ckalloc and ckfree to Tcl_Alloc and
* Tcl_Free for use in Tcl-8.x-compatible extensions.
*/
#ifndef BUILD_tcl
# define ckalloc Tcl_Alloc
# define attemptckalloc Tcl_AttemptAlloc
# ifdef _MSC_VER
/* Silence invalid C4090 warnings */
# define ckfree(a) Tcl_Free((void *)(a))
# define ckrealloc(a,b) Tcl_Realloc((void *)(a),(b))
# define attemptckrealloc(a,b) Tcl_AttemptRealloc((void *)(a),(b))
# else
# define ckfree Tcl_Free
# define ckrealloc Tcl_Realloc
# define attemptckrealloc Tcl_AttemptRealloc
# endif
#endif
#ifndef TCL_MEM_DEBUG
/*
* If we are not using the debugging allocator, we should call the Tcl_Alloc,
* et al. routines in order to guarantee that every module is using the same
* memory allocator both inside and outside of the Tcl library.
*/
# undef Tcl_InitMemory
# define Tcl_InitMemory(x)
# undef Tcl_DumpActiveMemory
# define Tcl_DumpActiveMemory(x)
# undef Tcl_ValidateAllMemory
# define Tcl_ValidateAllMemory(x,y)
#endif /* !TCL_MEM_DEBUG */
#ifdef TCL_MEM_DEBUG
# undef Tcl_IncrRefCount
# define Tcl_IncrRefCount(objPtr) \
Tcl_DbIncrRefCount(objPtr, __FILE__, __LINE__)
# undef Tcl_DecrRefCount
# define Tcl_DecrRefCount(objPtr) \
Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__)
# undef Tcl_IsShared
# define Tcl_IsShared(objPtr) \
Tcl_DbIsShared(objPtr, __FILE__, __LINE__)
/*
* Free the Obj by effectively doing:
*
* Tcl_IncrRefCount(objPtr);
* Tcl_DecrRefCount(objPtr);
*
* This will free the obj if there are no references to the obj.
*/
# define Tcl_BounceRefCount(objPtr) \
TclBounceRefCount(objPtr, __FILE__, __LINE__)
static inline void
TclBounceRefCount(
Tcl_Obj* objPtr,
const char* fn,
int line)
{
if (objPtr) {
if ((objPtr)->refCount == 0) {
Tcl_DbDecrRefCount(objPtr, fn, line);
}
}
}
#else
# undef Tcl_IncrRefCount
# define Tcl_IncrRefCount(objPtr) \
((void)++(objPtr)->refCount)
/*
* Use do/while0 idiom for optimum correctness without compiler warnings.
* https://wiki.c2.com/?TrivialDoWhileLoop
*/
# undef Tcl_DecrRefCount
# define Tcl_DecrRefCount(objPtr) \
do { \
Tcl_Obj *_objPtr = (objPtr); \
if (_objPtr->refCount-- <= 1) { \
TclFreeObj(_objPtr); \
} \
} while(0)
# undef Tcl_IsShared
# define Tcl_IsShared(objPtr) \
((objPtr)->refCount > 1)
/*
* Declare that obj will no longer be used or referenced.
* This will free the obj if there are no references to the obj.
*/
# define Tcl_BounceRefCount(objPtr) \
TclBounceRefCount(objPtr);
static inline void
TclBounceRefCount(
Tcl_Obj* objPtr)
{
if (objPtr) {
if ((objPtr)->refCount == 0) {
Tcl_DecrRefCount(objPtr);
}
}
}
#endif
/*
* Macros and definitions that help to debug the use of Tcl objects. When
* TCL_MEM_DEBUG is defined, the Tcl_New declarations are overridden to call
* debugging versions of the object creation functions.
*/
#ifdef TCL_MEM_DEBUG
# undef Tcl_NewBignumObj
# define Tcl_NewBignumObj(val) \
Tcl_DbNewBignumObj(val, __FILE__, __LINE__)
# undef Tcl_NewBooleanObj
# define Tcl_NewBooleanObj(val) \
Tcl_DbNewWideIntObj((val)!=0, __FILE__, __LINE__)
# undef Tcl_NewByteArrayObj
# define Tcl_NewByteArrayObj(bytes, len) \
Tcl_DbNewByteArrayObj(bytes, len, __FILE__, __LINE__)
# undef Tcl_NewDoubleObj
# define Tcl_NewDoubleObj(val) \
Tcl_DbNewDoubleObj(val, __FILE__, __LINE__)
# undef Tcl_NewListObj
# define Tcl_NewListObj(objc, objv) \
Tcl_DbNewListObj(objc, objv, __FILE__, __LINE__)
# undef Tcl_NewObj
# define Tcl_NewObj() \
Tcl_DbNewObj(__FILE__, __LINE__)
# undef Tcl_NewStringObj
# define Tcl_NewStringObj(bytes, len) \
Tcl_DbNewStringObj(bytes, len, __FILE__, __LINE__)
# undef Tcl_NewWideIntObj
# define Tcl_NewWideIntObj(val) \
Tcl_DbNewWideIntObj(val, __FILE__, __LINE__)
#endif /* TCL_MEM_DEBUG */
/*
*----------------------------------------------------------------------------
* Macros for clients to use to access fields of hash entries:
*/
#define Tcl_GetHashValue(h) ((h)->clientData)
#define Tcl_SetHashValue(h, value) ((h)->clientData = (void *)(value))
#define Tcl_GetHashKey(tablePtr, h) \
((void *) (((tablePtr)->keyType == TCL_ONE_WORD_KEYS || \
(tablePtr)->keyType == TCL_CUSTOM_PTR_KEYS) \
? (h)->key.oneWordValue \
: (h)->key.string))
/*
* Macros to use for clients to use to invoke find and create functions for
* hash tables:
*/
#define Tcl_FindHashEntry(tablePtr, key) \
(*((tablePtr)->findProc))(tablePtr, (const char *)(key))
#define Tcl_CreateHashEntry(tablePtr, key, newPtr) \
(*((tablePtr)->createProc))(tablePtr, (const char *)(key), newPtr)
#endif /* RC_INVOKED */
/*
* end block for C++
*/
#ifdef __cplusplus
}
#endif
#endif /* _TCL */
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
|
Added compat/tcl-9.0/generic/tclDecls.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 151 152 153 154 155 156 157 158 159 160 161 162 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 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 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 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 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 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 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 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 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 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 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 984 985 986 987 988 989 990 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 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 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 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 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 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 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 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 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 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 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 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 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 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 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 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 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 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 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 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 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 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 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 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 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 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 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 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 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 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 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 |
/*
* tclDecls.h --
*
* Declarations of functions in the platform independent public Tcl API.
*
* 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.
*/
#ifndef _TCLDECLS
#define _TCLDECLS
#include <stddef.h> /* for size_t */
#undef TCL_STORAGE_CLASS
#ifdef BUILD_tcl
# define TCL_STORAGE_CLASS DLLEXPORT
#else
# ifdef USE_TCL_STUBS
# define TCL_STORAGE_CLASS
# else
# define TCL_STORAGE_CLASS DLLIMPORT
# endif
#endif
#if !defined(BUILD_tcl)
# define TCL_DEPRECATED(msg) EXTERN TCL_DEPRECATED_API(msg)
#elif defined(TCL_NO_DEPRECATED)
# define TCL_DEPRECATED(msg) MODULE_SCOPE
#else
# define TCL_DEPRECATED(msg) EXTERN
#endif
/*
* WARNING: This file is automatically generated by the tools/genStubs.tcl
* script. Any modifications to the function declarations below should be made
* in the generic/tcl.decls script.
*/
/* !BEGIN!: Do not edit below this line. */
#ifdef __cplusplus
extern "C" {
#endif
/*
* Exported function declarations:
*/
/* 0 */
EXTERN int Tcl_PkgProvideEx(Tcl_Interp *interp,
const char *name, const char *version,
const void *clientData);
/* 1 */
EXTERN const char * Tcl_PkgRequireEx(Tcl_Interp *interp,
const char *name, const char *version,
int exact, void *clientDataPtr);
/* 2 */
EXTERN TCL_NORETURN void Tcl_Panic(const char *format, ...) TCL_FORMAT_PRINTF(1, 2);
/* 3 */
EXTERN void * Tcl_Alloc(TCL_HASH_TYPE size);
/* 4 */
EXTERN void Tcl_Free(void *ptr);
/* 5 */
EXTERN void * Tcl_Realloc(void *ptr, TCL_HASH_TYPE size);
/* 6 */
EXTERN void * Tcl_DbCkalloc(TCL_HASH_TYPE size, const char *file,
int line);
/* 7 */
EXTERN void Tcl_DbCkfree(void *ptr, const char *file, int line);
/* 8 */
EXTERN void * Tcl_DbCkrealloc(void *ptr, TCL_HASH_TYPE size,
const char *file, int line);
/* 9 */
EXTERN void Tcl_CreateFileHandler(int fd, int mask,
Tcl_FileProc *proc, void *clientData);
/* 10 */
EXTERN void Tcl_DeleteFileHandler(int fd);
/* 11 */
EXTERN void Tcl_SetTimer(const Tcl_Time *timePtr);
/* 12 */
EXTERN void Tcl_Sleep(int ms);
/* 13 */
EXTERN int Tcl_WaitForEvent(const Tcl_Time *timePtr);
/* 14 */
EXTERN int Tcl_AppendAllObjTypes(Tcl_Interp *interp,
Tcl_Obj *objPtr);
/* 15 */
EXTERN void Tcl_AppendStringsToObj(Tcl_Obj *objPtr, ...);
/* 16 */
EXTERN void Tcl_AppendToObj(Tcl_Obj *objPtr, const char *bytes,
Tcl_Size length);
/* 17 */
EXTERN Tcl_Obj * Tcl_ConcatObj(Tcl_Size objc, Tcl_Obj *const objv[]);
/* 18 */
EXTERN int Tcl_ConvertToType(Tcl_Interp *interp,
Tcl_Obj *objPtr, const Tcl_ObjType *typePtr);
/* 19 */
EXTERN void Tcl_DbDecrRefCount(Tcl_Obj *objPtr, const char *file,
int line);
/* 20 */
EXTERN void Tcl_DbIncrRefCount(Tcl_Obj *objPtr, const char *file,
int line);
/* 21 */
EXTERN int Tcl_DbIsShared(Tcl_Obj *objPtr, const char *file,
int line);
/* Slot 22 is reserved */
/* 23 */
EXTERN Tcl_Obj * Tcl_DbNewByteArrayObj(const unsigned char *bytes,
Tcl_Size numBytes, const char *file,
int line);
/* 24 */
EXTERN Tcl_Obj * Tcl_DbNewDoubleObj(double doubleValue,
const char *file, int line);
/* 25 */
EXTERN Tcl_Obj * Tcl_DbNewListObj(Tcl_Size objc, Tcl_Obj *const *objv,
const char *file, int line);
/* Slot 26 is reserved */
/* 27 */
EXTERN Tcl_Obj * Tcl_DbNewObj(const char *file, int line);
/* 28 */
EXTERN Tcl_Obj * Tcl_DbNewStringObj(const char *bytes,
Tcl_Size length, const char *file, int line);
/* 29 */
EXTERN Tcl_Obj * Tcl_DuplicateObj(Tcl_Obj *objPtr);
/* 30 */
EXTERN void TclFreeObj(Tcl_Obj *objPtr);
/* 31 */
EXTERN int Tcl_GetBoolean(Tcl_Interp *interp, const char *src,
int *intPtr);
/* 32 */
EXTERN int Tcl_GetBooleanFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, int *intPtr);
/* 33 */
EXTERN unsigned char * Tcl_GetByteArrayFromObj(Tcl_Obj *objPtr,
Tcl_Size *numBytesPtr);
/* 34 */
EXTERN int Tcl_GetDouble(Tcl_Interp *interp, const char *src,
double *doublePtr);
/* 35 */
EXTERN int Tcl_GetDoubleFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, double *doublePtr);
/* Slot 36 is reserved */
/* 37 */
EXTERN int Tcl_GetInt(Tcl_Interp *interp, const char *src,
int *intPtr);
/* 38 */
EXTERN int Tcl_GetIntFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, int *intPtr);
/* 39 */
EXTERN int Tcl_GetLongFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, long *longPtr);
/* 40 */
EXTERN const Tcl_ObjType * Tcl_GetObjType(const char *typeName);
/* 41 */
EXTERN char * TclGetStringFromObj(Tcl_Obj *objPtr, void *lengthPtr);
/* 42 */
EXTERN void Tcl_InvalidateStringRep(Tcl_Obj *objPtr);
/* 43 */
EXTERN int Tcl_ListObjAppendList(Tcl_Interp *interp,
Tcl_Obj *listPtr, Tcl_Obj *elemListPtr);
/* 44 */
EXTERN int Tcl_ListObjAppendElement(Tcl_Interp *interp,
Tcl_Obj *listPtr, Tcl_Obj *objPtr);
/* 45 */
EXTERN int TclListObjGetElements(Tcl_Interp *interp,
Tcl_Obj *listPtr, void *objcPtr,
Tcl_Obj ***objvPtr);
/* 46 */
EXTERN int Tcl_ListObjIndex(Tcl_Interp *interp,
Tcl_Obj *listPtr, Tcl_Size index,
Tcl_Obj **objPtrPtr);
/* 47 */
EXTERN int TclListObjLength(Tcl_Interp *interp,
Tcl_Obj *listPtr, void *lengthPtr);
/* 48 */
EXTERN int Tcl_ListObjReplace(Tcl_Interp *interp,
Tcl_Obj *listPtr, Tcl_Size first,
Tcl_Size count, Tcl_Size objc,
Tcl_Obj *const objv[]);
/* Slot 49 is reserved */
/* 50 */
EXTERN Tcl_Obj * Tcl_NewByteArrayObj(const unsigned char *bytes,
Tcl_Size numBytes);
/* 51 */
EXTERN Tcl_Obj * Tcl_NewDoubleObj(double doubleValue);
/* Slot 52 is reserved */
/* 53 */
EXTERN Tcl_Obj * Tcl_NewListObj(Tcl_Size objc, Tcl_Obj *const objv[]);
/* Slot 54 is reserved */
/* 55 */
EXTERN Tcl_Obj * Tcl_NewObj(void);
/* 56 */
EXTERN Tcl_Obj * Tcl_NewStringObj(const char *bytes, Tcl_Size length);
/* Slot 57 is reserved */
/* 58 */
EXTERN unsigned char * Tcl_SetByteArrayLength(Tcl_Obj *objPtr,
Tcl_Size numBytes);
/* 59 */
EXTERN void Tcl_SetByteArrayObj(Tcl_Obj *objPtr,
const unsigned char *bytes,
Tcl_Size numBytes);
/* 60 */
EXTERN void Tcl_SetDoubleObj(Tcl_Obj *objPtr, double doubleValue);
/* Slot 61 is reserved */
/* 62 */
EXTERN void Tcl_SetListObj(Tcl_Obj *objPtr, Tcl_Size objc,
Tcl_Obj *const objv[]);
/* Slot 63 is reserved */
/* 64 */
EXTERN void Tcl_SetObjLength(Tcl_Obj *objPtr, Tcl_Size length);
/* 65 */
EXTERN void Tcl_SetStringObj(Tcl_Obj *objPtr, const char *bytes,
Tcl_Size length);
/* Slot 66 is reserved */
/* Slot 67 is reserved */
/* 68 */
EXTERN void Tcl_AllowExceptions(Tcl_Interp *interp);
/* 69 */
EXTERN void Tcl_AppendElement(Tcl_Interp *interp,
const char *element);
/* 70 */
EXTERN void Tcl_AppendResult(Tcl_Interp *interp, ...);
/* 71 */
EXTERN Tcl_AsyncHandler Tcl_AsyncCreate(Tcl_AsyncProc *proc,
void *clientData);
/* 72 */
EXTERN void Tcl_AsyncDelete(Tcl_AsyncHandler async);
/* 73 */
EXTERN int Tcl_AsyncInvoke(Tcl_Interp *interp, int code);
/* 74 */
EXTERN void Tcl_AsyncMark(Tcl_AsyncHandler async);
/* 75 */
EXTERN int Tcl_AsyncReady(void);
/* Slot 76 is reserved */
/* Slot 77 is reserved */
/* 78 */
EXTERN int Tcl_BadChannelOption(Tcl_Interp *interp,
const char *optionName,
const char *optionList);
/* 79 */
EXTERN void Tcl_CallWhenDeleted(Tcl_Interp *interp,
Tcl_InterpDeleteProc *proc, void *clientData);
/* 80 */
EXTERN void Tcl_CancelIdleCall(Tcl_IdleProc *idleProc,
void *clientData);
/* 81 */
EXTERN int Tcl_Close(Tcl_Interp *interp, Tcl_Channel chan);
/* 82 */
EXTERN int Tcl_CommandComplete(const char *cmd);
/* 83 */
EXTERN char * Tcl_Concat(Tcl_Size argc, const char *const *argv);
/* 84 */
EXTERN Tcl_Size Tcl_ConvertElement(const char *src, char *dst,
int flags);
/* 85 */
EXTERN Tcl_Size Tcl_ConvertCountedElement(const char *src,
Tcl_Size length, char *dst, int flags);
/* 86 */
EXTERN int Tcl_CreateAlias(Tcl_Interp *childInterp,
const char *childCmd, Tcl_Interp *target,
const char *targetCmd, Tcl_Size argc,
const char *const *argv);
/* 87 */
EXTERN int Tcl_CreateAliasObj(Tcl_Interp *childInterp,
const char *childCmd, Tcl_Interp *target,
const char *targetCmd, Tcl_Size objc,
Tcl_Obj *const objv[]);
/* 88 */
EXTERN Tcl_Channel Tcl_CreateChannel(const Tcl_ChannelType *typePtr,
const char *chanName, void *instanceData,
int mask);
/* 89 */
EXTERN void Tcl_CreateChannelHandler(Tcl_Channel chan, int mask,
Tcl_ChannelProc *proc, void *clientData);
/* 90 */
EXTERN void Tcl_CreateCloseHandler(Tcl_Channel chan,
Tcl_CloseProc *proc, void *clientData);
/* 91 */
EXTERN Tcl_Command Tcl_CreateCommand(Tcl_Interp *interp,
const char *cmdName, Tcl_CmdProc *proc,
void *clientData,
Tcl_CmdDeleteProc *deleteProc);
/* 92 */
EXTERN void Tcl_CreateEventSource(Tcl_EventSetupProc *setupProc,
Tcl_EventCheckProc *checkProc,
void *clientData);
/* 93 */
EXTERN void Tcl_CreateExitHandler(Tcl_ExitProc *proc,
void *clientData);
/* 94 */
EXTERN Tcl_Interp * Tcl_CreateInterp(void);
/* Slot 95 is reserved */
/* 96 */
EXTERN Tcl_Command Tcl_CreateObjCommand(Tcl_Interp *interp,
const char *cmdName, Tcl_ObjCmdProc *proc,
void *clientData,
Tcl_CmdDeleteProc *deleteProc);
/* 97 */
EXTERN Tcl_Interp * Tcl_CreateChild(Tcl_Interp *interp, const char *name,
int isSafe);
/* 98 */
EXTERN Tcl_TimerToken Tcl_CreateTimerHandler(int milliseconds,
Tcl_TimerProc *proc, void *clientData);
/* 99 */
EXTERN Tcl_Trace Tcl_CreateTrace(Tcl_Interp *interp, Tcl_Size level,
Tcl_CmdTraceProc *proc, void *clientData);
/* 100 */
EXTERN void Tcl_DeleteAssocData(Tcl_Interp *interp,
const char *name);
/* 101 */
EXTERN void Tcl_DeleteChannelHandler(Tcl_Channel chan,
Tcl_ChannelProc *proc, void *clientData);
/* 102 */
EXTERN void Tcl_DeleteCloseHandler(Tcl_Channel chan,
Tcl_CloseProc *proc, void *clientData);
/* 103 */
EXTERN int Tcl_DeleteCommand(Tcl_Interp *interp,
const char *cmdName);
/* 104 */
EXTERN int Tcl_DeleteCommandFromToken(Tcl_Interp *interp,
Tcl_Command command);
/* 105 */
EXTERN void Tcl_DeleteEvents(Tcl_EventDeleteProc *proc,
void *clientData);
/* 106 */
EXTERN void Tcl_DeleteEventSource(Tcl_EventSetupProc *setupProc,
Tcl_EventCheckProc *checkProc,
void *clientData);
/* 107 */
EXTERN void Tcl_DeleteExitHandler(Tcl_ExitProc *proc,
void *clientData);
/* 108 */
EXTERN void Tcl_DeleteHashEntry(Tcl_HashEntry *entryPtr);
/* 109 */
EXTERN void Tcl_DeleteHashTable(Tcl_HashTable *tablePtr);
/* 110 */
EXTERN void Tcl_DeleteInterp(Tcl_Interp *interp);
/* 111 */
EXTERN void Tcl_DetachPids(Tcl_Size numPids, Tcl_Pid *pidPtr);
/* 112 */
EXTERN void Tcl_DeleteTimerHandler(Tcl_TimerToken token);
/* 113 */
EXTERN void Tcl_DeleteTrace(Tcl_Interp *interp, Tcl_Trace trace);
/* 114 */
EXTERN void Tcl_DontCallWhenDeleted(Tcl_Interp *interp,
Tcl_InterpDeleteProc *proc, void *clientData);
/* 115 */
EXTERN int Tcl_DoOneEvent(int flags);
/* 116 */
EXTERN void Tcl_DoWhenIdle(Tcl_IdleProc *proc, void *clientData);
/* 117 */
EXTERN char * Tcl_DStringAppend(Tcl_DString *dsPtr,
const char *bytes, Tcl_Size length);
/* 118 */
EXTERN char * Tcl_DStringAppendElement(Tcl_DString *dsPtr,
const char *element);
/* 119 */
EXTERN void Tcl_DStringEndSublist(Tcl_DString *dsPtr);
/* 120 */
EXTERN void Tcl_DStringFree(Tcl_DString *dsPtr);
/* 121 */
EXTERN void Tcl_DStringGetResult(Tcl_Interp *interp,
Tcl_DString *dsPtr);
/* 122 */
EXTERN void Tcl_DStringInit(Tcl_DString *dsPtr);
/* 123 */
EXTERN void Tcl_DStringResult(Tcl_Interp *interp,
Tcl_DString *dsPtr);
/* 124 */
EXTERN void Tcl_DStringSetLength(Tcl_DString *dsPtr,
Tcl_Size length);
/* 125 */
EXTERN void Tcl_DStringStartSublist(Tcl_DString *dsPtr);
/* 126 */
EXTERN int Tcl_Eof(Tcl_Channel chan);
/* 127 */
EXTERN const char * Tcl_ErrnoId(void);
/* 128 */
EXTERN const char * Tcl_ErrnoMsg(int err);
/* Slot 129 is reserved */
/* 130 */
EXTERN int Tcl_EvalFile(Tcl_Interp *interp,
const char *fileName);
/* Slot 131 is reserved */
/* 132 */
EXTERN void Tcl_EventuallyFree(void *clientData,
Tcl_FreeProc *freeProc);
/* 133 */
EXTERN TCL_NORETURN void Tcl_Exit(int status);
/* 134 */
EXTERN int Tcl_ExposeCommand(Tcl_Interp *interp,
const char *hiddenCmdToken,
const char *cmdName);
/* 135 */
EXTERN int Tcl_ExprBoolean(Tcl_Interp *interp, const char *expr,
int *ptr);
/* 136 */
EXTERN int Tcl_ExprBooleanObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, int *ptr);
/* 137 */
EXTERN int Tcl_ExprDouble(Tcl_Interp *interp, const char *expr,
double *ptr);
/* 138 */
EXTERN int Tcl_ExprDoubleObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, double *ptr);
/* 139 */
EXTERN int Tcl_ExprLong(Tcl_Interp *interp, const char *expr,
long *ptr);
/* 140 */
EXTERN int Tcl_ExprLongObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
long *ptr);
/* 141 */
EXTERN int Tcl_ExprObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
Tcl_Obj **resultPtrPtr);
/* 142 */
EXTERN int Tcl_ExprString(Tcl_Interp *interp, const char *expr);
/* 143 */
EXTERN void Tcl_Finalize(void);
/* Slot 144 is reserved */
/* 145 */
EXTERN Tcl_HashEntry * Tcl_FirstHashEntry(Tcl_HashTable *tablePtr,
Tcl_HashSearch *searchPtr);
/* 146 */
EXTERN int Tcl_Flush(Tcl_Channel chan);
/* Slot 147 is reserved */
/* Slot 148 is reserved */
/* 149 */
EXTERN int TclGetAliasObj(Tcl_Interp *interp,
const char *childCmd,
Tcl_Interp **targetInterpPtr,
const char **targetCmdPtr, int *objcPtr,
Tcl_Obj ***objvPtr);
/* 150 */
EXTERN void * Tcl_GetAssocData(Tcl_Interp *interp,
const char *name,
Tcl_InterpDeleteProc **procPtr);
/* 151 */
EXTERN Tcl_Channel Tcl_GetChannel(Tcl_Interp *interp,
const char *chanName, int *modePtr);
/* 152 */
EXTERN Tcl_Size Tcl_GetChannelBufferSize(Tcl_Channel chan);
/* 153 */
EXTERN int Tcl_GetChannelHandle(Tcl_Channel chan, int direction,
void **handlePtr);
/* 154 */
EXTERN void * Tcl_GetChannelInstanceData(Tcl_Channel chan);
/* 155 */
EXTERN int Tcl_GetChannelMode(Tcl_Channel chan);
/* 156 */
EXTERN const char * Tcl_GetChannelName(Tcl_Channel chan);
/* 157 */
EXTERN int Tcl_GetChannelOption(Tcl_Interp *interp,
Tcl_Channel chan, const char *optionName,
Tcl_DString *dsPtr);
/* 158 */
EXTERN const Tcl_ChannelType * Tcl_GetChannelType(Tcl_Channel chan);
/* 159 */
EXTERN int Tcl_GetCommandInfo(Tcl_Interp *interp,
const char *cmdName, Tcl_CmdInfo *infoPtr);
/* 160 */
EXTERN const char * Tcl_GetCommandName(Tcl_Interp *interp,
Tcl_Command command);
/* 161 */
EXTERN int Tcl_GetErrno(void);
/* 162 */
EXTERN const char * Tcl_GetHostName(void);
/* 163 */
EXTERN int Tcl_GetInterpPath(Tcl_Interp *interp,
Tcl_Interp *childInterp);
/* 164 */
EXTERN Tcl_Interp * Tcl_GetParent(Tcl_Interp *interp);
/* 165 */
EXTERN const char * Tcl_GetNameOfExecutable(void);
/* 166 */
EXTERN Tcl_Obj * Tcl_GetObjResult(Tcl_Interp *interp);
/* 167 */
EXTERN int Tcl_GetOpenFile(Tcl_Interp *interp,
const char *chanID, int forWriting,
int checkUsage, void **filePtr);
/* 168 */
EXTERN Tcl_PathType Tcl_GetPathType(const char *path);
/* 169 */
EXTERN Tcl_Size Tcl_Gets(Tcl_Channel chan, Tcl_DString *dsPtr);
/* 170 */
EXTERN Tcl_Size Tcl_GetsObj(Tcl_Channel chan, Tcl_Obj *objPtr);
/* 171 */
EXTERN int Tcl_GetServiceMode(void);
/* 172 */
EXTERN Tcl_Interp * Tcl_GetChild(Tcl_Interp *interp, const char *name);
/* 173 */
EXTERN Tcl_Channel Tcl_GetStdChannel(int type);
/* Slot 174 is reserved */
/* Slot 175 is reserved */
/* 176 */
EXTERN const char * Tcl_GetVar2(Tcl_Interp *interp, const char *part1,
const char *part2, int flags);
/* Slot 177 is reserved */
/* Slot 178 is reserved */
/* 179 */
EXTERN int Tcl_HideCommand(Tcl_Interp *interp,
const char *cmdName,
const char *hiddenCmdToken);
/* 180 */
EXTERN int Tcl_Init(Tcl_Interp *interp);
/* 181 */
EXTERN void Tcl_InitHashTable(Tcl_HashTable *tablePtr,
int keyType);
/* 182 */
EXTERN int Tcl_InputBlocked(Tcl_Channel chan);
/* 183 */
EXTERN int Tcl_InputBuffered(Tcl_Channel chan);
/* 184 */
EXTERN int Tcl_InterpDeleted(Tcl_Interp *interp);
/* 185 */
EXTERN int Tcl_IsSafe(Tcl_Interp *interp);
/* 186 */
EXTERN char * Tcl_JoinPath(Tcl_Size argc, const char *const *argv,
Tcl_DString *resultPtr);
/* 187 */
EXTERN int Tcl_LinkVar(Tcl_Interp *interp, const char *varName,
void *addr, int type);
/* Slot 188 is reserved */
/* 189 */
EXTERN Tcl_Channel Tcl_MakeFileChannel(void *handle, int mode);
/* Slot 190 is reserved */
/* 191 */
EXTERN Tcl_Channel Tcl_MakeTcpClientChannel(void *tcpSocket);
/* 192 */
EXTERN char * Tcl_Merge(Tcl_Size argc, const char *const *argv);
/* 193 */
EXTERN Tcl_HashEntry * Tcl_NextHashEntry(Tcl_HashSearch *searchPtr);
/* 194 */
EXTERN void Tcl_NotifyChannel(Tcl_Channel channel, int mask);
/* 195 */
EXTERN Tcl_Obj * Tcl_ObjGetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
Tcl_Obj *part2Ptr, int flags);
/* 196 */
EXTERN Tcl_Obj * Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr,
int flags);
/* 197 */
EXTERN Tcl_Channel Tcl_OpenCommandChannel(Tcl_Interp *interp,
Tcl_Size argc, const char **argv, int flags);
/* 198 */
EXTERN Tcl_Channel Tcl_OpenFileChannel(Tcl_Interp *interp,
const char *fileName, const char *modeString,
int permissions);
/* 199 */
EXTERN Tcl_Channel Tcl_OpenTcpClient(Tcl_Interp *interp, int port,
const char *address, const char *myaddr,
int myport, int flags);
/* 200 */
EXTERN Tcl_Channel Tcl_OpenTcpServer(Tcl_Interp *interp, int port,
const char *host,
Tcl_TcpAcceptProc *acceptProc,
void *callbackData);
/* 201 */
EXTERN void Tcl_Preserve(void *data);
/* 202 */
EXTERN void Tcl_PrintDouble(Tcl_Interp *interp, double value,
char *dst);
/* 203 */
EXTERN int Tcl_PutEnv(const char *assignment);
/* 204 */
EXTERN const char * Tcl_PosixError(Tcl_Interp *interp);
/* 205 */
EXTERN void Tcl_QueueEvent(Tcl_Event *evPtr, int position);
/* 206 */
EXTERN Tcl_Size Tcl_Read(Tcl_Channel chan, char *bufPtr,
Tcl_Size toRead);
/* 207 */
EXTERN void Tcl_ReapDetachedProcs(void);
/* 208 */
EXTERN int Tcl_RecordAndEval(Tcl_Interp *interp,
const char *cmd, int flags);
/* 209 */
EXTERN int Tcl_RecordAndEvalObj(Tcl_Interp *interp,
Tcl_Obj *cmdPtr, int flags);
/* 210 */
EXTERN void Tcl_RegisterChannel(Tcl_Interp *interp,
Tcl_Channel chan);
/* 211 */
EXTERN void Tcl_RegisterObjType(const Tcl_ObjType *typePtr);
/* 212 */
EXTERN Tcl_RegExp Tcl_RegExpCompile(Tcl_Interp *interp,
const char *pattern);
/* 213 */
EXTERN int Tcl_RegExpExec(Tcl_Interp *interp, Tcl_RegExp regexp,
const char *text, const char *start);
/* 214 */
EXTERN int Tcl_RegExpMatch(Tcl_Interp *interp, const char *text,
const char *pattern);
/* 215 */
EXTERN void Tcl_RegExpRange(Tcl_RegExp regexp, Tcl_Size index,
const char **startPtr, const char **endPtr);
/* 216 */
EXTERN void Tcl_Release(void *clientData);
/* 217 */
EXTERN void Tcl_ResetResult(Tcl_Interp *interp);
/* 218 */
EXTERN Tcl_Size Tcl_ScanElement(const char *src, int *flagPtr);
/* 219 */
EXTERN Tcl_Size Tcl_ScanCountedElement(const char *src,
Tcl_Size length, int *flagPtr);
/* Slot 220 is reserved */
/* 221 */
EXTERN int Tcl_ServiceAll(void);
/* 222 */
EXTERN int Tcl_ServiceEvent(int flags);
/* 223 */
EXTERN void Tcl_SetAssocData(Tcl_Interp *interp,
const char *name, Tcl_InterpDeleteProc *proc,
void *clientData);
/* 224 */
EXTERN void Tcl_SetChannelBufferSize(Tcl_Channel chan,
Tcl_Size sz);
/* 225 */
EXTERN int Tcl_SetChannelOption(Tcl_Interp *interp,
Tcl_Channel chan, const char *optionName,
const char *newValue);
/* 226 */
EXTERN int Tcl_SetCommandInfo(Tcl_Interp *interp,
const char *cmdName,
const Tcl_CmdInfo *infoPtr);
/* 227 */
EXTERN void Tcl_SetErrno(int err);
/* 228 */
EXTERN void Tcl_SetErrorCode(Tcl_Interp *interp, ...);
/* 229 */
EXTERN void Tcl_SetMaxBlockTime(const Tcl_Time *timePtr);
/* Slot 230 is reserved */
/* 231 */
EXTERN Tcl_Size Tcl_SetRecursionLimit(Tcl_Interp *interp,
Tcl_Size depth);
/* Slot 232 is reserved */
/* 233 */
EXTERN int Tcl_SetServiceMode(int mode);
/* 234 */
EXTERN void Tcl_SetObjErrorCode(Tcl_Interp *interp,
Tcl_Obj *errorObjPtr);
/* 235 */
EXTERN void Tcl_SetObjResult(Tcl_Interp *interp,
Tcl_Obj *resultObjPtr);
/* 236 */
EXTERN void Tcl_SetStdChannel(Tcl_Channel channel, int type);
/* Slot 237 is reserved */
/* 238 */
EXTERN const char * Tcl_SetVar2(Tcl_Interp *interp, const char *part1,
const char *part2, const char *newValue,
int flags);
/* 239 */
EXTERN const char * Tcl_SignalId(int sig);
/* 240 */
EXTERN const char * Tcl_SignalMsg(int sig);
/* 241 */
EXTERN void Tcl_SourceRCFile(Tcl_Interp *interp);
/* 242 */
EXTERN int TclSplitList(Tcl_Interp *interp, const char *listStr,
void *argcPtr, const char ***argvPtr);
/* 243 */
EXTERN void TclSplitPath(const char *path, void *argcPtr,
const char ***argvPtr);
/* Slot 244 is reserved */
/* Slot 245 is reserved */
/* Slot 246 is reserved */
/* Slot 247 is reserved */
/* 248 */
EXTERN int Tcl_TraceVar2(Tcl_Interp *interp, const char *part1,
const char *part2, int flags,
Tcl_VarTraceProc *proc, void *clientData);
/* 249 */
EXTERN char * Tcl_TranslateFileName(Tcl_Interp *interp,
const char *name, Tcl_DString *bufferPtr);
/* 250 */
EXTERN Tcl_Size Tcl_Ungets(Tcl_Channel chan, const char *str,
Tcl_Size len, int atHead);
/* 251 */
EXTERN void Tcl_UnlinkVar(Tcl_Interp *interp,
const char *varName);
/* 252 */
EXTERN int Tcl_UnregisterChannel(Tcl_Interp *interp,
Tcl_Channel chan);
/* Slot 253 is reserved */
/* 254 */
EXTERN int Tcl_UnsetVar2(Tcl_Interp *interp, const char *part1,
const char *part2, int flags);
/* Slot 255 is reserved */
/* 256 */
EXTERN void Tcl_UntraceVar2(Tcl_Interp *interp,
const char *part1, const char *part2,
int flags, Tcl_VarTraceProc *proc,
void *clientData);
/* 257 */
EXTERN void Tcl_UpdateLinkedVar(Tcl_Interp *interp,
const char *varName);
/* Slot 258 is reserved */
/* 259 */
EXTERN int Tcl_UpVar2(Tcl_Interp *interp, const char *frameName,
const char *part1, const char *part2,
const char *localName, int flags);
/* 260 */
EXTERN int Tcl_VarEval(Tcl_Interp *interp, ...);
/* Slot 261 is reserved */
/* 262 */
EXTERN void * Tcl_VarTraceInfo2(Tcl_Interp *interp,
const char *part1, const char *part2,
int flags, Tcl_VarTraceProc *procPtr,
void *prevClientData);
/* 263 */
EXTERN Tcl_Size Tcl_Write(Tcl_Channel chan, const char *s,
Tcl_Size slen);
/* 264 */
EXTERN void Tcl_WrongNumArgs(Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[], const char *message);
/* 265 */
EXTERN int Tcl_DumpActiveMemory(const char *fileName);
/* 266 */
EXTERN void Tcl_ValidateAllMemory(const char *file, int line);
/* Slot 267 is reserved */
/* Slot 268 is reserved */
/* 269 */
EXTERN char * Tcl_HashStats(Tcl_HashTable *tablePtr);
/* 270 */
EXTERN const char * Tcl_ParseVar(Tcl_Interp *interp, const char *start,
const char **termPtr);
/* Slot 271 is reserved */
/* 272 */
EXTERN const char * Tcl_PkgPresentEx(Tcl_Interp *interp,
const char *name, const char *version,
int exact, void *clientDataPtr);
/* Slot 273 is reserved */
/* Slot 274 is reserved */
/* Slot 275 is reserved */
/* Slot 276 is reserved */
/* 277 */
EXTERN Tcl_Pid Tcl_WaitPid(Tcl_Pid pid, int *statPtr, int options);
/* Slot 278 is reserved */
/* 279 */
EXTERN void Tcl_GetVersion(int *major, int *minor,
int *patchLevel, int *type);
/* 280 */
EXTERN void Tcl_InitMemory(Tcl_Interp *interp);
/* 281 */
EXTERN Tcl_Channel Tcl_StackChannel(Tcl_Interp *interp,
const Tcl_ChannelType *typePtr,
void *instanceData, int mask,
Tcl_Channel prevChan);
/* 282 */
EXTERN int Tcl_UnstackChannel(Tcl_Interp *interp,
Tcl_Channel chan);
/* 283 */
EXTERN Tcl_Channel Tcl_GetStackedChannel(Tcl_Channel chan);
/* 284 */
EXTERN void Tcl_SetMainLoop(Tcl_MainLoopProc *proc);
/* 285 */
EXTERN int Tcl_GetAliasObj(Tcl_Interp *interp,
const char *childCmd,
Tcl_Interp **targetInterpPtr,
const char **targetCmdPtr, Tcl_Size *objcPtr,
Tcl_Obj ***objvPtr);
/* 286 */
EXTERN void Tcl_AppendObjToObj(Tcl_Obj *objPtr,
Tcl_Obj *appendObjPtr);
/* 287 */
EXTERN Tcl_Encoding Tcl_CreateEncoding(const Tcl_EncodingType *typePtr);
/* 288 */
EXTERN void Tcl_CreateThreadExitHandler(Tcl_ExitProc *proc,
void *clientData);
/* 289 */
EXTERN void Tcl_DeleteThreadExitHandler(Tcl_ExitProc *proc,
void *clientData);
/* Slot 290 is reserved */
/* 291 */
EXTERN int Tcl_EvalEx(Tcl_Interp *interp, const char *script,
Tcl_Size numBytes, int flags);
/* 292 */
EXTERN int Tcl_EvalObjv(Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[], int flags);
/* 293 */
EXTERN int Tcl_EvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr,
int flags);
/* 294 */
EXTERN TCL_NORETURN void Tcl_ExitThread(int status);
/* 295 */
EXTERN int Tcl_ExternalToUtf(Tcl_Interp *interp,
Tcl_Encoding encoding, const char *src,
Tcl_Size srcLen, int flags,
Tcl_EncodingState *statePtr, char *dst,
Tcl_Size dstLen, int *srcReadPtr,
int *dstWrotePtr, int *dstCharsPtr);
/* 296 */
EXTERN char * Tcl_ExternalToUtfDString(Tcl_Encoding encoding,
const char *src, Tcl_Size srcLen,
Tcl_DString *dsPtr);
/* 297 */
EXTERN void Tcl_FinalizeThread(void);
/* 298 */
EXTERN void Tcl_FinalizeNotifier(void *clientData);
/* 299 */
EXTERN void Tcl_FreeEncoding(Tcl_Encoding encoding);
/* 300 */
EXTERN Tcl_ThreadId Tcl_GetCurrentThread(void);
/* 301 */
EXTERN Tcl_Encoding Tcl_GetEncoding(Tcl_Interp *interp, const char *name);
/* 302 */
EXTERN const char * Tcl_GetEncodingName(Tcl_Encoding encoding);
/* 303 */
EXTERN void Tcl_GetEncodingNames(Tcl_Interp *interp);
/* 304 */
EXTERN int Tcl_GetIndexFromObjStruct(Tcl_Interp *interp,
Tcl_Obj *objPtr, const void *tablePtr,
Tcl_Size offset, const char *msg, int flags,
void *indexPtr);
/* 305 */
EXTERN void * Tcl_GetThreadData(Tcl_ThreadDataKey *keyPtr,
Tcl_Size size);
/* 306 */
EXTERN Tcl_Obj * Tcl_GetVar2Ex(Tcl_Interp *interp, const char *part1,
const char *part2, int flags);
/* 307 */
EXTERN void * Tcl_InitNotifier(void);
/* 308 */
EXTERN void Tcl_MutexLock(Tcl_Mutex *mutexPtr);
/* 309 */
EXTERN void Tcl_MutexUnlock(Tcl_Mutex *mutexPtr);
/* 310 */
EXTERN void Tcl_ConditionNotify(Tcl_Condition *condPtr);
/* 311 */
EXTERN void Tcl_ConditionWait(Tcl_Condition *condPtr,
Tcl_Mutex *mutexPtr, const Tcl_Time *timePtr);
/* 312 */
EXTERN Tcl_Size TclNumUtfChars(const char *src, Tcl_Size length);
/* 313 */
EXTERN Tcl_Size Tcl_ReadChars(Tcl_Channel channel, Tcl_Obj *objPtr,
Tcl_Size charsToRead, int appendFlag);
/* Slot 314 is reserved */
/* Slot 315 is reserved */
/* 316 */
EXTERN int Tcl_SetSystemEncoding(Tcl_Interp *interp,
const char *name);
/* 317 */
EXTERN Tcl_Obj * Tcl_SetVar2Ex(Tcl_Interp *interp, const char *part1,
const char *part2, Tcl_Obj *newValuePtr,
int flags);
/* 318 */
EXTERN void Tcl_ThreadAlert(Tcl_ThreadId threadId);
/* 319 */
EXTERN void Tcl_ThreadQueueEvent(Tcl_ThreadId threadId,
Tcl_Event *evPtr, int position);
/* 320 */
EXTERN int Tcl_UniCharAtIndex(const char *src, Tcl_Size index);
/* 321 */
EXTERN int Tcl_UniCharToLower(int ch);
/* 322 */
EXTERN int Tcl_UniCharToTitle(int ch);
/* 323 */
EXTERN int Tcl_UniCharToUpper(int ch);
/* 324 */
EXTERN Tcl_Size Tcl_UniCharToUtf(int ch, char *buf);
/* 325 */
EXTERN const char * TclUtfAtIndex(const char *src, Tcl_Size index);
/* 326 */
EXTERN int TclUtfCharComplete(const char *src, Tcl_Size length);
/* 327 */
EXTERN Tcl_Size Tcl_UtfBackslash(const char *src, int *readPtr,
char *dst);
/* 328 */
EXTERN const char * Tcl_UtfFindFirst(const char *src, int ch);
/* 329 */
EXTERN const char * Tcl_UtfFindLast(const char *src, int ch);
/* 330 */
EXTERN const char * TclUtfNext(const char *src);
/* 331 */
EXTERN const char * TclUtfPrev(const char *src, const char *start);
/* 332 */
EXTERN int Tcl_UtfToExternal(Tcl_Interp *interp,
Tcl_Encoding encoding, const char *src,
Tcl_Size srcLen, int flags,
Tcl_EncodingState *statePtr, char *dst,
Tcl_Size dstLen, int *srcReadPtr,
int *dstWrotePtr, int *dstCharsPtr);
/* 333 */
EXTERN char * Tcl_UtfToExternalDString(Tcl_Encoding encoding,
const char *src, Tcl_Size srcLen,
Tcl_DString *dsPtr);
/* 334 */
EXTERN Tcl_Size Tcl_UtfToLower(char *src);
/* 335 */
EXTERN Tcl_Size Tcl_UtfToTitle(char *src);
/* 336 */
EXTERN Tcl_Size Tcl_UtfToChar16(const char *src,
unsigned short *chPtr);
/* 337 */
EXTERN Tcl_Size Tcl_UtfToUpper(char *src);
/* 338 */
EXTERN Tcl_Size Tcl_WriteChars(Tcl_Channel chan, const char *src,
Tcl_Size srcLen);
/* 339 */
EXTERN Tcl_Size Tcl_WriteObj(Tcl_Channel chan, Tcl_Obj *objPtr);
/* 340 */
EXTERN char * Tcl_GetString(Tcl_Obj *objPtr);
/* Slot 341 is reserved */
/* Slot 342 is reserved */
/* 343 */
EXTERN void Tcl_AlertNotifier(void *clientData);
/* 344 */
EXTERN void Tcl_ServiceModeHook(int mode);
/* 345 */
EXTERN int Tcl_UniCharIsAlnum(int ch);
/* 346 */
EXTERN int Tcl_UniCharIsAlpha(int ch);
/* 347 */
EXTERN int Tcl_UniCharIsDigit(int ch);
/* 348 */
EXTERN int Tcl_UniCharIsLower(int ch);
/* 349 */
EXTERN int Tcl_UniCharIsSpace(int ch);
/* 350 */
EXTERN int Tcl_UniCharIsUpper(int ch);
/* 351 */
EXTERN int Tcl_UniCharIsWordChar(int ch);
/* 352 */
EXTERN Tcl_Size Tcl_Char16Len(const unsigned short *uniStr);
/* Slot 353 is reserved */
/* 354 */
EXTERN char * Tcl_Char16ToUtfDString(const unsigned short *uniStr,
Tcl_Size uniLength, Tcl_DString *dsPtr);
/* 355 */
EXTERN unsigned short * Tcl_UtfToChar16DString(const char *src,
Tcl_Size length, Tcl_DString *dsPtr);
/* 356 */
EXTERN Tcl_RegExp Tcl_GetRegExpFromObj(Tcl_Interp *interp,
Tcl_Obj *patObj, int flags);
/* Slot 357 is reserved */
/* 358 */
EXTERN void Tcl_FreeParse(Tcl_Parse *parsePtr);
/* 359 */
EXTERN void Tcl_LogCommandInfo(Tcl_Interp *interp,
const char *script, const char *command,
Tcl_Size length);
/* 360 */
EXTERN int Tcl_ParseBraces(Tcl_Interp *interp,
const char *start, Tcl_Size numBytes,
Tcl_Parse *parsePtr, int append,
const char **termPtr);
/* 361 */
EXTERN int Tcl_ParseCommand(Tcl_Interp *interp,
const char *start, Tcl_Size numBytes,
int nested, Tcl_Parse *parsePtr);
/* 362 */
EXTERN int Tcl_ParseExpr(Tcl_Interp *interp, const char *start,
Tcl_Size numBytes, Tcl_Parse *parsePtr);
/* 363 */
EXTERN int Tcl_ParseQuotedString(Tcl_Interp *interp,
const char *start, Tcl_Size numBytes,
Tcl_Parse *parsePtr, int append,
const char **termPtr);
/* 364 */
EXTERN int Tcl_ParseVarName(Tcl_Interp *interp,
const char *start, Tcl_Size numBytes,
Tcl_Parse *parsePtr, int append);
/* 365 */
EXTERN char * Tcl_GetCwd(Tcl_Interp *interp, Tcl_DString *cwdPtr);
/* 366 */
EXTERN int Tcl_Chdir(const char *dirName);
/* 367 */
EXTERN int Tcl_Access(const char *path, int mode);
/* 368 */
EXTERN int Tcl_Stat(const char *path, struct stat *bufPtr);
/* 369 */
EXTERN int TclUtfNcmp(const char *s1, const char *s2, size_t n);
/* 370 */
EXTERN int TclUtfNcasecmp(const char *s1, const char *s2,
size_t n);
/* 371 */
EXTERN int Tcl_StringCaseMatch(const char *str,
const char *pattern, int nocase);
/* 372 */
EXTERN int Tcl_UniCharIsControl(int ch);
/* 373 */
EXTERN int Tcl_UniCharIsGraph(int ch);
/* 374 */
EXTERN int Tcl_UniCharIsPrint(int ch);
/* 375 */
EXTERN int Tcl_UniCharIsPunct(int ch);
/* 376 */
EXTERN int Tcl_RegExpExecObj(Tcl_Interp *interp,
Tcl_RegExp regexp, Tcl_Obj *textObj,
Tcl_Size offset, Tcl_Size nmatches,
int flags);
/* 377 */
EXTERN void Tcl_RegExpGetInfo(Tcl_RegExp regexp,
Tcl_RegExpInfo *infoPtr);
/* 378 */
EXTERN Tcl_Obj * Tcl_NewUnicodeObj(const Tcl_UniChar *unicode,
Tcl_Size numChars);
/* 379 */
EXTERN void Tcl_SetUnicodeObj(Tcl_Obj *objPtr,
const Tcl_UniChar *unicode,
Tcl_Size numChars);
/* 380 */
EXTERN Tcl_Size TclGetCharLength(Tcl_Obj *objPtr);
/* 381 */
EXTERN int TclGetUniChar(Tcl_Obj *objPtr, Tcl_Size index);
/* Slot 382 is reserved */
/* 383 */
EXTERN Tcl_Obj * TclGetRange(Tcl_Obj *objPtr, Tcl_Size first,
Tcl_Size last);
/* 384 */
EXTERN void Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr,
const Tcl_UniChar *unicode, Tcl_Size length);
/* 385 */
EXTERN int Tcl_RegExpMatchObj(Tcl_Interp *interp,
Tcl_Obj *textObj, Tcl_Obj *patternObj);
/* 386 */
EXTERN void Tcl_SetNotifier(
const Tcl_NotifierProcs *notifierProcPtr);
/* 387 */
EXTERN Tcl_Mutex * Tcl_GetAllocMutex(void);
/* 388 */
EXTERN int Tcl_GetChannelNames(Tcl_Interp *interp);
/* 389 */
EXTERN int Tcl_GetChannelNamesEx(Tcl_Interp *interp,
const char *pattern);
/* 390 */
EXTERN int Tcl_ProcObjCmd(void *clientData, Tcl_Interp *interp,
Tcl_Size objc, Tcl_Obj *const objv[]);
/* 391 */
EXTERN void Tcl_ConditionFinalize(Tcl_Condition *condPtr);
/* 392 */
EXTERN void Tcl_MutexFinalize(Tcl_Mutex *mutex);
/* 393 */
EXTERN int Tcl_CreateThread(Tcl_ThreadId *idPtr,
Tcl_ThreadCreateProc *proc, void *clientData,
TCL_HASH_TYPE stackSize, int flags);
/* 394 */
EXTERN Tcl_Size Tcl_ReadRaw(Tcl_Channel chan, char *dst,
Tcl_Size bytesToRead);
/* 395 */
EXTERN Tcl_Size Tcl_WriteRaw(Tcl_Channel chan, const char *src,
Tcl_Size srcLen);
/* 396 */
EXTERN Tcl_Channel Tcl_GetTopChannel(Tcl_Channel chan);
/* 397 */
EXTERN int Tcl_ChannelBuffered(Tcl_Channel chan);
/* 398 */
EXTERN const char * Tcl_ChannelName(const Tcl_ChannelType *chanTypePtr);
/* 399 */
EXTERN Tcl_ChannelTypeVersion Tcl_ChannelVersion(
const Tcl_ChannelType *chanTypePtr);
/* 400 */
EXTERN Tcl_DriverBlockModeProc * Tcl_ChannelBlockModeProc(
const Tcl_ChannelType *chanTypePtr);
/* Slot 401 is reserved */
/* 402 */
EXTERN Tcl_DriverClose2Proc * Tcl_ChannelClose2Proc(
const Tcl_ChannelType *chanTypePtr);
/* 403 */
EXTERN Tcl_DriverInputProc * Tcl_ChannelInputProc(
const Tcl_ChannelType *chanTypePtr);
/* 404 */
EXTERN Tcl_DriverOutputProc * Tcl_ChannelOutputProc(
const Tcl_ChannelType *chanTypePtr);
/* Slot 405 is reserved */
/* 406 */
EXTERN Tcl_DriverSetOptionProc * Tcl_ChannelSetOptionProc(
const Tcl_ChannelType *chanTypePtr);
/* 407 */
EXTERN Tcl_DriverGetOptionProc * Tcl_ChannelGetOptionProc(
const Tcl_ChannelType *chanTypePtr);
/* 408 */
EXTERN Tcl_DriverWatchProc * Tcl_ChannelWatchProc(
const Tcl_ChannelType *chanTypePtr);
/* 409 */
EXTERN Tcl_DriverGetHandleProc * Tcl_ChannelGetHandleProc(
const Tcl_ChannelType *chanTypePtr);
/* 410 */
EXTERN Tcl_DriverFlushProc * Tcl_ChannelFlushProc(
const Tcl_ChannelType *chanTypePtr);
/* 411 */
EXTERN Tcl_DriverHandlerProc * Tcl_ChannelHandlerProc(
const Tcl_ChannelType *chanTypePtr);
/* 412 */
EXTERN int Tcl_JoinThread(Tcl_ThreadId threadId, int *result);
/* 413 */
EXTERN int Tcl_IsChannelShared(Tcl_Channel channel);
/* 414 */
EXTERN int Tcl_IsChannelRegistered(Tcl_Interp *interp,
Tcl_Channel channel);
/* 415 */
EXTERN void Tcl_CutChannel(Tcl_Channel channel);
/* 416 */
EXTERN void Tcl_SpliceChannel(Tcl_Channel channel);
/* 417 */
EXTERN void Tcl_ClearChannelHandlers(Tcl_Channel channel);
/* 418 */
EXTERN int Tcl_IsChannelExisting(const char *channelName);
/* Slot 419 is reserved */
/* Slot 420 is reserved */
/* Slot 421 is reserved */
/* 422 */
EXTERN Tcl_HashEntry * Tcl_CreateHashEntry(Tcl_HashTable *tablePtr,
const void *key, int *newPtr);
/* 423 */
EXTERN void Tcl_InitCustomHashTable(Tcl_HashTable *tablePtr,
int keyType, const Tcl_HashKeyType *typePtr);
/* 424 */
EXTERN void Tcl_InitObjHashTable(Tcl_HashTable *tablePtr);
/* 425 */
EXTERN void * Tcl_CommandTraceInfo(Tcl_Interp *interp,
const char *varName, int flags,
Tcl_CommandTraceProc *procPtr,
void *prevClientData);
/* 426 */
EXTERN int Tcl_TraceCommand(Tcl_Interp *interp,
const char *varName, int flags,
Tcl_CommandTraceProc *proc, void *clientData);
/* 427 */
EXTERN void Tcl_UntraceCommand(Tcl_Interp *interp,
const char *varName, int flags,
Tcl_CommandTraceProc *proc, void *clientData);
/* 428 */
EXTERN void * Tcl_AttemptAlloc(TCL_HASH_TYPE size);
/* 429 */
EXTERN void * Tcl_AttemptDbCkalloc(TCL_HASH_TYPE size,
const char *file, int line);
/* 430 */
EXTERN void * Tcl_AttemptRealloc(void *ptr, TCL_HASH_TYPE size);
/* 431 */
EXTERN void * Tcl_AttemptDbCkrealloc(void *ptr, TCL_HASH_TYPE size,
const char *file, int line);
/* 432 */
EXTERN int Tcl_AttemptSetObjLength(Tcl_Obj *objPtr,
Tcl_Size length);
/* 433 */
EXTERN Tcl_ThreadId Tcl_GetChannelThread(Tcl_Channel channel);
/* 434 */
EXTERN Tcl_UniChar * TclGetUnicodeFromObj(Tcl_Obj *objPtr,
void *lengthPtr);
/* Slot 435 is reserved */
/* Slot 436 is reserved */
/* 437 */
EXTERN Tcl_Obj * Tcl_SubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
int flags);
/* 438 */
EXTERN int Tcl_DetachChannel(Tcl_Interp *interp,
Tcl_Channel channel);
/* 439 */
EXTERN int Tcl_IsStandardChannel(Tcl_Channel channel);
/* 440 */
EXTERN int Tcl_FSCopyFile(Tcl_Obj *srcPathPtr,
Tcl_Obj *destPathPtr);
/* 441 */
EXTERN int Tcl_FSCopyDirectory(Tcl_Obj *srcPathPtr,
Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr);
/* 442 */
EXTERN int Tcl_FSCreateDirectory(Tcl_Obj *pathPtr);
/* 443 */
EXTERN int Tcl_FSDeleteFile(Tcl_Obj *pathPtr);
/* 444 */
EXTERN int Tcl_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr,
const char *sym1, const char *sym2,
Tcl_LibraryInitProc **proc1Ptr,
Tcl_LibraryInitProc **proc2Ptr,
Tcl_LoadHandle *handlePtr,
Tcl_FSUnloadFileProc **unloadProcPtr);
/* 445 */
EXTERN int Tcl_FSMatchInDirectory(Tcl_Interp *interp,
Tcl_Obj *result, Tcl_Obj *pathPtr,
const char *pattern, Tcl_GlobTypeData *types);
/* 446 */
EXTERN Tcl_Obj * Tcl_FSLink(Tcl_Obj *pathPtr, Tcl_Obj *toPtr,
int linkAction);
/* 447 */
EXTERN int Tcl_FSRemoveDirectory(Tcl_Obj *pathPtr,
int recursive, Tcl_Obj **errorPtr);
/* 448 */
EXTERN int Tcl_FSRenameFile(Tcl_Obj *srcPathPtr,
Tcl_Obj *destPathPtr);
/* 449 */
EXTERN int Tcl_FSLstat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf);
/* 450 */
EXTERN int Tcl_FSUtime(Tcl_Obj *pathPtr, struct utimbuf *tval);
/* 451 */
EXTERN int Tcl_FSFileAttrsGet(Tcl_Interp *interp, int index,
Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef);
/* 452 */
EXTERN int Tcl_FSFileAttrsSet(Tcl_Interp *interp, int index,
Tcl_Obj *pathPtr, Tcl_Obj *objPtr);
/* 453 */
EXTERN const char *const * Tcl_FSFileAttrStrings(Tcl_Obj *pathPtr,
Tcl_Obj **objPtrRef);
/* 454 */
EXTERN int Tcl_FSStat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf);
/* 455 */
EXTERN int Tcl_FSAccess(Tcl_Obj *pathPtr, int mode);
/* 456 */
EXTERN Tcl_Channel Tcl_FSOpenFileChannel(Tcl_Interp *interp,
Tcl_Obj *pathPtr, const char *modeString,
int permissions);
/* 457 */
EXTERN Tcl_Obj * Tcl_FSGetCwd(Tcl_Interp *interp);
/* 458 */
EXTERN int Tcl_FSChdir(Tcl_Obj *pathPtr);
/* 459 */
EXTERN int Tcl_FSConvertToPathType(Tcl_Interp *interp,
Tcl_Obj *pathPtr);
/* 460 */
EXTERN Tcl_Obj * Tcl_FSJoinPath(Tcl_Obj *listObj, Tcl_Size elements);
/* 461 */
EXTERN Tcl_Obj * TclFSSplitPath(Tcl_Obj *pathPtr, void *lenPtr);
/* 462 */
EXTERN int Tcl_FSEqualPaths(Tcl_Obj *firstPtr,
Tcl_Obj *secondPtr);
/* 463 */
EXTERN Tcl_Obj * Tcl_FSGetNormalizedPath(Tcl_Interp *interp,
Tcl_Obj *pathPtr);
/* 464 */
EXTERN Tcl_Obj * Tcl_FSJoinToPath(Tcl_Obj *pathPtr, Tcl_Size objc,
Tcl_Obj *const objv[]);
/* 465 */
EXTERN void * Tcl_FSGetInternalRep(Tcl_Obj *pathPtr,
const Tcl_Filesystem *fsPtr);
/* 466 */
EXTERN Tcl_Obj * Tcl_FSGetTranslatedPath(Tcl_Interp *interp,
Tcl_Obj *pathPtr);
/* 467 */
EXTERN int Tcl_FSEvalFile(Tcl_Interp *interp, Tcl_Obj *fileName);
/* 468 */
EXTERN Tcl_Obj * Tcl_FSNewNativePath(
const Tcl_Filesystem *fromFilesystem,
void *clientData);
/* 469 */
EXTERN const void * Tcl_FSGetNativePath(Tcl_Obj *pathPtr);
/* 470 */
EXTERN Tcl_Obj * Tcl_FSFileSystemInfo(Tcl_Obj *pathPtr);
/* 471 */
EXTERN Tcl_Obj * Tcl_FSPathSeparator(Tcl_Obj *pathPtr);
/* 472 */
EXTERN Tcl_Obj * Tcl_FSListVolumes(void);
/* 473 */
EXTERN int Tcl_FSRegister(void *clientData,
const Tcl_Filesystem *fsPtr);
/* 474 */
EXTERN int Tcl_FSUnregister(const Tcl_Filesystem *fsPtr);
/* 475 */
EXTERN void * Tcl_FSData(const Tcl_Filesystem *fsPtr);
/* 476 */
EXTERN const char * Tcl_FSGetTranslatedStringPath(Tcl_Interp *interp,
Tcl_Obj *pathPtr);
/* 477 */
EXTERN const Tcl_Filesystem * Tcl_FSGetFileSystemForPath(Tcl_Obj *pathPtr);
/* 478 */
EXTERN Tcl_PathType Tcl_FSGetPathType(Tcl_Obj *pathPtr);
/* 479 */
EXTERN int Tcl_OutputBuffered(Tcl_Channel chan);
/* 480 */
EXTERN void Tcl_FSMountsChanged(const Tcl_Filesystem *fsPtr);
/* 481 */
EXTERN int Tcl_EvalTokensStandard(Tcl_Interp *interp,
Tcl_Token *tokenPtr, Tcl_Size count);
/* 482 */
EXTERN void Tcl_GetTime(Tcl_Time *timeBuf);
/* 483 */
EXTERN Tcl_Trace Tcl_CreateObjTrace(Tcl_Interp *interp,
Tcl_Size level, int flags,
Tcl_CmdObjTraceProc *objProc,
void *clientData,
Tcl_CmdObjTraceDeleteProc *delProc);
/* 484 */
EXTERN int Tcl_GetCommandInfoFromToken(Tcl_Command token,
Tcl_CmdInfo *infoPtr);
/* 485 */
EXTERN int Tcl_SetCommandInfoFromToken(Tcl_Command token,
const Tcl_CmdInfo *infoPtr);
/* 486 */
EXTERN Tcl_Obj * Tcl_DbNewWideIntObj(Tcl_WideInt wideValue,
const char *file, int line);
/* 487 */
EXTERN int Tcl_GetWideIntFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, Tcl_WideInt *widePtr);
/* 488 */
EXTERN Tcl_Obj * Tcl_NewWideIntObj(Tcl_WideInt wideValue);
/* 489 */
EXTERN void Tcl_SetWideIntObj(Tcl_Obj *objPtr,
Tcl_WideInt wideValue);
/* 490 */
EXTERN Tcl_StatBuf * Tcl_AllocStatBuf(void);
/* 491 */
EXTERN long long Tcl_Seek(Tcl_Channel chan, long long offset,
int mode);
/* 492 */
EXTERN long long Tcl_Tell(Tcl_Channel chan);
/* 493 */
EXTERN Tcl_DriverWideSeekProc * Tcl_ChannelWideSeekProc(
const Tcl_ChannelType *chanTypePtr);
/* 494 */
EXTERN int Tcl_DictObjPut(Tcl_Interp *interp, Tcl_Obj *dictPtr,
Tcl_Obj *keyPtr, Tcl_Obj *valuePtr);
/* 495 */
EXTERN int Tcl_DictObjGet(Tcl_Interp *interp, Tcl_Obj *dictPtr,
Tcl_Obj *keyPtr, Tcl_Obj **valuePtrPtr);
/* 496 */
EXTERN int Tcl_DictObjRemove(Tcl_Interp *interp,
Tcl_Obj *dictPtr, Tcl_Obj *keyPtr);
/* 497 */
EXTERN int TclDictObjSize(Tcl_Interp *interp, Tcl_Obj *dictPtr,
void *sizePtr);
/* 498 */
EXTERN int Tcl_DictObjFirst(Tcl_Interp *interp,
Tcl_Obj *dictPtr, Tcl_DictSearch *searchPtr,
Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr,
int *donePtr);
/* 499 */
EXTERN void Tcl_DictObjNext(Tcl_DictSearch *searchPtr,
Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr,
int *donePtr);
/* 500 */
EXTERN void Tcl_DictObjDone(Tcl_DictSearch *searchPtr);
/* 501 */
EXTERN int Tcl_DictObjPutKeyList(Tcl_Interp *interp,
Tcl_Obj *dictPtr, Tcl_Size keyc,
Tcl_Obj *const *keyv, Tcl_Obj *valuePtr);
/* 502 */
EXTERN int Tcl_DictObjRemoveKeyList(Tcl_Interp *interp,
Tcl_Obj *dictPtr, Tcl_Size keyc,
Tcl_Obj *const *keyv);
/* 503 */
EXTERN Tcl_Obj * Tcl_NewDictObj(void);
/* 504 */
EXTERN Tcl_Obj * Tcl_DbNewDictObj(const char *file, int line);
/* 505 */
EXTERN void Tcl_RegisterConfig(Tcl_Interp *interp,
const char *pkgName,
const Tcl_Config *configuration,
const char *valEncoding);
/* 506 */
EXTERN Tcl_Namespace * Tcl_CreateNamespace(Tcl_Interp *interp,
const char *name, void *clientData,
Tcl_NamespaceDeleteProc *deleteProc);
/* 507 */
EXTERN void Tcl_DeleteNamespace(Tcl_Namespace *nsPtr);
/* 508 */
EXTERN int Tcl_AppendExportList(Tcl_Interp *interp,
Tcl_Namespace *nsPtr, Tcl_Obj *objPtr);
/* 509 */
EXTERN int Tcl_Export(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
const char *pattern, int resetListFirst);
/* 510 */
EXTERN int Tcl_Import(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
const char *pattern, int allowOverwrite);
/* 511 */
EXTERN int Tcl_ForgetImport(Tcl_Interp *interp,
Tcl_Namespace *nsPtr, const char *pattern);
/* 512 */
EXTERN Tcl_Namespace * Tcl_GetCurrentNamespace(Tcl_Interp *interp);
/* 513 */
EXTERN Tcl_Namespace * Tcl_GetGlobalNamespace(Tcl_Interp *interp);
/* 514 */
EXTERN Tcl_Namespace * Tcl_FindNamespace(Tcl_Interp *interp,
const char *name,
Tcl_Namespace *contextNsPtr, int flags);
/* 515 */
EXTERN Tcl_Command Tcl_FindCommand(Tcl_Interp *interp, const char *name,
Tcl_Namespace *contextNsPtr, int flags);
/* 516 */
EXTERN Tcl_Command Tcl_GetCommandFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr);
/* 517 */
EXTERN void Tcl_GetCommandFullName(Tcl_Interp *interp,
Tcl_Command command, Tcl_Obj *objPtr);
/* 518 */
EXTERN int Tcl_FSEvalFileEx(Tcl_Interp *interp,
Tcl_Obj *fileName, const char *encodingName);
/* Slot 519 is reserved */
/* 520 */
EXTERN void Tcl_LimitAddHandler(Tcl_Interp *interp, int type,
Tcl_LimitHandlerProc *handlerProc,
void *clientData,
Tcl_LimitHandlerDeleteProc *deleteProc);
/* 521 */
EXTERN void Tcl_LimitRemoveHandler(Tcl_Interp *interp, int type,
Tcl_LimitHandlerProc *handlerProc,
void *clientData);
/* 522 */
EXTERN int Tcl_LimitReady(Tcl_Interp *interp);
/* 523 */
EXTERN int Tcl_LimitCheck(Tcl_Interp *interp);
/* 524 */
EXTERN int Tcl_LimitExceeded(Tcl_Interp *interp);
/* 525 */
EXTERN void Tcl_LimitSetCommands(Tcl_Interp *interp,
Tcl_Size commandLimit);
/* 526 */
EXTERN void Tcl_LimitSetTime(Tcl_Interp *interp,
Tcl_Time *timeLimitPtr);
/* 527 */
EXTERN void Tcl_LimitSetGranularity(Tcl_Interp *interp, int type,
int granularity);
/* 528 */
EXTERN int Tcl_LimitTypeEnabled(Tcl_Interp *interp, int type);
/* 529 */
EXTERN int Tcl_LimitTypeExceeded(Tcl_Interp *interp, int type);
/* 530 */
EXTERN void Tcl_LimitTypeSet(Tcl_Interp *interp, int type);
/* 531 */
EXTERN void Tcl_LimitTypeReset(Tcl_Interp *interp, int type);
/* 532 */
EXTERN Tcl_Size Tcl_LimitGetCommands(Tcl_Interp *interp);
/* 533 */
EXTERN void Tcl_LimitGetTime(Tcl_Interp *interp,
Tcl_Time *timeLimitPtr);
/* 534 */
EXTERN int Tcl_LimitGetGranularity(Tcl_Interp *interp, int type);
/* 535 */
EXTERN Tcl_InterpState Tcl_SaveInterpState(Tcl_Interp *interp, int status);
/* 536 */
EXTERN int Tcl_RestoreInterpState(Tcl_Interp *interp,
Tcl_InterpState state);
/* 537 */
EXTERN void Tcl_DiscardInterpState(Tcl_InterpState state);
/* 538 */
EXTERN int Tcl_SetReturnOptions(Tcl_Interp *interp,
Tcl_Obj *options);
/* 539 */
EXTERN Tcl_Obj * Tcl_GetReturnOptions(Tcl_Interp *interp, int result);
/* 540 */
EXTERN int Tcl_IsEnsemble(Tcl_Command token);
/* 541 */
EXTERN Tcl_Command Tcl_CreateEnsemble(Tcl_Interp *interp,
const char *name,
Tcl_Namespace *namespacePtr, int flags);
/* 542 */
EXTERN Tcl_Command Tcl_FindEnsemble(Tcl_Interp *interp,
Tcl_Obj *cmdNameObj, int flags);
/* 543 */
EXTERN int Tcl_SetEnsembleSubcommandList(Tcl_Interp *interp,
Tcl_Command token, Tcl_Obj *subcmdList);
/* 544 */
EXTERN int Tcl_SetEnsembleMappingDict(Tcl_Interp *interp,
Tcl_Command token, Tcl_Obj *mapDict);
/* 545 */
EXTERN int Tcl_SetEnsembleUnknownHandler(Tcl_Interp *interp,
Tcl_Command token, Tcl_Obj *unknownList);
/* 546 */
EXTERN int Tcl_SetEnsembleFlags(Tcl_Interp *interp,
Tcl_Command token, int flags);
/* 547 */
EXTERN int Tcl_GetEnsembleSubcommandList(Tcl_Interp *interp,
Tcl_Command token, Tcl_Obj **subcmdListPtr);
/* 548 */
EXTERN int Tcl_GetEnsembleMappingDict(Tcl_Interp *interp,
Tcl_Command token, Tcl_Obj **mapDictPtr);
/* 549 */
EXTERN int Tcl_GetEnsembleUnknownHandler(Tcl_Interp *interp,
Tcl_Command token, Tcl_Obj **unknownListPtr);
/* 550 */
EXTERN int Tcl_GetEnsembleFlags(Tcl_Interp *interp,
Tcl_Command token, int *flagsPtr);
/* 551 */
EXTERN int Tcl_GetEnsembleNamespace(Tcl_Interp *interp,
Tcl_Command token,
Tcl_Namespace **namespacePtrPtr);
/* 552 */
EXTERN void Tcl_SetTimeProc(Tcl_GetTimeProc *getProc,
Tcl_ScaleTimeProc *scaleProc,
void *clientData);
/* 553 */
EXTERN void Tcl_QueryTimeProc(Tcl_GetTimeProc **getProc,
Tcl_ScaleTimeProc **scaleProc,
void **clientData);
/* 554 */
EXTERN Tcl_DriverThreadActionProc * Tcl_ChannelThreadActionProc(
const Tcl_ChannelType *chanTypePtr);
/* 555 */
EXTERN Tcl_Obj * Tcl_NewBignumObj(void *value);
/* 556 */
EXTERN Tcl_Obj * Tcl_DbNewBignumObj(void *value, const char *file,
int line);
/* 557 */
EXTERN void Tcl_SetBignumObj(Tcl_Obj *obj, void *value);
/* 558 */
EXTERN int Tcl_GetBignumFromObj(Tcl_Interp *interp,
Tcl_Obj *obj, void *value);
/* 559 */
EXTERN int Tcl_TakeBignumFromObj(Tcl_Interp *interp,
Tcl_Obj *obj, void *value);
/* 560 */
EXTERN int Tcl_TruncateChannel(Tcl_Channel chan,
long long length);
/* 561 */
EXTERN Tcl_DriverTruncateProc * Tcl_ChannelTruncateProc(
const Tcl_ChannelType *chanTypePtr);
/* 562 */
EXTERN void Tcl_SetChannelErrorInterp(Tcl_Interp *interp,
Tcl_Obj *msg);
/* 563 */
EXTERN void Tcl_GetChannelErrorInterp(Tcl_Interp *interp,
Tcl_Obj **msg);
/* 564 */
EXTERN void Tcl_SetChannelError(Tcl_Channel chan, Tcl_Obj *msg);
/* 565 */
EXTERN void Tcl_GetChannelError(Tcl_Channel chan, Tcl_Obj **msg);
/* 566 */
EXTERN int Tcl_InitBignumFromDouble(Tcl_Interp *interp,
double initval, void *toInit);
/* 567 */
EXTERN Tcl_Obj * Tcl_GetNamespaceUnknownHandler(Tcl_Interp *interp,
Tcl_Namespace *nsPtr);
/* 568 */
EXTERN int Tcl_SetNamespaceUnknownHandler(Tcl_Interp *interp,
Tcl_Namespace *nsPtr, Tcl_Obj *handlerPtr);
/* 569 */
EXTERN int Tcl_GetEncodingFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, Tcl_Encoding *encodingPtr);
/* 570 */
EXTERN Tcl_Obj * Tcl_GetEncodingSearchPath(void);
/* 571 */
EXTERN int Tcl_SetEncodingSearchPath(Tcl_Obj *searchPath);
/* 572 */
EXTERN const char * Tcl_GetEncodingNameFromEnvironment(
Tcl_DString *bufPtr);
/* 573 */
EXTERN int Tcl_PkgRequireProc(Tcl_Interp *interp,
const char *name, Tcl_Size objc,
Tcl_Obj *const objv[], void *clientDataPtr);
/* 574 */
EXTERN void Tcl_AppendObjToErrorInfo(Tcl_Interp *interp,
Tcl_Obj *objPtr);
/* 575 */
EXTERN void Tcl_AppendLimitedToObj(Tcl_Obj *objPtr,
const char *bytes, Tcl_Size length,
Tcl_Size limit, const char *ellipsis);
/* 576 */
EXTERN Tcl_Obj * Tcl_Format(Tcl_Interp *interp, const char *format,
Tcl_Size objc, Tcl_Obj *const objv[]);
/* 577 */
EXTERN int Tcl_AppendFormatToObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, const char *format,
Tcl_Size objc, Tcl_Obj *const objv[]);
/* 578 */
EXTERN Tcl_Obj * Tcl_ObjPrintf(const char *format, ...) TCL_FORMAT_PRINTF(1, 2);
/* 579 */
EXTERN void Tcl_AppendPrintfToObj(Tcl_Obj *objPtr,
const char *format, ...) TCL_FORMAT_PRINTF(2, 3);
/* 580 */
EXTERN int Tcl_CancelEval(Tcl_Interp *interp,
Tcl_Obj *resultObjPtr, void *clientData,
int flags);
/* 581 */
EXTERN int Tcl_Canceled(Tcl_Interp *interp, int flags);
/* 582 */
EXTERN int Tcl_CreatePipe(Tcl_Interp *interp,
Tcl_Channel *rchan, Tcl_Channel *wchan,
int flags);
/* 583 */
EXTERN Tcl_Command Tcl_NRCreateCommand(Tcl_Interp *interp,
const char *cmdName, Tcl_ObjCmdProc *proc,
Tcl_ObjCmdProc *nreProc, void *clientData,
Tcl_CmdDeleteProc *deleteProc);
/* 584 */
EXTERN int Tcl_NREvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
int flags);
/* 585 */
EXTERN int Tcl_NREvalObjv(Tcl_Interp *interp, Tcl_Size objc,
Tcl_Obj *const objv[], int flags);
/* 586 */
EXTERN int Tcl_NRCmdSwap(Tcl_Interp *interp, Tcl_Command cmd,
Tcl_Size objc, Tcl_Obj *const objv[],
int flags);
/* 587 */
EXTERN void Tcl_NRAddCallback(Tcl_Interp *interp,
Tcl_NRPostProc *postProcPtr, void *data0,
void *data1, void *data2, void *data3);
/* 588 */
EXTERN int Tcl_NRCallObjProc(Tcl_Interp *interp,
Tcl_ObjCmdProc *objProc, void *clientData,
Tcl_Size objc, Tcl_Obj *const objv[]);
/* 589 */
EXTERN unsigned Tcl_GetFSDeviceFromStat(const Tcl_StatBuf *statPtr);
/* 590 */
EXTERN unsigned Tcl_GetFSInodeFromStat(const Tcl_StatBuf *statPtr);
/* 591 */
EXTERN unsigned Tcl_GetModeFromStat(const Tcl_StatBuf *statPtr);
/* 592 */
EXTERN int Tcl_GetLinkCountFromStat(const Tcl_StatBuf *statPtr);
/* 593 */
EXTERN int Tcl_GetUserIdFromStat(const Tcl_StatBuf *statPtr);
/* 594 */
EXTERN int Tcl_GetGroupIdFromStat(const Tcl_StatBuf *statPtr);
/* 595 */
EXTERN int Tcl_GetDeviceTypeFromStat(const Tcl_StatBuf *statPtr);
/* 596 */
EXTERN long long Tcl_GetAccessTimeFromStat(const Tcl_StatBuf *statPtr);
/* 597 */
EXTERN long long Tcl_GetModificationTimeFromStat(
const Tcl_StatBuf *statPtr);
/* 598 */
EXTERN long long Tcl_GetChangeTimeFromStat(const Tcl_StatBuf *statPtr);
/* 599 */
EXTERN unsigned long long Tcl_GetSizeFromStat(const Tcl_StatBuf *statPtr);
/* 600 */
EXTERN unsigned long long Tcl_GetBlocksFromStat(const Tcl_StatBuf *statPtr);
/* 601 */
EXTERN unsigned Tcl_GetBlockSizeFromStat(const Tcl_StatBuf *statPtr);
/* 602 */
EXTERN int Tcl_SetEnsembleParameterList(Tcl_Interp *interp,
Tcl_Command token, Tcl_Obj *paramList);
/* 603 */
EXTERN int Tcl_GetEnsembleParameterList(Tcl_Interp *interp,
Tcl_Command token, Tcl_Obj **paramListPtr);
/* 604 */
EXTERN int TclParseArgsObjv(Tcl_Interp *interp,
const Tcl_ArgvInfo *argTable, void *objcPtr,
Tcl_Obj *const *objv, Tcl_Obj ***remObjv);
/* 605 */
EXTERN int Tcl_GetErrorLine(Tcl_Interp *interp);
/* 606 */
EXTERN void Tcl_SetErrorLine(Tcl_Interp *interp, int lineNum);
/* 607 */
EXTERN void Tcl_TransferResult(Tcl_Interp *sourceInterp,
int code, Tcl_Interp *targetInterp);
/* 608 */
EXTERN int Tcl_InterpActive(Tcl_Interp *interp);
/* 609 */
EXTERN void Tcl_BackgroundException(Tcl_Interp *interp, int code);
/* 610 */
EXTERN int Tcl_ZlibDeflate(Tcl_Interp *interp, int format,
Tcl_Obj *data, int level,
Tcl_Obj *gzipHeaderDictObj);
/* 611 */
EXTERN int Tcl_ZlibInflate(Tcl_Interp *interp, int format,
Tcl_Obj *data, Tcl_Size buffersize,
Tcl_Obj *gzipHeaderDictObj);
/* 612 */
EXTERN unsigned int Tcl_ZlibCRC32(unsigned int crc,
const unsigned char *buf, Tcl_Size len);
/* 613 */
EXTERN unsigned int Tcl_ZlibAdler32(unsigned int adler,
const unsigned char *buf, Tcl_Size len);
/* 614 */
EXTERN int Tcl_ZlibStreamInit(Tcl_Interp *interp, int mode,
int format, int level, Tcl_Obj *dictObj,
Tcl_ZlibStream *zshandle);
/* 615 */
EXTERN Tcl_Obj * Tcl_ZlibStreamGetCommandName(Tcl_ZlibStream zshandle);
/* 616 */
EXTERN int Tcl_ZlibStreamEof(Tcl_ZlibStream zshandle);
/* 617 */
EXTERN int Tcl_ZlibStreamChecksum(Tcl_ZlibStream zshandle);
/* 618 */
EXTERN int Tcl_ZlibStreamPut(Tcl_ZlibStream zshandle,
Tcl_Obj *data, int flush);
/* 619 */
EXTERN int Tcl_ZlibStreamGet(Tcl_ZlibStream zshandle,
Tcl_Obj *data, Tcl_Size count);
/* 620 */
EXTERN int Tcl_ZlibStreamClose(Tcl_ZlibStream zshandle);
/* 621 */
EXTERN int Tcl_ZlibStreamReset(Tcl_ZlibStream zshandle);
/* 622 */
EXTERN void Tcl_SetStartupScript(Tcl_Obj *path,
const char *encoding);
/* 623 */
EXTERN Tcl_Obj * Tcl_GetStartupScript(const char **encodingPtr);
/* 624 */
EXTERN int Tcl_CloseEx(Tcl_Interp *interp, Tcl_Channel chan,
int flags);
/* 625 */
EXTERN int Tcl_NRExprObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
Tcl_Obj *resultPtr);
/* 626 */
EXTERN int Tcl_NRSubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
int flags);
/* 627 */
EXTERN int Tcl_LoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr,
const char *const symv[], int flags,
void *procPtrs, Tcl_LoadHandle *handlePtr);
/* 628 */
EXTERN void * Tcl_FindSymbol(Tcl_Interp *interp,
Tcl_LoadHandle handle, const char *symbol);
/* 629 */
EXTERN int Tcl_FSUnloadFile(Tcl_Interp *interp,
Tcl_LoadHandle handlePtr);
/* 630 */
EXTERN void Tcl_ZlibStreamSetCompressionDictionary(
Tcl_ZlibStream zhandle,
Tcl_Obj *compressionDictionaryObj);
/* 631 */
EXTERN Tcl_Channel Tcl_OpenTcpServerEx(Tcl_Interp *interp,
const char *service, const char *host,
unsigned int flags, int backlog,
Tcl_TcpAcceptProc *acceptProc,
void *callbackData);
/* 632 */
EXTERN int TclZipfs_Mount(Tcl_Interp *interp,
const char *zipname, const char *mountPoint,
const char *passwd);
/* 633 */
EXTERN int TclZipfs_Unmount(Tcl_Interp *interp,
const char *mountPoint);
/* 634 */
EXTERN Tcl_Obj * TclZipfs_TclLibrary(void);
/* 635 */
EXTERN int TclZipfs_MountBuffer(Tcl_Interp *interp,
const void *data, size_t datalen,
const char *mountPoint, int copy);
/* 636 */
EXTERN void Tcl_FreeInternalRep(Tcl_Obj *objPtr);
/* 637 */
EXTERN char * Tcl_InitStringRep(Tcl_Obj *objPtr, const char *bytes,
TCL_HASH_TYPE numBytes);
/* 638 */
EXTERN Tcl_ObjInternalRep * Tcl_FetchInternalRep(Tcl_Obj *objPtr,
const Tcl_ObjType *typePtr);
/* 639 */
EXTERN void Tcl_StoreInternalRep(Tcl_Obj *objPtr,
const Tcl_ObjType *typePtr,
const Tcl_ObjInternalRep *irPtr);
/* 640 */
EXTERN int Tcl_HasStringRep(Tcl_Obj *objPtr);
/* 641 */
EXTERN void Tcl_IncrRefCount(Tcl_Obj *objPtr);
/* 642 */
EXTERN void Tcl_DecrRefCount(Tcl_Obj *objPtr);
/* 643 */
EXTERN int Tcl_IsShared(Tcl_Obj *objPtr);
/* 644 */
EXTERN int Tcl_LinkArray(Tcl_Interp *interp,
const char *varName, void *addr, int type,
Tcl_Size size);
/* 645 */
EXTERN int Tcl_GetIntForIndex(Tcl_Interp *interp,
Tcl_Obj *objPtr, Tcl_Size endValue,
Tcl_Size *indexPtr);
/* 646 */
EXTERN Tcl_Size Tcl_UtfToUniChar(const char *src, int *chPtr);
/* 647 */
EXTERN char * Tcl_UniCharToUtfDString(const int *uniStr,
Tcl_Size uniLength, Tcl_DString *dsPtr);
/* 648 */
EXTERN int * Tcl_UtfToUniCharDString(const char *src,
Tcl_Size length, Tcl_DString *dsPtr);
/* 649 */
EXTERN unsigned char * TclGetBytesFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, void *numBytesPtr);
/* 650 */
EXTERN unsigned char * Tcl_GetBytesFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, Tcl_Size *numBytesPtr);
/* 651 */
EXTERN char * Tcl_GetStringFromObj(Tcl_Obj *objPtr,
Tcl_Size *lengthPtr);
/* 652 */
EXTERN Tcl_UniChar * Tcl_GetUnicodeFromObj(Tcl_Obj *objPtr,
Tcl_Size *lengthPtr);
/* 653 */
EXTERN int Tcl_GetSizeIntFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, Tcl_Size *sizePtr);
/* 654 */
EXTERN int Tcl_UtfCharComplete(const char *src, Tcl_Size length);
/* 655 */
EXTERN const char * Tcl_UtfNext(const char *src);
/* 656 */
EXTERN const char * Tcl_UtfPrev(const char *src, const char *start);
/* 657 */
EXTERN int Tcl_FSTildeExpand(Tcl_Interp *interp,
const char *path, Tcl_DString *dsPtr);
/* 658 */
EXTERN int Tcl_ExternalToUtfDStringEx(Tcl_Interp *interp,
Tcl_Encoding encoding, const char *src,
Tcl_Size srcLen, int flags,
Tcl_DString *dsPtr,
Tcl_Size *errorLocationPtr);
/* 659 */
EXTERN int Tcl_UtfToExternalDStringEx(Tcl_Interp *interp,
Tcl_Encoding encoding, const char *src,
Tcl_Size srcLen, int flags,
Tcl_DString *dsPtr,
Tcl_Size *errorLocationPtr);
/* 660 */
EXTERN int Tcl_AsyncMarkFromSignal(Tcl_AsyncHandler async,
int sigNumber);
/* 661 */
EXTERN int Tcl_ListObjGetElements(Tcl_Interp *interp,
Tcl_Obj *listPtr, Tcl_Size *objcPtr,
Tcl_Obj ***objvPtr);
/* 662 */
EXTERN int Tcl_ListObjLength(Tcl_Interp *interp,
Tcl_Obj *listPtr, Tcl_Size *lengthPtr);
/* 663 */
EXTERN int Tcl_DictObjSize(Tcl_Interp *interp, Tcl_Obj *dictPtr,
Tcl_Size *sizePtr);
/* 664 */
EXTERN int Tcl_SplitList(Tcl_Interp *interp,
const char *listStr, Tcl_Size *argcPtr,
const char ***argvPtr);
/* 665 */
EXTERN void Tcl_SplitPath(const char *path, Tcl_Size *argcPtr,
const char ***argvPtr);
/* 666 */
EXTERN Tcl_Obj * Tcl_FSSplitPath(Tcl_Obj *pathPtr, Tcl_Size *lenPtr);
/* 667 */
EXTERN int Tcl_ParseArgsObjv(Tcl_Interp *interp,
const Tcl_ArgvInfo *argTable,
Tcl_Size *objcPtr, Tcl_Obj *const *objv,
Tcl_Obj ***remObjv);
/* 668 */
EXTERN Tcl_Size Tcl_UniCharLen(const int *uniStr);
/* 669 */
EXTERN Tcl_Size Tcl_NumUtfChars(const char *src, Tcl_Size length);
/* 670 */
EXTERN Tcl_Size Tcl_GetCharLength(Tcl_Obj *objPtr);
/* 671 */
EXTERN const char * Tcl_UtfAtIndex(const char *src, Tcl_Size index);
/* 672 */
EXTERN Tcl_Obj * Tcl_GetRange(Tcl_Obj *objPtr, Tcl_Size first,
Tcl_Size last);
/* 673 */
EXTERN int Tcl_GetUniChar(Tcl_Obj *objPtr, Tcl_Size index);
/* 674 */
EXTERN int Tcl_GetBool(Tcl_Interp *interp, const char *src,
int flags, char *charPtr);
/* 675 */
EXTERN int Tcl_GetBoolFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, int flags, char *charPtr);
/* 676 */
EXTERN Tcl_Command Tcl_CreateObjCommand2(Tcl_Interp *interp,
const char *cmdName, Tcl_ObjCmdProc2 *proc2,
void *clientData,
Tcl_CmdDeleteProc *deleteProc);
/* 677 */
EXTERN Tcl_Trace Tcl_CreateObjTrace2(Tcl_Interp *interp,
Tcl_Size level, int flags,
Tcl_CmdObjTraceProc2 *objProc2,
void *clientData,
Tcl_CmdObjTraceDeleteProc *delProc);
/* 678 */
EXTERN Tcl_Command Tcl_NRCreateCommand2(Tcl_Interp *interp,
const char *cmdName, Tcl_ObjCmdProc2 *proc,
Tcl_ObjCmdProc2 *nreProc2, void *clientData,
Tcl_CmdDeleteProc *deleteProc);
/* 679 */
EXTERN int Tcl_NRCallObjProc2(Tcl_Interp *interp,
Tcl_ObjCmdProc2 *objProc2, void *clientData,
Tcl_Size objc, Tcl_Obj *const objv[]);
/* 680 */
EXTERN int Tcl_GetNumberFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, void **clientDataPtr,
int *typePtr);
/* 681 */
EXTERN int Tcl_GetNumber(Tcl_Interp *interp, const char *bytes,
Tcl_Size numBytes, void **clientDataPtr,
int *typePtr);
/* 682 */
EXTERN int Tcl_RemoveChannelMode(Tcl_Interp *interp,
Tcl_Channel chan, int mode);
/* 683 */
EXTERN Tcl_Size Tcl_GetEncodingNulLength(Tcl_Encoding encoding);
/* 684 */
EXTERN int Tcl_GetWideUIntFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, Tcl_WideUInt *uwidePtr);
/* 685 */
EXTERN Tcl_Obj * Tcl_DStringToObj(Tcl_DString *dsPtr);
/* 686 */
EXTERN int Tcl_UtfNcmp(const char *s1, const char *s2, size_t n);
/* 687 */
EXTERN int Tcl_UtfNcasecmp(const char *s1, const char *s2,
size_t n);
/* 688 */
EXTERN Tcl_Obj * Tcl_NewWideUIntObj(Tcl_WideUInt wideValue);
/* 689 */
EXTERN void Tcl_SetWideUIntObj(Tcl_Obj *objPtr,
Tcl_WideUInt uwideValue);
/* 690 */
EXTERN void TclUnusedStubEntry(void);
typedef struct {
const struct TclPlatStubs *tclPlatStubs;
const struct TclIntStubs *tclIntStubs;
const struct TclIntPlatStubs *tclIntPlatStubs;
} TclStubHooks;
typedef struct TclStubs {
int magic;
const TclStubHooks *hooks;
int (*tcl_PkgProvideEx) (Tcl_Interp *interp, const char *name, const char *version, const void *clientData); /* 0 */
const char * (*tcl_PkgRequireEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 1 */
TCL_NORETURN1 void (*tcl_Panic) (const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 2 */
void * (*tcl_Alloc) (TCL_HASH_TYPE size); /* 3 */
void (*tcl_Free) (void *ptr); /* 4 */
void * (*tcl_Realloc) (void *ptr, TCL_HASH_TYPE size); /* 5 */
void * (*tcl_DbCkalloc) (TCL_HASH_TYPE size, const char *file, int line); /* 6 */
void (*tcl_DbCkfree) (void *ptr, const char *file, int line); /* 7 */
void * (*tcl_DbCkrealloc) (void *ptr, TCL_HASH_TYPE size, const char *file, int line); /* 8 */
void (*tcl_CreateFileHandler) (int fd, int mask, Tcl_FileProc *proc, void *clientData); /* 9 */
void (*tcl_DeleteFileHandler) (int fd); /* 10 */
void (*tcl_SetTimer) (const Tcl_Time *timePtr); /* 11 */
void (*tcl_Sleep) (int ms); /* 12 */
int (*tcl_WaitForEvent) (const Tcl_Time *timePtr); /* 13 */
int (*tcl_AppendAllObjTypes) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 14 */
void (*tcl_AppendStringsToObj) (Tcl_Obj *objPtr, ...); /* 15 */
void (*tcl_AppendToObj) (Tcl_Obj *objPtr, const char *bytes, Tcl_Size length); /* 16 */
Tcl_Obj * (*tcl_ConcatObj) (Tcl_Size objc, Tcl_Obj *const objv[]); /* 17 */
int (*tcl_ConvertToType) (Tcl_Interp *interp, Tcl_Obj *objPtr, const Tcl_ObjType *typePtr); /* 18 */
void (*tcl_DbDecrRefCount) (Tcl_Obj *objPtr, const char *file, int line); /* 19 */
void (*tcl_DbIncrRefCount) (Tcl_Obj *objPtr, const char *file, int line); /* 20 */
int (*tcl_DbIsShared) (Tcl_Obj *objPtr, const char *file, int line); /* 21 */
void (*reserved22)(void);
Tcl_Obj * (*tcl_DbNewByteArrayObj) (const unsigned char *bytes, Tcl_Size numBytes, const char *file, int line); /* 23 */
Tcl_Obj * (*tcl_DbNewDoubleObj) (double doubleValue, const char *file, int line); /* 24 */
Tcl_Obj * (*tcl_DbNewListObj) (Tcl_Size objc, Tcl_Obj *const *objv, const char *file, int line); /* 25 */
void (*reserved26)(void);
Tcl_Obj * (*tcl_DbNewObj) (const char *file, int line); /* 27 */
Tcl_Obj * (*tcl_DbNewStringObj) (const char *bytes, Tcl_Size length, const char *file, int line); /* 28 */
Tcl_Obj * (*tcl_DuplicateObj) (Tcl_Obj *objPtr); /* 29 */
void (*tclFreeObj) (Tcl_Obj *objPtr); /* 30 */
int (*tcl_GetBoolean) (Tcl_Interp *interp, const char *src, int *intPtr); /* 31 */
int (*tcl_GetBooleanFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *intPtr); /* 32 */
unsigned char * (*tcl_GetByteArrayFromObj) (Tcl_Obj *objPtr, Tcl_Size *numBytesPtr); /* 33 */
int (*tcl_GetDouble) (Tcl_Interp *interp, const char *src, double *doublePtr); /* 34 */
int (*tcl_GetDoubleFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, double *doublePtr); /* 35 */
void (*reserved36)(void);
int (*tcl_GetInt) (Tcl_Interp *interp, const char *src, int *intPtr); /* 37 */
int (*tcl_GetIntFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *intPtr); /* 38 */
int (*tcl_GetLongFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, long *longPtr); /* 39 */
const Tcl_ObjType * (*tcl_GetObjType) (const char *typeName); /* 40 */
char * (*tclGetStringFromObj) (Tcl_Obj *objPtr, void *lengthPtr); /* 41 */
void (*tcl_InvalidateStringRep) (Tcl_Obj *objPtr); /* 42 */
int (*tcl_ListObjAppendList) (Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *elemListPtr); /* 43 */
int (*tcl_ListObjAppendElement) (Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *objPtr); /* 44 */
int (*tclListObjGetElements) (Tcl_Interp *interp, Tcl_Obj *listPtr, void *objcPtr, Tcl_Obj ***objvPtr); /* 45 */
int (*tcl_ListObjIndex) (Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Size index, Tcl_Obj **objPtrPtr); /* 46 */
int (*tclListObjLength) (Tcl_Interp *interp, Tcl_Obj *listPtr, void *lengthPtr); /* 47 */
int (*tcl_ListObjReplace) (Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Size first, Tcl_Size count, Tcl_Size objc, Tcl_Obj *const objv[]); /* 48 */
void (*reserved49)(void);
Tcl_Obj * (*tcl_NewByteArrayObj) (const unsigned char *bytes, Tcl_Size numBytes); /* 50 */
Tcl_Obj * (*tcl_NewDoubleObj) (double doubleValue); /* 51 */
void (*reserved52)(void);
Tcl_Obj * (*tcl_NewListObj) (Tcl_Size objc, Tcl_Obj *const objv[]); /* 53 */
void (*reserved54)(void);
Tcl_Obj * (*tcl_NewObj) (void); /* 55 */
Tcl_Obj * (*tcl_NewStringObj) (const char *bytes, Tcl_Size length); /* 56 */
void (*reserved57)(void);
unsigned char * (*tcl_SetByteArrayLength) (Tcl_Obj *objPtr, Tcl_Size numBytes); /* 58 */
void (*tcl_SetByteArrayObj) (Tcl_Obj *objPtr, const unsigned char *bytes, Tcl_Size numBytes); /* 59 */
void (*tcl_SetDoubleObj) (Tcl_Obj *objPtr, double doubleValue); /* 60 */
void (*reserved61)(void);
void (*tcl_SetListObj) (Tcl_Obj *objPtr, Tcl_Size objc, Tcl_Obj *const objv[]); /* 62 */
void (*reserved63)(void);
void (*tcl_SetObjLength) (Tcl_Obj *objPtr, Tcl_Size length); /* 64 */
void (*tcl_SetStringObj) (Tcl_Obj *objPtr, const char *bytes, Tcl_Size length); /* 65 */
void (*reserved66)(void);
void (*reserved67)(void);
void (*tcl_AllowExceptions) (Tcl_Interp *interp); /* 68 */
void (*tcl_AppendElement) (Tcl_Interp *interp, const char *element); /* 69 */
void (*tcl_AppendResult) (Tcl_Interp *interp, ...); /* 70 */
Tcl_AsyncHandler (*tcl_AsyncCreate) (Tcl_AsyncProc *proc, void *clientData); /* 71 */
void (*tcl_AsyncDelete) (Tcl_AsyncHandler async); /* 72 */
int (*tcl_AsyncInvoke) (Tcl_Interp *interp, int code); /* 73 */
void (*tcl_AsyncMark) (Tcl_AsyncHandler async); /* 74 */
int (*tcl_AsyncReady) (void); /* 75 */
void (*reserved76)(void);
void (*reserved77)(void);
int (*tcl_BadChannelOption) (Tcl_Interp *interp, const char *optionName, const char *optionList); /* 78 */
void (*tcl_CallWhenDeleted) (Tcl_Interp *interp, Tcl_InterpDeleteProc *proc, void *clientData); /* 79 */
void (*tcl_CancelIdleCall) (Tcl_IdleProc *idleProc, void *clientData); /* 80 */
int (*tcl_Close) (Tcl_Interp *interp, Tcl_Channel chan); /* 81 */
int (*tcl_CommandComplete) (const char *cmd); /* 82 */
char * (*tcl_Concat) (Tcl_Size argc, const char *const *argv); /* 83 */
Tcl_Size (*tcl_ConvertElement) (const char *src, char *dst, int flags); /* 84 */
Tcl_Size (*tcl_ConvertCountedElement) (const char *src, Tcl_Size length, char *dst, int flags); /* 85 */
int (*tcl_CreateAlias) (Tcl_Interp *childInterp, const char *childCmd, Tcl_Interp *target, const char *targetCmd, Tcl_Size argc, const char *const *argv); /* 86 */
int (*tcl_CreateAliasObj) (Tcl_Interp *childInterp, const char *childCmd, Tcl_Interp *target, const char *targetCmd, Tcl_Size objc, Tcl_Obj *const objv[]); /* 87 */
Tcl_Channel (*tcl_CreateChannel) (const Tcl_ChannelType *typePtr, const char *chanName, void *instanceData, int mask); /* 88 */
void (*tcl_CreateChannelHandler) (Tcl_Channel chan, int mask, Tcl_ChannelProc *proc, void *clientData); /* 89 */
void (*tcl_CreateCloseHandler) (Tcl_Channel chan, Tcl_CloseProc *proc, void *clientData); /* 90 */
Tcl_Command (*tcl_CreateCommand) (Tcl_Interp *interp, const char *cmdName, Tcl_CmdProc *proc, void *clientData, Tcl_CmdDeleteProc *deleteProc); /* 91 */
void (*tcl_CreateEventSource) (Tcl_EventSetupProc *setupProc, Tcl_EventCheckProc *checkProc, void *clientData); /* 92 */
void (*tcl_CreateExitHandler) (Tcl_ExitProc *proc, void *clientData); /* 93 */
Tcl_Interp * (*tcl_CreateInterp) (void); /* 94 */
void (*reserved95)(void);
Tcl_Command (*tcl_CreateObjCommand) (Tcl_Interp *interp, const char *cmdName, Tcl_ObjCmdProc *proc, void *clientData, Tcl_CmdDeleteProc *deleteProc); /* 96 */
Tcl_Interp * (*tcl_CreateChild) (Tcl_Interp *interp, const char *name, int isSafe); /* 97 */
Tcl_TimerToken (*tcl_CreateTimerHandler) (int milliseconds, Tcl_TimerProc *proc, void *clientData); /* 98 */
Tcl_Trace (*tcl_CreateTrace) (Tcl_Interp *interp, Tcl_Size level, Tcl_CmdTraceProc *proc, void *clientData); /* 99 */
void (*tcl_DeleteAssocData) (Tcl_Interp *interp, const char *name); /* 100 */
void (*tcl_DeleteChannelHandler) (Tcl_Channel chan, Tcl_ChannelProc *proc, void *clientData); /* 101 */
void (*tcl_DeleteCloseHandler) (Tcl_Channel chan, Tcl_CloseProc *proc, void *clientData); /* 102 */
int (*tcl_DeleteCommand) (Tcl_Interp *interp, const char *cmdName); /* 103 */
int (*tcl_DeleteCommandFromToken) (Tcl_Interp *interp, Tcl_Command command); /* 104 */
void (*tcl_DeleteEvents) (Tcl_EventDeleteProc *proc, void *clientData); /* 105 */
void (*tcl_DeleteEventSource) (Tcl_EventSetupProc *setupProc, Tcl_EventCheckProc *checkProc, void *clientData); /* 106 */
void (*tcl_DeleteExitHandler) (Tcl_ExitProc *proc, void *clientData); /* 107 */
void (*tcl_DeleteHashEntry) (Tcl_HashEntry *entryPtr); /* 108 */
void (*tcl_DeleteHashTable) (Tcl_HashTable *tablePtr); /* 109 */
void (*tcl_DeleteInterp) (Tcl_Interp *interp); /* 110 */
void (*tcl_DetachPids) (Tcl_Size numPids, Tcl_Pid *pidPtr); /* 111 */
void (*tcl_DeleteTimerHandler) (Tcl_TimerToken token); /* 112 */
void (*tcl_DeleteTrace) (Tcl_Interp *interp, Tcl_Trace trace); /* 113 */
void (*tcl_DontCallWhenDeleted) (Tcl_Interp *interp, Tcl_InterpDeleteProc *proc, void *clientData); /* 114 */
int (*tcl_DoOneEvent) (int flags); /* 115 */
void (*tcl_DoWhenIdle) (Tcl_IdleProc *proc, void *clientData); /* 116 */
char * (*tcl_DStringAppend) (Tcl_DString *dsPtr, const char *bytes, Tcl_Size length); /* 117 */
char * (*tcl_DStringAppendElement) (Tcl_DString *dsPtr, const char *element); /* 118 */
void (*tcl_DStringEndSublist) (Tcl_DString *dsPtr); /* 119 */
void (*tcl_DStringFree) (Tcl_DString *dsPtr); /* 120 */
void (*tcl_DStringGetResult) (Tcl_Interp *interp, Tcl_DString *dsPtr); /* 121 */
void (*tcl_DStringInit) (Tcl_DString *dsPtr); /* 122 */
void (*tcl_DStringResult) (Tcl_Interp *interp, Tcl_DString *dsPtr); /* 123 */
void (*tcl_DStringSetLength) (Tcl_DString *dsPtr, Tcl_Size length); /* 124 */
void (*tcl_DStringStartSublist) (Tcl_DString *dsPtr); /* 125 */
int (*tcl_Eof) (Tcl_Channel chan); /* 126 */
const char * (*tcl_ErrnoId) (void); /* 127 */
const char * (*tcl_ErrnoMsg) (int err); /* 128 */
void (*reserved129)(void);
int (*tcl_EvalFile) (Tcl_Interp *interp, const char *fileName); /* 130 */
void (*reserved131)(void);
void (*tcl_EventuallyFree) (void *clientData, Tcl_FreeProc *freeProc); /* 132 */
TCL_NORETURN1 void (*tcl_Exit) (int status); /* 133 */
int (*tcl_ExposeCommand) (Tcl_Interp *interp, const char *hiddenCmdToken, const char *cmdName); /* 134 */
int (*tcl_ExprBoolean) (Tcl_Interp *interp, const char *expr, int *ptr); /* 135 */
int (*tcl_ExprBooleanObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *ptr); /* 136 */
int (*tcl_ExprDouble) (Tcl_Interp *interp, const char *expr, double *ptr); /* 137 */
int (*tcl_ExprDoubleObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, double *ptr); /* 138 */
int (*tcl_ExprLong) (Tcl_Interp *interp, const char *expr, long *ptr); /* 139 */
int (*tcl_ExprLongObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, long *ptr); /* 140 */
int (*tcl_ExprObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj **resultPtrPtr); /* 141 */
int (*tcl_ExprString) (Tcl_Interp *interp, const char *expr); /* 142 */
void (*tcl_Finalize) (void); /* 143 */
void (*reserved144)(void);
Tcl_HashEntry * (*tcl_FirstHashEntry) (Tcl_HashTable *tablePtr, Tcl_HashSearch *searchPtr); /* 145 */
int (*tcl_Flush) (Tcl_Channel chan); /* 146 */
void (*reserved147)(void);
void (*reserved148)(void);
int (*tclGetAliasObj) (Tcl_Interp *interp, const char *childCmd, Tcl_Interp **targetInterpPtr, const char **targetCmdPtr, int *objcPtr, Tcl_Obj ***objvPtr); /* 149 */
void * (*tcl_GetAssocData) (Tcl_Interp *interp, const char *name, Tcl_InterpDeleteProc **procPtr); /* 150 */
Tcl_Channel (*tcl_GetChannel) (Tcl_Interp *interp, const char *chanName, int *modePtr); /* 151 */
Tcl_Size (*tcl_GetChannelBufferSize) (Tcl_Channel chan); /* 152 */
int (*tcl_GetChannelHandle) (Tcl_Channel chan, int direction, void **handlePtr); /* 153 */
void * (*tcl_GetChannelInstanceData) (Tcl_Channel chan); /* 154 */
int (*tcl_GetChannelMode) (Tcl_Channel chan); /* 155 */
const char * (*tcl_GetChannelName) (Tcl_Channel chan); /* 156 */
int (*tcl_GetChannelOption) (Tcl_Interp *interp, Tcl_Channel chan, const char *optionName, Tcl_DString *dsPtr); /* 157 */
const Tcl_ChannelType * (*tcl_GetChannelType) (Tcl_Channel chan); /* 158 */
int (*tcl_GetCommandInfo) (Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr); /* 159 */
const char * (*tcl_GetCommandName) (Tcl_Interp *interp, Tcl_Command command); /* 160 */
int (*tcl_GetErrno) (void); /* 161 */
const char * (*tcl_GetHostName) (void); /* 162 */
int (*tcl_GetInterpPath) (Tcl_Interp *interp, Tcl_Interp *childInterp); /* 163 */
Tcl_Interp * (*tcl_GetParent) (Tcl_Interp *interp); /* 164 */
const char * (*tcl_GetNameOfExecutable) (void); /* 165 */
Tcl_Obj * (*tcl_GetObjResult) (Tcl_Interp *interp); /* 166 */
int (*tcl_GetOpenFile) (Tcl_Interp *interp, const char *chanID, int forWriting, int checkUsage, void **filePtr); /* 167 */
Tcl_PathType (*tcl_GetPathType) (const char *path); /* 168 */
Tcl_Size (*tcl_Gets) (Tcl_Channel chan, Tcl_DString *dsPtr); /* 169 */
Tcl_Size (*tcl_GetsObj) (Tcl_Channel chan, Tcl_Obj *objPtr); /* 170 */
int (*tcl_GetServiceMode) (void); /* 171 */
Tcl_Interp * (*tcl_GetChild) (Tcl_Interp *interp, const char *name); /* 172 */
Tcl_Channel (*tcl_GetStdChannel) (int type); /* 173 */
void (*reserved174)(void);
void (*reserved175)(void);
const char * (*tcl_GetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 176 */
void (*reserved177)(void);
void (*reserved178)(void);
int (*tcl_HideCommand) (Tcl_Interp *interp, const char *cmdName, const char *hiddenCmdToken); /* 179 */
int (*tcl_Init) (Tcl_Interp *interp); /* 180 */
void (*tcl_InitHashTable) (Tcl_HashTable *tablePtr, int keyType); /* 181 */
int (*tcl_InputBlocked) (Tcl_Channel chan); /* 182 */
int (*tcl_InputBuffered) (Tcl_Channel chan); /* 183 */
int (*tcl_InterpDeleted) (Tcl_Interp *interp); /* 184 */
int (*tcl_IsSafe) (Tcl_Interp *interp); /* 185 */
char * (*tcl_JoinPath) (Tcl_Size argc, const char *const *argv, Tcl_DString *resultPtr); /* 186 */
int (*tcl_LinkVar) (Tcl_Interp *interp, const char *varName, void *addr, int type); /* 187 */
void (*reserved188)(void);
Tcl_Channel (*tcl_MakeFileChannel) (void *handle, int mode); /* 189 */
void (*reserved190)(void);
Tcl_Channel (*tcl_MakeTcpClientChannel) (void *tcpSocket); /* 191 */
char * (*tcl_Merge) (Tcl_Size argc, const char *const *argv); /* 192 */
Tcl_HashEntry * (*tcl_NextHashEntry) (Tcl_HashSearch *searchPtr); /* 193 */
void (*tcl_NotifyChannel) (Tcl_Channel channel, int mask); /* 194 */
Tcl_Obj * (*tcl_ObjGetVar2) (Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags); /* 195 */
Tcl_Obj * (*tcl_ObjSetVar2) (Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags); /* 196 */
Tcl_Channel (*tcl_OpenCommandChannel) (Tcl_Interp *interp, Tcl_Size argc, const char **argv, int flags); /* 197 */
Tcl_Channel (*tcl_OpenFileChannel) (Tcl_Interp *interp, const char *fileName, const char *modeString, int permissions); /* 198 */
Tcl_Channel (*tcl_OpenTcpClient) (Tcl_Interp *interp, int port, const char *address, const char *myaddr, int myport, int flags); /* 199 */
Tcl_Channel (*tcl_OpenTcpServer) (Tcl_Interp *interp, int port, const char *host, Tcl_TcpAcceptProc *acceptProc, void *callbackData); /* 200 */
void (*tcl_Preserve) (void *data); /* 201 */
void (*tcl_PrintDouble) (Tcl_Interp *interp, double value, char *dst); /* 202 */
int (*tcl_PutEnv) (const char *assignment); /* 203 */
const char * (*tcl_PosixError) (Tcl_Interp *interp); /* 204 */
void (*tcl_QueueEvent) (Tcl_Event *evPtr, int position); /* 205 */
Tcl_Size (*tcl_Read) (Tcl_Channel chan, char *bufPtr, Tcl_Size toRead); /* 206 */
void (*tcl_ReapDetachedProcs) (void); /* 207 */
int (*tcl_RecordAndEval) (Tcl_Interp *interp, const char *cmd, int flags); /* 208 */
int (*tcl_RecordAndEvalObj) (Tcl_Interp *interp, Tcl_Obj *cmdPtr, int flags); /* 209 */
void (*tcl_RegisterChannel) (Tcl_Interp *interp, Tcl_Channel chan); /* 210 */
void (*tcl_RegisterObjType) (const Tcl_ObjType *typePtr); /* 211 */
Tcl_RegExp (*tcl_RegExpCompile) (Tcl_Interp *interp, const char *pattern); /* 212 */
int (*tcl_RegExpExec) (Tcl_Interp *interp, Tcl_RegExp regexp, const char *text, const char *start); /* 213 */
int (*tcl_RegExpMatch) (Tcl_Interp *interp, const char *text, const char *pattern); /* 214 */
void (*tcl_RegExpRange) (Tcl_RegExp regexp, Tcl_Size index, const char **startPtr, const char **endPtr); /* 215 */
void (*tcl_Release) (void *clientData); /* 216 */
void (*tcl_ResetResult) (Tcl_Interp *interp); /* 217 */
Tcl_Size (*tcl_ScanElement) (const char *src, int *flagPtr); /* 218 */
Tcl_Size (*tcl_ScanCountedElement) (const char *src, Tcl_Size length, int *flagPtr); /* 219 */
void (*reserved220)(void);
int (*tcl_ServiceAll) (void); /* 221 */
int (*tcl_ServiceEvent) (int flags); /* 222 */
void (*tcl_SetAssocData) (Tcl_Interp *interp, const char *name, Tcl_InterpDeleteProc *proc, void *clientData); /* 223 */
void (*tcl_SetChannelBufferSize) (Tcl_Channel chan, Tcl_Size sz); /* 224 */
int (*tcl_SetChannelOption) (Tcl_Interp *interp, Tcl_Channel chan, const char *optionName, const char *newValue); /* 225 */
int (*tcl_SetCommandInfo) (Tcl_Interp *interp, const char *cmdName, const Tcl_CmdInfo *infoPtr); /* 226 */
void (*tcl_SetErrno) (int err); /* 227 */
void (*tcl_SetErrorCode) (Tcl_Interp *interp, ...); /* 228 */
void (*tcl_SetMaxBlockTime) (const Tcl_Time *timePtr); /* 229 */
void (*reserved230)(void);
Tcl_Size (*tcl_SetRecursionLimit) (Tcl_Interp *interp, Tcl_Size depth); /* 231 */
void (*reserved232)(void);
int (*tcl_SetServiceMode) (int mode); /* 233 */
void (*tcl_SetObjErrorCode) (Tcl_Interp *interp, Tcl_Obj *errorObjPtr); /* 234 */
void (*tcl_SetObjResult) (Tcl_Interp *interp, Tcl_Obj *resultObjPtr); /* 235 */
void (*tcl_SetStdChannel) (Tcl_Channel channel, int type); /* 236 */
void (*reserved237)(void);
const char * (*tcl_SetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, const char *newValue, int flags); /* 238 */
const char * (*tcl_SignalId) (int sig); /* 239 */
const char * (*tcl_SignalMsg) (int sig); /* 240 */
void (*tcl_SourceRCFile) (Tcl_Interp *interp); /* 241 */
int (*tclSplitList) (Tcl_Interp *interp, const char *listStr, void *argcPtr, const char ***argvPtr); /* 242 */
void (*tclSplitPath) (const char *path, void *argcPtr, const char ***argvPtr); /* 243 */
void (*reserved244)(void);
void (*reserved245)(void);
void (*reserved246)(void);
void (*reserved247)(void);
int (*tcl_TraceVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *proc, void *clientData); /* 248 */
char * (*tcl_TranslateFileName) (Tcl_Interp *interp, const char *name, Tcl_DString *bufferPtr); /* 249 */
Tcl_Size (*tcl_Ungets) (Tcl_Channel chan, const char *str, Tcl_Size len, int atHead); /* 250 */
void (*tcl_UnlinkVar) (Tcl_Interp *interp, const char *varName); /* 251 */
int (*tcl_UnregisterChannel) (Tcl_Interp *interp, Tcl_Channel chan); /* 252 */
void (*reserved253)(void);
int (*tcl_UnsetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 254 */
void (*reserved255)(void);
void (*tcl_UntraceVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *proc, void *clientData); /* 256 */
void (*tcl_UpdateLinkedVar) (Tcl_Interp *interp, const char *varName); /* 257 */
void (*reserved258)(void);
int (*tcl_UpVar2) (Tcl_Interp *interp, const char *frameName, const char *part1, const char *part2, const char *localName, int flags); /* 259 */
int (*tcl_VarEval) (Tcl_Interp *interp, ...); /* 260 */
void (*reserved261)(void);
void * (*tcl_VarTraceInfo2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *procPtr, void *prevClientData); /* 262 */
Tcl_Size (*tcl_Write) (Tcl_Channel chan, const char *s, Tcl_Size slen); /* 263 */
void (*tcl_WrongNumArgs) (Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[], const char *message); /* 264 */
int (*tcl_DumpActiveMemory) (const char *fileName); /* 265 */
void (*tcl_ValidateAllMemory) (const char *file, int line); /* 266 */
void (*reserved267)(void);
void (*reserved268)(void);
char * (*tcl_HashStats) (Tcl_HashTable *tablePtr); /* 269 */
const char * (*tcl_ParseVar) (Tcl_Interp *interp, const char *start, const char **termPtr); /* 270 */
void (*reserved271)(void);
const char * (*tcl_PkgPresentEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 272 */
void (*reserved273)(void);
void (*reserved274)(void);
void (*reserved275)(void);
void (*reserved276)(void);
Tcl_Pid (*tcl_WaitPid) (Tcl_Pid pid, int *statPtr, int options); /* 277 */
void (*reserved278)(void);
void (*tcl_GetVersion) (int *major, int *minor, int *patchLevel, int *type); /* 279 */
void (*tcl_InitMemory) (Tcl_Interp *interp); /* 280 */
Tcl_Channel (*tcl_StackChannel) (Tcl_Interp *interp, const Tcl_ChannelType *typePtr, void *instanceData, int mask, Tcl_Channel prevChan); /* 281 */
int (*tcl_UnstackChannel) (Tcl_Interp *interp, Tcl_Channel chan); /* 282 */
Tcl_Channel (*tcl_GetStackedChannel) (Tcl_Channel chan); /* 283 */
void (*tcl_SetMainLoop) (Tcl_MainLoopProc *proc); /* 284 */
int (*tcl_GetAliasObj) (Tcl_Interp *interp, const char *childCmd, Tcl_Interp **targetInterpPtr, const char **targetCmdPtr, Tcl_Size *objcPtr, Tcl_Obj ***objvPtr); /* 285 */
void (*tcl_AppendObjToObj) (Tcl_Obj *objPtr, Tcl_Obj *appendObjPtr); /* 286 */
Tcl_Encoding (*tcl_CreateEncoding) (const Tcl_EncodingType *typePtr); /* 287 */
void (*tcl_CreateThreadExitHandler) (Tcl_ExitProc *proc, void *clientData); /* 288 */
void (*tcl_DeleteThreadExitHandler) (Tcl_ExitProc *proc, void *clientData); /* 289 */
void (*reserved290)(void);
int (*tcl_EvalEx) (Tcl_Interp *interp, const char *script, Tcl_Size numBytes, int flags); /* 291 */
int (*tcl_EvalObjv) (Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[], int flags); /* 292 */
int (*tcl_EvalObjEx) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 293 */
TCL_NORETURN1 void (*tcl_ExitThread) (int status); /* 294 */
int (*tcl_ExternalToUtf) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, Tcl_Size dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr); /* 295 */
char * (*tcl_ExternalToUtfDString) (Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, Tcl_DString *dsPtr); /* 296 */
void (*tcl_FinalizeThread) (void); /* 297 */
void (*tcl_FinalizeNotifier) (void *clientData); /* 298 */
void (*tcl_FreeEncoding) (Tcl_Encoding encoding); /* 299 */
Tcl_ThreadId (*tcl_GetCurrentThread) (void); /* 300 */
Tcl_Encoding (*tcl_GetEncoding) (Tcl_Interp *interp, const char *name); /* 301 */
const char * (*tcl_GetEncodingName) (Tcl_Encoding encoding); /* 302 */
void (*tcl_GetEncodingNames) (Tcl_Interp *interp); /* 303 */
int (*tcl_GetIndexFromObjStruct) (Tcl_Interp *interp, Tcl_Obj *objPtr, const void *tablePtr, Tcl_Size offset, const char *msg, int flags, void *indexPtr); /* 304 */
void * (*tcl_GetThreadData) (Tcl_ThreadDataKey *keyPtr, Tcl_Size size); /* 305 */
Tcl_Obj * (*tcl_GetVar2Ex) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 306 */
void * (*tcl_InitNotifier) (void); /* 307 */
void (*tcl_MutexLock) (Tcl_Mutex *mutexPtr); /* 308 */
void (*tcl_MutexUnlock) (Tcl_Mutex *mutexPtr); /* 309 */
void (*tcl_ConditionNotify) (Tcl_Condition *condPtr); /* 310 */
void (*tcl_ConditionWait) (Tcl_Condition *condPtr, Tcl_Mutex *mutexPtr, const Tcl_Time *timePtr); /* 311 */
Tcl_Size (*tclNumUtfChars) (const char *src, Tcl_Size length); /* 312 */
Tcl_Size (*tcl_ReadChars) (Tcl_Channel channel, Tcl_Obj *objPtr, Tcl_Size charsToRead, int appendFlag); /* 313 */
void (*reserved314)(void);
void (*reserved315)(void);
int (*tcl_SetSystemEncoding) (Tcl_Interp *interp, const char *name); /* 316 */
Tcl_Obj * (*tcl_SetVar2Ex) (Tcl_Interp *interp, const char *part1, const char *part2, Tcl_Obj *newValuePtr, int flags); /* 317 */
void (*tcl_ThreadAlert) (Tcl_ThreadId threadId); /* 318 */
void (*tcl_ThreadQueueEvent) (Tcl_ThreadId threadId, Tcl_Event *evPtr, int position); /* 319 */
int (*tcl_UniCharAtIndex) (const char *src, Tcl_Size index); /* 320 */
int (*tcl_UniCharToLower) (int ch); /* 321 */
int (*tcl_UniCharToTitle) (int ch); /* 322 */
int (*tcl_UniCharToUpper) (int ch); /* 323 */
Tcl_Size (*tcl_UniCharToUtf) (int ch, char *buf); /* 324 */
const char * (*tclUtfAtIndex) (const char *src, Tcl_Size index); /* 325 */
int (*tclUtfCharComplete) (const char *src, Tcl_Size length); /* 326 */
Tcl_Size (*tcl_UtfBackslash) (const char *src, int *readPtr, char *dst); /* 327 */
const char * (*tcl_UtfFindFirst) (const char *src, int ch); /* 328 */
const char * (*tcl_UtfFindLast) (const char *src, int ch); /* 329 */
const char * (*tclUtfNext) (const char *src); /* 330 */
const char * (*tclUtfPrev) (const char *src, const char *start); /* 331 */
int (*tcl_UtfToExternal) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, Tcl_Size dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr); /* 332 */
char * (*tcl_UtfToExternalDString) (Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, Tcl_DString *dsPtr); /* 333 */
Tcl_Size (*tcl_UtfToLower) (char *src); /* 334 */
Tcl_Size (*tcl_UtfToTitle) (char *src); /* 335 */
Tcl_Size (*tcl_UtfToChar16) (const char *src, unsigned short *chPtr); /* 336 */
Tcl_Size (*tcl_UtfToUpper) (char *src); /* 337 */
Tcl_Size (*tcl_WriteChars) (Tcl_Channel chan, const char *src, Tcl_Size srcLen); /* 338 */
Tcl_Size (*tcl_WriteObj) (Tcl_Channel chan, Tcl_Obj *objPtr); /* 339 */
char * (*tcl_GetString) (Tcl_Obj *objPtr); /* 340 */
void (*reserved341)(void);
void (*reserved342)(void);
void (*tcl_AlertNotifier) (void *clientData); /* 343 */
void (*tcl_ServiceModeHook) (int mode); /* 344 */
int (*tcl_UniCharIsAlnum) (int ch); /* 345 */
int (*tcl_UniCharIsAlpha) (int ch); /* 346 */
int (*tcl_UniCharIsDigit) (int ch); /* 347 */
int (*tcl_UniCharIsLower) (int ch); /* 348 */
int (*tcl_UniCharIsSpace) (int ch); /* 349 */
int (*tcl_UniCharIsUpper) (int ch); /* 350 */
int (*tcl_UniCharIsWordChar) (int ch); /* 351 */
Tcl_Size (*tcl_Char16Len) (const unsigned short *uniStr); /* 352 */
void (*reserved353)(void);
char * (*tcl_Char16ToUtfDString) (const unsigned short *uniStr, Tcl_Size uniLength, Tcl_DString *dsPtr); /* 354 */
unsigned short * (*tcl_UtfToChar16DString) (const char *src, Tcl_Size length, Tcl_DString *dsPtr); /* 355 */
Tcl_RegExp (*tcl_GetRegExpFromObj) (Tcl_Interp *interp, Tcl_Obj *patObj, int flags); /* 356 */
void (*reserved357)(void);
void (*tcl_FreeParse) (Tcl_Parse *parsePtr); /* 358 */
void (*tcl_LogCommandInfo) (Tcl_Interp *interp, const char *script, const char *command, Tcl_Size length); /* 359 */
int (*tcl_ParseBraces) (Tcl_Interp *interp, const char *start, Tcl_Size numBytes, Tcl_Parse *parsePtr, int append, const char **termPtr); /* 360 */
int (*tcl_ParseCommand) (Tcl_Interp *interp, const char *start, Tcl_Size numBytes, int nested, Tcl_Parse *parsePtr); /* 361 */
int (*tcl_ParseExpr) (Tcl_Interp *interp, const char *start, Tcl_Size numBytes, Tcl_Parse *parsePtr); /* 362 */
int (*tcl_ParseQuotedString) (Tcl_Interp *interp, const char *start, Tcl_Size numBytes, Tcl_Parse *parsePtr, int append, const char **termPtr); /* 363 */
int (*tcl_ParseVarName) (Tcl_Interp *interp, const char *start, Tcl_Size numBytes, Tcl_Parse *parsePtr, int append); /* 364 */
char * (*tcl_GetCwd) (Tcl_Interp *interp, Tcl_DString *cwdPtr); /* 365 */
int (*tcl_Chdir) (const char *dirName); /* 366 */
int (*tcl_Access) (const char *path, int mode); /* 367 */
int (*tcl_Stat) (const char *path, struct stat *bufPtr); /* 368 */
int (*tclUtfNcmp) (const char *s1, const char *s2, size_t n); /* 369 */
int (*tclUtfNcasecmp) (const char *s1, const char *s2, size_t n); /* 370 */
int (*tcl_StringCaseMatch) (const char *str, const char *pattern, int nocase); /* 371 */
int (*tcl_UniCharIsControl) (int ch); /* 372 */
int (*tcl_UniCharIsGraph) (int ch); /* 373 */
int (*tcl_UniCharIsPrint) (int ch); /* 374 */
int (*tcl_UniCharIsPunct) (int ch); /* 375 */
int (*tcl_RegExpExecObj) (Tcl_Interp *interp, Tcl_RegExp regexp, Tcl_Obj *textObj, Tcl_Size offset, Tcl_Size nmatches, int flags); /* 376 */
void (*tcl_RegExpGetInfo) (Tcl_RegExp regexp, Tcl_RegExpInfo *infoPtr); /* 377 */
Tcl_Obj * (*tcl_NewUnicodeObj) (const Tcl_UniChar *unicode, Tcl_Size numChars); /* 378 */
void (*tcl_SetUnicodeObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, Tcl_Size numChars); /* 379 */
Tcl_Size (*tclGetCharLength) (Tcl_Obj *objPtr); /* 380 */
int (*tclGetUniChar) (Tcl_Obj *objPtr, Tcl_Size index); /* 381 */
void (*reserved382)(void);
Tcl_Obj * (*tclGetRange) (Tcl_Obj *objPtr, Tcl_Size first, Tcl_Size last); /* 383 */
void (*tcl_AppendUnicodeToObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, Tcl_Size length); /* 384 */
int (*tcl_RegExpMatchObj) (Tcl_Interp *interp, Tcl_Obj *textObj, Tcl_Obj *patternObj); /* 385 */
void (*tcl_SetNotifier) (const Tcl_NotifierProcs *notifierProcPtr); /* 386 */
Tcl_Mutex * (*tcl_GetAllocMutex) (void); /* 387 */
int (*tcl_GetChannelNames) (Tcl_Interp *interp); /* 388 */
int (*tcl_GetChannelNamesEx) (Tcl_Interp *interp, const char *pattern); /* 389 */
int (*tcl_ProcObjCmd) (void *clientData, Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[]); /* 390 */
void (*tcl_ConditionFinalize) (Tcl_Condition *condPtr); /* 391 */
void (*tcl_MutexFinalize) (Tcl_Mutex *mutex); /* 392 */
int (*tcl_CreateThread) (Tcl_ThreadId *idPtr, Tcl_ThreadCreateProc *proc, void *clientData, TCL_HASH_TYPE stackSize, int flags); /* 393 */
Tcl_Size (*tcl_ReadRaw) (Tcl_Channel chan, char *dst, Tcl_Size bytesToRead); /* 394 */
Tcl_Size (*tcl_WriteRaw) (Tcl_Channel chan, const char *src, Tcl_Size srcLen); /* 395 */
Tcl_Channel (*tcl_GetTopChannel) (Tcl_Channel chan); /* 396 */
int (*tcl_ChannelBuffered) (Tcl_Channel chan); /* 397 */
const char * (*tcl_ChannelName) (const Tcl_ChannelType *chanTypePtr); /* 398 */
Tcl_ChannelTypeVersion (*tcl_ChannelVersion) (const Tcl_ChannelType *chanTypePtr); /* 399 */
Tcl_DriverBlockModeProc * (*tcl_ChannelBlockModeProc) (const Tcl_ChannelType *chanTypePtr); /* 400 */
void (*reserved401)(void);
Tcl_DriverClose2Proc * (*tcl_ChannelClose2Proc) (const Tcl_ChannelType *chanTypePtr); /* 402 */
Tcl_DriverInputProc * (*tcl_ChannelInputProc) (const Tcl_ChannelType *chanTypePtr); /* 403 */
Tcl_DriverOutputProc * (*tcl_ChannelOutputProc) (const Tcl_ChannelType *chanTypePtr); /* 404 */
void (*reserved405)(void);
Tcl_DriverSetOptionProc * (*tcl_ChannelSetOptionProc) (const Tcl_ChannelType *chanTypePtr); /* 406 */
Tcl_DriverGetOptionProc * (*tcl_ChannelGetOptionProc) (const Tcl_ChannelType *chanTypePtr); /* 407 */
Tcl_DriverWatchProc * (*tcl_ChannelWatchProc) (const Tcl_ChannelType *chanTypePtr); /* 408 */
Tcl_DriverGetHandleProc * (*tcl_ChannelGetHandleProc) (const Tcl_ChannelType *chanTypePtr); /* 409 */
Tcl_DriverFlushProc * (*tcl_ChannelFlushProc) (const Tcl_ChannelType *chanTypePtr); /* 410 */
Tcl_DriverHandlerProc * (*tcl_ChannelHandlerProc) (const Tcl_ChannelType *chanTypePtr); /* 411 */
int (*tcl_JoinThread) (Tcl_ThreadId threadId, int *result); /* 412 */
int (*tcl_IsChannelShared) (Tcl_Channel channel); /* 413 */
int (*tcl_IsChannelRegistered) (Tcl_Interp *interp, Tcl_Channel channel); /* 414 */
void (*tcl_CutChannel) (Tcl_Channel channel); /* 415 */
void (*tcl_SpliceChannel) (Tcl_Channel channel); /* 416 */
void (*tcl_ClearChannelHandlers) (Tcl_Channel channel); /* 417 */
int (*tcl_IsChannelExisting) (const char *channelName); /* 418 */
void (*reserved419)(void);
void (*reserved420)(void);
void (*reserved421)(void);
Tcl_HashEntry * (*tcl_CreateHashEntry) (Tcl_HashTable *tablePtr, const void *key, int *newPtr); /* 422 */
void (*tcl_InitCustomHashTable) (Tcl_HashTable *tablePtr, int keyType, const Tcl_HashKeyType *typePtr); /* 423 */
void (*tcl_InitObjHashTable) (Tcl_HashTable *tablePtr); /* 424 */
void * (*tcl_CommandTraceInfo) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *procPtr, void *prevClientData); /* 425 */
int (*tcl_TraceCommand) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, void *clientData); /* 426 */
void (*tcl_UntraceCommand) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, void *clientData); /* 427 */
void * (*tcl_AttemptAlloc) (TCL_HASH_TYPE size); /* 428 */
void * (*tcl_AttemptDbCkalloc) (TCL_HASH_TYPE size, const char *file, int line); /* 429 */
void * (*tcl_AttemptRealloc) (void *ptr, TCL_HASH_TYPE size); /* 430 */
void * (*tcl_AttemptDbCkrealloc) (void *ptr, TCL_HASH_TYPE size, const char *file, int line); /* 431 */
int (*tcl_AttemptSetObjLength) (Tcl_Obj *objPtr, Tcl_Size length); /* 432 */
Tcl_ThreadId (*tcl_GetChannelThread) (Tcl_Channel channel); /* 433 */
Tcl_UniChar * (*tclGetUnicodeFromObj) (Tcl_Obj *objPtr, void *lengthPtr); /* 434 */
void (*reserved435)(void);
void (*reserved436)(void);
Tcl_Obj * (*tcl_SubstObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 437 */
int (*tcl_DetachChannel) (Tcl_Interp *interp, Tcl_Channel channel); /* 438 */
int (*tcl_IsStandardChannel) (Tcl_Channel channel); /* 439 */
int (*tcl_FSCopyFile) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); /* 440 */
int (*tcl_FSCopyDirectory) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr); /* 441 */
int (*tcl_FSCreateDirectory) (Tcl_Obj *pathPtr); /* 442 */
int (*tcl_FSDeleteFile) (Tcl_Obj *pathPtr); /* 443 */
int (*tcl_FSLoadFile) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *sym1, const char *sym2, Tcl_LibraryInitProc **proc1Ptr, Tcl_LibraryInitProc **proc2Ptr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr); /* 444 */
int (*tcl_FSMatchInDirectory) (Tcl_Interp *interp, Tcl_Obj *result, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); /* 445 */
Tcl_Obj * (*tcl_FSLink) (Tcl_Obj *pathPtr, Tcl_Obj *toPtr, int linkAction); /* 446 */
int (*tcl_FSRemoveDirectory) (Tcl_Obj *pathPtr, int recursive, Tcl_Obj **errorPtr); /* 447 */
int (*tcl_FSRenameFile) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); /* 448 */
int (*tcl_FSLstat) (Tcl_Obj *pathPtr, Tcl_StatBuf *buf); /* 449 */
int (*tcl_FSUtime) (Tcl_Obj *pathPtr, struct utimbuf *tval); /* 450 */
int (*tcl_FSFileAttrsGet) (Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); /* 451 */
int (*tcl_FSFileAttrsSet) (Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr); /* 452 */
const char *const * (*tcl_FSFileAttrStrings) (Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); /* 453 */
int (*tcl_FSStat) (Tcl_Obj *pathPtr, Tcl_StatBuf *buf); /* 454 */
int (*tcl_FSAccess) (Tcl_Obj *pathPtr, int mode); /* 455 */
Tcl_Channel (*tcl_FSOpenFileChannel) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *modeString, int permissions); /* 456 */
Tcl_Obj * (*tcl_FSGetCwd) (Tcl_Interp *interp); /* 457 */
int (*tcl_FSChdir) (Tcl_Obj *pathPtr); /* 458 */
int (*tcl_FSConvertToPathType) (Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 459 */
Tcl_Obj * (*tcl_FSJoinPath) (Tcl_Obj *listObj, Tcl_Size elements); /* 460 */
Tcl_Obj * (*tclFSSplitPath) (Tcl_Obj *pathPtr, void *lenPtr); /* 461 */
int (*tcl_FSEqualPaths) (Tcl_Obj *firstPtr, Tcl_Obj *secondPtr); /* 462 */
Tcl_Obj * (*tcl_FSGetNormalizedPath) (Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 463 */
Tcl_Obj * (*tcl_FSJoinToPath) (Tcl_Obj *pathPtr, Tcl_Size objc, Tcl_Obj *const objv[]); /* 464 */
void * (*tcl_FSGetInternalRep) (Tcl_Obj *pathPtr, const Tcl_Filesystem *fsPtr); /* 465 */
Tcl_Obj * (*tcl_FSGetTranslatedPath) (Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 466 */
int (*tcl_FSEvalFile) (Tcl_Interp *interp, Tcl_Obj *fileName); /* 467 */
Tcl_Obj * (*tcl_FSNewNativePath) (const Tcl_Filesystem *fromFilesystem, void *clientData); /* 468 */
const void * (*tcl_FSGetNativePath) (Tcl_Obj *pathPtr); /* 469 */
Tcl_Obj * (*tcl_FSFileSystemInfo) (Tcl_Obj *pathPtr); /* 470 */
Tcl_Obj * (*tcl_FSPathSeparator) (Tcl_Obj *pathPtr); /* 471 */
Tcl_Obj * (*tcl_FSListVolumes) (void); /* 472 */
int (*tcl_FSRegister) (void *clientData, const Tcl_Filesystem *fsPtr); /* 473 */
int (*tcl_FSUnregister) (const Tcl_Filesystem *fsPtr); /* 474 */
void * (*tcl_FSData) (const Tcl_Filesystem *fsPtr); /* 475 */
const char * (*tcl_FSGetTranslatedStringPath) (Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 476 */
const Tcl_Filesystem * (*tcl_FSGetFileSystemForPath) (Tcl_Obj *pathPtr); /* 477 */
Tcl_PathType (*tcl_FSGetPathType) (Tcl_Obj *pathPtr); /* 478 */
int (*tcl_OutputBuffered) (Tcl_Channel chan); /* 479 */
void (*tcl_FSMountsChanged) (const Tcl_Filesystem *fsPtr); /* 480 */
int (*tcl_EvalTokensStandard) (Tcl_Interp *interp, Tcl_Token *tokenPtr, Tcl_Size count); /* 481 */
void (*tcl_GetTime) (Tcl_Time *timeBuf); /* 482 */
Tcl_Trace (*tcl_CreateObjTrace) (Tcl_Interp *interp, Tcl_Size level, int flags, Tcl_CmdObjTraceProc *objProc, void *clientData, Tcl_CmdObjTraceDeleteProc *delProc); /* 483 */
int (*tcl_GetCommandInfoFromToken) (Tcl_Command token, Tcl_CmdInfo *infoPtr); /* 484 */
int (*tcl_SetCommandInfoFromToken) (Tcl_Command token, const Tcl_CmdInfo *infoPtr); /* 485 */
Tcl_Obj * (*tcl_DbNewWideIntObj) (Tcl_WideInt wideValue, const char *file, int line); /* 486 */
int (*tcl_GetWideIntFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_WideInt *widePtr); /* 487 */
Tcl_Obj * (*tcl_NewWideIntObj) (Tcl_WideInt wideValue); /* 488 */
void (*tcl_SetWideIntObj) (Tcl_Obj *objPtr, Tcl_WideInt wideValue); /* 489 */
Tcl_StatBuf * (*tcl_AllocStatBuf) (void); /* 490 */
long long (*tcl_Seek) (Tcl_Channel chan, long long offset, int mode); /* 491 */
long long (*tcl_Tell) (Tcl_Channel chan); /* 492 */
Tcl_DriverWideSeekProc * (*tcl_ChannelWideSeekProc) (const Tcl_ChannelType *chanTypePtr); /* 493 */
int (*tcl_DictObjPut) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr, Tcl_Obj *valuePtr); /* 494 */
int (*tcl_DictObjGet) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr, Tcl_Obj **valuePtrPtr); /* 495 */
int (*tcl_DictObjRemove) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr); /* 496 */
int (*tclDictObjSize) (Tcl_Interp *interp, Tcl_Obj *dictPtr, void *sizePtr); /* 497 */
int (*tcl_DictObjFirst) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_DictSearch *searchPtr, Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr); /* 498 */
void (*tcl_DictObjNext) (Tcl_DictSearch *searchPtr, Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr); /* 499 */
void (*tcl_DictObjDone) (Tcl_DictSearch *searchPtr); /* 500 */
int (*tcl_DictObjPutKeyList) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Size keyc, Tcl_Obj *const *keyv, Tcl_Obj *valuePtr); /* 501 */
int (*tcl_DictObjRemoveKeyList) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Size keyc, Tcl_Obj *const *keyv); /* 502 */
Tcl_Obj * (*tcl_NewDictObj) (void); /* 503 */
Tcl_Obj * (*tcl_DbNewDictObj) (const char *file, int line); /* 504 */
void (*tcl_RegisterConfig) (Tcl_Interp *interp, const char *pkgName, const Tcl_Config *configuration, const char *valEncoding); /* 505 */
Tcl_Namespace * (*tcl_CreateNamespace) (Tcl_Interp *interp, const char *name, void *clientData, Tcl_NamespaceDeleteProc *deleteProc); /* 506 */
void (*tcl_DeleteNamespace) (Tcl_Namespace *nsPtr); /* 507 */
int (*tcl_AppendExportList) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, Tcl_Obj *objPtr); /* 508 */
int (*tcl_Export) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern, int resetListFirst); /* 509 */
int (*tcl_Import) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern, int allowOverwrite); /* 510 */
int (*tcl_ForgetImport) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern); /* 511 */
Tcl_Namespace * (*tcl_GetCurrentNamespace) (Tcl_Interp *interp); /* 512 */
Tcl_Namespace * (*tcl_GetGlobalNamespace) (Tcl_Interp *interp); /* 513 */
Tcl_Namespace * (*tcl_FindNamespace) (Tcl_Interp *interp, const char *name, Tcl_Namespace *contextNsPtr, int flags); /* 514 */
Tcl_Command (*tcl_FindCommand) (Tcl_Interp *interp, const char *name, Tcl_Namespace *contextNsPtr, int flags); /* 515 */
Tcl_Command (*tcl_GetCommandFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 516 */
void (*tcl_GetCommandFullName) (Tcl_Interp *interp, Tcl_Command command, Tcl_Obj *objPtr); /* 517 */
int (*tcl_FSEvalFileEx) (Tcl_Interp *interp, Tcl_Obj *fileName, const char *encodingName); /* 518 */
void (*reserved519)(void);
void (*tcl_LimitAddHandler) (Tcl_Interp *interp, int type, Tcl_LimitHandlerProc *handlerProc, void *clientData, Tcl_LimitHandlerDeleteProc *deleteProc); /* 520 */
void (*tcl_LimitRemoveHandler) (Tcl_Interp *interp, int type, Tcl_LimitHandlerProc *handlerProc, void *clientData); /* 521 */
int (*tcl_LimitReady) (Tcl_Interp *interp); /* 522 */
int (*tcl_LimitCheck) (Tcl_Interp *interp); /* 523 */
int (*tcl_LimitExceeded) (Tcl_Interp *interp); /* 524 */
void (*tcl_LimitSetCommands) (Tcl_Interp *interp, Tcl_Size commandLimit); /* 525 */
void (*tcl_LimitSetTime) (Tcl_Interp *interp, Tcl_Time *timeLimitPtr); /* 526 */
void (*tcl_LimitSetGranularity) (Tcl_Interp *interp, int type, int granularity); /* 527 */
int (*tcl_LimitTypeEnabled) (Tcl_Interp *interp, int type); /* 528 */
int (*tcl_LimitTypeExceeded) (Tcl_Interp *interp, int type); /* 529 */
void (*tcl_LimitTypeSet) (Tcl_Interp *interp, int type); /* 530 */
void (*tcl_LimitTypeReset) (Tcl_Interp *interp, int type); /* 531 */
Tcl_Size (*tcl_LimitGetCommands) (Tcl_Interp *interp); /* 532 */
void (*tcl_LimitGetTime) (Tcl_Interp *interp, Tcl_Time *timeLimitPtr); /* 533 */
int (*tcl_LimitGetGranularity) (Tcl_Interp *interp, int type); /* 534 */
Tcl_InterpState (*tcl_SaveInterpState) (Tcl_Interp *interp, int status); /* 535 */
int (*tcl_RestoreInterpState) (Tcl_Interp *interp, Tcl_InterpState state); /* 536 */
void (*tcl_DiscardInterpState) (Tcl_InterpState state); /* 537 */
int (*tcl_SetReturnOptions) (Tcl_Interp *interp, Tcl_Obj *options); /* 538 */
Tcl_Obj * (*tcl_GetReturnOptions) (Tcl_Interp *interp, int result); /* 539 */
int (*tcl_IsEnsemble) (Tcl_Command token); /* 540 */
Tcl_Command (*tcl_CreateEnsemble) (Tcl_Interp *interp, const char *name, Tcl_Namespace *namespacePtr, int flags); /* 541 */
Tcl_Command (*tcl_FindEnsemble) (Tcl_Interp *interp, Tcl_Obj *cmdNameObj, int flags); /* 542 */
int (*tcl_SetEnsembleSubcommandList) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj *subcmdList); /* 543 */
int (*tcl_SetEnsembleMappingDict) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj *mapDict); /* 544 */
int (*tcl_SetEnsembleUnknownHandler) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj *unknownList); /* 545 */
int (*tcl_SetEnsembleFlags) (Tcl_Interp *interp, Tcl_Command token, int flags); /* 546 */
int (*tcl_GetEnsembleSubcommandList) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj **subcmdListPtr); /* 547 */
int (*tcl_GetEnsembleMappingDict) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj **mapDictPtr); /* 548 */
int (*tcl_GetEnsembleUnknownHandler) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj **unknownListPtr); /* 549 */
int (*tcl_GetEnsembleFlags) (Tcl_Interp *interp, Tcl_Command token, int *flagsPtr); /* 550 */
int (*tcl_GetEnsembleNamespace) (Tcl_Interp *interp, Tcl_Command token, Tcl_Namespace **namespacePtrPtr); /* 551 */
void (*tcl_SetTimeProc) (Tcl_GetTimeProc *getProc, Tcl_ScaleTimeProc *scaleProc, void *clientData); /* 552 */
void (*tcl_QueryTimeProc) (Tcl_GetTimeProc **getProc, Tcl_ScaleTimeProc **scaleProc, void **clientData); /* 553 */
Tcl_DriverThreadActionProc * (*tcl_ChannelThreadActionProc) (const Tcl_ChannelType *chanTypePtr); /* 554 */
Tcl_Obj * (*tcl_NewBignumObj) (void *value); /* 555 */
Tcl_Obj * (*tcl_DbNewBignumObj) (void *value, const char *file, int line); /* 556 */
void (*tcl_SetBignumObj) (Tcl_Obj *obj, void *value); /* 557 */
int (*tcl_GetBignumFromObj) (Tcl_Interp *interp, Tcl_Obj *obj, void *value); /* 558 */
int (*tcl_TakeBignumFromObj) (Tcl_Interp *interp, Tcl_Obj *obj, void *value); /* 559 */
int (*tcl_TruncateChannel) (Tcl_Channel chan, long long length); /* 560 */
Tcl_DriverTruncateProc * (*tcl_ChannelTruncateProc) (const Tcl_ChannelType *chanTypePtr); /* 561 */
void (*tcl_SetChannelErrorInterp) (Tcl_Interp *interp, Tcl_Obj *msg); /* 562 */
void (*tcl_GetChannelErrorInterp) (Tcl_Interp *interp, Tcl_Obj **msg); /* 563 */
void (*tcl_SetChannelError) (Tcl_Channel chan, Tcl_Obj *msg); /* 564 */
void (*tcl_GetChannelError) (Tcl_Channel chan, Tcl_Obj **msg); /* 565 */
int (*tcl_InitBignumFromDouble) (Tcl_Interp *interp, double initval, void *toInit); /* 566 */
Tcl_Obj * (*tcl_GetNamespaceUnknownHandler) (Tcl_Interp *interp, Tcl_Namespace *nsPtr); /* 567 */
int (*tcl_SetNamespaceUnknownHandler) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, Tcl_Obj *handlerPtr); /* 568 */
int (*tcl_GetEncodingFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Encoding *encodingPtr); /* 569 */
Tcl_Obj * (*tcl_GetEncodingSearchPath) (void); /* 570 */
int (*tcl_SetEncodingSearchPath) (Tcl_Obj *searchPath); /* 571 */
const char * (*tcl_GetEncodingNameFromEnvironment) (Tcl_DString *bufPtr); /* 572 */
int (*tcl_PkgRequireProc) (Tcl_Interp *interp, const char *name, Tcl_Size objc, Tcl_Obj *const objv[], void *clientDataPtr); /* 573 */
void (*tcl_AppendObjToErrorInfo) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 574 */
void (*tcl_AppendLimitedToObj) (Tcl_Obj *objPtr, const char *bytes, Tcl_Size length, Tcl_Size limit, const char *ellipsis); /* 575 */
Tcl_Obj * (*tcl_Format) (Tcl_Interp *interp, const char *format, Tcl_Size objc, Tcl_Obj *const objv[]); /* 576 */
int (*tcl_AppendFormatToObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, const char *format, Tcl_Size objc, Tcl_Obj *const objv[]); /* 577 */
Tcl_Obj * (*tcl_ObjPrintf) (const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 578 */
void (*tcl_AppendPrintfToObj) (Tcl_Obj *objPtr, const char *format, ...) TCL_FORMAT_PRINTF(2, 3); /* 579 */
int (*tcl_CancelEval) (Tcl_Interp *interp, Tcl_Obj *resultObjPtr, void *clientData, int flags); /* 580 */
int (*tcl_Canceled) (Tcl_Interp *interp, int flags); /* 581 */
int (*tcl_CreatePipe) (Tcl_Interp *interp, Tcl_Channel *rchan, Tcl_Channel *wchan, int flags); /* 582 */
Tcl_Command (*tcl_NRCreateCommand) (Tcl_Interp *interp, const char *cmdName, Tcl_ObjCmdProc *proc, Tcl_ObjCmdProc *nreProc, void *clientData, Tcl_CmdDeleteProc *deleteProc); /* 583 */
int (*tcl_NREvalObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 584 */
int (*tcl_NREvalObjv) (Tcl_Interp *interp, Tcl_Size objc, Tcl_Obj *const objv[], int flags); /* 585 */
int (*tcl_NRCmdSwap) (Tcl_Interp *interp, Tcl_Command cmd, Tcl_Size objc, Tcl_Obj *const objv[], int flags); /* 586 */
void (*tcl_NRAddCallback) (Tcl_Interp *interp, Tcl_NRPostProc *postProcPtr, void *data0, void *data1, void *data2, void *data3); /* 587 */
int (*tcl_NRCallObjProc) (Tcl_Interp *interp, Tcl_ObjCmdProc *objProc, void *clientData, Tcl_Size objc, Tcl_Obj *const objv[]); /* 588 */
unsigned (*tcl_GetFSDeviceFromStat) (const Tcl_StatBuf *statPtr); /* 589 */
unsigned (*tcl_GetFSInodeFromStat) (const Tcl_StatBuf *statPtr); /* 590 */
unsigned (*tcl_GetModeFromStat) (const Tcl_StatBuf *statPtr); /* 591 */
int (*tcl_GetLinkCountFromStat) (const Tcl_StatBuf *statPtr); /* 592 */
int (*tcl_GetUserIdFromStat) (const Tcl_StatBuf *statPtr); /* 593 */
int (*tcl_GetGroupIdFromStat) (const Tcl_StatBuf *statPtr); /* 594 */
int (*tcl_GetDeviceTypeFromStat) (const Tcl_StatBuf *statPtr); /* 595 */
long long (*tcl_GetAccessTimeFromStat) (const Tcl_StatBuf *statPtr); /* 596 */
long long (*tcl_GetModificationTimeFromStat) (const Tcl_StatBuf *statPtr); /* 597 */
long long (*tcl_GetChangeTimeFromStat) (const Tcl_StatBuf *statPtr); /* 598 */
unsigned long long (*tcl_GetSizeFromStat) (const Tcl_StatBuf *statPtr); /* 599 */
unsigned long long (*tcl_GetBlocksFromStat) (const Tcl_StatBuf *statPtr); /* 600 */
unsigned (*tcl_GetBlockSizeFromStat) (const Tcl_StatBuf *statPtr); /* 601 */
int (*tcl_SetEnsembleParameterList) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj *paramList); /* 602 */
int (*tcl_GetEnsembleParameterList) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj **paramListPtr); /* 603 */
int (*tclParseArgsObjv) (Tcl_Interp *interp, const Tcl_ArgvInfo *argTable, void *objcPtr, Tcl_Obj *const *objv, Tcl_Obj ***remObjv); /* 604 */
int (*tcl_GetErrorLine) (Tcl_Interp *interp); /* 605 */
void (*tcl_SetErrorLine) (Tcl_Interp *interp, int lineNum); /* 606 */
void (*tcl_TransferResult) (Tcl_Interp *sourceInterp, int code, Tcl_Interp *targetInterp); /* 607 */
int (*tcl_InterpActive) (Tcl_Interp *interp); /* 608 */
void (*tcl_BackgroundException) (Tcl_Interp *interp, int code); /* 609 */
int (*tcl_ZlibDeflate) (Tcl_Interp *interp, int format, Tcl_Obj *data, int level, Tcl_Obj *gzipHeaderDictObj); /* 610 */
int (*tcl_ZlibInflate) (Tcl_Interp *interp, int format, Tcl_Obj *data, Tcl_Size buffersize, Tcl_Obj *gzipHeaderDictObj); /* 611 */
unsigned int (*tcl_ZlibCRC32) (unsigned int crc, const unsigned char *buf, Tcl_Size len); /* 612 */
unsigned int (*tcl_ZlibAdler32) (unsigned int adler, const unsigned char *buf, Tcl_Size len); /* 613 */
int (*tcl_ZlibStreamInit) (Tcl_Interp *interp, int mode, int format, int level, Tcl_Obj *dictObj, Tcl_ZlibStream *zshandle); /* 614 */
Tcl_Obj * (*tcl_ZlibStreamGetCommandName) (Tcl_ZlibStream zshandle); /* 615 */
int (*tcl_ZlibStreamEof) (Tcl_ZlibStream zshandle); /* 616 */
int (*tcl_ZlibStreamChecksum) (Tcl_ZlibStream zshandle); /* 617 */
int (*tcl_ZlibStreamPut) (Tcl_ZlibStream zshandle, Tcl_Obj *data, int flush); /* 618 */
int (*tcl_ZlibStreamGet) (Tcl_ZlibStream zshandle, Tcl_Obj *data, Tcl_Size count); /* 619 */
int (*tcl_ZlibStreamClose) (Tcl_ZlibStream zshandle); /* 620 */
int (*tcl_ZlibStreamReset) (Tcl_ZlibStream zshandle); /* 621 */
void (*tcl_SetStartupScript) (Tcl_Obj *path, const char *encoding); /* 622 */
Tcl_Obj * (*tcl_GetStartupScript) (const char **encodingPtr); /* 623 */
int (*tcl_CloseEx) (Tcl_Interp *interp, Tcl_Channel chan, int flags); /* 624 */
int (*tcl_NRExprObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj *resultPtr); /* 625 */
int (*tcl_NRSubstObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 626 */
int (*tcl_LoadFile) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *const symv[], int flags, void *procPtrs, Tcl_LoadHandle *handlePtr); /* 627 */
void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */
int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */
void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */
Tcl_Channel (*tcl_OpenTcpServerEx) (Tcl_Interp *interp, const char *service, const char *host, unsigned int flags, int backlog, Tcl_TcpAcceptProc *acceptProc, void *callbackData); /* 631 */
int (*tclZipfs_Mount) (Tcl_Interp *interp, const char *zipname, const char *mountPoint, const char *passwd); /* 632 */
int (*tclZipfs_Unmount) (Tcl_Interp *interp, const char *mountPoint); /* 633 */
Tcl_Obj * (*tclZipfs_TclLibrary) (void); /* 634 */
int (*tclZipfs_MountBuffer) (Tcl_Interp *interp, const void *data, size_t datalen, const char *mountPoint, int copy); /* 635 */
void (*tcl_FreeInternalRep) (Tcl_Obj *objPtr); /* 636 */
char * (*tcl_InitStringRep) (Tcl_Obj *objPtr, const char *bytes, TCL_HASH_TYPE numBytes); /* 637 */
Tcl_ObjInternalRep * (*tcl_FetchInternalRep) (Tcl_Obj *objPtr, const Tcl_ObjType *typePtr); /* 638 */
void (*tcl_StoreInternalRep) (Tcl_Obj *objPtr, const Tcl_ObjType *typePtr, const Tcl_ObjInternalRep *irPtr); /* 639 */
int (*tcl_HasStringRep) (Tcl_Obj *objPtr); /* 640 */
void (*tcl_IncrRefCount) (Tcl_Obj *objPtr); /* 641 */
void (*tcl_DecrRefCount) (Tcl_Obj *objPtr); /* 642 */
int (*tcl_IsShared) (Tcl_Obj *objPtr); /* 643 */
int (*tcl_LinkArray) (Tcl_Interp *interp, const char *varName, void *addr, int type, Tcl_Size size); /* 644 */
int (*tcl_GetIntForIndex) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Size endValue, Tcl_Size *indexPtr); /* 645 */
Tcl_Size (*tcl_UtfToUniChar) (const char *src, int *chPtr); /* 646 */
char * (*tcl_UniCharToUtfDString) (const int *uniStr, Tcl_Size uniLength, Tcl_DString *dsPtr); /* 647 */
int * (*tcl_UtfToUniCharDString) (const char *src, Tcl_Size length, Tcl_DString *dsPtr); /* 648 */
unsigned char * (*tclGetBytesFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, void *numBytesPtr); /* 649 */
unsigned char * (*tcl_GetBytesFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Size *numBytesPtr); /* 650 */
char * (*tcl_GetStringFromObj) (Tcl_Obj *objPtr, Tcl_Size *lengthPtr); /* 651 */
Tcl_UniChar * (*tcl_GetUnicodeFromObj) (Tcl_Obj *objPtr, Tcl_Size *lengthPtr); /* 652 */
int (*tcl_GetSizeIntFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Size *sizePtr); /* 653 */
int (*tcl_UtfCharComplete) (const char *src, Tcl_Size length); /* 654 */
const char * (*tcl_UtfNext) (const char *src); /* 655 */
const char * (*tcl_UtfPrev) (const char *src, const char *start); /* 656 */
int (*tcl_FSTildeExpand) (Tcl_Interp *interp, const char *path, Tcl_DString *dsPtr); /* 657 */
int (*tcl_ExternalToUtfDStringEx) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr, Tcl_Size *errorLocationPtr); /* 658 */
int (*tcl_UtfToExternalDStringEx) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, Tcl_Size srcLen, int flags, Tcl_DString *dsPtr, Tcl_Size *errorLocationPtr); /* 659 */
int (*tcl_AsyncMarkFromSignal) (Tcl_AsyncHandler async, int sigNumber); /* 660 */
int (*tcl_ListObjGetElements) (Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Size *objcPtr, Tcl_Obj ***objvPtr); /* 661 */
int (*tcl_ListObjLength) (Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Size *lengthPtr); /* 662 */
int (*tcl_DictObjSize) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Size *sizePtr); /* 663 */
int (*tcl_SplitList) (Tcl_Interp *interp, const char *listStr, Tcl_Size *argcPtr, const char ***argvPtr); /* 664 */
void (*tcl_SplitPath) (const char *path, Tcl_Size *argcPtr, const char ***argvPtr); /* 665 */
Tcl_Obj * (*tcl_FSSplitPath) (Tcl_Obj *pathPtr, Tcl_Size *lenPtr); /* 666 */
int (*tcl_ParseArgsObjv) (Tcl_Interp *interp, const Tcl_ArgvInfo *argTable, Tcl_Size *objcPtr, Tcl_Obj *const *objv, Tcl_Obj ***remObjv); /* 667 */
Tcl_Size (*tcl_UniCharLen) (const int *uniStr); /* 668 */
Tcl_Size (*tcl_NumUtfChars) (const char *src, Tcl_Size length); /* 669 */
Tcl_Size (*tcl_GetCharLength) (Tcl_Obj *objPtr); /* 670 */
const char * (*tcl_UtfAtIndex) (const char *src, Tcl_Size index); /* 671 */
Tcl_Obj * (*tcl_GetRange) (Tcl_Obj *objPtr, Tcl_Size first, Tcl_Size last); /* 672 */
int (*tcl_GetUniChar) (Tcl_Obj *objPtr, Tcl_Size index); /* 673 */
int (*tcl_GetBool) (Tcl_Interp *interp, const char *src, int flags, char *charPtr); /* 674 */
int (*tcl_GetBoolFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags, char *charPtr); /* 675 */
Tcl_Command (*tcl_CreateObjCommand2) (Tcl_Interp *interp, const char *cmdName, Tcl_ObjCmdProc2 *proc2, void *clientData, Tcl_CmdDeleteProc *deleteProc); /* 676 */
Tcl_Trace (*tcl_CreateObjTrace2) (Tcl_Interp *interp, Tcl_Size level, int flags, Tcl_CmdObjTraceProc2 *objProc2, void *clientData, Tcl_CmdObjTraceDeleteProc *delProc); /* 677 */
Tcl_Command (*tcl_NRCreateCommand2) (Tcl_Interp *interp, const char *cmdName, Tcl_ObjCmdProc2 *proc, Tcl_ObjCmdProc2 *nreProc2, void *clientData, Tcl_CmdDeleteProc *deleteProc); /* 678 */
int (*tcl_NRCallObjProc2) (Tcl_Interp *interp, Tcl_ObjCmdProc2 *objProc2, void *clientData, Tcl_Size objc, Tcl_Obj *const objv[]); /* 679 */
int (*tcl_GetNumberFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, void **clientDataPtr, int *typePtr); /* 680 */
int (*tcl_GetNumber) (Tcl_Interp *interp, const char *bytes, Tcl_Size numBytes, void **clientDataPtr, int *typePtr); /* 681 */
int (*tcl_RemoveChannelMode) (Tcl_Interp *interp, Tcl_Channel chan, int mode); /* 682 */
Tcl_Size (*tcl_GetEncodingNulLength) (Tcl_Encoding encoding); /* 683 */
int (*tcl_GetWideUIntFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_WideUInt *uwidePtr); /* 684 */
Tcl_Obj * (*tcl_DStringToObj) (Tcl_DString *dsPtr); /* 685 */
int (*tcl_UtfNcmp) (const char *s1, const char *s2, size_t n); /* 686 */
int (*tcl_UtfNcasecmp) (const char *s1, const char *s2, size_t n); /* 687 */
Tcl_Obj * (*tcl_NewWideUIntObj) (Tcl_WideUInt wideValue); /* 688 */
void (*tcl_SetWideUIntObj) (Tcl_Obj *objPtr, Tcl_WideUInt uwideValue); /* 689 */
void (*tclUnusedStubEntry) (void); /* 690 */
} TclStubs;
extern const TclStubs *tclStubsPtr;
#ifdef __cplusplus
}
#endif
#if defined(USE_TCL_STUBS)
/*
* Inline function declarations:
*/
#define Tcl_PkgProvideEx \
(tclStubsPtr->tcl_PkgProvideEx) /* 0 */
#define Tcl_PkgRequireEx \
(tclStubsPtr->tcl_PkgRequireEx) /* 1 */
#define Tcl_Panic \
(tclStubsPtr->tcl_Panic) /* 2 */
#define Tcl_Alloc \
(tclStubsPtr->tcl_Alloc) /* 3 */
#define Tcl_Free \
(tclStubsPtr->tcl_Free) /* 4 */
#define Tcl_Realloc \
(tclStubsPtr->tcl_Realloc) /* 5 */
#define Tcl_DbCkalloc \
(tclStubsPtr->tcl_DbCkalloc) /* 6 */
#define Tcl_DbCkfree \
(tclStubsPtr->tcl_DbCkfree) /* 7 */
#define Tcl_DbCkrealloc \
(tclStubsPtr->tcl_DbCkrealloc) /* 8 */
#define Tcl_CreateFileHandler \
(tclStubsPtr->tcl_CreateFileHandler) /* 9 */
#define Tcl_DeleteFileHandler \
(tclStubsPtr->tcl_DeleteFileHandler) /* 10 */
#define Tcl_SetTimer \
(tclStubsPtr->tcl_SetTimer) /* 11 */
#define Tcl_Sleep \
(tclStubsPtr->tcl_Sleep) /* 12 */
#define Tcl_WaitForEvent \
(tclStubsPtr->tcl_WaitForEvent) /* 13 */
#define Tcl_AppendAllObjTypes \
(tclStubsPtr->tcl_AppendAllObjTypes) /* 14 */
#define Tcl_AppendStringsToObj \
(tclStubsPtr->tcl_AppendStringsToObj) /* 15 */
#define Tcl_AppendToObj \
(tclStubsPtr->tcl_AppendToObj) /* 16 */
#define Tcl_ConcatObj \
(tclStubsPtr->tcl_ConcatObj) /* 17 */
#define Tcl_ConvertToType \
(tclStubsPtr->tcl_ConvertToType) /* 18 */
#define Tcl_DbDecrRefCount \
(tclStubsPtr->tcl_DbDecrRefCount) /* 19 */
#define Tcl_DbIncrRefCount \
(tclStubsPtr->tcl_DbIncrRefCount) /* 20 */
#define Tcl_DbIsShared \
(tclStubsPtr->tcl_DbIsShared) /* 21 */
/* Slot 22 is reserved */
#define Tcl_DbNewByteArrayObj \
(tclStubsPtr->tcl_DbNewByteArrayObj) /* 23 */
#define Tcl_DbNewDoubleObj \
(tclStubsPtr->tcl_DbNewDoubleObj) /* 24 */
#define Tcl_DbNewListObj \
(tclStubsPtr->tcl_DbNewListObj) /* 25 */
/* Slot 26 is reserved */
#define Tcl_DbNewObj \
(tclStubsPtr->tcl_DbNewObj) /* 27 */
#define Tcl_DbNewStringObj \
(tclStubsPtr->tcl_DbNewStringObj) /* 28 */
#define Tcl_DuplicateObj \
(tclStubsPtr->tcl_DuplicateObj) /* 29 */
#define TclFreeObj \
(tclStubsPtr->tclFreeObj) /* 30 */
#define Tcl_GetBoolean \
(tclStubsPtr->tcl_GetBoolean) /* 31 */
#define Tcl_GetBooleanFromObj \
(tclStubsPtr->tcl_GetBooleanFromObj) /* 32 */
#define Tcl_GetByteArrayFromObj \
(tclStubsPtr->tcl_GetByteArrayFromObj) /* 33 */
#define Tcl_GetDouble \
(tclStubsPtr->tcl_GetDouble) /* 34 */
#define Tcl_GetDoubleFromObj \
(tclStubsPtr->tcl_GetDoubleFromObj) /* 35 */
/* Slot 36 is reserved */
#define Tcl_GetInt \
(tclStubsPtr->tcl_GetInt) /* 37 */
#define Tcl_GetIntFromObj \
(tclStubsPtr->tcl_GetIntFromObj) /* 38 */
#define Tcl_GetLongFromObj \
(tclStubsPtr->tcl_GetLongFromObj) /* 39 */
#define Tcl_GetObjType \
(tclStubsPtr->tcl_GetObjType) /* 40 */
#define TclGetStringFromObj \
(tclStubsPtr->tclGetStringFromObj) /* 41 */
#define Tcl_InvalidateStringRep \
(tclStubsPtr->tcl_InvalidateStringRep) /* 42 */
#define Tcl_ListObjAppendList \
(tclStubsPtr->tcl_ListObjAppendList) /* 43 */
#define Tcl_ListObjAppendElement \
(tclStubsPtr->tcl_ListObjAppendElement) /* 44 */
#define TclListObjGetElements \
(tclStubsPtr->tclListObjGetElements) /* 45 */
#define Tcl_ListObjIndex \
(tclStubsPtr->tcl_ListObjIndex) /* 46 */
#define TclListObjLength \
(tclStubsPtr->tclListObjLength) /* 47 */
#define Tcl_ListObjReplace \
(tclStubsPtr->tcl_ListObjReplace) /* 48 */
/* Slot 49 is reserved */
#define Tcl_NewByteArrayObj \
(tclStubsPtr->tcl_NewByteArrayObj) /* 50 */
#define Tcl_NewDoubleObj \
(tclStubsPtr->tcl_NewDoubleObj) /* 51 */
/* Slot 52 is reserved */
#define Tcl_NewListObj \
(tclStubsPtr->tcl_NewListObj) /* 53 */
/* Slot 54 is reserved */
#define Tcl_NewObj \
(tclStubsPtr->tcl_NewObj) /* 55 */
#define Tcl_NewStringObj \
(tclStubsPtr->tcl_NewStringObj) /* 56 */
/* Slot 57 is reserved */
#define Tcl_SetByteArrayLength \
(tclStubsPtr->tcl_SetByteArrayLength) /* 58 */
#define Tcl_SetByteArrayObj \
(tclStubsPtr->tcl_SetByteArrayObj) /* 59 */
#define Tcl_SetDoubleObj \
(tclStubsPtr->tcl_SetDoubleObj) /* 60 */
/* Slot 61 is reserved */
#define Tcl_SetListObj \
(tclStubsPtr->tcl_SetListObj) /* 62 */
/* Slot 63 is reserved */
#define Tcl_SetObjLength \
(tclStubsPtr->tcl_SetObjLength) /* 64 */
#define Tcl_SetStringObj \
(tclStubsPtr->tcl_SetStringObj) /* 65 */
/* Slot 66 is reserved */
/* Slot 67 is reserved */
#define Tcl_AllowExceptions \
(tclStubsPtr->tcl_AllowExceptions) /* 68 */
#define Tcl_AppendElement \
(tclStubsPtr->tcl_AppendElement) /* 69 */
#define Tcl_AppendResult \
(tclStubsPtr->tcl_AppendResult) /* 70 */
#define Tcl_AsyncCreate \
(tclStubsPtr->tcl_AsyncCreate) /* 71 */
#define Tcl_AsyncDelete \
(tclStubsPtr->tcl_AsyncDelete) /* 72 */
#define Tcl_AsyncInvoke \
(tclStubsPtr->tcl_AsyncInvoke) /* 73 */
#define Tcl_AsyncMark \
(tclStubsPtr->tcl_AsyncMark) /* 74 */
#define Tcl_AsyncReady \
(tclStubsPtr->tcl_AsyncReady) /* 75 */
/* Slot 76 is reserved */
/* Slot 77 is reserved */
#define Tcl_BadChannelOption \
(tclStubsPtr->tcl_BadChannelOption) /* 78 */
#define Tcl_CallWhenDeleted \
(tclStubsPtr->tcl_CallWhenDeleted) /* 79 */
#define Tcl_CancelIdleCall \
(tclStubsPtr->tcl_CancelIdleCall) /* 80 */
#define Tcl_Close \
(tclStubsPtr->tcl_Close) /* 81 */
#define Tcl_CommandComplete \
(tclStubsPtr->tcl_CommandComplete) /* 82 */
#define Tcl_Concat \
(tclStubsPtr->tcl_Concat) /* 83 */
#define Tcl_ConvertElement \
(tclStubsPtr->tcl_ConvertElement) /* 84 */
#define Tcl_ConvertCountedElement \
(tclStubsPtr->tcl_ConvertCountedElement) /* 85 */
#define Tcl_CreateAlias \
(tclStubsPtr->tcl_CreateAlias) /* 86 */
#define Tcl_CreateAliasObj \
(tclStubsPtr->tcl_CreateAliasObj) /* 87 */
#define Tcl_CreateChannel \
(tclStubsPtr->tcl_CreateChannel) /* 88 */
#define Tcl_CreateChannelHandler \
(tclStubsPtr->tcl_CreateChannelHandler) /* 89 */
#define Tcl_CreateCloseHandler \
(tclStubsPtr->tcl_CreateCloseHandler) /* 90 */
#define Tcl_CreateCommand \
(tclStubsPtr->tcl_CreateCommand) /* 91 */
#define Tcl_CreateEventSource \
(tclStubsPtr->tcl_CreateEventSource) /* 92 */
#define Tcl_CreateExitHandler \
(tclStubsPtr->tcl_CreateExitHandler) /* 93 */
#define Tcl_CreateInterp \
(tclStubsPtr->tcl_CreateInterp) /* 94 */
/* Slot 95 is reserved */
#define Tcl_CreateObjCommand \
(tclStubsPtr->tcl_CreateObjCommand) /* 96 */
#define Tcl_CreateChild \
(tclStubsPtr->tcl_CreateChild) /* 97 */
#define Tcl_CreateTimerHandler \
(tclStubsPtr->tcl_CreateTimerHandler) /* 98 */
#define Tcl_CreateTrace \
(tclStubsPtr->tcl_CreateTrace) /* 99 */
#define Tcl_DeleteAssocData \
(tclStubsPtr->tcl_DeleteAssocData) /* 100 */
#define Tcl_DeleteChannelHandler \
(tclStubsPtr->tcl_DeleteChannelHandler) /* 101 */
#define Tcl_DeleteCloseHandler \
(tclStubsPtr->tcl_DeleteCloseHandler) /* 102 */
#define Tcl_DeleteCommand \
(tclStubsPtr->tcl_DeleteCommand) /* 103 */
#define Tcl_DeleteCommandFromToken \
(tclStubsPtr->tcl_DeleteCommandFromToken) /* 104 */
#define Tcl_DeleteEvents \
(tclStubsPtr->tcl_DeleteEvents) /* 105 */
#define Tcl_DeleteEventSource \
(tclStubsPtr->tcl_DeleteEventSource) /* 106 */
#define Tcl_DeleteExitHandler \
(tclStubsPtr->tcl_DeleteExitHandler) /* 107 */
#define Tcl_DeleteHashEntry \
(tclStubsPtr->tcl_DeleteHashEntry) /* 108 */
#define Tcl_DeleteHashTable \
(tclStubsPtr->tcl_DeleteHashTable) /* 109 */
#define Tcl_DeleteInterp \
(tclStubsPtr->tcl_DeleteInterp) /* 110 */
#define Tcl_DetachPids \
(tclStubsPtr->tcl_DetachPids) /* 111 */
#define Tcl_DeleteTimerHandler \
(tclStubsPtr->tcl_DeleteTimerHandler) /* 112 */
#define Tcl_DeleteTrace \
(tclStubsPtr->tcl_DeleteTrace) /* 113 */
#define Tcl_DontCallWhenDeleted \
(tclStubsPtr->tcl_DontCallWhenDeleted) /* 114 */
#define Tcl_DoOneEvent \
(tclStubsPtr->tcl_DoOneEvent) /* 115 */
#define Tcl_DoWhenIdle \
(tclStubsPtr->tcl_DoWhenIdle) /* 116 */
#define Tcl_DStringAppend \
(tclStubsPtr->tcl_DStringAppend) /* 117 */
#define Tcl_DStringAppendElement \
(tclStubsPtr->tcl_DStringAppendElement) /* 118 */
#define Tcl_DStringEndSublist \
(tclStubsPtr->tcl_DStringEndSublist) /* 119 */
#define Tcl_DStringFree \
(tclStubsPtr->tcl_DStringFree) /* 120 */
#define Tcl_DStringGetResult \
(tclStubsPtr->tcl_DStringGetResult) /* 121 */
#define Tcl_DStringInit \
(tclStubsPtr->tcl_DStringInit) /* 122 */
#define Tcl_DStringResult \
(tclStubsPtr->tcl_DStringResult) /* 123 */
#define Tcl_DStringSetLength \
(tclStubsPtr->tcl_DStringSetLength) /* 124 */
#define Tcl_DStringStartSublist \
(tclStubsPtr->tcl_DStringStartSublist) /* 125 */
#define Tcl_Eof \
(tclStubsPtr->tcl_Eof) /* 126 */
#define Tcl_ErrnoId \
(tclStubsPtr->tcl_ErrnoId) /* 127 */
#define Tcl_ErrnoMsg \
(tclStubsPtr->tcl_ErrnoMsg) /* 128 */
/* Slot 129 is reserved */
#define Tcl_EvalFile \
(tclStubsPtr->tcl_EvalFile) /* 130 */
/* Slot 131 is reserved */
#define Tcl_EventuallyFree \
(tclStubsPtr->tcl_EventuallyFree) /* 132 */
#define Tcl_Exit \
(tclStubsPtr->tcl_Exit) /* 133 */
#define Tcl_ExposeCommand \
(tclStubsPtr->tcl_ExposeCommand) /* 134 */
#define Tcl_ExprBoolean \
(tclStubsPtr->tcl_ExprBoolean) /* 135 */
#define Tcl_ExprBooleanObj \
(tclStubsPtr->tcl_ExprBooleanObj) /* 136 */
#define Tcl_ExprDouble \
(tclStubsPtr->tcl_ExprDouble) /* 137 */
#define Tcl_ExprDoubleObj \
(tclStubsPtr->tcl_ExprDoubleObj) /* 138 */
#define Tcl_ExprLong \
(tclStubsPtr->tcl_ExprLong) /* 139 */
#define Tcl_ExprLongObj \
(tclStubsPtr->tcl_ExprLongObj) /* 140 */
#define Tcl_ExprObj \
(tclStubsPtr->tcl_ExprObj) /* 141 */
#define Tcl_ExprString \
(tclStubsPtr->tcl_ExprString) /* 142 */
#define Tcl_Finalize \
(tclStubsPtr->tcl_Finalize) /* 143 */
/* Slot 144 is reserved */
#define Tcl_FirstHashEntry \
(tclStubsPtr->tcl_FirstHashEntry) /* 145 */
#define Tcl_Flush \
(tclStubsPtr->tcl_Flush) /* 146 */
/* Slot 147 is reserved */
/* Slot 148 is reserved */
#define TclGetAliasObj \
(tclStubsPtr->tclGetAliasObj) /* 149 */
#define Tcl_GetAssocData \
(tclStubsPtr->tcl_GetAssocData) /* 150 */
#define Tcl_GetChannel \
(tclStubsPtr->tcl_GetChannel) /* 151 */
#define Tcl_GetChannelBufferSize \
(tclStubsPtr->tcl_GetChannelBufferSize) /* 152 */
#define Tcl_GetChannelHandle \
(tclStubsPtr->tcl_GetChannelHandle) /* 153 */
#define Tcl_GetChannelInstanceData \
(tclStubsPtr->tcl_GetChannelInstanceData) /* 154 */
#define Tcl_GetChannelMode \
(tclStubsPtr->tcl_GetChannelMode) /* 155 */
#define Tcl_GetChannelName \
(tclStubsPtr->tcl_GetChannelName) /* 156 */
#define Tcl_GetChannelOption \
(tclStubsPtr->tcl_GetChannelOption) /* 157 */
#define Tcl_GetChannelType \
(tclStubsPtr->tcl_GetChannelType) /* 158 */
#define Tcl_GetCommandInfo \
(tclStubsPtr->tcl_GetCommandInfo) /* 159 */
#define Tcl_GetCommandName \
(tclStubsPtr->tcl_GetCommandName) /* 160 */
#define Tcl_GetErrno \
(tclStubsPtr->tcl_GetErrno) /* 161 */
#define Tcl_GetHostName \
(tclStubsPtr->tcl_GetHostName) /* 162 */
#define Tcl_GetInterpPath \
(tclStubsPtr->tcl_GetInterpPath) /* 163 */
#define Tcl_GetParent \
(tclStubsPtr->tcl_GetParent) /* 164 */
#define Tcl_GetNameOfExecutable \
(tclStubsPtr->tcl_GetNameOfExecutable) /* 165 */
#define Tcl_GetObjResult \
(tclStubsPtr->tcl_GetObjResult) /* 166 */
#define Tcl_GetOpenFile \
(tclStubsPtr->tcl_GetOpenFile) /* 167 */
#define Tcl_GetPathType \
(tclStubsPtr->tcl_GetPathType) /* 168 */
#define Tcl_Gets \
(tclStubsPtr->tcl_Gets) /* 169 */
#define Tcl_GetsObj \
(tclStubsPtr->tcl_GetsObj) /* 170 */
#define Tcl_GetServiceMode \
(tclStubsPtr->tcl_GetServiceMode) /* 171 */
#define Tcl_GetChild \
(tclStubsPtr->tcl_GetChild) /* 172 */
#define Tcl_GetStdChannel \
(tclStubsPtr->tcl_GetStdChannel) /* 173 */
/* Slot 174 is reserved */
/* Slot 175 is reserved */
#define Tcl_GetVar2 \
(tclStubsPtr->tcl_GetVar2) /* 176 */
/* Slot 177 is reserved */
/* Slot 178 is reserved */
#define Tcl_HideCommand \
(tclStubsPtr->tcl_HideCommand) /* 179 */
#define Tcl_Init \
(tclStubsPtr->tcl_Init) /* 180 */
#define Tcl_InitHashTable \
(tclStubsPtr->tcl_InitHashTable) /* 181 */
#define Tcl_InputBlocked \
(tclStubsPtr->tcl_InputBlocked) /* 182 */
#define Tcl_InputBuffered \
(tclStubsPtr->tcl_InputBuffered) /* 183 */
#define Tcl_InterpDeleted \
(tclStubsPtr->tcl_InterpDeleted) /* 184 */
#define Tcl_IsSafe \
(tclStubsPtr->tcl_IsSafe) /* 185 */
#define Tcl_JoinPath \
(tclStubsPtr->tcl_JoinPath) /* 186 */
#define Tcl_LinkVar \
(tclStubsPtr->tcl_LinkVar) /* 187 */
/* Slot 188 is reserved */
#define Tcl_MakeFileChannel \
(tclStubsPtr->tcl_MakeFileChannel) /* 189 */
/* Slot 190 is reserved */
#define Tcl_MakeTcpClientChannel \
(tclStubsPtr->tcl_MakeTcpClientChannel) /* 191 */
#define Tcl_Merge \
(tclStubsPtr->tcl_Merge) /* 192 */
#define Tcl_NextHashEntry \
(tclStubsPtr->tcl_NextHashEntry) /* 193 */
#define Tcl_NotifyChannel \
(tclStubsPtr->tcl_NotifyChannel) /* 194 */
#define Tcl_ObjGetVar2 \
(tclStubsPtr->tcl_ObjGetVar2) /* 195 */
#define Tcl_ObjSetVar2 \
(tclStubsPtr->tcl_ObjSetVar2) /* 196 */
#define Tcl_OpenCommandChannel \
(tclStubsPtr->tcl_OpenCommandChannel) /* 197 */
#define Tcl_OpenFileChannel \
(tclStubsPtr->tcl_OpenFileChannel) /* 198 */
#define Tcl_OpenTcpClient \
(tclStubsPtr->tcl_OpenTcpClient) /* 199 */
#define Tcl_OpenTcpServer \
(tclStubsPtr->tcl_OpenTcpServer) /* 200 */
#define Tcl_Preserve \
(tclStubsPtr->tcl_Preserve) /* 201 */
#define Tcl_PrintDouble \
(tclStubsPtr->tcl_PrintDouble) /* 202 */
#define Tcl_PutEnv \
(tclStubsPtr->tcl_PutEnv) /* 203 */
#define Tcl_PosixError \
(tclStubsPtr->tcl_PosixError) /* 204 */
#define Tcl_QueueEvent \
(tclStubsPtr->tcl_QueueEvent) /* 205 */
#define Tcl_Read \
(tclStubsPtr->tcl_Read) /* 206 */
#define Tcl_ReapDetachedProcs \
(tclStubsPtr->tcl_ReapDetachedProcs) /* 207 */
#define Tcl_RecordAndEval \
(tclStubsPtr->tcl_RecordAndEval) /* 208 */
#define Tcl_RecordAndEvalObj \
(tclStubsPtr->tcl_RecordAndEvalObj) /* 209 */
#define Tcl_RegisterChannel \
(tclStubsPtr->tcl_RegisterChannel) /* 210 */
#define Tcl_RegisterObjType \
(tclStubsPtr->tcl_RegisterObjType) /* 211 */
#define Tcl_RegExpCompile \
(tclStubsPtr->tcl_RegExpCompile) /* 212 */
#define Tcl_RegExpExec \
(tclStubsPtr->tcl_RegExpExec) /* 213 */
#define Tcl_RegExpMatch \
(tclStubsPtr->tcl_RegExpMatch) /* 214 */
#define Tcl_RegExpRange \
(tclStubsPtr->tcl_RegExpRange) /* 215 */
#define Tcl_Release \
(tclStubsPtr->tcl_Release) /* 216 */
#define Tcl_ResetResult \
(tclStubsPtr->tcl_ResetResult) /* 217 */
#define Tcl_ScanElement \
(tclStubsPtr->tcl_ScanElement) /* 218 */
#define Tcl_ScanCountedElement \
(tclStubsPtr->tcl_ScanCountedElement) /* 219 */
/* Slot 220 is reserved */
#define Tcl_ServiceAll \
(tclStubsPtr->tcl_ServiceAll) /* 221 */
#define Tcl_ServiceEvent \
(tclStubsPtr->tcl_ServiceEvent) /* 222 */
#define Tcl_SetAssocData \
(tclStubsPtr->tcl_SetAssocData) /* 223 */
#define Tcl_SetChannelBufferSize \
(tclStubsPtr->tcl_SetChannelBufferSize) /* 224 */
#define Tcl_SetChannelOption \
(tclStubsPtr->tcl_SetChannelOption) /* 225 */
#define Tcl_SetCommandInfo \
(tclStubsPtr->tcl_SetCommandInfo) /* 226 */
#define Tcl_SetErrno \
(tclStubsPtr->tcl_SetErrno) /* 227 */
#define Tcl_SetErrorCode \
(tclStubsPtr->tcl_SetErrorCode) /* 228 */
#define Tcl_SetMaxBlockTime \
(tclStubsPtr->tcl_SetMaxBlockTime) /* 229 */
/* Slot 230 is reserved */
#define Tcl_SetRecursionLimit \
(tclStubsPtr->tcl_SetRecursionLimit) /* 231 */
/* Slot 232 is reserved */
#define Tcl_SetServiceMode \
(tclStubsPtr->tcl_SetServiceMode) /* 233 */
#define Tcl_SetObjErrorCode \
(tclStubsPtr->tcl_SetObjErrorCode) /* 234 */
#define Tcl_SetObjResult \
(tclStubsPtr->tcl_SetObjResult) /* 235 */
#define Tcl_SetStdChannel \
(tclStubsPtr->tcl_SetStdChannel) /* 236 */
/* Slot 237 is reserved */
#define Tcl_SetVar2 \
(tclStubsPtr->tcl_SetVar2) /* 238 */
#define Tcl_SignalId \
(tclStubsPtr->tcl_SignalId) /* 239 */
#define Tcl_SignalMsg \
(tclStubsPtr->tcl_SignalMsg) /* 240 */
#define Tcl_SourceRCFile \
(tclStubsPtr->tcl_SourceRCFile) /* 241 */
#define TclSplitList \
(tclStubsPtr->tclSplitList) /* 242 */
#define TclSplitPath \
(tclStubsPtr->tclSplitPath) /* 243 */
/* Slot 244 is reserved */
/* Slot 245 is reserved */
/* Slot 246 is reserved */
/* Slot 247 is reserved */
#define Tcl_TraceVar2 \
(tclStubsPtr->tcl_TraceVar2) /* 248 */
#define Tcl_TranslateFileName \
(tclStubsPtr->tcl_TranslateFileName) /* 249 */
#define Tcl_Ungets \
(tclStubsPtr->tcl_Ungets) /* 250 */
#define Tcl_UnlinkVar \
(tclStubsPtr->tcl_UnlinkVar) /* 251 */
#define Tcl_UnregisterChannel \
(tclStubsPtr->tcl_UnregisterChannel) /* 252 */
/* Slot 253 is reserved */
#define Tcl_UnsetVar2 \
(tclStubsPtr->tcl_UnsetVar2) /* 254 */
/* Slot 255 is reserved */
#define Tcl_UntraceVar2 \
(tclStubsPtr->tcl_UntraceVar2) /* 256 */
#define Tcl_UpdateLinkedVar \
(tclStubsPtr->tcl_UpdateLinkedVar) /* 257 */
/* Slot 258 is reserved */
#define Tcl_UpVar2 \
(tclStubsPtr->tcl_UpVar2) /* 259 */
#define Tcl_VarEval \
(tclStubsPtr->tcl_VarEval) /* 260 */
/* Slot 261 is reserved */
#define Tcl_VarTraceInfo2 \
(tclStubsPtr->tcl_VarTraceInfo2) /* 262 */
#define Tcl_Write \
(tclStubsPtr->tcl_Write) /* 263 */
#define Tcl_WrongNumArgs \
(tclStubsPtr->tcl_WrongNumArgs) /* 264 */
#define Tcl_DumpActiveMemory \
(tclStubsPtr->tcl_DumpActiveMemory) /* 265 */
#define Tcl_ValidateAllMemory \
(tclStubsPtr->tcl_ValidateAllMemory) /* 266 */
/* Slot 267 is reserved */
/* Slot 268 is reserved */
#define Tcl_HashStats \
(tclStubsPtr->tcl_HashStats) /* 269 */
#define Tcl_ParseVar \
(tclStubsPtr->tcl_ParseVar) /* 270 */
/* Slot 271 is reserved */
#define Tcl_PkgPresentEx \
(tclStubsPtr->tcl_PkgPresentEx) /* 272 */
/* Slot 273 is reserved */
/* Slot 274 is reserved */
/* Slot 275 is reserved */
/* Slot 276 is reserved */
#define Tcl_WaitPid \
(tclStubsPtr->tcl_WaitPid) /* 277 */
/* Slot 278 is reserved */
#define Tcl_GetVersion \
(tclStubsPtr->tcl_GetVersion) /* 279 */
#define Tcl_InitMemory \
(tclStubsPtr->tcl_InitMemory) /* 280 */
#define Tcl_StackChannel \
(tclStubsPtr->tcl_StackChannel) /* 281 */
#define Tcl_UnstackChannel \
(tclStubsPtr->tcl_UnstackChannel) /* 282 */
#define Tcl_GetStackedChannel \
(tclStubsPtr->tcl_GetStackedChannel) /* 283 */
#define Tcl_SetMainLoop \
(tclStubsPtr->tcl_SetMainLoop) /* 284 */
#define Tcl_GetAliasObj \
(tclStubsPtr->tcl_GetAliasObj) /* 285 */
#define Tcl_AppendObjToObj \
(tclStubsPtr->tcl_AppendObjToObj) /* 286 */
#define Tcl_CreateEncoding \
(tclStubsPtr->tcl_CreateEncoding) /* 287 */
#define Tcl_CreateThreadExitHandler \
(tclStubsPtr->tcl_CreateThreadExitHandler) /* 288 */
#define Tcl_DeleteThreadExitHandler \
(tclStubsPtr->tcl_DeleteThreadExitHandler) /* 289 */
/* Slot 290 is reserved */
#define Tcl_EvalEx \
(tclStubsPtr->tcl_EvalEx) /* 291 */
#define Tcl_EvalObjv \
(tclStubsPtr->tcl_EvalObjv) /* 292 */
#define Tcl_EvalObjEx \
(tclStubsPtr->tcl_EvalObjEx) /* 293 */
#define Tcl_ExitThread \
(tclStubsPtr->tcl_ExitThread) /* 294 */
#define Tcl_ExternalToUtf \
(tclStubsPtr->tcl_ExternalToUtf) /* 295 */
#define Tcl_ExternalToUtfDString \
(tclStubsPtr->tcl_ExternalToUtfDString) /* 296 */
#define Tcl_FinalizeThread \
(tclStubsPtr->tcl_FinalizeThread) /* 297 */
#define Tcl_FinalizeNotifier \
(tclStubsPtr->tcl_FinalizeNotifier) /* 298 */
#define Tcl_FreeEncoding \
(tclStubsPtr->tcl_FreeEncoding) /* 299 */
#define Tcl_GetCurrentThread \
(tclStubsPtr->tcl_GetCurrentThread) /* 300 */
#define Tcl_GetEncoding \
(tclStubsPtr->tcl_GetEncoding) /* 301 */
#define Tcl_GetEncodingName \
(tclStubsPtr->tcl_GetEncodingName) /* 302 */
#define Tcl_GetEncodingNames \
(tclStubsPtr->tcl_GetEncodingNames) /* 303 */
#define Tcl_GetIndexFromObjStruct \
(tclStubsPtr->tcl_GetIndexFromObjStruct) /* 304 */
#define Tcl_GetThreadData \
(tclStubsPtr->tcl_GetThreadData) /* 305 */
#define Tcl_GetVar2Ex \
(tclStubsPtr->tcl_GetVar2Ex) /* 306 */
#define Tcl_InitNotifier \
(tclStubsPtr->tcl_InitNotifier) /* 307 */
#define Tcl_MutexLock \
(tclStubsPtr->tcl_MutexLock) /* 308 */
#define Tcl_MutexUnlock \
(tclStubsPtr->tcl_MutexUnlock) /* 309 */
#define Tcl_ConditionNotify \
(tclStubsPtr->tcl_ConditionNotify) /* 310 */
#define Tcl_ConditionWait \
(tclStubsPtr->tcl_ConditionWait) /* 311 */
#define TclNumUtfChars \
(tclStubsPtr->tclNumUtfChars) /* 312 */
#define Tcl_ReadChars \
(tclStubsPtr->tcl_ReadChars) /* 313 */
/* Slot 314 is reserved */
/* Slot 315 is reserved */
#define Tcl_SetSystemEncoding \
(tclStubsPtr->tcl_SetSystemEncoding) /* 316 */
#define Tcl_SetVar2Ex \
(tclStubsPtr->tcl_SetVar2Ex) /* 317 */
#define Tcl_ThreadAlert \
(tclStubsPtr->tcl_ThreadAlert) /* 318 */
#define Tcl_ThreadQueueEvent \
(tclStubsPtr->tcl_ThreadQueueEvent) /* 319 */
#define Tcl_UniCharAtIndex \
(tclStubsPtr->tcl_UniCharAtIndex) /* 320 */
#define Tcl_UniCharToLower \
(tclStubsPtr->tcl_UniCharToLower) /* 321 */
#define Tcl_UniCharToTitle \
(tclStubsPtr->tcl_UniCharToTitle) /* 322 */
#define Tcl_UniCharToUpper \
(tclStubsPtr->tcl_UniCharToUpper) /* 323 */
#define Tcl_UniCharToUtf \
(tclStubsPtr->tcl_UniCharToUtf) /* 324 */
#define TclUtfAtIndex \
(tclStubsPtr->tclUtfAtIndex) /* 325 */
#define TclUtfCharComplete \
(tclStubsPtr->tclUtfCharComplete) /* 326 */
#define Tcl_UtfBackslash \
(tclStubsPtr->tcl_UtfBackslash) /* 327 */
#define Tcl_UtfFindFirst \
(tclStubsPtr->tcl_UtfFindFirst) /* 328 */
#define Tcl_UtfFindLast \
(tclStubsPtr->tcl_UtfFindLast) /* 329 */
#define TclUtfNext \
(tclStubsPtr->tclUtfNext) /* 330 */
#define TclUtfPrev \
(tclStubsPtr->tclUtfPrev) /* 331 */
#define Tcl_UtfToExternal \
(tclStubsPtr->tcl_UtfToExternal) /* 332 */
#define Tcl_UtfToExternalDString \
(tclStubsPtr->tcl_UtfToExternalDString) /* 333 */
#define Tcl_UtfToLower \
(tclStubsPtr->tcl_UtfToLower) /* 334 */
#define Tcl_UtfToTitle \
(tclStubsPtr->tcl_UtfToTitle) /* 335 */
#define Tcl_UtfToChar16 \
(tclStubsPtr->tcl_UtfToChar16) /* 336 */
#define Tcl_UtfToUpper \
(tclStubsPtr->tcl_UtfToUpper) /* 337 */
#define Tcl_WriteChars \
(tclStubsPtr->tcl_WriteChars) /* 338 */
#define Tcl_WriteObj \
(tclStubsPtr->tcl_WriteObj) /* 339 */
#define Tcl_GetString \
(tclStubsPtr->tcl_GetString) /* 340 */
/* Slot 341 is reserved */
/* Slot 342 is reserved */
#define Tcl_AlertNotifier \
(tclStubsPtr->tcl_AlertNotifier) /* 343 */
#define Tcl_ServiceModeHook \
(tclStubsPtr->tcl_ServiceModeHook) /* 344 */
#define Tcl_UniCharIsAlnum \
(tclStubsPtr->tcl_UniCharIsAlnum) /* 345 */
#define Tcl_UniCharIsAlpha \
(tclStubsPtr->tcl_UniCharIsAlpha) /* 346 */
#define Tcl_UniCharIsDigit \
(tclStubsPtr->tcl_UniCharIsDigit) /* 347 */
#define Tcl_UniCharIsLower \
(tclStubsPtr->tcl_UniCharIsLower) /* 348 */
#define Tcl_UniCharIsSpace \
(tclStubsPtr->tcl_UniCharIsSpace) /* 349 */
#define Tcl_UniCharIsUpper \
(tclStubsPtr->tcl_UniCharIsUpper) /* 350 */
#define Tcl_UniCharIsWordChar \
(tclStubsPtr->tcl_UniCharIsWordChar) /* 351 */
#define Tcl_Char16Len \
(tclStubsPtr->tcl_Char16Len) /* 352 */
/* Slot 353 is reserved */
#define Tcl_Char16ToUtfDString \
(tclStubsPtr->tcl_Char16ToUtfDString) /* 354 */
#define Tcl_UtfToChar16DString \
(tclStubsPtr->tcl_UtfToChar16DString) /* 355 */
#define Tcl_GetRegExpFromObj \
(tclStubsPtr->tcl_GetRegExpFromObj) /* 356 */
/* Slot 357 is reserved */
#define Tcl_FreeParse \
(tclStubsPtr->tcl_FreeParse) /* 358 */
#define Tcl_LogCommandInfo \
(tclStubsPtr->tcl_LogCommandInfo) /* 359 */
#define Tcl_ParseBraces \
(tclStubsPtr->tcl_ParseBraces) /* 360 */
#define Tcl_ParseCommand \
(tclStubsPtr->tcl_ParseCommand) /* 361 */
#define Tcl_ParseExpr \
(tclStubsPtr->tcl_ParseExpr) /* 362 */
#define Tcl_ParseQuotedString \
(tclStubsPtr->tcl_ParseQuotedString) /* 363 */
#define Tcl_ParseVarName \
(tclStubsPtr->tcl_ParseVarName) /* 364 */
#define Tcl_GetCwd \
(tclStubsPtr->tcl_GetCwd) /* 365 */
#define Tcl_Chdir \
(tclStubsPtr->tcl_Chdir) /* 366 */
#define Tcl_Access \
(tclStubsPtr->tcl_Access) /* 367 */
#define Tcl_Stat \
(tclStubsPtr->tcl_Stat) /* 368 */
#define TclUtfNcmp \
(tclStubsPtr->tclUtfNcmp) /* 369 */
#define TclUtfNcasecmp \
(tclStubsPtr->tclUtfNcasecmp) /* 370 */
#define Tcl_StringCaseMatch \
(tclStubsPtr->tcl_StringCaseMatch) /* 371 */
#define Tcl_UniCharIsControl \
(tclStubsPtr->tcl_UniCharIsControl) /* 372 */
#define Tcl_UniCharIsGraph \
(tclStubsPtr->tcl_UniCharIsGraph) /* 373 */
#define Tcl_UniCharIsPrint \
(tclStubsPtr->tcl_UniCharIsPrint) /* 374 */
#define Tcl_UniCharIsPunct \
(tclStubsPtr->tcl_UniCharIsPunct) /* 375 */
#define Tcl_RegExpExecObj \
(tclStubsPtr->tcl_RegExpExecObj) /* 376 */
#define Tcl_RegExpGetInfo \
(tclStubsPtr->tcl_RegExpGetInfo) /* 377 */
#define Tcl_NewUnicodeObj \
(tclStubsPtr->tcl_NewUnicodeObj) /* 378 */
#define Tcl_SetUnicodeObj \
(tclStubsPtr->tcl_SetUnicodeObj) /* 379 */
#define TclGetCharLength \
(tclStubsPtr->tclGetCharLength) /* 380 */
#define TclGetUniChar \
(tclStubsPtr->tclGetUniChar) /* 381 */
/* Slot 382 is reserved */
#define TclGetRange \
(tclStubsPtr->tclGetRange) /* 383 */
#define Tcl_AppendUnicodeToObj \
(tclStubsPtr->tcl_AppendUnicodeToObj) /* 384 */
#define Tcl_RegExpMatchObj \
(tclStubsPtr->tcl_RegExpMatchObj) /* 385 */
#define Tcl_SetNotifier \
(tclStubsPtr->tcl_SetNotifier) /* 386 */
#define Tcl_GetAllocMutex \
(tclStubsPtr->tcl_GetAllocMutex) /* 387 */
#define Tcl_GetChannelNames \
(tclStubsPtr->tcl_GetChannelNames) /* 388 */
#define Tcl_GetChannelNamesEx \
(tclStubsPtr->tcl_GetChannelNamesEx) /* 389 */
#define Tcl_ProcObjCmd \
(tclStubsPtr->tcl_ProcObjCmd) /* 390 */
#define Tcl_ConditionFinalize \
(tclStubsPtr->tcl_ConditionFinalize) /* 391 */
#define Tcl_MutexFinalize \
(tclStubsPtr->tcl_MutexFinalize) /* 392 */
#define Tcl_CreateThread \
(tclStubsPtr->tcl_CreateThread) /* 393 */
#define Tcl_ReadRaw \
(tclStubsPtr->tcl_ReadRaw) /* 394 */
#define Tcl_WriteRaw \
(tclStubsPtr->tcl_WriteRaw) /* 395 */
#define Tcl_GetTopChannel \
(tclStubsPtr->tcl_GetTopChannel) /* 396 */
#define Tcl_ChannelBuffered \
(tclStubsPtr->tcl_ChannelBuffered) /* 397 */
#define Tcl_ChannelName \
(tclStubsPtr->tcl_ChannelName) /* 398 */
#define Tcl_ChannelVersion \
(tclStubsPtr->tcl_ChannelVersion) /* 399 */
#define Tcl_ChannelBlockModeProc \
(tclStubsPtr->tcl_ChannelBlockModeProc) /* 400 */
/* Slot 401 is reserved */
#define Tcl_ChannelClose2Proc \
(tclStubsPtr->tcl_ChannelClose2Proc) /* 402 */
#define Tcl_ChannelInputProc \
(tclStubsPtr->tcl_ChannelInputProc) /* 403 */
#define Tcl_ChannelOutputProc \
(tclStubsPtr->tcl_ChannelOutputProc) /* 404 */
/* Slot 405 is reserved */
#define Tcl_ChannelSetOptionProc \
(tclStubsPtr->tcl_ChannelSetOptionProc) /* 406 */
#define Tcl_ChannelGetOptionProc \
(tclStubsPtr->tcl_ChannelGetOptionProc) /* 407 */
#define Tcl_ChannelWatchProc \
(tclStubsPtr->tcl_ChannelWatchProc) /* 408 */
#define Tcl_ChannelGetHandleProc \
(tclStubsPtr->tcl_ChannelGetHandleProc) /* 409 */
#define Tcl_ChannelFlushProc \
(tclStubsPtr->tcl_ChannelFlushProc) /* 410 */
#define Tcl_ChannelHandlerProc \
(tclStubsPtr->tcl_ChannelHandlerProc) /* 411 */
#define Tcl_JoinThread \
(tclStubsPtr->tcl_JoinThread) /* 412 */
#define Tcl_IsChannelShared \
(tclStubsPtr->tcl_IsChannelShared) /* 413 */
#define Tcl_IsChannelRegistered \
(tclStubsPtr->tcl_IsChannelRegistered) /* 414 */
#define Tcl_CutChannel \
(tclStubsPtr->tcl_CutChannel) /* 415 */
#define Tcl_SpliceChannel \
(tclStubsPtr->tcl_SpliceChannel) /* 416 */
#define Tcl_ClearChannelHandlers \
(tclStubsPtr->tcl_ClearChannelHandlers) /* 417 */
#define Tcl_IsChannelExisting \
(tclStubsPtr->tcl_IsChannelExisting) /* 418 */
/* Slot 419 is reserved */
/* Slot 420 is reserved */
/* Slot 421 is reserved */
#define Tcl_CreateHashEntry \
(tclStubsPtr->tcl_CreateHashEntry) /* 422 */
#define Tcl_InitCustomHashTable \
(tclStubsPtr->tcl_InitCustomHashTable) /* 423 */
#define Tcl_InitObjHashTable \
(tclStubsPtr->tcl_InitObjHashTable) /* 424 */
#define Tcl_CommandTraceInfo \
(tclStubsPtr->tcl_CommandTraceInfo) /* 425 */
#define Tcl_TraceCommand \
(tclStubsPtr->tcl_TraceCommand) /* 426 */
#define Tcl_UntraceCommand \
(tclStubsPtr->tcl_UntraceCommand) /* 427 */
#define Tcl_AttemptAlloc \
(tclStubsPtr->tcl_AttemptAlloc) /* 428 */
#define Tcl_AttemptDbCkalloc \
(tclStubsPtr->tcl_AttemptDbCkalloc) /* 429 */
#define Tcl_AttemptRealloc \
(tclStubsPtr->tcl_AttemptRealloc) /* 430 */
#define Tcl_AttemptDbCkrealloc \
(tclStubsPtr->tcl_AttemptDbCkrealloc) /* 431 */
#define Tcl_AttemptSetObjLength \
(tclStubsPtr->tcl_AttemptSetObjLength) /* 432 */
#define Tcl_GetChannelThread \
(tclStubsPtr->tcl_GetChannelThread) /* 433 */
#define TclGetUnicodeFromObj \
(tclStubsPtr->tclGetUnicodeFromObj) /* 434 */
/* Slot 435 is reserved */
/* Slot 436 is reserved */
#define Tcl_SubstObj \
(tclStubsPtr->tcl_SubstObj) /* 437 */
#define Tcl_DetachChannel \
(tclStubsPtr->tcl_DetachChannel) /* 438 */
#define Tcl_IsStandardChannel \
(tclStubsPtr->tcl_IsStandardChannel) /* 439 */
#define Tcl_FSCopyFile \
(tclStubsPtr->tcl_FSCopyFile) /* 440 */
#define Tcl_FSCopyDirectory \
(tclStubsPtr->tcl_FSCopyDirectory) /* 441 */
#define Tcl_FSCreateDirectory \
(tclStubsPtr->tcl_FSCreateDirectory) /* 442 */
#define Tcl_FSDeleteFile \
(tclStubsPtr->tcl_FSDeleteFile) /* 443 */
#define Tcl_FSLoadFile \
(tclStubsPtr->tcl_FSLoadFile) /* 444 */
#define Tcl_FSMatchInDirectory \
(tclStubsPtr->tcl_FSMatchInDirectory) /* 445 */
#define Tcl_FSLink \
(tclStubsPtr->tcl_FSLink) /* 446 */
#define Tcl_FSRemoveDirectory \
(tclStubsPtr->tcl_FSRemoveDirectory) /* 447 */
#define Tcl_FSRenameFile \
(tclStubsPtr->tcl_FSRenameFile) /* 448 */
#define Tcl_FSLstat \
(tclStubsPtr->tcl_FSLstat) /* 449 */
#define Tcl_FSUtime \
(tclStubsPtr->tcl_FSUtime) /* 450 */
#define Tcl_FSFileAttrsGet \
(tclStubsPtr->tcl_FSFileAttrsGet) /* 451 */
#define Tcl_FSFileAttrsSet \
(tclStubsPtr->tcl_FSFileAttrsSet) /* 452 */
#define Tcl_FSFileAttrStrings \
(tclStubsPtr->tcl_FSFileAttrStrings) /* 453 */
#define Tcl_FSStat \
(tclStubsPtr->tcl_FSStat) /* 454 */
#define Tcl_FSAccess \
(tclStubsPtr->tcl_FSAccess) /* 455 */
#define Tcl_FSOpenFileChannel \
(tclStubsPtr->tcl_FSOpenFileChannel) /* 456 */
#define Tcl_FSGetCwd \
(tclStubsPtr->tcl_FSGetCwd) /* 457 */
#define Tcl_FSChdir \
(tclStubsPtr->tcl_FSChdir) /* 458 */
#define Tcl_FSConvertToPathType \
(tclStubsPtr->tcl_FSConvertToPathType) /* 459 */
#define Tcl_FSJoinPath \
(tclStubsPtr->tcl_FSJoinPath) /* 460 */
#define TclFSSplitPath \
(tclStubsPtr->tclFSSplitPath) /* 461 */
#define Tcl_FSEqualPaths \
(tclStubsPtr->tcl_FSEqualPaths) /* 462 */
#define Tcl_FSGetNormalizedPath \
(tclStubsPtr->tcl_FSGetNormalizedPath) /* 463 */
#define Tcl_FSJoinToPath \
(tclStubsPtr->tcl_FSJoinToPath) /* 464 */
#define Tcl_FSGetInternalRep \
(tclStubsPtr->tcl_FSGetInternalRep) /* 465 */
#define Tcl_FSGetTranslatedPath \
(tclStubsPtr->tcl_FSGetTranslatedPath) /* 466 */
#define Tcl_FSEvalFile \
(tclStubsPtr->tcl_FSEvalFile) /* 467 */
#define Tcl_FSNewNativePath \
(tclStubsPtr->tcl_FSNewNativePath) /* 468 */
#define Tcl_FSGetNativePath \
(tclStubsPtr->tcl_FSGetNativePath) /* 469 */
#define Tcl_FSFileSystemInfo \
(tclStubsPtr->tcl_FSFileSystemInfo) /* 470 */
#define Tcl_FSPathSeparator \
(tclStubsPtr->tcl_FSPathSeparator) /* 471 */
#define Tcl_FSListVolumes \
(tclStubsPtr->tcl_FSListVolumes) /* 472 */
#define Tcl_FSRegister \
(tclStubsPtr->tcl_FSRegister) /* 473 */
#define Tcl_FSUnregister \
(tclStubsPtr->tcl_FSUnregister) /* 474 */
#define Tcl_FSData \
(tclStubsPtr->tcl_FSData) /* 475 */
#define Tcl_FSGetTranslatedStringPath \
(tclStubsPtr->tcl_FSGetTranslatedStringPath) /* 476 */
#define Tcl_FSGetFileSystemForPath \
(tclStubsPtr->tcl_FSGetFileSystemForPath) /* 477 */
#define Tcl_FSGetPathType \
(tclStubsPtr->tcl_FSGetPathType) /* 478 */
#define Tcl_OutputBuffered \
(tclStubsPtr->tcl_OutputBuffered) /* 479 */
#define Tcl_FSMountsChanged \
(tclStubsPtr->tcl_FSMountsChanged) /* 480 */
#define Tcl_EvalTokensStandard \
(tclStubsPtr->tcl_EvalTokensStandard) /* 481 */
#define Tcl_GetTime \
(tclStubsPtr->tcl_GetTime) /* 482 */
#define Tcl_CreateObjTrace \
(tclStubsPtr->tcl_CreateObjTrace) /* 483 */
#define Tcl_GetCommandInfoFromToken \
(tclStubsPtr->tcl_GetCommandInfoFromToken) /* 484 */
#define Tcl_SetCommandInfoFromToken \
(tclStubsPtr->tcl_SetCommandInfoFromToken) /* 485 */
#define Tcl_DbNewWideIntObj \
(tclStubsPtr->tcl_DbNewWideIntObj) /* 486 */
#define Tcl_GetWideIntFromObj \
(tclStubsPtr->tcl_GetWideIntFromObj) /* 487 */
#define Tcl_NewWideIntObj \
(tclStubsPtr->tcl_NewWideIntObj) /* 488 */
#define Tcl_SetWideIntObj \
(tclStubsPtr->tcl_SetWideIntObj) /* 489 */
#define Tcl_AllocStatBuf \
(tclStubsPtr->tcl_AllocStatBuf) /* 490 */
#define Tcl_Seek \
(tclStubsPtr->tcl_Seek) /* 491 */
#define Tcl_Tell \
(tclStubsPtr->tcl_Tell) /* 492 */
#define Tcl_ChannelWideSeekProc \
(tclStubsPtr->tcl_ChannelWideSeekProc) /* 493 */
#define Tcl_DictObjPut \
(tclStubsPtr->tcl_DictObjPut) /* 494 */
#define Tcl_DictObjGet \
(tclStubsPtr->tcl_DictObjGet) /* 495 */
#define Tcl_DictObjRemove \
(tclStubsPtr->tcl_DictObjRemove) /* 496 */
#define TclDictObjSize \
(tclStubsPtr->tclDictObjSize) /* 497 */
#define Tcl_DictObjFirst \
(tclStubsPtr->tcl_DictObjFirst) /* 498 */
#define Tcl_DictObjNext \
(tclStubsPtr->tcl_DictObjNext) /* 499 */
#define Tcl_DictObjDone \
(tclStubsPtr->tcl_DictObjDone) /* 500 */
#define Tcl_DictObjPutKeyList \
(tclStubsPtr->tcl_DictObjPutKeyList) /* 501 */
#define Tcl_DictObjRemoveKeyList \
(tclStubsPtr->tcl_DictObjRemoveKeyList) /* 502 */
#define Tcl_NewDictObj \
(tclStubsPtr->tcl_NewDictObj) /* 503 */
#define Tcl_DbNewDictObj \
(tclStubsPtr->tcl_DbNewDictObj) /* 504 */
#define Tcl_RegisterConfig \
(tclStubsPtr->tcl_RegisterConfig) /* 505 */
#define Tcl_CreateNamespace \
(tclStubsPtr->tcl_CreateNamespace) /* 506 */
#define Tcl_DeleteNamespace \
(tclStubsPtr->tcl_DeleteNamespace) /* 507 */
#define Tcl_AppendExportList \
(tclStubsPtr->tcl_AppendExportList) /* 508 */
#define Tcl_Export \
(tclStubsPtr->tcl_Export) /* 509 */
#define Tcl_Import \
(tclStubsPtr->tcl_Import) /* 510 */
#define Tcl_ForgetImport \
(tclStubsPtr->tcl_ForgetImport) /* 511 */
#define Tcl_GetCurrentNamespace \
(tclStubsPtr->tcl_GetCurrentNamespace) /* 512 */
#define Tcl_GetGlobalNamespace \
(tclStubsPtr->tcl_GetGlobalNamespace) /* 513 */
#define Tcl_FindNamespace \
(tclStubsPtr->tcl_FindNamespace) /* 514 */
#define Tcl_FindCommand \
(tclStubsPtr->tcl_FindCommand) /* 515 */
#define Tcl_GetCommandFromObj \
(tclStubsPtr->tcl_GetCommandFromObj) /* 516 */
#define Tcl_GetCommandFullName \
(tclStubsPtr->tcl_GetCommandFullName) /* 517 */
#define Tcl_FSEvalFileEx \
(tclStubsPtr->tcl_FSEvalFileEx) /* 518 */
/* Slot 519 is reserved */
#define Tcl_LimitAddHandler \
(tclStubsPtr->tcl_LimitAddHandler) /* 520 */
#define Tcl_LimitRemoveHandler \
(tclStubsPtr->tcl_LimitRemoveHandler) /* 521 */
#define Tcl_LimitReady \
(tclStubsPtr->tcl_LimitReady) /* 522 */
#define Tcl_LimitCheck \
(tclStubsPtr->tcl_LimitCheck) /* 523 */
#define Tcl_LimitExceeded \
(tclStubsPtr->tcl_LimitExceeded) /* 524 */
#define Tcl_LimitSetCommands \
(tclStubsPtr->tcl_LimitSetCommands) /* 525 */
#define Tcl_LimitSetTime \
(tclStubsPtr->tcl_LimitSetTime) /* 526 */
#define Tcl_LimitSetGranularity \
(tclStubsPtr->tcl_LimitSetGranularity) /* 527 */
#define Tcl_LimitTypeEnabled \
(tclStubsPtr->tcl_LimitTypeEnabled) /* 528 */
#define Tcl_LimitTypeExceeded \
(tclStubsPtr->tcl_LimitTypeExceeded) /* 529 */
#define Tcl_LimitTypeSet \
(tclStubsPtr->tcl_LimitTypeSet) /* 530 */
#define Tcl_LimitTypeReset \
(tclStubsPtr->tcl_LimitTypeReset) /* 531 */
#define Tcl_LimitGetCommands \
(tclStubsPtr->tcl_LimitGetCommands) /* 532 */
#define Tcl_LimitGetTime \
(tclStubsPtr->tcl_LimitGetTime) /* 533 */
#define Tcl_LimitGetGranularity \
(tclStubsPtr->tcl_LimitGetGranularity) /* 534 */
#define Tcl_SaveInterpState \
(tclStubsPtr->tcl_SaveInterpState) /* 535 */
#define Tcl_RestoreInterpState \
(tclStubsPtr->tcl_RestoreInterpState) /* 536 */
#define Tcl_DiscardInterpState \
(tclStubsPtr->tcl_DiscardInterpState) /* 537 */
#define Tcl_SetReturnOptions \
(tclStubsPtr->tcl_SetReturnOptions) /* 538 */
#define Tcl_GetReturnOptions \
(tclStubsPtr->tcl_GetReturnOptions) /* 539 */
#define Tcl_IsEnsemble \
(tclStubsPtr->tcl_IsEnsemble) /* 540 */
#define Tcl_CreateEnsemble \
(tclStubsPtr->tcl_CreateEnsemble) /* 541 */
#define Tcl_FindEnsemble \
(tclStubsPtr->tcl_FindEnsemble) /* 542 */
#define Tcl_SetEnsembleSubcommandList \
(tclStubsPtr->tcl_SetEnsembleSubcommandList) /* 543 */
#define Tcl_SetEnsembleMappingDict \
(tclStubsPtr->tcl_SetEnsembleMappingDict) /* 544 */
#define Tcl_SetEnsembleUnknownHandler \
(tclStubsPtr->tcl_SetEnsembleUnknownHandler) /* 545 */
#define Tcl_SetEnsembleFlags \
(tclStubsPtr->tcl_SetEnsembleFlags) /* 546 */
#define Tcl_GetEnsembleSubcommandList \
(tclStubsPtr->tcl_GetEnsembleSubcommandList) /* 547 */
#define Tcl_GetEnsembleMappingDict \
(tclStubsPtr->tcl_GetEnsembleMappingDict) /* 548 */
#define Tcl_GetEnsembleUnknownHandler \
(tclStubsPtr->tcl_GetEnsembleUnknownHandler) /* 549 */
#define Tcl_GetEnsembleFlags \
(tclStubsPtr->tcl_GetEnsembleFlags) /* 550 */
#define Tcl_GetEnsembleNamespace \
(tclStubsPtr->tcl_GetEnsembleNamespace) /* 551 */
#define Tcl_SetTimeProc \
(tclStubsPtr->tcl_SetTimeProc) /* 552 */
#define Tcl_QueryTimeProc \
(tclStubsPtr->tcl_QueryTimeProc) /* 553 */
#define Tcl_ChannelThreadActionProc \
(tclStubsPtr->tcl_ChannelThreadActionProc) /* 554 */
#define Tcl_NewBignumObj \
(tclStubsPtr->tcl_NewBignumObj) /* 555 */
#define Tcl_DbNewBignumObj \
(tclStubsPtr->tcl_DbNewBignumObj) /* 556 */
#define Tcl_SetBignumObj \
(tclStubsPtr->tcl_SetBignumObj) /* 557 */
#define Tcl_GetBignumFromObj \
(tclStubsPtr->tcl_GetBignumFromObj) /* 558 */
#define Tcl_TakeBignumFromObj \
(tclStubsPtr->tcl_TakeBignumFromObj) /* 559 */
#define Tcl_TruncateChannel \
(tclStubsPtr->tcl_TruncateChannel) /* 560 */
#define Tcl_ChannelTruncateProc \
(tclStubsPtr->tcl_ChannelTruncateProc) /* 561 */
#define Tcl_SetChannelErrorInterp \
(tclStubsPtr->tcl_SetChannelErrorInterp) /* 562 */
#define Tcl_GetChannelErrorInterp \
(tclStubsPtr->tcl_GetChannelErrorInterp) /* 563 */
#define Tcl_SetChannelError \
(tclStubsPtr->tcl_SetChannelError) /* 564 */
#define Tcl_GetChannelError \
(tclStubsPtr->tcl_GetChannelError) /* 565 */
#define Tcl_InitBignumFromDouble \
(tclStubsPtr->tcl_InitBignumFromDouble) /* 566 */
#define Tcl_GetNamespaceUnknownHandler \
(tclStubsPtr->tcl_GetNamespaceUnknownHandler) /* 567 */
#define Tcl_SetNamespaceUnknownHandler \
(tclStubsPtr->tcl_SetNamespaceUnknownHandler) /* 568 */
#define Tcl_GetEncodingFromObj \
(tclStubsPtr->tcl_GetEncodingFromObj) /* 569 */
#define Tcl_GetEncodingSearchPath \
(tclStubsPtr->tcl_GetEncodingSearchPath) /* 570 */
#define Tcl_SetEncodingSearchPath \
(tclStubsPtr->tcl_SetEncodingSearchPath) /* 571 */
#define Tcl_GetEncodingNameFromEnvironment \
(tclStubsPtr->tcl_GetEncodingNameFromEnvironment) /* 572 */
#define Tcl_PkgRequireProc \
(tclStubsPtr->tcl_PkgRequireProc) /* 573 */
#define Tcl_AppendObjToErrorInfo \
(tclStubsPtr->tcl_AppendObjToErrorInfo) /* 574 */
#define Tcl_AppendLimitedToObj \
(tclStubsPtr->tcl_AppendLimitedToObj) /* 575 */
#define Tcl_Format \
(tclStubsPtr->tcl_Format) /* 576 */
#define Tcl_AppendFormatToObj \
(tclStubsPtr->tcl_AppendFormatToObj) /* 577 */
#define Tcl_ObjPrintf \
(tclStubsPtr->tcl_ObjPrintf) /* 578 */
#define Tcl_AppendPrintfToObj \
(tclStubsPtr->tcl_AppendPrintfToObj) /* 579 */
#define Tcl_CancelEval \
(tclStubsPtr->tcl_CancelEval) /* 580 */
#define Tcl_Canceled \
(tclStubsPtr->tcl_Canceled) /* 581 */
#define Tcl_CreatePipe \
(tclStubsPtr->tcl_CreatePipe) /* 582 */
#define Tcl_NRCreateCommand \
(tclStubsPtr->tcl_NRCreateCommand) /* 583 */
#define Tcl_NREvalObj \
(tclStubsPtr->tcl_NREvalObj) /* 584 */
#define Tcl_NREvalObjv \
(tclStubsPtr->tcl_NREvalObjv) /* 585 */
#define Tcl_NRCmdSwap \
(tclStubsPtr->tcl_NRCmdSwap) /* 586 */
#define Tcl_NRAddCallback \
(tclStubsPtr->tcl_NRAddCallback) /* 587 */
#define Tcl_NRCallObjProc \
(tclStubsPtr->tcl_NRCallObjProc) /* 588 */
#define Tcl_GetFSDeviceFromStat \
(tclStubsPtr->tcl_GetFSDeviceFromStat) /* 589 */
#define Tcl_GetFSInodeFromStat \
(tclStubsPtr->tcl_GetFSInodeFromStat) /* 590 */
#define Tcl_GetModeFromStat \
(tclStubsPtr->tcl_GetModeFromStat) /* 591 */
#define Tcl_GetLinkCountFromStat \
(tclStubsPtr->tcl_GetLinkCountFromStat) /* 592 */
#define Tcl_GetUserIdFromStat \
(tclStubsPtr->tcl_GetUserIdFromStat) /* 593 */
#define Tcl_GetGroupIdFromStat \
(tclStubsPtr->tcl_GetGroupIdFromStat) /* 594 */
#define Tcl_GetDeviceTypeFromStat \
(tclStubsPtr->tcl_GetDeviceTypeFromStat) /* 595 */
#define Tcl_GetAccessTimeFromStat \
(tclStubsPtr->tcl_GetAccessTimeFromStat) /* 596 */
#define Tcl_GetModificationTimeFromStat \
(tclStubsPtr->tcl_GetModificationTimeFromStat) /* 597 */
#define Tcl_GetChangeTimeFromStat \
(tclStubsPtr->tcl_GetChangeTimeFromStat) /* 598 */
#define Tcl_GetSizeFromStat \
(tclStubsPtr->tcl_GetSizeFromStat) /* 599 */
#define Tcl_GetBlocksFromStat \
(tclStubsPtr->tcl_GetBlocksFromStat) /* 600 */
#define Tcl_GetBlockSizeFromStat \
(tclStubsPtr->tcl_GetBlockSizeFromStat) /* 601 */
#define Tcl_SetEnsembleParameterList \
(tclStubsPtr->tcl_SetEnsembleParameterList) /* 602 */
#define Tcl_GetEnsembleParameterList \
(tclStubsPtr->tcl_GetEnsembleParameterList) /* 603 */
#define TclParseArgsObjv \
(tclStubsPtr->tclParseArgsObjv) /* 604 */
#define Tcl_GetErrorLine \
(tclStubsPtr->tcl_GetErrorLine) /* 605 */
#define Tcl_SetErrorLine \
(tclStubsPtr->tcl_SetErrorLine) /* 606 */
#define Tcl_TransferResult \
(tclStubsPtr->tcl_TransferResult) /* 607 */
#define Tcl_InterpActive \
(tclStubsPtr->tcl_InterpActive) /* 608 */
#define Tcl_BackgroundException \
(tclStubsPtr->tcl_BackgroundException) /* 609 */
#define Tcl_ZlibDeflate \
(tclStubsPtr->tcl_ZlibDeflate) /* 610 */
#define Tcl_ZlibInflate \
(tclStubsPtr->tcl_ZlibInflate) /* 611 */
#define Tcl_ZlibCRC32 \
(tclStubsPtr->tcl_ZlibCRC32) /* 612 */
#define Tcl_ZlibAdler32 \
(tclStubsPtr->tcl_ZlibAdler32) /* 613 */
#define Tcl_ZlibStreamInit \
(tclStubsPtr->tcl_ZlibStreamInit) /* 614 */
#define Tcl_ZlibStreamGetCommandName \
(tclStubsPtr->tcl_ZlibStreamGetCommandName) /* 615 */
#define Tcl_ZlibStreamEof \
(tclStubsPtr->tcl_ZlibStreamEof) /* 616 */
#define Tcl_ZlibStreamChecksum \
(tclStubsPtr->tcl_ZlibStreamChecksum) /* 617 */
#define Tcl_ZlibStreamPut \
(tclStubsPtr->tcl_ZlibStreamPut) /* 618 */
#define Tcl_ZlibStreamGet \
(tclStubsPtr->tcl_ZlibStreamGet) /* 619 */
#define Tcl_ZlibStreamClose \
(tclStubsPtr->tcl_ZlibStreamClose) /* 620 */
#define Tcl_ZlibStreamReset \
(tclStubsPtr->tcl_ZlibStreamReset) /* 621 */
#define Tcl_SetStartupScript \
(tclStubsPtr->tcl_SetStartupScript) /* 622 */
#define Tcl_GetStartupScript \
(tclStubsPtr->tcl_GetStartupScript) /* 623 */
#define Tcl_CloseEx \
(tclStubsPtr->tcl_CloseEx) /* 624 */
#define Tcl_NRExprObj \
(tclStubsPtr->tcl_NRExprObj) /* 625 */
#define Tcl_NRSubstObj \
(tclStubsPtr->tcl_NRSubstObj) /* 626 */
#define Tcl_LoadFile \
(tclStubsPtr->tcl_LoadFile) /* 627 */
#define Tcl_FindSymbol \
(tclStubsPtr->tcl_FindSymbol) /* 628 */
#define Tcl_FSUnloadFile \
(tclStubsPtr->tcl_FSUnloadFile) /* 629 */
#define Tcl_ZlibStreamSetCompressionDictionary \
(tclStubsPtr->tcl_ZlibStreamSetCompressionDictionary) /* 630 */
#define Tcl_OpenTcpServerEx \
(tclStubsPtr->tcl_OpenTcpServerEx) /* 631 */
#define TclZipfs_Mount \
(tclStubsPtr->tclZipfs_Mount) /* 632 */
#define TclZipfs_Unmount \
(tclStubsPtr->tclZipfs_Unmount) /* 633 */
#define TclZipfs_TclLibrary \
(tclStubsPtr->tclZipfs_TclLibrary) /* 634 */
#define TclZipfs_MountBuffer \
(tclStubsPtr->tclZipfs_MountBuffer) /* 635 */
#define Tcl_FreeInternalRep \
(tclStubsPtr->tcl_FreeInternalRep) /* 636 */
#define Tcl_InitStringRep \
(tclStubsPtr->tcl_InitStringRep) /* 637 */
#define Tcl_FetchInternalRep \
(tclStubsPtr->tcl_FetchInternalRep) /* 638 */
#define Tcl_StoreInternalRep \
(tclStubsPtr->tcl_StoreInternalRep) /* 639 */
#define Tcl_HasStringRep \
(tclStubsPtr->tcl_HasStringRep) /* 640 */
#define Tcl_IncrRefCount \
(tclStubsPtr->tcl_IncrRefCount) /* 641 */
#define Tcl_DecrRefCount \
(tclStubsPtr->tcl_DecrRefCount) /* 642 */
#define Tcl_IsShared \
(tclStubsPtr->tcl_IsShared) /* 643 */
#define Tcl_LinkArray \
(tclStubsPtr->tcl_LinkArray) /* 644 */
#define Tcl_GetIntForIndex \
(tclStubsPtr->tcl_GetIntForIndex) /* 645 */
#define Tcl_UtfToUniChar \
(tclStubsPtr->tcl_UtfToUniChar) /* 646 */
#define Tcl_UniCharToUtfDString \
(tclStubsPtr->tcl_UniCharToUtfDString) /* 647 */
#define Tcl_UtfToUniCharDString \
(tclStubsPtr->tcl_UtfToUniCharDString) /* 648 */
#define TclGetBytesFromObj \
(tclStubsPtr->tclGetBytesFromObj) /* 649 */
#define Tcl_GetBytesFromObj \
(tclStubsPtr->tcl_GetBytesFromObj) /* 650 */
#define Tcl_GetStringFromObj \
(tclStubsPtr->tcl_GetStringFromObj) /* 651 */
#define Tcl_GetUnicodeFromObj \
(tclStubsPtr->tcl_GetUnicodeFromObj) /* 652 */
#define Tcl_GetSizeIntFromObj \
(tclStubsPtr->tcl_GetSizeIntFromObj) /* 653 */
#define Tcl_UtfCharComplete \
(tclStubsPtr->tcl_UtfCharComplete) /* 654 */
#define Tcl_UtfNext \
(tclStubsPtr->tcl_UtfNext) /* 655 */
#define Tcl_UtfPrev \
(tclStubsPtr->tcl_UtfPrev) /* 656 */
#define Tcl_FSTildeExpand \
(tclStubsPtr->tcl_FSTildeExpand) /* 657 */
#define Tcl_ExternalToUtfDStringEx \
(tclStubsPtr->tcl_ExternalToUtfDStringEx) /* 658 */
#define Tcl_UtfToExternalDStringEx \
(tclStubsPtr->tcl_UtfToExternalDStringEx) /* 659 */
#define Tcl_AsyncMarkFromSignal \
(tclStubsPtr->tcl_AsyncMarkFromSignal) /* 660 */
#define Tcl_ListObjGetElements \
(tclStubsPtr->tcl_ListObjGetElements) /* 661 */
#define Tcl_ListObjLength \
(tclStubsPtr->tcl_ListObjLength) /* 662 */
#define Tcl_DictObjSize \
(tclStubsPtr->tcl_DictObjSize) /* 663 */
#define Tcl_SplitList \
(tclStubsPtr->tcl_SplitList) /* 664 */
#define Tcl_SplitPath \
(tclStubsPtr->tcl_SplitPath) /* 665 */
#define Tcl_FSSplitPath \
(tclStubsPtr->tcl_FSSplitPath) /* 666 */
#define Tcl_ParseArgsObjv \
(tclStubsPtr->tcl_ParseArgsObjv) /* 667 */
#define Tcl_UniCharLen \
(tclStubsPtr->tcl_UniCharLen) /* 668 */
#define Tcl_NumUtfChars \
(tclStubsPtr->tcl_NumUtfChars) /* 669 */
#define Tcl_GetCharLength \
(tclStubsPtr->tcl_GetCharLength) /* 670 */
#define Tcl_UtfAtIndex \
(tclStubsPtr->tcl_UtfAtIndex) /* 671 */
#define Tcl_GetRange \
(tclStubsPtr->tcl_GetRange) /* 672 */
#define Tcl_GetUniChar \
(tclStubsPtr->tcl_GetUniChar) /* 673 */
#define Tcl_GetBool \
(tclStubsPtr->tcl_GetBool) /* 674 */
#define Tcl_GetBoolFromObj \
(tclStubsPtr->tcl_GetBoolFromObj) /* 675 */
#define Tcl_CreateObjCommand2 \
(tclStubsPtr->tcl_CreateObjCommand2) /* 676 */
#define Tcl_CreateObjTrace2 \
(tclStubsPtr->tcl_CreateObjTrace2) /* 677 */
#define Tcl_NRCreateCommand2 \
(tclStubsPtr->tcl_NRCreateCommand2) /* 678 */
#define Tcl_NRCallObjProc2 \
(tclStubsPtr->tcl_NRCallObjProc2) /* 679 */
#define Tcl_GetNumberFromObj \
(tclStubsPtr->tcl_GetNumberFromObj) /* 680 */
#define Tcl_GetNumber \
(tclStubsPtr->tcl_GetNumber) /* 681 */
#define Tcl_RemoveChannelMode \
(tclStubsPtr->tcl_RemoveChannelMode) /* 682 */
#define Tcl_GetEncodingNulLength \
(tclStubsPtr->tcl_GetEncodingNulLength) /* 683 */
#define Tcl_GetWideUIntFromObj \
(tclStubsPtr->tcl_GetWideUIntFromObj) /* 684 */
#define Tcl_DStringToObj \
(tclStubsPtr->tcl_DStringToObj) /* 685 */
#define Tcl_UtfNcmp \
(tclStubsPtr->tcl_UtfNcmp) /* 686 */
#define Tcl_UtfNcasecmp \
(tclStubsPtr->tcl_UtfNcasecmp) /* 687 */
#define Tcl_NewWideUIntObj \
(tclStubsPtr->tcl_NewWideUIntObj) /* 688 */
#define Tcl_SetWideUIntObj \
(tclStubsPtr->tcl_SetWideUIntObj) /* 689 */
#define TclUnusedStubEntry \
(tclStubsPtr->tclUnusedStubEntry) /* 690 */
#endif /* defined(USE_TCL_STUBS) */
/* !END!: Do not edit above this line. */
#undef TclUnusedStubEntry
#ifdef _WIN32
# undef Tcl_CreateFileHandler
# undef Tcl_DeleteFileHandler
# undef Tcl_GetOpenFile
#endif
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT
#define Tcl_PkgPresent(interp, name, version, exact) \
Tcl_PkgPresentEx(interp, name, version, exact, NULL)
#define Tcl_PkgProvide(interp, name, version) \
Tcl_PkgProvideEx(interp, name, version, NULL)
#define Tcl_PkgRequire(interp, name, version, exact) \
Tcl_PkgRequireEx(interp, name, version, exact, NULL)
#define Tcl_GetIndexFromObj(interp, objPtr, tablePtr, msg, flags, indexPtr) \
Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, \
sizeof(char *), msg, flags, indexPtr)
#define Tcl_NewBooleanObj(intValue) \
Tcl_NewWideIntObj((intValue)!=0)
#define Tcl_DbNewBooleanObj(intValue, file, line) \
Tcl_DbNewWideIntObj((intValue)!=0, file, line)
#define Tcl_SetBooleanObj(objPtr, intValue) \
Tcl_SetWideIntObj(objPtr, (intValue)!=0)
#define Tcl_SetVar(interp, varName, newValue, flags) \
Tcl_SetVar2(interp, varName, NULL, newValue, flags)
#define Tcl_UnsetVar(interp, varName, flags) \
Tcl_UnsetVar2(interp, varName, NULL, flags)
#define Tcl_GetVar(interp, varName, flags) \
Tcl_GetVar2(interp, varName, NULL, flags)
#define Tcl_TraceVar(interp, varName, flags, proc, clientData) \
Tcl_TraceVar2(interp, varName, NULL, flags, proc, clientData)
#define Tcl_UntraceVar(interp, varName, flags, proc, clientData) \
Tcl_UntraceVar2(interp, varName, NULL, flags, proc, clientData)
#define Tcl_VarTraceInfo(interp, varName, flags, proc, prevClientData) \
Tcl_VarTraceInfo2(interp, varName, NULL, flags, proc, prevClientData)
#define Tcl_UpVar(interp, frameName, varName, localName, flags) \
Tcl_UpVar2(interp, frameName, varName, NULL, localName, flags)
#define Tcl_AddErrorInfo(interp, message) \
Tcl_AppendObjToErrorInfo(interp, Tcl_NewStringObj(message, -1))
#define Tcl_AddObjErrorInfo(interp, message, length) \
Tcl_AppendObjToErrorInfo(interp, Tcl_NewStringObj(message, length))
#define Tcl_Eval(interp, objPtr) \
Tcl_EvalEx(interp, objPtr, TCL_INDEX_NONE, 0)
#define Tcl_GlobalEval(interp, objPtr) \
Tcl_EvalEx(interp, objPtr, TCL_INDEX_NONE, TCL_EVAL_GLOBAL)
#define Tcl_GetStringResult(interp) Tcl_GetString(Tcl_GetObjResult(interp))
#define Tcl_SetResult(interp, result, freeProc) \
do { \
const char *__result = result; \
Tcl_FreeProc *__freeProc = freeProc; \
Tcl_SetObjResult(interp, Tcl_NewStringObj(__result, -1)); \
if (__result != NULL && __freeProc != NULL && __freeProc != TCL_VOLATILE) { \
if (__freeProc == TCL_DYNAMIC) { \
Tcl_Free((void *)__result); \
} else { \
(*__freeProc)((void *)__result); \
} \
} \
} while(0)
#if defined(USE_TCL_STUBS)
# if defined(_WIN32) && defined(_WIN64) && TCL_MAJOR_VERSION < 9
# undef Tcl_GetTime
/* Handle Win64 tk.dll being loaded in Cygwin64 (only needed for Tcl 8). */
# define Tcl_GetTime(t) \
do { \
struct { \
Tcl_Time now; \
long long reserved; \
} _t; \
_t.reserved = -1; \
tclStubsPtr->tcl_GetTime((&_t.now)); \
if (_t.reserved != -1) { \
_t.now.usec = (long) _t.reserved; \
} \
*(t) = _t.now; \
} while (0)
# endif
# if defined(__CYGWIN__) && defined(TCL_WIDE_INT_IS_LONG)
/* On Cygwin64, long is 64-bit while on Win64 long is 32-bit. Therefore
* we have to make sure that all stub entries on Cygwin64 follow the
* Win64 signature. Cygwin64 stubbed extensions cannot use those stub
* entries any more, they should use the 64-bit alternatives where
* possible. Tcl 9 must find a better solution, but that cannot be done
* without introducing a binary incompatibility.
*/
# undef Tcl_GetLongFromObj
# undef Tcl_ExprLong
# undef Tcl_ExprLongObj
# define Tcl_GetLongFromObj ((int(*)(Tcl_Interp*,Tcl_Obj*,long*))Tcl_GetWideIntFromObj)
# define Tcl_ExprLong TclExprLong
static inline int TclExprLong(Tcl_Interp *interp, const char *string, long *ptr){
int intValue;
int result = tclStubsPtr->tcl_ExprLong(interp, string, (long *)&intValue);
if (result == TCL_OK) *ptr = (long)intValue;
return result;
}
# define Tcl_ExprLongObj TclExprLongObj
static inline int TclExprLongObj(Tcl_Interp *interp, Tcl_Obj *obj, long *ptr){
int intValue;
int result = tclStubsPtr->tcl_ExprLongObj(interp, obj, (long *)&intValue);
if (result == TCL_OK) *ptr = (long)intValue;
return result;
}
# endif
#endif
#undef Tcl_GetString
#undef Tcl_GetUnicode
#undef Tcl_CreateHashEntry
#define Tcl_GetString(objPtr) \
Tcl_GetStringFromObj(objPtr, (Tcl_Size *)NULL)
#define Tcl_GetUnicode(objPtr) \
Tcl_GetUnicodeFromObj(objPtr, (Tcl_Size *)NULL)
#undef Tcl_GetIndexFromObjStruct
#undef Tcl_GetBooleanFromObj
#undef Tcl_GetBoolean
#if !defined(TCLBOOLWARNING)
#if !defined(__cplusplus) && !defined(BUILD_tcl) && !defined(BUILD_tk) && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
# define TCLBOOLWARNING(boolPtr) (void)(sizeof(struct {_Static_assert(sizeof(*(boolPtr)) <= sizeof(int), "sizeof(boolPtr) too large");int dummy;})),
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
/* If this gives: "error: size of array ‘_bool_Var’ is negative", it means that sizeof(*boolPtr)>sizeof(int), which is not allowed */
# define TCLBOOLWARNING(boolPtr) ({__attribute__((unused)) char _bool_Var[sizeof(*(boolPtr)) <= sizeof(int) ? 1 : -1];}),
#else
# define TCLBOOLWARNING(boolPtr)
#endif
#endif /* !TCLBOOLWARNING */
#if defined(USE_TCL_STUBS)
#define Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, indexPtr) \
(tclStubsPtr->tcl_GetIndexFromObjStruct((interp), (objPtr), (tablePtr), (offset), (msg), \
(flags)|(int)(sizeof(*(indexPtr))<<1), (indexPtr)))
#define Tcl_GetBooleanFromObj(interp, objPtr, boolPtr) \
((sizeof(*(boolPtr)) == sizeof(int) && (TCL_MAJOR_VERSION == 8)) ? tclStubsPtr->tcl_GetBooleanFromObj(interp, objPtr, (int *)(boolPtr)) : \
((sizeof(*(boolPtr)) <= sizeof(int)) ? Tcl_GetBoolFromObj(interp, objPtr, (TCL_NULL_OK-2)&(int)sizeof((*(boolPtr))), (char *)(boolPtr)) : \
(TCLBOOLWARNING(boolPtr)Tcl_Panic("sizeof(%s) must be <= sizeof(int)", & #boolPtr [1]),TCL_ERROR)))
#define Tcl_GetBoolean(interp, src, boolPtr) \
((sizeof(*(boolPtr)) == sizeof(int) && (TCL_MAJOR_VERSION == 8)) ? tclStubsPtr->tcl_GetBoolean(interp, src, (int *)(boolPtr)) : \
((sizeof(*(boolPtr)) <= sizeof(int)) ? Tcl_GetBool(interp, src, (TCL_NULL_OK-2)&(int)sizeof((*(boolPtr))), (char *)(boolPtr)) : \
(TCLBOOLWARNING(boolPtr)Tcl_Panic("sizeof(%s) must be <= sizeof(int)", & #boolPtr [1]),TCL_ERROR)))
#else
#define Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, offset, msg, flags, indexPtr) \
((Tcl_GetIndexFromObjStruct)((interp), (objPtr), (tablePtr), (offset), (msg), \
(flags)|(int)(sizeof(*(indexPtr))<<1), (indexPtr)))
#define Tcl_GetBooleanFromObj(interp, objPtr, boolPtr) \
((sizeof(*(boolPtr)) == sizeof(int) && (TCL_MAJOR_VERSION == 8)) ? Tcl_GetBooleanFromObj(interp, objPtr, (int *)(boolPtr)) : \
((sizeof(*(boolPtr)) <= sizeof(int)) ? Tcl_GetBoolFromObj(interp, objPtr, (TCL_NULL_OK-2)&(int)sizeof((*(boolPtr))), (char *)(boolPtr)) : \
(TCLBOOLWARNING(boolPtr)Tcl_Panic("sizeof(%s) must be <= sizeof(int)", & #boolPtr [1]),TCL_ERROR)))
#define Tcl_GetBoolean(interp, src, boolPtr) \
((sizeof(*(boolPtr)) == sizeof(int) && (TCL_MAJOR_VERSION == 8)) ? Tcl_GetBoolean(interp, src, (int *)(boolPtr)) : \
((sizeof(*(boolPtr)) <= sizeof(int)) ? Tcl_GetBool(interp, src, (TCL_NULL_OK-2)&(int)sizeof((*(boolPtr))), (char *)(boolPtr)) : \
(TCLBOOLWARNING(boolPtr)Tcl_Panic("sizeof(%s) must be <= sizeof(int)", & #boolPtr [1]),TCL_ERROR)))
#endif
#ifdef TCL_MEM_DEBUG
# undef Tcl_Alloc
# define Tcl_Alloc(x) \
(Tcl_DbCkalloc((x), __FILE__, __LINE__))
# undef Tcl_Free
# define Tcl_Free(x) \
Tcl_DbCkfree((x), __FILE__, __LINE__)
# undef Tcl_Realloc
# define Tcl_Realloc(x,y) \
(Tcl_DbCkrealloc((x), (y), __FILE__, __LINE__))
# undef Tcl_AttemptAlloc
# define Tcl_AttemptAlloc(x) \
(Tcl_AttemptDbCkalloc((x), __FILE__, __LINE__))
# undef Tcl_AttemptRealloc
# define Tcl_AttemptRealloc(x,y) \
(Tcl_AttemptDbCkrealloc((x), (y), __FILE__, __LINE__))
#endif /* !TCL_MEM_DEBUG */
#define Tcl_NewLongObj(value) Tcl_NewWideIntObj((long)(value))
#define Tcl_NewIntObj(value) Tcl_NewWideIntObj((int)(value))
#define Tcl_DbNewLongObj(value, file, line) Tcl_DbNewWideIntObj((long)(value), file, line)
#define Tcl_SetIntObj(objPtr, value) Tcl_SetWideIntObj((objPtr), (int)(value))
#define Tcl_SetLongObj(objPtr, value) Tcl_SetWideIntObj((objPtr), (long)(value))
#define Tcl_BackgroundError(interp) Tcl_BackgroundException((interp), TCL_ERROR)
#define Tcl_StringMatch(str, pattern) Tcl_StringCaseMatch((str), (pattern), 0)
#if TCL_UTF_MAX < 4
# undef Tcl_UniCharToUtfDString
# define Tcl_UniCharToUtfDString Tcl_Char16ToUtfDString
# undef Tcl_UtfToUniCharDString
# define Tcl_UtfToUniCharDString Tcl_UtfToChar16DString
# undef Tcl_UtfToUniChar
# define Tcl_UtfToUniChar Tcl_UtfToChar16
# undef Tcl_UniCharLen
# define Tcl_UniCharLen Tcl_Char16Len
# undef Tcl_UniCharToUtf
# if defined(USE_TCL_STUBS)
# define Tcl_UniCharToUtf(c, p) \
(tclStubsPtr->tcl_UniCharToUtf((c)|TCL_COMBINE, (p)))
# else
# define Tcl_UniCharToUtf(c, p) \
((Tcl_UniCharToUtf)((c)|TCL_COMBINE, (p)))
# endif
# undef Tcl_NumUtfChars
# define Tcl_NumUtfChars TclNumUtfChars
# undef Tcl_GetCharLength
# define Tcl_GetCharLength TclGetCharLength
# undef Tcl_UtfAtIndex
# define Tcl_UtfAtIndex TclUtfAtIndex
# undef Tcl_GetRange
# define Tcl_GetRange TclGetRange
# undef Tcl_GetUniChar
# define Tcl_GetUniChar TclGetUniChar
# undef Tcl_UtfNcmp
# define Tcl_UtfNcmp TclUtfNcmp
# undef Tcl_UtfNcasecmp
# define Tcl_UtfNcasecmp TclUtfNcasecmp
#endif
#if TCL_MAJOR_VERSION > 8
# if defined(USE_TCL_STUBS)
# define Tcl_WCharToUtfDString (sizeof(wchar_t) != sizeof(short) \
? (char *(*)(const wchar_t *, Tcl_Size, Tcl_DString *))tclStubsPtr->tcl_UniCharToUtfDString \
: (char *(*)(const wchar_t *, Tcl_Size, Tcl_DString *))Tcl_Char16ToUtfDString)
# define Tcl_UtfToWCharDString (sizeof(wchar_t) != sizeof(short) \
? (wchar_t *(*)(const char *, Tcl_Size, Tcl_DString *))tclStubsPtr->tcl_UtfToUniCharDString \
: (wchar_t *(*)(const char *, Tcl_Size, Tcl_DString *))Tcl_UtfToChar16DString)
# define Tcl_UtfToWChar (sizeof(wchar_t) != sizeof(short) \
? (Tcl_Size (*)(const char *, wchar_t *))tclStubsPtr->tcl_UtfToUniChar \
: (Tcl_Size (*)(const char *, wchar_t *))Tcl_UtfToChar16)
# define Tcl_WCharLen (sizeof(wchar_t) != sizeof(short) \
? (Tcl_Size (*)(wchar_t *))tclStubsPtr->tcl_UniCharLen \
: (Tcl_Size (*)(wchar_t *))Tcl_Char16Len)
# else
# define Tcl_WCharToUtfDString (sizeof(wchar_t) != sizeof(short) \
? (char *(*)(const wchar_t *, Tcl_Size, Tcl_DString *))Tcl_UniCharToUtfDString \
: (char *(*)(const wchar_t *, Tcl_Size, Tcl_DString *))Tcl_Char16ToUtfDString)
# define Tcl_UtfToWCharDString (sizeof(wchar_t) != sizeof(short) \
? (wchar_t *(*)(const char *, Tcl_Size, Tcl_DString *))Tcl_UtfToUniCharDString \
: (wchar_t *(*)(const char *, Tcl_Size, Tcl_DString *))Tcl_UtfToChar16DString)
# define Tcl_UtfToWChar (sizeof(wchar_t) != sizeof(short) \
? (Tcl_Size (*)(const char *, wchar_t *))Tcl_UtfToUniChar \
: (Tcl_Size (*)(const char *, wchar_t *))Tcl_UtfToChar16)
# define Tcl_WCharLen (sizeof(wchar_t) != sizeof(short) \
? (Tcl_Size (*)(wchar_t *))Tcl_UniCharLen \
: (Tcl_Size (*)(wchar_t *))Tcl_Char16Len)
# endif
#endif
/*
* Deprecated Tcl procedures:
*/
#define Tcl_EvalObj(interp, objPtr) \
Tcl_EvalObjEx(interp, objPtr, 0)
#define Tcl_GlobalEvalObj(interp, objPtr) \
Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL)
#if TCL_MAJOR_VERSION > 8
# undef Tcl_Close
# define Tcl_Close(interp, chan) Tcl_CloseEx(interp, chan, 0)
#endif
#undef TclUtfCharComplete
#undef TclUtfNext
#undef TclUtfPrev
#ifndef TCL_NO_DEPRECATED
# define Tcl_CreateSlave Tcl_CreateChild
# define Tcl_GetSlave Tcl_GetChild
# define Tcl_GetMaster Tcl_GetParent
#endif
/* Protect those 11 functions, make them useless through the stub table */
#undef TclGetStringFromObj
#undef TclGetBytesFromObj
#undef TclGetUnicodeFromObj
#undef TclListObjGetElements
#undef TclListObjLength
#undef TclDictObjSize
#undef TclSplitList
#undef TclSplitPath
#undef TclFSSplitPath
#undef TclParseArgsObjv
#undef TclGetAliasObj
#if TCL_MAJOR_VERSION < 9
/* TIP #627 */
# undef Tcl_CreateObjCommand2
# define Tcl_CreateObjCommand2 Tcl_CreateObjCommand
# undef Tcl_CreateObjTrace2
# define Tcl_CreateObjTrace2 Tcl_CreateObjTrace
# undef Tcl_NRCreateCommand2
# define Tcl_NRCreateCommand2 Tcl_NRCreateCommand
# undef Tcl_NRCallObjProc2
# define Tcl_NRCallObjProc2 Tcl_NRCallObjProc
/* TIP #660 */
# undef Tcl_GetSizeIntFromObj
# define Tcl_GetSizeIntFromObj Tcl_GetIntFromObj
# undef Tcl_GetBytesFromObj
# define Tcl_GetBytesFromObj(interp, objPtr, sizePtr) \
tclStubsPtr->tclGetBytesFromObj((interp), (objPtr), (sizePtr))
# undef Tcl_GetStringFromObj
# define Tcl_GetStringFromObj(objPtr, sizePtr) \
tclStubsPtr->tclGetStringFromObj((objPtr), (sizePtr))
# undef Tcl_GetUnicodeFromObj
# define Tcl_GetUnicodeFromObj(objPtr, sizePtr) \
tclStubsPtr->tclGetUnicodeFromObj((objPtr), (sizePtr))
# undef Tcl_ListObjGetElements
# define Tcl_ListObjGetElements(interp, listPtr, objcPtr, objvPtr) \
tclStubsPtr->tclListObjGetElements((interp), (listPtr), (objcPtr), (objvPtr))
# undef Tcl_ListObjLength
# define Tcl_ListObjLength(interp, listPtr, lengthPtr) \
tclStubsPtr->tclListObjLength((interp), (listPtr), (lengthPtr))
# undef Tcl_DictObjSize
# define Tcl_DictObjSize(interp, dictPtr, sizePtr) \
tclStubsPtr->tclDictObjSize((interp), (dictPtr), (sizePtr))
# undef Tcl_SplitList
# define Tcl_SplitList(interp, listStr, argcPtr, argvPtr) \
tclStubsPtr->tclSplitList((interp), (listStr), (argcPtr), (argvPtr))
# undef Tcl_SplitPath
# define Tcl_SplitPath(path, argcPtr, argvPtr) \
tclStubsPtr->tclSplitPath((path), (argcPtr), (argvPtr))
# undef Tcl_FSSplitPath
# define Tcl_FSSplitPath(pathPtr, lenPtr) \
tclStubsPtr->tclFSSplitPath((pathPtr), (lenPtr))
# undef Tcl_ParseArgsObjv
# define Tcl_ParseArgsObjv(interp, argTable, objcPtr, objv, remObjv) \
tclStubsPtr->tclParseArgsObjv((interp), (argTable), (objcPtr), (objv), (remObjv))
# undef Tcl_GetAliasObj
# define Tcl_GetAliasObj(interp, childCmd, targetInterpPtr, targetCmdPtr, objcPtr, objv) \
tclStubsPtr->tclGetAliasObj((interp), (childCmd), (targetInterpPtr), (targetCmdPtr), (objcPtr), (objv))
# undef Tcl_OpenTcpServerEx
# undef TclZipfs_Mount
# undef TclZipfs_Unmount
# undef TclZipfs_TclLibrary
# undef TclZipfs_MountBuffer
# undef Tcl_FreeInternalRep
# undef Tcl_InitStringRep
# undef Tcl_FetchInternalRep
# undef Tcl_StoreInternalRep
# undef Tcl_HasStringRep
# undef Tcl_LinkArray
# undef Tcl_GetIntForIndex
# undef Tcl_FSTildeExpand
# undef Tcl_ExternalToUtfDStringEx
# undef Tcl_UtfToExternalDStringEx
# undef Tcl_AsyncMarkFromSignal
# undef Tcl_GetBool
# undef Tcl_GetBoolFromObj
# undef Tcl_GetNumberFromObj
# undef Tcl_GetNumber
# undef Tcl_RemoveChannelMode
# undef Tcl_GetEncodingNulLength
# undef Tcl_GetWideUIntFromObj
# undef Tcl_DStringToObj
# undef Tcl_NewWideUIntObj
# undef Tcl_SetWideUIntObj
#elif defined(TCL_8_API)
# undef Tcl_GetByteArrayFromObj
# undef Tcl_GetBytesFromObj
# undef Tcl_GetStringFromObj
# undef Tcl_GetUnicodeFromObj
# undef Tcl_ListObjGetElements
# undef Tcl_ListObjLength
# undef Tcl_DictObjSize
# undef Tcl_SplitList
# undef Tcl_SplitPath
# undef Tcl_FSSplitPath
# undef Tcl_ParseArgsObjv
# undef Tcl_GetAliasObj
# if !defined(USE_TCL_STUBS)
# define Tcl_GetByteArrayFromObj(objPtr, sizePtr) (sizeof(*(sizePtr)) <= sizeof(int) ? \
TclGetBytesFromObj(NULL, (objPtr), (sizePtr)) : \
(Tcl_GetBytesFromObj)(NULL, (objPtr), (Tcl_Size *)(void *)(sizePtr)))
# define Tcl_GetBytesFromObj(interp, objPtr, sizePtr) (sizeof(*(sizePtr)) <= sizeof(int) ? \
TclGetBytesFromObj((interp), (objPtr), (sizePtr)) : \
(Tcl_GetBytesFromObj)((interp), (objPtr), (Tcl_Size *)(void *)(sizePtr)))
# define Tcl_GetStringFromObj(objPtr, sizePtr) (sizeof(*(sizePtr)) <= sizeof(int) ? \
(TclGetStringFromObj)((objPtr), (sizePtr)) : \
(Tcl_GetStringFromObj)((objPtr), (Tcl_Size *)(void *)(sizePtr)))
# define Tcl_GetUnicodeFromObj(objPtr, sizePtr) (sizeof(*(sizePtr)) <= sizeof(int) ? \
TclGetUnicodeFromObj((objPtr), (sizePtr)) : \
(Tcl_GetUnicodeFromObj)((objPtr), (Tcl_Size *)(void *)(sizePtr)))
# define Tcl_ListObjGetElements(interp, listPtr, objcPtr, objvPtr) (sizeof(*(objcPtr)) <= sizeof(int) ? \
(TclListObjGetElements)((interp), (listPtr), (objcPtr), (objvPtr)) : \
(Tcl_ListObjGetElements)((interp), (listPtr), (Tcl_Size *)(void *)(objcPtr), (objvPtr)))
# define Tcl_ListObjLength(interp, listPtr, lengthPtr) (sizeof(*(lengthPtr)) <= sizeof(int) ? \
(TclListObjLength)((interp), (listPtr), (lengthPtr)) : \
(Tcl_ListObjLength)((interp), (listPtr), (Tcl_Size *)(void *)(lengthPtr)))
# define Tcl_DictObjSize(interp, dictPtr, sizePtr) (sizeof(*(sizePtr)) <= sizeof(int) ? \
TclDictObjSize((interp), (dictPtr), (sizePtr)) : \
(Tcl_DictObjSize)((interp), (dictPtr), (Tcl_Size *)(void *)(sizePtr)))
# define Tcl_SplitList(interp, listStr, argcPtr, argvPtr) (sizeof(*(argcPtr)) <= sizeof(int) ? \
TclSplitList((interp), (listStr), (argcPtr), (argvPtr)) : \
(Tcl_SplitList)((interp), (listStr), (Tcl_Size *)(void *)(argcPtr), (argvPtr)))
# define Tcl_SplitPath(path, argcPtr, argvPtr) (sizeof(*(argcPtr)) <= sizeof(int) ? \
TclSplitPath((path), (argcPtr), (argvPtr)) : \
(Tcl_SplitPath)((path), (Tcl_Size *)(void *)(argcPtr), (argvPtr)))
# define Tcl_FSSplitPath(pathPtr, lenPtr) (sizeof(*(lenPtr)) <= sizeof(int) ? \
TclFSSplitPath((pathPtr), (lenPtr)) : \
(Tcl_FSSplitPath)((pathPtr), (Tcl_Size *)(void *)(lenPtr)))
# define Tcl_ParseArgsObjv(interp, argTable, objcPtr, objv, remObjv) (sizeof(*(objcPtr)) <= sizeof(int) ? \
TclParseArgsObjv((interp), (argTable), (objcPtr), (objv), (remObjv)) : \
(Tcl_ParseArgsObjv)((interp), (argTable), (Tcl_Size *)(void *)(objcPtr), (objv), (remObjv)))
# define Tcl_GetAliasObj(interp, childCmd, targetInterpPtr, targetCmdPtr, objcPtr, objv) (sizeof(*(objcPtr)) <= sizeof(int) ? \
TclGetAliasObj((interp), (childCmd), (targetInterpPtr), (targetCmdPtr), (objcPtr), (objv)) : \
(Tcl_GetAliasObj)((interp), (childCmd), (targetInterpPtr), (targetCmdPtr), (Tcl_Size *)(void *)(objcPtr), (objv)))
# elif !defined(BUILD_tcl)
# define Tcl_GetByteArrayFromObj(objPtr, sizePtr) (sizeof(*(sizePtr)) <= sizeof(int) ? \
tclStubsPtr->tclGetBytesFromObj(NULL, (objPtr), (sizePtr)) : \
tclStubsPtr->tcl_GetBytesFromObj(NULL, (objPtr), (Tcl_Size *)(void *)(sizePtr)))
# define Tcl_GetBytesFromObj(interp, objPtr, sizePtr) (sizeof(*(sizePtr)) <= sizeof(int) ? \
tclStubsPtr->tclGetBytesFromObj((interp), (objPtr), (sizePtr)) : \
tclStubsPtr->tcl_GetBytesFromObj((interp), (objPtr), (Tcl_Size *)(void *)(sizePtr)))
# define Tcl_GetStringFromObj(objPtr, sizePtr) (sizeof(*(sizePtr)) <= sizeof(int) ? \
tclStubsPtr->tclGetStringFromObj((objPtr), (sizePtr)) : \
tclStubsPtr->tcl_GetStringFromObj((objPtr), (Tcl_Size *)(void *)(sizePtr)))
# define Tcl_GetUnicodeFromObj(objPtr, sizePtr) (sizeof(*(sizePtr)) <= sizeof(int) ? \
tclStubsPtr->tclGetUnicodeFromObj((objPtr), (sizePtr)) : \
tclStubsPtr->tcl_GetUnicodeFromObj((objPtr), (Tcl_Size *)(void *)(sizePtr)))
# define Tcl_ListObjGetElements(interp, listPtr, objcPtr, objvPtr) (sizeof(*(objcPtr)) <= sizeof(int) ? \
tclStubsPtr->tclListObjGetElements((interp), (listPtr), (objcPtr), (objvPtr)) : \
tclStubsPtr->tcl_ListObjGetElements((interp), (listPtr), (Tcl_Size *)(void *)(objcPtr), (objvPtr)))
# define Tcl_ListObjLength(interp, listPtr, lengthPtr) (sizeof(*(lengthPtr)) <= sizeof(int) ? \
tclStubsPtr->tclListObjLength((interp), (listPtr), (lengthPtr)) : \
tclStubsPtr->tcl_ListObjLength((interp), (listPtr), (Tcl_Size *)(void *)(lengthPtr)))
# define Tcl_DictObjSize(interp, dictPtr, sizePtr) (sizeof(*(sizePtr)) <= sizeof(int) ? \
tclStubsPtr->tclDictObjSize((interp), (dictPtr), (sizePtr)) : \
tclStubsPtr->tcl_DictObjSize((interp), (dictPtr), (Tcl_Size *)(void *)(sizePtr)))
# define Tcl_SplitList(interp, listStr, argcPtr, argvPtr) (sizeof(*(argcPtr)) <= sizeof(int) ? \
tclStubsPtr->tclSplitList((interp), (listStr), (argcPtr), (argvPtr)) : \
tclStubsPtr->tcl_SplitList((interp), (listStr), (Tcl_Size *)(void *)(argcPtr), (argvPtr)))
# define Tcl_SplitPath(path, argcPtr, argvPtr) (sizeof(*(argcPtr)) <= sizeof(int) ? \
tclStubsPtr->tclSplitPath((path), (argcPtr), (argvPtr)) : \
tclStubsPtr->tcl_SplitPath((path), (Tcl_Size *)(void *)(argcPtr), (argvPtr)))
# define Tcl_FSSplitPath(pathPtr, lenPtr) (sizeof(*(lenPtr)) <= sizeof(int) ? \
tclStubsPtr->tclFSSplitPath((pathPtr), (lenPtr)) : \
tclStubsPtr->tcl_FSSplitPath((pathPtr), (Tcl_Size *)(void *)(lenPtr)))
# define Tcl_ParseArgsObjv(interp, argTable, objcPtr, objv, remObjv) (sizeof(*(objcPtr)) <= sizeof(int) ? \
tclStubsPtr->tclParseArgsObjv((interp), (argTable), (objcPtr), (objv), (remObjv)) : \
tclStubsPtr->tcl_ParseArgsObjv((interp), (argTable), (Tcl_Size *)(void *)(objcPtr), (objv), (remObjv)))
# define Tcl_GetAliasObj(interp, childCmd, targetInterpPtr, targetCmdPtr, objcPtr, objv) (sizeof(*(objcPtr)) <= sizeof(int) ? \
tclStubsPtr->tclGetAliasObj((interp), (childCmd), (targetInterpPtr), (targetCmdPtr), (objcPtr), (objv)) : \
tclStubsPtr->tcl_GetAliasObj((interp), (childCmd), (targetInterpPtr), (targetCmdPtr), (Tcl_Size *)(void *)(objcPtr), (objv)))
# endif /* defined(USE_TCL_STUBS) */
#else /* !defined(TCL_8_API) */
# undef Tcl_GetByteArrayFromObj
# define Tcl_GetByteArrayFromObj(objPtr, sizePtr) \
Tcl_GetBytesFromObj(NULL, (objPtr), (sizePtr))
#endif /* defined(TCL_8_API) */
#endif /* _TCLDECLS */
|
Changes to extsrc/pikchr.c.
| ︙ | ︙ | |||
8282 8283 8284 8285 8286 8287 8288 | ** ** gcc -c pikchr.so -DPIKCHR_TCL -shared pikchr.c */ static int pik_tcl_command( ClientData clientData, /* Not Used */ Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ | | | 8282 8283 8284 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 |
**
** gcc -c pikchr.so -DPIKCHR_TCL -shared pikchr.c
*/
static int pik_tcl_command(
ClientData clientData, /* Not Used */
Tcl_Interp *interp, /* The TCL interpreter that invoked this command */
int objc, /* Number of arguments */
Tcl_Obj *const objv[] /* Command arguments */
){
int w, h; /* Width and height of the pikchr */
const char *zIn; /* Source text input */
char *zOut; /* SVG output text */
Tcl_Obj *pRes; /* The result TCL object */
(void)clientData;
|
| ︙ | ︙ |
Added extsrc/qrf.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 151 152 153 154 155 156 157 158 159 160 161 162 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 |
/*
** 2025-10-20
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
** Header file for the Result-Format or "resfmt" utility library for SQLite.
** See the resfmt.md documentation for additional information.
*/
#ifndef SQLITE_QRF_H
#define SQLITE_QRF_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include "sqlite3.h"
/*
** Specification used by clients to define the output format they want
*/
typedef struct sqlite3_qrf_spec sqlite3_qrf_spec;
struct sqlite3_qrf_spec {
unsigned char iVersion; /* Version number of this structure */
unsigned char eStyle; /* Formatting style. "box", "csv", etc... */
unsigned char eEsc; /* How to escape control characters in text */
unsigned char eText; /* Quoting style for text */
unsigned char eTitle; /* Quating style for the text of column names */
unsigned char eBlob; /* Quoting style for BLOBs */
unsigned char bTitles; /* True to show column names */
unsigned char bWordWrap; /* Try to wrap on word boundaries */
unsigned char bTextJsonb; /* Render JSONB blobs as JSON text */
unsigned char eDfltAlign; /* Default alignment, no covered by aAlignment */
unsigned char eTitleAlign; /* Alignment for column headers */
unsigned char bSplitColumn; /* Wrap single-column output into many columns */
short int nWrap; /* Wrap columns wider than this */
short int nScreenWidth; /* Maximum overall table width */
short int nLineLimit; /* Maximum number of lines for any row */
int nCharLimit; /* Maximum number of characters in a cell */
int nWidth; /* Number of entries in aWidth[] */
int nAlign; /* Number of entries in aAlignment[] */
short int *aWidth; /* Column widths */
unsigned char *aAlign; /* Column alignments */
char *zColumnSep; /* Alternative column separator */
char *zRowSep; /* Alternative row separator */
char *zTableName; /* Output table name */
char *zNull; /* Rendering of NULL */
char *(*xRender)(void*,sqlite3_value*); /* Render a value */
int (*xWrite)(void*,const char*,sqlite3_int64); /* Write output */
void *pRenderArg; /* First argument to the xRender callback */
void *pWriteArg; /* First argument to the xWrite callback */
char **pzOutput; /* Storage location for output string */
/* Additional fields may be added in the future */
};
/*
** Interfaces
*/
int sqlite3_format_query_result(
sqlite3_stmt *pStmt, /* SQL statement to run */
const sqlite3_qrf_spec *pSpec, /* Result format specification */
char **pzErr /* OUT: Write error message here */
);
/*
** Range of values for sqlite3_qrf_spec.aWidth[] entries and for
** sqlite3_qrf_spec.mxColWidth and .nScreenWidth
*/
#define QRF_MAX_WIDTH 10000
#define QRF_MIN_WIDTH 0
/*
** Output styles:
*/
#define QRF_STYLE_Auto 0 /* Choose a style automatically */
#define QRF_STYLE_Box 1 /* Unicode box-drawing characters */
#define QRF_STYLE_Column 2 /* One record per line in neat columns */
#define QRF_STYLE_Count 3 /* Output only a count of the rows of output */
#define QRF_STYLE_Csv 4 /* Comma-separated-value */
#define QRF_STYLE_Eqp 5 /* Format EXPLAIN QUERY PLAN output */
#define QRF_STYLE_Explain 6 /* EXPLAIN output */
#define QRF_STYLE_Html 7 /* Generate an XHTML table */
#define QRF_STYLE_Insert 8 /* Generate SQL "insert" statements */
#define QRF_STYLE_Json 9 /* Output is a list of JSON objects */
#define QRF_STYLE_JObject 10 /* Independent JSON objects for each row */
#define QRF_STYLE_Line 11 /* One column per line. */
#define QRF_STYLE_List 12 /* One record per line with a separator */
#define QRF_STYLE_Markdown 13 /* Markdown formatting */
#define QRF_STYLE_Off 14 /* No query output shown */
#define QRF_STYLE_Quote 15 /* SQL-quoted, comma-separated */
#define QRF_STYLE_Stats 16 /* EQP-like output but with performance stats */
#define QRF_STYLE_StatsEst 17 /* EQP-like output with planner estimates */
#define QRF_STYLE_StatsVm 18 /* EXPLAIN-like output with performance stats */
#define QRF_STYLE_Table 19 /* MySQL-style table formatting */
/*
** Quoting styles for text.
** Allowed values for sqlite3_qrf_spec.eText
*/
#define QRF_TEXT_Auto 0 /* Choose text encoding automatically */
#define QRF_TEXT_Plain 1 /* Literal text */
#define QRF_TEXT_Sql 2 /* Quote as an SQL literal */
#define QRF_TEXT_Csv 3 /* CSV-style quoting */
#define QRF_TEXT_Html 4 /* HTML-style quoting */
#define QRF_TEXT_Tcl 5 /* C/Tcl quoting */
#define QRF_TEXT_Json 6 /* JSON quoting */
/*
** Quoting styles for BLOBs
** Allowed values for sqlite3_qrf_spec.eBlob
*/
#define QRF_BLOB_Auto 0 /* Determine BLOB quoting using eText */
#define QRF_BLOB_Text 1 /* Display content exactly as it is */
#define QRF_BLOB_Sql 2 /* Quote as an SQL literal */
#define QRF_BLOB_Hex 3 /* Hexadecimal representation */
#define QRF_BLOB_Tcl 4 /* "\000" notation */
#define QRF_BLOB_Json 5 /* A JSON string */
#define QRF_BLOB_Size 6 /* Display the blob size only */
/*
** Control-character escape modes.
** Allowed values for sqlite3_qrf_spec.eEsc
*/
#define QRF_ESC_Auto 0 /* Choose the ctrl-char escape automatically */
#define QRF_ESC_Off 1 /* Do not escape control characters */
#define QRF_ESC_Ascii 2 /* Unix-style escapes. Ex: U+0007 shows ^G */
#define QRF_ESC_Symbol 3 /* Unicode escapes. Ex: U+0007 shows U+2407 */
/*
** Allowed values for "boolean" fields, such as "bColumnNames", "bWordWrap",
** and "bTextJsonb". There is an extra "auto" variants so these are actually
** tri-state settings, not booleans.
*/
#define QRF_SW_Auto 0 /* Let QRF choose the best value */
#define QRF_SW_Off 1 /* This setting is forced off */
#define QRF_SW_On 2 /* This setting is forced on */
#define QRF_Auto 0 /* Alternate spelling for QRF_*_Auto */
#define QRF_No 1 /* Alternate spelling for QRF_SW_Off */
#define QRF_Yes 2 /* Alternate spelling for QRF_SW_On */
/*
** Possible alignment values alignment settings
**
** Horizontal Vertial
** ---------- -------- */
#define QRF_ALIGN_Auto 0 /* auto auto */
#define QRF_ALIGN_Left 1 /* left auto */
#define QRF_ALIGN_Center 2 /* center auto */
#define QRF_ALIGN_Right 3 /* right auto */
#define QRF_ALIGN_Top 4 /* auto top */
#define QRF_ALIGN_NW 5 /* left top */
#define QRF_ALIGN_N 6 /* center top */
#define QRF_ALIGN_NE 7 /* right top */
#define QRF_ALIGN_Middle 8 /* auto middle */
#define QRF_ALIGN_W 9 /* left middle */
#define QRF_ALIGN_C 10 /* center middle */
#define QRF_ALIGN_E 11 /* right middle */
#define QRF_ALIGN_Bottom 12 /* auto bottom */
#define QRF_ALIGN_SW 13 /* left bottom */
#define QRF_ALIGN_S 14 /* center bottom */
#define QRF_ALIGN_SE 15 /* right bottom */
#define QRF_ALIGN_HMASK 3 /* Horizontal alignment mask */
#define QRF_ALIGN_VMASK 12 /* Vertical alignment mask */
/*
** Auxiliary routines contined within this module that might be useful
** in other contexts, and which are therefore exported.
*/
/*
** Return an estimate of the width, in columns, for the single Unicode
** character c. For normal characters, the answer is always 1. But the
** estimate might be 0 or 2 for zero-width and double-width characters.
**
** Different display devices display unicode using different widths. So
** it is impossible to know that true display width with 100% accuracy.
** Inaccuracies in the width estimates might cause columns to be misaligned.
** Unfortunately, there is nothing we can do about that.
*/
int sqlite3_qrf_wcwidth(int c);
#ifdef __cplusplus
}
#endif
#endif /* !defined(SQLITE_QRF_H) */
|
Changes to extsrc/shell.c.
more than 10,000 changes
Changes to extsrc/sqlite3.c.
1 2 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite | | | | 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 | /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite ** version 3.52.0. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a single translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements ** of 5% or more are commonly seen when SQLite is compiled as a single ** translation unit. ** ** This file is all you need to compile SQLite. To use SQLite in other ** programs, you need this file and the "sqlite3.h" header file that defines ** the programming interface to the SQLite library. (If you do not have ** the "sqlite3.h" header file at hand, you will find a copy embedded within ** the text of this file. Search for "Begin file sqlite3.h" to find the start ** of the embedded sqlite3.h header file.) Additional code files may be needed ** if you want a wrapper to interface SQLite with your choice of programming ** language. The code for the "sqlite3" command-line shell is also in a ** separate file. This file contains only code for the core SQLite library. ** ** The content in this amalgamation comes from Fossil check-in ** 5804ba4874cc41b11e8bb559d5533283c289 with changes in files: ** ** */ #ifndef SQLITE_AMALGAMATION #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 #ifndef SQLITE_PRIVATE |
| ︙ | ︙ | |||
463 464 465 466 467 468 469 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | | 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.52.0" #define SQLITE_VERSION_NUMBER 3052000 #define SQLITE_SOURCE_ID "2025-11-25 18:20:33 5804ba4874cc41b11e8bb559d5533283c2895d2b13316830955663575567f911" #define SQLITE_SCM_BRANCH "trunk" #define SQLITE_SCM_TAGS "" #define SQLITE_SCM_DATETIME "2025-11-25T18:20:33.534Z" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
1249 1250 1251 1252 1253 1254 1255 | ** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]] ** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer ** to the [sqlite3_file] object associated with the journal file (either ** the [rollback journal] or the [write-ahead log]) for a particular database ** connection. See also [SQLITE_FCNTL_FILE_POINTER]. ** ** <li>[[SQLITE_FCNTL_SYNC_OMITTED]] | | | 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 | ** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]] ** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer ** to the [sqlite3_file] object associated with the journal file (either ** the [rollback journal] or the [write-ahead log]) for a particular database ** connection. See also [SQLITE_FCNTL_FILE_POINTER]. ** ** <li>[[SQLITE_FCNTL_SYNC_OMITTED]] ** The SQLITE_FCNTL_SYNC_OMITTED file-control is no longer used. ** ** <li>[[SQLITE_FCNTL_SYNC]] ** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and ** sent to the VFS immediately before the xSync method is invoked on a ** database file descriptor. Or, if the xSync method is not invoked ** because the user has configured SQLite with ** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place |
| ︙ | ︙ | |||
1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 | ** [checksum VFS shim] only. ** ** <li>[[SQLITE_FCNTL_RESET_CACHE]] ** If there is currently no transaction open on the database, and the ** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control ** purges the contents of the in-memory page cache. If there is an open ** transaction, or if the db is a temp-db, this opcode is a no-op, not an error. ** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 #define SQLITE_FCNTL_LAST_ERRNO 4 #define SQLITE_FCNTL_SIZE_HINT 5 | > > > > > > > > > | 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 | ** [checksum VFS shim] only. ** ** <li>[[SQLITE_FCNTL_RESET_CACHE]] ** If there is currently no transaction open on the database, and the ** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control ** purges the contents of the in-memory page cache. If there is an open ** transaction, or if the db is a temp-db, this opcode is a no-op, not an error. ** ** <li>[[SQLITE_FCNTL_FILESTAT]] ** The [SQLITE_FCNTL_FILESTAT] opcode returns low-level diagnostic information ** about the [sqlite3_file] objects used access the database and journal files ** for the given schema. The fourth parameter to [sqlite3_file_control()] ** should be an initialized [sqlite3_str] pointer. JSON text describing ** various aspects of the sqlite3_file object is appended to the sqlite3_str. ** The SQLITE_FCNTL_FILESTAT opcode is usually a no-op, unless compile-time ** options are used to enable it. ** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 #define SQLITE_FCNTL_LAST_ERRNO 4 #define SQLITE_FCNTL_SIZE_HINT 5 |
| ︙ | ︙ | |||
1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 | #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 #define SQLITE_FCNTL_NULL_IO 43 #define SQLITE_FCNTL_BLOCK_ON_CONNECT 44 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO | > | 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 | #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 #define SQLITE_FCNTL_NULL_IO 43 #define SQLITE_FCNTL_BLOCK_ON_CONNECT 44 #define SQLITE_FCNTL_FILESTAT 45 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO |
| ︙ | ︙ | |||
2874 2875 2876 2877 2878 2879 2880 | ** not considered a bug since SQLite versions 3.3.0 and earlier do not support ** either generated columns or descending indexes. ** </dd> ** ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] ** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt> ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in | | | > > | | > | | | 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 | ** not considered a bug since SQLite versions 3.3.0 and earlier do not support ** either generated columns or descending indexes. ** </dd> ** ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] ** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt> ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in ** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears ** a flag that enables collection of run-time performance statistics ** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle] ** columns of the [bytecode virtual table]. ** For statistics to be collected, the flag must be set on ** the database handle both when the SQL statement is ** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped]. ** The flag is set (collection of statistics is enabled) by default. ** <p>This option takes two arguments: an integer and a pointer to ** an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the statement scanstatus option. If the second argument ** is not NULL, then the value of the statement scanstatus setting after ** processing the first argument is written into the integer that the second ** argument points to. ** </dd> ** |
| ︙ | ︙ | |||
4524 4525 4526 4527 4528 4529 4530 | SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); SQLITE_API const char *sqlite3_errmsg(sqlite3*); SQLITE_API const void *sqlite3_errmsg16(sqlite3*); SQLITE_API const char *sqlite3_errstr(int); SQLITE_API int sqlite3_error_offset(sqlite3 *db); /* | | | 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 | SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); SQLITE_API const char *sqlite3_errmsg(sqlite3*); SQLITE_API const void *sqlite3_errmsg16(sqlite3*); SQLITE_API const char *sqlite3_errstr(int); SQLITE_API int sqlite3_error_offset(sqlite3 *db); /* ** CAPI3REF: Set Error Code And Message ** METHOD: sqlite3 ** ** Set the error code of the database handle passed as the first argument ** to errcode, and the error message to a copy of nul-terminated string ** zErrMsg. If zErrMsg is passed NULL, then the error message is set to ** the default message associated with the supplied error code. Subsequent ** calls to [sqlite3_errcode()] and [sqlite3_errmsg()] and similar will |
| ︙ | ︙ | |||
4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 | ** [[SQLITE_LIMIT_COLUMN]] ^(<dt>SQLITE_LIMIT_COLUMN</dt> ** <dd>The maximum number of columns in a table definition or in the ** result set of a [SELECT] or the maximum number of columns in an index ** or in an ORDER BY or GROUP BY clause.</dd>)^ ** ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt> ** <dd>The maximum depth of the parse tree on any expression.</dd>)^ ** ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt> ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^ ** ** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt> ** <dd>The maximum number of instructions in a virtual machine program ** used to implement an SQL statement. If [sqlite3_prepare_v2()] or | > > > > | 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 | ** [[SQLITE_LIMIT_COLUMN]] ^(<dt>SQLITE_LIMIT_COLUMN</dt> ** <dd>The maximum number of columns in a table definition or in the ** result set of a [SELECT] or the maximum number of columns in an index ** or in an ORDER BY or GROUP BY clause.</dd>)^ ** ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt> ** <dd>The maximum depth of the parse tree on any expression.</dd>)^ ** ** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(<dt>SQLITE_LIMIT_PARSER_DEPTH</dt> ** <dd>The maximum depth of the LALR(1) parser stack used to analyze ** input SQL statements.</dd>)^ ** ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt> ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^ ** ** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt> ** <dd>The maximum number of instructions in a virtual machine program ** used to implement an SQL statement. If [sqlite3_prepare_v2()] or |
| ︙ | ︙ | |||
4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 | #define SQLITE_LIMIT_VDBE_OP 5 #define SQLITE_LIMIT_FUNCTION_ARG 6 #define SQLITE_LIMIT_ATTACHED 7 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 #define SQLITE_LIMIT_VARIABLE_NUMBER 9 #define SQLITE_LIMIT_TRIGGER_DEPTH 10 #define SQLITE_LIMIT_WORKER_THREADS 11 /* ** CAPI3REF: Prepare Flags ** ** These constants define various flags that can be passed into the ** "prepFlags" parameter of the [sqlite3_prepare_v3()] and ** [sqlite3_prepare16_v3()] interfaces. | > | 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 | #define SQLITE_LIMIT_VDBE_OP 5 #define SQLITE_LIMIT_FUNCTION_ARG 6 #define SQLITE_LIMIT_ATTACHED 7 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 #define SQLITE_LIMIT_VARIABLE_NUMBER 9 #define SQLITE_LIMIT_TRIGGER_DEPTH 10 #define SQLITE_LIMIT_WORKER_THREADS 11 #define SQLITE_LIMIT_PARSER_DEPTH 12 /* ** CAPI3REF: Prepare Flags ** ** These constants define various flags that can be passed into the ** "prepFlags" parameter of the [sqlite3_prepare_v3()] and ** [sqlite3_prepare16_v3()] interfaces. |
| ︙ | ︙ | |||
5224 5225 5226 5227 5228 5229 5230 | ** ^A negative value for the zeroblob results in a zero-length BLOB. ** ** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in ** [prepared statement] S to have an SQL value of NULL, but to also be ** associated with the pointer P of type T. ^D is either a NULL pointer or ** a pointer to a destructor function for P. ^SQLite will invoke the ** destructor D with a single argument of P when it is finished using | > > | | | | 5242 5243 5244 5245 5246 5247 5248 5249 5250 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 | ** ^A negative value for the zeroblob results in a zero-length BLOB. ** ** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in ** [prepared statement] S to have an SQL value of NULL, but to also be ** associated with the pointer P of type T. ^D is either a NULL pointer or ** a pointer to a destructor function for P. ^SQLite will invoke the ** destructor D with a single argument of P when it is finished using ** P, even if the call to sqlite3_bind_pointer() fails. Due to a ** historical design quirk, results are undefined if D is ** SQLITE_TRANSIENT. The T parameter should be a static string, ** preferably a string literal. The sqlite3_bind_pointer() routine is ** part of the [pointer passing interface] added for SQLite 3.20.0. ** ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer ** for the [prepared statement] or with a prepared statement for which ** [sqlite3_step()] has been called more recently than [sqlite3_reset()], ** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() ** routine is passed a [prepared statement] that has been finalized, the ** result is undefined and probably harmful. |
| ︙ | ︙ | |||
9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 | ** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()] ** that contains the constructed string. The calling application should ** pass the returned value to [sqlite3_free()] to avoid a memory leak. ** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any ** errors were encountered during construction of the string. ^The ** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the ** string in [sqlite3_str] object X is zero bytes long. */ SQLITE_API char *sqlite3_str_finish(sqlite3_str*); /* ** CAPI3REF: Add Content To A Dynamic String ** METHOD: sqlite3_str ** | > > > > > | | | 9049 9050 9051 9052 9053 9054 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 9073 9074 9075 9076 | ** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()] ** that contains the constructed string. The calling application should ** pass the returned value to [sqlite3_free()] to avoid a memory leak. ** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any ** errors were encountered during construction of the string. ^The ** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the ** string in [sqlite3_str] object X is zero bytes long. ** ** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object ** X and the string content it contains. Calling sqlite3_str_free(X) is ** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)). */ SQLITE_API char *sqlite3_str_finish(sqlite3_str*); SQLITE_API void sqlite3_str_free(sqlite3_str*); /* ** CAPI3REF: Add Content To A Dynamic String ** METHOD: sqlite3_str ** ** These interfaces add or remove content to an sqlite3_str object ** previously obtained from [sqlite3_str_new()]. ** ** ^The [sqlite3_str_appendf(X,F,...)] and ** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] ** functionality of SQLite to append formatted text onto the end of ** [sqlite3_str] object X. ** ** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S |
| ︙ | ︙ | |||
9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 9073 9074 9075 9076 9077 9078 9079 9080 9081 9082 9083 | ** ** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the ** single-byte character C onto the end of [sqlite3_str] object X. ** ^This method can be used, for example, to add whitespace indentation. ** ** ^The [sqlite3_str_reset(X)] method resets the string under construction ** inside [sqlite3_str] object X back to zero bytes in length. ** ** These methods do not return a result code. ^If an error occurs, that fact ** is recorded in the [sqlite3_str] object and can be recovered by a ** subsequent call to [sqlite3_str_errcode(X)]. */ SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...); SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list); SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn); SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C); SQLITE_API void sqlite3_str_reset(sqlite3_str*); /* ** CAPI3REF: Status Of A Dynamic String ** METHOD: sqlite3_str ** ** These interfaces return the current status of an [sqlite3_str] object. ** | > > > > > | 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 | ** ** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the ** single-byte character C onto the end of [sqlite3_str] object X. ** ^This method can be used, for example, to add whitespace indentation. ** ** ^The [sqlite3_str_reset(X)] method resets the string under construction ** inside [sqlite3_str] object X back to zero bytes in length. ** ** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string ** under construction to be N bytes are less. This routine is a no-op if ** N is negative or if the string is already N bytes or smaller in size. ** ** These methods do not return a result code. ^If an error occurs, that fact ** is recorded in the [sqlite3_str] object and can be recovered by a ** subsequent call to [sqlite3_str_errcode(X)]. */ SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...); SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list); SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn); SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C); SQLITE_API void sqlite3_str_reset(sqlite3_str*); SQLITE_API void sqlite3_str_truncate(sqlite3_str*,int N); /* ** CAPI3REF: Status Of A Dynamic String ** METHOD: sqlite3_str ** ** These interfaces return the current status of an [sqlite3_str] object. ** |
| ︙ | ︙ | |||
9237 9238 9239 9240 9241 9242 9243 9244 9245 9246 9247 9248 9249 9250 9251 9252 9253 9254 |
** ^The current value of the requested parameter is written into *pCur
** and the highest instantaneous value is written into *pHiwtr. ^If
** the resetFlg is true, then the highest instantaneous value is
** reset back down to the current value.
**
** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
** non-zero [error code] on failure.
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
/*
** CAPI3REF: Status Parameters for database connections
** KEYWORDS: {SQLITE_DBSTATUS options}
**
** These constants are the available integer "verbs" that can be passed as
** the second argument to the [sqlite3_db_status()] interface.
| > > > > > > > > > | 9267 9268 9269 9270 9271 9272 9273 9274 9275 9276 9277 9278 9279 9280 9281 9282 9283 9284 9285 9286 9287 9288 9289 9290 9291 9292 9293 |
** ^The current value of the requested parameter is written into *pCur
** and the highest instantaneous value is written into *pHiwtr. ^If
** the resetFlg is true, then the highest instantaneous value is
** reset back down to the current value.
**
** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
** non-zero [error code] on failure.
**
** ^The sqlite3_db_status64(D,O,C,H,R) routine works exactly the same
** way as sqlite3_db_status(D,O,C,H,R) routine except that the C and H
** parameters are pointer to 64-bit integers (type: sqlite3_int64) instead
** of pointers to 32-bit integers, which allows larger status values
** to be returned. If a status value exceeds 2,147,483,647 then
** sqlite3_db_status() will truncate the value whereas sqlite3_db_status64()
** will return the full value.
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
SQLITE_API int sqlite3_db_status64(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
/*
** CAPI3REF: Status Parameters for database connections
** KEYWORDS: {SQLITE_DBSTATUS options}
**
** These constants are the available integer "verbs" that can be passed as
** the second argument to the [sqlite3_db_status()] interface.
|
| ︙ | ︙ | |||
9337 9338 9339 9340 9341 9342 9343 9344 9345 9346 9347 9348 9349 9350 9351 9352 9353 9354 9355 9356 9357 9358 9359 9360 9361 9362 9363 9364 9365 9366 9367 9368 9369 9370 9371 9372 9373 9374 | ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk in the middle of a transaction due to the page ** cache overflowing. Transactions are more efficient if they are written ** to disk all at once. When pages spill mid-transaction, that introduces ** additional overhead. This parameter can be used to help identify ** inefficiencies that can be resolved by increasing the cache size. ** </dd> ** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> ** <dd>This parameter returns zero for the current value if and only if ** all foreign key constraints (deferred or immediate) have been ** resolved.)^ ^The highwater mark is always 0. ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 #define SQLITE_DBSTATUS_STMT_USED 3 #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 #define SQLITE_DBSTATUS_CACHE_HIT 7 #define SQLITE_DBSTATUS_CACHE_MISS 8 #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_DEFERRED_FKS 10 #define SQLITE_DBSTATUS_CACHE_USED_SHARED 11 #define SQLITE_DBSTATUS_CACHE_SPILL 12 | > > > > > > > > > > > > > > > > > | | 9376 9377 9378 9379 9380 9381 9382 9383 9384 9385 9386 9387 9388 9389 9390 9391 9392 9393 9394 9395 9396 9397 9398 9399 9400 9401 9402 9403 9404 9405 9406 9407 9408 9409 9410 9411 9412 9413 9414 9415 9416 9417 9418 9419 9420 9421 9422 9423 9424 9425 9426 9427 9428 9429 9430 9431 9432 9433 9434 9435 9436 9437 9438 | ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** <p> ** ^(There is overlap between the quantities measured by this parameter ** (SQLITE_DBSTATUS_CACHE_WRITE) and SQLITE_DBSTATUS_TEMPBUF_SPILL. ** Resetting one will reduce the other.)^ ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk in the middle of a transaction due to the page ** cache overflowing. Transactions are more efficient if they are written ** to disk all at once. When pages spill mid-transaction, that introduces ** additional overhead. This parameter can be used to help identify ** inefficiencies that can be resolved by increasing the cache size. ** </dd> ** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> ** <dd>This parameter returns zero for the current value if and only if ** all foreign key constraints (deferred or immediate) have been ** resolved.)^ ^The highwater mark is always 0. ** ** [[SQLITE_DBSTATUS_TEMPBUF_SPILL] ^(<dt>SQLITE_DBSTATUS_TEMPBUF_SPILL</dt> ** <dd>^(This parameter returns the number of bytes written to temporary ** files on disk that could have been kept in memory had sufficient memory ** been available. This value includes writes to intermediate tables that ** are part of complex queries, external sorts that spill to disk, and ** writes to TEMP tables.)^ ** ^The highwater mark is always 0. ** <p> ** ^(There is overlap between the quantities measured by this parameter ** (SQLITE_DBSTATUS_TEMPBUF_SPILL) and SQLITE_DBSTATUS_CACHE_WRITE. ** Resetting one will reduce the other.)^ ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 #define SQLITE_DBSTATUS_STMT_USED 3 #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 #define SQLITE_DBSTATUS_CACHE_HIT 7 #define SQLITE_DBSTATUS_CACHE_MISS 8 #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_DEFERRED_FKS 10 #define SQLITE_DBSTATUS_CACHE_USED_SHARED 11 #define SQLITE_DBSTATUS_CACHE_SPILL 12 #define SQLITE_DBSTATUS_TEMPBUF_SPILL 13 #define SQLITE_DBSTATUS_MAX 13 /* Largest defined DBSTATUS */ /* ** CAPI3REF: Prepared Statement Status ** METHOD: sqlite3_stmt ** ** ^(Each prepared statement maintains various |
| ︙ | ︙ | |||
10705 10706 10707 10708 10709 10710 10711 |
** <blockquote><pre>
** for(rc=sqlite3_vtab_in_first(pList, &pVal);
** rc==SQLITE_OK && pVal;
** rc=sqlite3_vtab_in_next(pList, &pVal)
** ){
** // do something with pVal
** }
| | | 10761 10762 10763 10764 10765 10766 10767 10768 10769 10770 10771 10772 10773 10774 10775 |
** <blockquote><pre>
** for(rc=sqlite3_vtab_in_first(pList, &pVal);
** rc==SQLITE_OK && pVal;
** rc=sqlite3_vtab_in_next(pList, &pVal)
** ){
** // do something with pVal
** }
** if( rc!=SQLITE_DONE ){
** // an error has occurred
** }
** </pre></blockquote>)^
**
** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
** routines return SQLITE_OK and set *P to point to the first or next value
** on the RHS of the IN constraint. ^If there are no more values on the
|
| ︙ | ︙ | |||
10877 10878 10879 10880 10881 10882 10883 | ** ** The "iScanStatusOp" parameter determines which status information to return. ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior ** of this interface is undefined. ^The requested measurement is written into ** a variable pointed to by the "pOut" parameter. ** ** The "flags" parameter must be passed a mask of flags. At present only | | | | > | 10933 10934 10935 10936 10937 10938 10939 10940 10941 10942 10943 10944 10945 10946 10947 10948 10949 10950 10951 10952 10953 10954 10955 10956 10957 10958 10959 10960 10961 10962 10963 10964 | ** ** The "iScanStatusOp" parameter determines which status information to return. ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior ** of this interface is undefined. ^The requested measurement is written into ** a variable pointed to by the "pOut" parameter. ** ** The "flags" parameter must be passed a mask of flags. At present only ** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX ** is specified, then status information is available for all elements ** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of ** the EXPLAIN QUERY PLAN output) are available. Invoking API ** sqlite3_stmt_scanstatus() is equivalent to calling ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. ** ** Parameter "idx" identifies the specific query element to retrieve statistics ** for. Query elements are numbered starting from zero. A value of -1 may ** retrieve statistics for the entire query. ^If idx is out of range ** - less than -1 or greater than or equal to the total number of query ** elements used to implement the statement - a non-zero value is returned and ** the variable that pOut points to is unchanged. ** ** See also: [sqlite3_stmt_scanstatus_reset()] and the ** [nexec and ncycle] columnes of the [bytecode virtual table]. */ SQLITE_API int sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ void *pOut /* Result written here */ ); |
| ︙ | ︙ | |||
11432 11433 11434 11435 11436 11437 11438 11439 11440 11441 11442 11443 11444 11445 | ** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database ** should be treated as read-only. */ #define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */ #define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */ #define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 11489 11490 11491 11492 11493 11494 11495 11496 11497 11498 11499 11500 11501 11502 11503 11504 11505 11506 11507 11508 11509 11510 11511 11512 11513 11514 11515 11516 11517 11518 11519 11520 11521 11522 11523 11524 11525 11526 11527 11528 11529 11530 11531 11532 11533 11534 11535 11536 11537 11538 11539 11540 11541 11542 11543 11544 11545 11546 11547 11548 11549 11550 | ** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database ** should be treated as read-only. */ #define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */ #define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */ #define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ /* ** CAPI3REF: Bind array values to the CARRAY table-valued function ** ** The sqlite3_carray_bind(S,I,P,N,F,X) interface binds an array value to ** one of the first argument of the [carray() table-valued function]. The ** S parameter is a pointer to the [prepared statement] that uses the carray() ** functions. I is the parameter index to be bound. P is a pointer to the ** array to be bound, and N is the number of eements in the array. The ** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], ** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to ** indicate the datatype of the array being bound. The X argument is not a ** NULL pointer, then SQLite will invoke the function X on the P parameter ** after it has finished using P, even if the call to ** sqlite3_carray_bind() fails. The special-case finalizer ** SQLITE_TRANSIENT has no effect here. */ SQLITE_API int sqlite3_carray_bind( sqlite3_stmt *pStmt, /* Statement to be bound */ int i, /* Parameter index */ void *aData, /* Pointer to array data */ int nData, /* Number of data elements */ int mFlags, /* CARRAY flags */ void (*xDel)(void*) /* Destructor for aData */ ); /* ** CAPI3REF: Datatypes for the CARRAY table-valued function ** ** The fifth argument to the [sqlite3_carray_bind()] interface musts be ** one of the following constants, to specify the datatype of the array ** that is being bound into the [carray table-valued function]. */ #define SQLITE_CARRAY_INT32 0 /* Data is 32-bit signed integers */ #define SQLITE_CARRAY_INT64 1 /* Data is 64-bit signed integers */ #define SQLITE_CARRAY_DOUBLE 2 /* Data is doubles */ #define SQLITE_CARRAY_TEXT 3 /* Data is char* */ #define SQLITE_CARRAY_BLOB 4 /* Data is struct iovec */ /* ** Versions of the above #defines that omit the initial SQLITE_, for ** legacy compatibility. */ #define CARRAY_INT32 0 /* Data is 32-bit signed integers */ #define CARRAY_INT64 1 /* Data is 64-bit signed integers */ #define CARRAY_DOUBLE 2 /* Data is doubles */ #define CARRAY_TEXT 3 /* Data is char* */ #define CARRAY_BLOB 4 /* Data is struct iovec */ /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif |
| ︙ | ︙ | |||
14285 14286 14287 14288 14289 14290 14291 | ** to turn this limit off. */ #ifndef SQLITE_MAX_SQL_LENGTH # define SQLITE_MAX_SQL_LENGTH 1000000000 #endif /* | | | | > > | > > > > > > > > > > > > > > > > | 14390 14391 14392 14393 14394 14395 14396 14397 14398 14399 14400 14401 14402 14403 14404 14405 14406 14407 14408 14409 14410 14411 14412 14413 14414 14415 14416 14417 14418 14419 14420 14421 14422 14423 14424 14425 14426 14427 14428 14429 14430 | ** to turn this limit off. */ #ifndef SQLITE_MAX_SQL_LENGTH # define SQLITE_MAX_SQL_LENGTH 1000000000 #endif /* ** The maximum depth of an expression tree. The expression tree depth ** is also limited indirectly by SQLITE_MAX_SQL_LENGTH and by ** SQLITE_MAX_PARSER_DEPTH. Reducing the maximum complexity of ** expressions can help prevent excess memory usage by hostile SQL. ** ** A value of 0 for this compile-time option causes all expression ** depth limiting code to be omitted. */ #ifndef SQLITE_MAX_EXPR_DEPTH # define SQLITE_MAX_EXPR_DEPTH 1000 #endif /* ** The maximum depth of the LALR(1) stack used in the parser that ** interprets SQL inputs. The parser stack depth can also be limited ** indirectly by SQLITE_MAX_SQL_LENGTH. Limiting the parser stack ** depth can help prevent excess memory usage and excess CPU stack ** usage when processing hostile SQL. ** ** Prior to version 3.45.0 (2024-01-15), the parser stack was ** hard-coded to 100 entries, and that worked fine for almost all ** applications. So the upper bound on this limit need not be large. */ #ifndef SQLITE_MAX_PARSER_DEPTH # define SQLITE_MAX_PARSER_DEPTH 2500 #endif /* ** The maximum number of terms in a compound SELECT statement. ** The code generator for compound SELECT statements does one ** level of recursion for each term. A stack overflow can result ** if the number of terms is too large. In practice, most SQL ** never has more than 3 or 4 terms. Use a value of 0 to disable ** any limit on the number of terms in a compound SELECT. |
| ︙ | ︙ | |||
16011 16012 16013 16014 16015 16016 16017 | ** If none of the macros are initially defined, then select either ** SQLITE_OS_UNIX or SQLITE_OS_WIN depending on the target platform. ** ** If SQLITE_OS_OTHER=1 is specified at compile-time, then the application ** must provide its own VFS implementation together with sqlite3_os_init() ** and sqlite3_os_end() routines. */ | | | | 16134 16135 16136 16137 16138 16139 16140 16141 16142 16143 16144 16145 16146 16147 16148 16149 |
** If none of the macros are initially defined, then select either
** SQLITE_OS_UNIX or SQLITE_OS_WIN depending on the target platform.
**
** If SQLITE_OS_OTHER=1 is specified at compile-time, then the application
** must provide its own VFS implementation together with sqlite3_os_init()
** and sqlite3_os_end() routines.
*/
#if SQLITE_OS_KV+1<=1 && SQLITE_OS_OTHER+1<=1 && \
SQLITE_OS_WIN+1<=1 && SQLITE_OS_UNIX+1<=1
# if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || \
defined(__MINGW32__) || defined(__BORLANDC__)
# define SQLITE_OS_WIN 1
# define SQLITE_OS_UNIX 0
# else
# define SQLITE_OS_WIN 0
# define SQLITE_OS_UNIX 1
|
| ︙ | ︙ | |||
17514 17515 17516 17517 17518 17519 17520 17521 17522 17523 17524 17525 17526 17527 | SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8); SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); #ifndef SQLITE_OMIT_TRACE SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); | > > > | 17637 17638 17639 17640 17641 17642 17643 17644 17645 17646 17647 17648 17649 17650 17651 17652 17653 | SQLITE_PRIVATE sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8); SQLITE_PRIVATE void sqlite3VdbeSetVarmask(Vdbe*, int); #ifndef SQLITE_OMIT_TRACE SQLITE_PRIVATE char *sqlite3VdbeExpandSql(Vdbe*, const char*); #endif SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); SQLITE_PRIVATE int sqlite3BlobCompare(const Mem*, const Mem*); #ifdef SQLITE_ENABLE_PERCENTILE SQLITE_PRIVATE const char *sqlite3VdbeFuncName(const sqlite3_context*); #endif SQLITE_PRIVATE void sqlite3VdbeRecordUnpack(int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompare(int,const void*,UnpackedRecord*); SQLITE_PRIVATE int sqlite3VdbeRecordCompareWithSkip(int, const void *, UnpackedRecord *, int); SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeAllocUnpackedRecord(KeyInfo*); typedef int (*RecordCompare)(int,const void*,UnpackedRecord*); |
| ︙ | ︙ | |||
18022 18023 18024 18025 18026 18027 18028 | #define DB_UnresetViews 0x0002 /* Some views have defined column names */ #define DB_ResetWanted 0x0008 /* Reset the schema when nSchemaLock==0 */ /* ** The number of different kinds of things that can be limited ** using the sqlite3_limit() interface. */ | | | 18148 18149 18150 18151 18152 18153 18154 18155 18156 18157 18158 18159 18160 18161 18162 | #define DB_UnresetViews 0x0002 /* Some views have defined column names */ #define DB_ResetWanted 0x0008 /* Reset the schema when nSchemaLock==0 */ /* ** The number of different kinds of things that can be limited ** using the sqlite3_limit() interface. */ #define SQLITE_N_LIMIT (SQLITE_LIMIT_PARSER_DEPTH+1) /* ** Lookaside malloc is a set of fixed-size buffers that can be used ** to satisfy small transient memory allocation requests for objects ** associated with a particular database connection. The use of ** lookaside malloc provides a significant performance enhancement ** (approx 10%) by avoiding numerous malloc/free requests while parsing |
| ︙ | ︙ | |||
18269 18270 18271 18272 18273 18274 18275 18276 18277 18278 18279 18280 18281 18282 | #endif int nSavepoint; /* Number of non-transaction savepoints */ int nStatement; /* Number of nested statement-transactions */ i64 nDeferredCons; /* Net deferred constraints this transaction. */ i64 nDeferredImmCons; /* Net deferred immediate constraints */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ DbClientData *pDbData; /* sqlite3_set_clientdata() content */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY /* The following variables are all protected by the STATIC_MAIN ** mutex, not by sqlite3.mutex. They are used by code in notify.c. ** ** When X.pUnlockConnection==Y, that means that X is waiting for Y to ** unlock so that it can proceed. ** | > | 18395 18396 18397 18398 18399 18400 18401 18402 18403 18404 18405 18406 18407 18408 18409 | #endif int nSavepoint; /* Number of non-transaction savepoints */ int nStatement; /* Number of nested statement-transactions */ i64 nDeferredCons; /* Net deferred constraints this transaction. */ i64 nDeferredImmCons; /* Net deferred immediate constraints */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ DbClientData *pDbData; /* sqlite3_set_clientdata() content */ u64 nSpill; /* TEMP content spilled to disk */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY /* The following variables are all protected by the STATIC_MAIN ** mutex, not by sqlite3.mutex. They are used by code in notify.c. ** ** When X.pUnlockConnection==Y, that means that X is waiting for Y to ** unlock so that it can proceed. ** |
| ︙ | ︙ | |||
20752 20753 20754 20755 20756 20757 20758 | u32 nInitRow; /* Number of rows processed */ Pgno mxPage; /* Maximum page number. 0 for no limit. */ } InitData; /* ** Allowed values for mInitFlags */ | | > | 20879 20880 20881 20882 20883 20884 20885 20886 20887 20888 20889 20890 20891 20892 20893 20894 20895 20896 20897 | u32 nInitRow; /* Number of rows processed */ Pgno mxPage; /* Maximum page number. 0 for no limit. */ } InitData; /* ** Allowed values for mInitFlags */ #define INITFLAG_AlterMask 0x0007 /* Types of ALTER */ #define INITFLAG_AlterRename 0x0001 /* Reparse after a RENAME */ #define INITFLAG_AlterDrop 0x0002 /* Reparse after a DROP COLUMN */ #define INITFLAG_AlterAdd 0x0003 /* Reparse after an ADD COLUMN */ #define INITFLAG_AlterDropCons 0x0004 /* Reparse after an ADD COLUMN */ /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning ** parameters are for temporary use during development, to help find ** optimal values for parameters in the query planner. The should not ** be used on trunk check-ins. They are a temporary mechanism available ** for transient development builds only. |
| ︙ | ︙ | |||
21705 21706 21707 21708 21709 21710 21711 | SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum*,sqlite3_value*,int); SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char*, u32); SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void); SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*); #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) | | > > > > | 21833 21834 21835 21836 21837 21838 21839 21840 21841 21842 21843 21844 21845 21846 21847 21848 21849 21850 21851 21852 21853 21854 21855 21856 | SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum*,sqlite3_value*,int); SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char*, u32); SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void); SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void); SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void); SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*); #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) SQLITE_PRIVATE Module *sqlite3JsonVtabRegister(sqlite3*,const char*); #endif SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*); SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*); SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int); SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p); #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_CARRAY) SQLITE_PRIVATE Module *sqlite3CarrayRegister(sqlite3*); #endif #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) SQLITE_PRIVATE void sqlite3MaterializeView(Parse*, Table*, Expr*, ExprList*,Expr*,int); #endif #ifndef SQLITE_OMIT_TRIGGER SQLITE_PRIVATE void sqlite3BeginTrigger(Parse*, Token*,Token*,int,int,IdList*,SrcList*, |
| ︙ | ︙ | |||
21932 21933 21934 21935 21936 21937 21938 | SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt; #endif SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, Pgno, Pgno); SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*); SQLITE_PRIVATE void sqlite3AlterFunctions(void); SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); | > > > | | 22064 22065 22066 22067 22068 22069 22070 22071 22072 22073 22074 22075 22076 22077 22078 22079 22080 22081 | SQLITE_PRIVATE sqlite3_uint64 sqlite3NProfileCnt; #endif SQLITE_PRIVATE void sqlite3RootPageMoved(sqlite3*, int, Pgno, Pgno); SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*); SQLITE_PRIVATE void sqlite3AlterFunctions(void); SQLITE_PRIVATE void sqlite3AlterRenameTable(Parse*, SrcList*, Token*); SQLITE_PRIVATE void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*); SQLITE_PRIVATE void sqlite3AlterDropConstraint(Parse*,SrcList*,Token*,Token*); SQLITE_PRIVATE void sqlite3AlterAddConstraint(Parse*,SrcList*,Token*,Token*,const char*,int); SQLITE_PRIVATE void sqlite3AlterSetNotNull(Parse*, SrcList*, Token*, Token*); SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *, int *); SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...); SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*, int); SQLITE_PRIVATE void sqlite3CodeRhsOfIN(Parse*, Expr*, int); SQLITE_PRIVATE int sqlite3CodeSubselect(Parse*, Expr*); SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); SQLITE_PRIVATE int sqlite3ExpandSubquery(Parse*, SrcItem*); SQLITE_PRIVATE void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p); |
| ︙ | ︙ | |||
22697 22698 22699 22700 22701 22702 22703 22704 22705 22706 22707 22708 22709 22710 | "ENABLE_ATOMIC_WRITE", #endif #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE "ENABLE_BATCH_ATOMIC_WRITE", #endif #ifdef SQLITE_ENABLE_BYTECODE_VTAB "ENABLE_BYTECODE_VTAB", #endif #ifdef SQLITE_ENABLE_CEROD "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD), #endif #ifdef SQLITE_ENABLE_COLUMN_METADATA "ENABLE_COLUMN_METADATA", #endif | > > > | 22832 22833 22834 22835 22836 22837 22838 22839 22840 22841 22842 22843 22844 22845 22846 22847 22848 | "ENABLE_ATOMIC_WRITE", #endif #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE "ENABLE_BATCH_ATOMIC_WRITE", #endif #ifdef SQLITE_ENABLE_BYTECODE_VTAB "ENABLE_BYTECODE_VTAB", #endif #ifdef SQLITE_ENABLE_CARRAY "ENABLE_CARRAY", #endif #ifdef SQLITE_ENABLE_CEROD "ENABLE_CEROD=" CTIMEOPT_VAL(SQLITE_ENABLE_CEROD), #endif #ifdef SQLITE_ENABLE_COLUMN_METADATA "ENABLE_COLUMN_METADATA", #endif |
| ︙ | ︙ | |||
22787 22788 22789 22790 22791 22792 22793 22794 22795 22796 22797 22798 22799 22800 | "ENABLE_OFFSET_SQL_FUNC", #endif #ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES "ENABLE_ORDERED_SET_AGGREGATES", #endif #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK "ENABLE_OVERSIZE_CELL_CHECK", #endif #ifdef SQLITE_ENABLE_PREUPDATE_HOOK "ENABLE_PREUPDATE_HOOK", #endif #ifdef SQLITE_ENABLE_QPSG "ENABLE_QPSG", #endif | > > > | 22925 22926 22927 22928 22929 22930 22931 22932 22933 22934 22935 22936 22937 22938 22939 22940 22941 | "ENABLE_OFFSET_SQL_FUNC", #endif #ifdef SQLITE_ENABLE_ORDERED_SET_AGGREGATES "ENABLE_ORDERED_SET_AGGREGATES", #endif #ifdef SQLITE_ENABLE_OVERSIZE_CELL_CHECK "ENABLE_OVERSIZE_CELL_CHECK", #endif #ifdef SQLITE_ENABLE_PERCENTILE "ENABLE_PERCENTILE", #endif #ifdef SQLITE_ENABLE_PREUPDATE_HOOK "ENABLE_PREUPDATE_HOOK", #endif #ifdef SQLITE_ENABLE_QPSG "ENABLE_QPSG", #endif |
| ︙ | ︙ | |||
24271 24272 24273 24274 24275 24276 24277 | i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ Mem oldipk; /* Memory cell holding "old" IPK value */ Mem *aNew; /* Array of new.* values */ Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ sqlite3_value **apDflt; /* Array of default values, if required */ | | < | 24412 24413 24414 24415 24416 24417 24418 24419 24420 24421 24422 24423 24424 24425 24426 |
i64 iKey1; /* First key value passed to hook */
i64 iKey2; /* Second key value passed to hook */
Mem oldipk; /* Memory cell holding "old" IPK value */
Mem *aNew; /* Array of new.* values */
Table *pTab; /* Schema object being updated */
Index *pPk; /* PK index if pTab is WITHOUT ROWID */
sqlite3_value **apDflt; /* Array of default values, if required */
struct {
u8 keyinfoSpace[SZ_KEYINFO_0]; /* Space to hold pKeyinfo[0] content */
} uKey;
};
/*
** An instance of this object is used to pass an vector of values into
** OP_VFilter, the xFilter method of a virtual table. The vector is the
|
| ︙ | ︙ | |||
24651 24652 24653 24654 24655 24656 24657 | if( pHighwater ) *pHighwater = (int)(db->lookaside.nSlot - nInit); return (int)(db->lookaside.nSlot - (nInit+nFree)); } /* ** Query status information for a single database connection */ | | | | | | | | > | > | 24791 24792 24793 24794 24795 24796 24797 24798 24799 24800 24801 24802 24803 24804 24805 24806 24807 24808 24809 24810 24811 24812 24813 24814 24815 24816 24817 24818 24819 24820 24821 24822 24823 |
if( pHighwater ) *pHighwater = (int)(db->lookaside.nSlot - nInit);
return (int)(db->lookaside.nSlot - (nInit+nFree));
}
/*
** Query status information for a single database connection
*/
SQLITE_API int sqlite3_db_status64(
sqlite3 *db, /* The database connection whose status is desired */
int op, /* Status verb */
sqlite3_int64 *pCurrent, /* Write current value here */
sqlite3_int64 *pHighwtr, /* Write high-water mark here */
int resetFlag /* Reset high-water mark if true */
){
int rc = SQLITE_OK; /* Return code */
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwtr==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
sqlite3_mutex_enter(db->mutex);
switch( op ){
case SQLITE_DBSTATUS_LOOKASIDE_USED: {
int H = 0;
*pCurrent = sqlite3LookasideUsed(db, &H);
*pHighwtr = H;
if( resetFlag ){
LookasideSlot *p = db->lookaside.pFree;
if( p ){
while( p->pNext ) p = p->pNext;
p->pNext = db->lookaside.pInit;
db->lookaside.pInit = db->lookaside.pFree;
db->lookaside.pFree = 0;
|
| ︙ | ︙ | |||
24698 24699 24700 24701 24702 24703 24704 |
case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: {
testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT );
testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE );
testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL );
assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 );
assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 );
*pCurrent = 0;
| | | | | | | | 24840 24841 24842 24843 24844 24845 24846 24847 24848 24849 24850 24851 24852 24853 24854 24855 24856 24857 24858 24859 24860 24861 24862 24863 24864 24865 24866 24867 24868 24869 24870 24871 24872 24873 24874 24875 24876 24877 24878 24879 24880 24881 24882 24883 24884 24885 24886 24887 24888 24889 24890 24891 24892 24893 24894 24895 |
case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: {
testcase( op==SQLITE_DBSTATUS_LOOKASIDE_HIT );
testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE );
testcase( op==SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL );
assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)>=0 );
assert( (op-SQLITE_DBSTATUS_LOOKASIDE_HIT)<3 );
*pCurrent = 0;
*pHighwtr = db->lookaside.anStat[op-SQLITE_DBSTATUS_LOOKASIDE_HIT];
if( resetFlag ){
db->lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0;
}
break;
}
/*
** Return an approximation for the amount of memory currently used
** by all pagers associated with the given database connection. The
** highwater mark is meaningless and is returned as zero.
*/
case SQLITE_DBSTATUS_CACHE_USED_SHARED:
case SQLITE_DBSTATUS_CACHE_USED: {
sqlite3_int64 totalUsed = 0;
int i;
sqlite3BtreeEnterAll(db);
for(i=0; i<db->nDb; i++){
Btree *pBt = db->aDb[i].pBt;
if( pBt ){
Pager *pPager = sqlite3BtreePager(pBt);
int nByte = sqlite3PagerMemUsed(pPager);
if( op==SQLITE_DBSTATUS_CACHE_USED_SHARED ){
nByte = nByte / sqlite3BtreeConnectionCount(pBt);
}
totalUsed += nByte;
}
}
sqlite3BtreeLeaveAll(db);
*pCurrent = totalUsed;
*pHighwtr = 0;
break;
}
/*
** *pCurrent gets an accurate estimate of the amount of memory used
** to store the schema for all databases (main, temp, and any ATTACHed
** databases. *pHighwtr is set to zero.
*/
case SQLITE_DBSTATUS_SCHEMA_USED: {
int i; /* Used to iterate through schemas */
int nByte = 0; /* Used to accumulate return value */
sqlite3BtreeEnterAll(db);
db->pnBytesFreed = &nByte;
assert( db->lookaside.pEnd==db->lookaside.pTrueEnd );
db->lookaside.pEnd = db->lookaside.pStart;
for(i=0; i<db->nDb; i++){
Schema *pSchema = db->aDb[i].pSchema;
|
| ︙ | ︙ | |||
24773 24774 24775 24776 24777 24778 24779 |
}
}
}
db->pnBytesFreed = 0;
db->lookaside.pEnd = db->lookaside.pTrueEnd;
sqlite3BtreeLeaveAll(db);
| | | | | | | > > > > > > > > > > > > > > > > > > > > | | > > > > > > > > > > > > > > > > > > > > > > > > > | 24915 24916 24917 24918 24919 24920 24921 24922 24923 24924 24925 24926 24927 24928 24929 24930 24931 24932 24933 24934 24935 24936 24937 24938 24939 24940 24941 24942 24943 24944 24945 24946 24947 24948 24949 24950 24951 24952 24953 24954 24955 24956 24957 24958 24959 24960 24961 24962 24963 24964 24965 24966 24967 24968 24969 24970 24971 24972 24973 24974 24975 24976 24977 24978 24979 24980 24981 24982 24983 24984 24985 24986 24987 24988 24989 24990 24991 24992 24993 24994 24995 24996 24997 24998 24999 25000 25001 25002 25003 25004 25005 25006 25007 25008 25009 25010 25011 25012 25013 25014 25015 25016 25017 25018 25019 25020 25021 25022 25023 25024 25025 25026 25027 25028 25029 25030 25031 25032 25033 25034 25035 25036 25037 25038 25039 25040 25041 25042 25043 25044 25045 25046 25047 25048 |
}
}
}
db->pnBytesFreed = 0;
db->lookaside.pEnd = db->lookaside.pTrueEnd;
sqlite3BtreeLeaveAll(db);
*pHighwtr = 0;
*pCurrent = nByte;
break;
}
/*
** *pCurrent gets an accurate estimate of the amount of memory used
** to store all prepared statements.
** *pHighwtr is set to zero.
*/
case SQLITE_DBSTATUS_STMT_USED: {
struct Vdbe *pVdbe; /* Used to iterate through VMs */
int nByte = 0; /* Used to accumulate return value */
db->pnBytesFreed = &nByte;
assert( db->lookaside.pEnd==db->lookaside.pTrueEnd );
db->lookaside.pEnd = db->lookaside.pStart;
for(pVdbe=db->pVdbe; pVdbe; pVdbe=pVdbe->pVNext){
sqlite3VdbeDelete(pVdbe);
}
db->lookaside.pEnd = db->lookaside.pTrueEnd;
db->pnBytesFreed = 0;
*pHighwtr = 0; /* IMP: R-64479-57858 */
*pCurrent = nByte;
break;
}
/*
** Set *pCurrent to the total cache hits or misses encountered by all
** pagers the database handle is connected to. *pHighwtr is always set
** to zero.
*/
case SQLITE_DBSTATUS_CACHE_SPILL:
op = SQLITE_DBSTATUS_CACHE_WRITE+1;
/* no break */ deliberate_fall_through
case SQLITE_DBSTATUS_CACHE_HIT:
case SQLITE_DBSTATUS_CACHE_MISS:
case SQLITE_DBSTATUS_CACHE_WRITE:{
int i;
u64 nRet = 0;
assert( SQLITE_DBSTATUS_CACHE_MISS==SQLITE_DBSTATUS_CACHE_HIT+1 );
assert( SQLITE_DBSTATUS_CACHE_WRITE==SQLITE_DBSTATUS_CACHE_HIT+2 );
for(i=0; i<db->nDb; i++){
if( db->aDb[i].pBt ){
Pager *pPager = sqlite3BtreePager(db->aDb[i].pBt);
sqlite3PagerCacheStat(pPager, op, resetFlag, &nRet);
}
}
*pHighwtr = 0; /* IMP: R-42420-56072 */
/* IMP: R-54100-20147 */
/* IMP: R-29431-39229 */
*pCurrent = nRet;
break;
}
/* Set *pCurrent to the number of bytes that the db database connection
** has spilled to the filesystem in temporary files that could have been
** stored in memory, had sufficient memory been available.
** The *pHighwater is always set to zero.
*/
case SQLITE_DBSTATUS_TEMPBUF_SPILL: {
u64 nRet = 0;
if( db->aDb[1].pBt ){
Pager *pPager = sqlite3BtreePager(db->aDb[1].pBt);
sqlite3PagerCacheStat(pPager, SQLITE_DBSTATUS_CACHE_WRITE,
resetFlag, &nRet);
nRet *= sqlite3BtreeGetPageSize(db->aDb[1].pBt);
}
nRet += db->nSpill;
if( resetFlag ) db->nSpill = 0;
*pHighwtr = 0;
*pCurrent = nRet;
break;
}
/* Set *pCurrent to non-zero if there are unresolved deferred foreign
** key constraints. Set *pCurrent to zero if all foreign key constraints
** have been satisfied. The *pHighwtr is always set to zero.
*/
case SQLITE_DBSTATUS_DEFERRED_FKS: {
*pHighwtr = 0; /* IMP: R-11967-56545 */
*pCurrent = db->nDeferredImmCons>0 || db->nDeferredCons>0;
break;
}
default: {
rc = SQLITE_ERROR;
}
}
sqlite3_mutex_leave(db->mutex);
return rc;
}
/*
** 32-bit variant of sqlite3_db_status64()
*/
SQLITE_API int sqlite3_db_status(
sqlite3 *db, /* The database connection whose status is desired */
int op, /* Status verb */
int *pCurrent, /* Write current value here */
int *pHighwtr, /* Write high-water mark here */
int resetFlag /* Reset high-water mark if true */
){
sqlite3_int64 C = 0, H = 0;
int rc;
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) || pCurrent==0|| pHighwtr==0 ){
return SQLITE_MISUSE_BKPT;
}
#endif
rc = sqlite3_db_status64(db, op, &C, &H, resetFlag);
if( rc==0 ){
*pCurrent = C & 0x7fffffff;
*pHighwtr = H & 0x7fffffff;
}
return rc;
}
/************** End of status.c **********************************************/
/************** Begin file date.c ********************************************/
/*
** 2003 October 31
**
** The author disclaims copyright to this source code. In place of
|
| ︙ | ︙ | |||
26240 26241 26242 26243 26244 26245 26246 | ** %k hour 0-24 (leading zero converted to space) ** %I hour 01-12 ** %j day of year 001-366 ** %J ** julian day number ** %l hour 1-12 (leading zero converted to space) ** %m month 01-12 ** %M minute 00-59 | | | | 26427 26428 26429 26430 26431 26432 26433 26434 26435 26436 26437 26438 26439 26440 26441 26442 | ** %k hour 0-24 (leading zero converted to space) ** %I hour 01-12 ** %j day of year 001-366 ** %J ** julian day number ** %l hour 1-12 (leading zero converted to space) ** %m month 01-12 ** %M minute 00-59 ** %p "AM" or "PM" ** %P "am" or "pm" ** %R time as HH:MM ** %s seconds since 1970-01-01 ** %S seconds 00-59 ** %T time as HH:MM:SS ** %u day of week 1-7 Monday==1, Sunday==7 ** %w day of week 0-6 Sunday==0, Monday==1 ** %U week of year 00-53 (First Sunday is start of week 01) |
| ︙ | ︙ | |||
31848 31849 31850 31851 31852 31853 31854 31855 31856 31857 31858 31859 31860 31861 31862 |
typedef struct et_info { /* Information about each format field */
char fmttype; /* The format field code letter */
etByte base; /* The base for radix conversion */
etByte flags; /* One or more of FLAG_ constants below */
etByte type; /* Conversion paradigm */
etByte charset; /* Offset into aDigits[] of the digits string */
etByte prefix; /* Offset into aPrefix[] of the prefix string */
} et_info;
/*
** Allowed values for et_info.flags
*/
#define FLAG_SIGNED 1 /* True if the value to convert is signed */
#define FLAG_STRING 4 /* Allow infinite precision */
| > < | > | > > > > > > > > > > > > > > > > > > > > > | < | > > | < < < | < < < | | < > | | | | < > | < | < < < | | > > > > > | | | 32035 32036 32037 32038 32039 32040 32041 32042 32043 32044 32045 32046 32047 32048 32049 32050 32051 32052 32053 32054 32055 32056 32057 32058 32059 32060 32061 32062 32063 32064 32065 32066 32067 32068 32069 32070 32071 32072 32073 32074 32075 32076 32077 32078 32079 32080 32081 32082 32083 32084 32085 32086 32087 32088 32089 32090 32091 32092 32093 32094 32095 32096 32097 32098 32099 32100 32101 32102 32103 32104 32105 32106 32107 32108 32109 32110 32111 32112 |
typedef struct et_info { /* Information about each format field */
char fmttype; /* The format field code letter */
etByte base; /* The base for radix conversion */
etByte flags; /* One or more of FLAG_ constants below */
etByte type; /* Conversion paradigm */
etByte charset; /* Offset into aDigits[] of the digits string */
etByte prefix; /* Offset into aPrefix[] of the prefix string */
char iNxt; /* Next with same hash, or 0 for end of chain */
} et_info;
/*
** Allowed values for et_info.flags
*/
#define FLAG_SIGNED 1 /* True if the value to convert is signed */
#define FLAG_STRING 4 /* Allow infinite precision */
/*
** The table is searched by hash. In the case of %C where C is the character
** and that character has ASCII value j, then the hash is j%23.
**
** The order of the entries in fmtinfo[] and the hash chain was entered
** manually, but based on the output of the following TCL script:
*/
#if 0 /***** Beginning of script ******/
foreach c {d s g z q Q w c o u x X f e E G i n % p T S r} {
scan $c %c x
set n($c) $x
}
set mx [llength [array names n]]
puts "count: $mx"
set mx 27
puts "*********** mx=$mx ************"
for {set r 0} {$r<$mx} {incr r} {
puts -nonewline [format %2d: $r]
foreach c [array names n] {
if {($n($c))%$mx==$r} {puts -nonewline " $c"}
}
puts ""
}
#endif /***** End of script ********/
static const char aDigits[] = "0123456789ABCDEF0123456789abcdef";
static const char aPrefix[] = "-x0\000X0";
static const et_info fmtinfo[23] = {
/* 0 */ { 's', 0, 4, etSTRING, 0, 0, 1 },
/* 1 */ { 'E', 0, 1, etEXP, 14, 0, 0 }, /* Hash: 0 */
/* 2 */ { 'u', 10, 0, etDECIMAL, 0, 0, 3 },
/* 3 */ { 'G', 0, 1, etGENERIC, 14, 0, 0 }, /* Hash: 2 */
/* 4 */ { 'w', 0, 4, etESCAPE_w, 0, 0, 0 },
/* 5 */ { 'x', 16, 0, etRADIX, 16, 1, 0 },
/* 6 */ { 'c', 0, 0, etCHARX, 0, 0, 0 }, /* Hash: 7 */
/* 7 */ { 'z', 0, 4, etDYNSTRING, 0, 0, 6 },
/* 8 */ { 'd', 10, 1, etDECIMAL, 0, 0, 0 },
/* 9 */ { 'e', 0, 1, etEXP, 30, 0, 0 },
/* 10 */ { 'f', 0, 1, etFLOAT, 0, 0, 0 },
/* 11 */ { 'g', 0, 1, etGENERIC, 30, 0, 0 },
/* 12 */ { 'Q', 0, 4, etESCAPE_Q, 0, 0, 0 },
/* 13 */ { 'i', 10, 1, etDECIMAL, 0, 0, 0 },
/* 14 */ { '%', 0, 0, etPERCENT, 0, 0, 16 },
/* 15 */ { 'T', 0, 0, etTOKEN, 0, 0, 0 },
/* 16 */ { 'S', 0, 0, etSRCITEM, 0, 0, 0 }, /* Hash: 14 */
/* 17 */ { 'X', 16, 0, etRADIX, 0, 4, 0 }, /* Hash: 19 */
/* 18 */ { 'n', 0, 0, etSIZE, 0, 0, 0 },
/* 19 */ { 'o', 8, 0, etRADIX, 0, 2, 17 },
/* 20 */ { 'p', 16, 0, etPOINTER, 0, 1, 0 },
/* 21 */ { 'q', 0, 4, etESCAPE_q, 0, 0, 0 },
/* 22 */ { 'r', 10, 1, etORDINAL, 0, 0, 0 }
};
/* Additional Notes:
**
** %S Takes a pointer to SrcItem. Shows name or database.name
** %!S Like %S but prefer the zName over the zAlias
*/
/*
** Set the StrAccum object to an error mode.
|
| ︙ | ︙ | |||
32020 32021 32022 32023 32024 32025 32026 |
}
for(; (c=(*fmt))!=0; ++fmt){
if( c!='%' ){
bufpt = (char *)fmt;
#if HAVE_STRCHRNUL
fmt = strchrnul(fmt, '%');
#else
| > | > > | 32225 32226 32227 32228 32229 32230 32231 32232 32233 32234 32235 32236 32237 32238 32239 32240 32241 32242 |
}
for(; (c=(*fmt))!=0; ++fmt){
if( c!='%' ){
bufpt = (char *)fmt;
#if HAVE_STRCHRNUL
fmt = strchrnul(fmt, '%');
#else
fmt = strchr(fmt, '%');
if( fmt==0 ){
fmt = bufpt + strlen(bufpt);
}
#endif
sqlite3_str_append(pAccum, bufpt, (int)(fmt - bufpt));
if( *fmt==0 ) break;
}
if( (c=(*++fmt))==0 ){
sqlite3_str_append(pAccum, "%", 1);
break;
|
| ︙ | ︙ | |||
32134 32135 32136 32137 32138 32139 32140 32141 32142 32143 32144 32145 32146 32147 32148 32149 32150 32151 32152 32153 32154 32155 32156 |
}
break;
}
}
}while( !done && (c=(*++fmt))!=0 );
/* Fetch the info entry for the field */
infop = &fmtinfo[0];
xtype = etINVALID;
for(idx=0; idx<ArraySize(fmtinfo); idx++){
if( c==fmtinfo[idx].fmttype ){
infop = &fmtinfo[idx];
xtype = infop->type;
break;
}
}
/*
** At this point, variables are initialized as follows:
**
** flag_alternateform TRUE if a '#' is present.
** flag_altform2 TRUE if a '!' is present.
** flag_prefix '+' or ' ' or zero
| > > > > > > > > > > > > > > > > > | 32342 32343 32344 32345 32346 32347 32348 32349 32350 32351 32352 32353 32354 32355 32356 32357 32358 32359 32360 32361 32362 32363 32364 32365 32366 32367 32368 32369 32370 32371 32372 32373 32374 32375 32376 32377 32378 32379 32380 32381 |
}
break;
}
}
}while( !done && (c=(*++fmt))!=0 );
/* Fetch the info entry for the field */
#ifdef SQLITE_EBCDIC
/* The hash table only works for ASCII. For EBCDIC, we need to do
** a linear search of the table */
infop = &fmtinfo[0];
xtype = etINVALID;
for(idx=0; idx<ArraySize(fmtinfo); idx++){
if( c==fmtinfo[idx].fmttype ){
infop = &fmtinfo[idx];
xtype = infop->type;
break;
}
}
#else
/* Fast hash-table lookup */
assert( ArraySize(fmtinfo)==23 );
idx = ((unsigned)c) % 23;
if( fmtinfo[idx].fmttype==c
|| fmtinfo[idx = fmtinfo[idx].iNxt].fmttype==c
){
infop = &fmtinfo[idx];
xtype = infop->type;
}else{
infop = &fmtinfo[0];
xtype = etINVALID;
}
#endif
/*
** At this point, variables are initialized as follows:
**
** flag_alternateform TRUE if a '#' is present.
** flag_altform2 TRUE if a '!' is present.
** flag_prefix '+' or ' ' or zero
|
| ︙ | ︙ | |||
32983 32984 32985 32986 32987 32988 32989 32990 32991 32992 32993 32994 32995 32996 32997 32998 32999 33000 33001 33002 33003 33004 33005 33006 33007 33008 33009 33010 33011 33012 33013 33014 33015 33016 |
return p ? p->accError : SQLITE_NOMEM;
}
/* Return the current length of p in bytes */
SQLITE_API int sqlite3_str_length(sqlite3_str *p){
return p ? p->nChar : 0;
}
/* Return the current value for p */
SQLITE_API char *sqlite3_str_value(sqlite3_str *p){
if( p==0 || p->nChar==0 ) return 0;
p->zText[p->nChar] = 0;
return p->zText;
}
/*
** Reset an StrAccum string. Reclaim all malloced memory.
*/
SQLITE_API void sqlite3_str_reset(StrAccum *p){
if( isMalloced(p) ){
sqlite3DbFree(p->db, p->zText);
p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
}
p->nAlloc = 0;
p->nChar = 0;
p->zText = 0;
}
/*
** Initialize a string accumulator.
**
** p: The accumulator to be initialized.
** db: Pointer to a database connection. May be NULL. Lookaside
** memory is used if not NULL. db->mallocFailed is set appropriately
| > > > > > > > > > > > > > > > > > > > | 33208 33209 33210 33211 33212 33213 33214 33215 33216 33217 33218 33219 33220 33221 33222 33223 33224 33225 33226 33227 33228 33229 33230 33231 33232 33233 33234 33235 33236 33237 33238 33239 33240 33241 33242 33243 33244 33245 33246 33247 33248 33249 33250 33251 33252 33253 33254 33255 33256 33257 33258 33259 33260 |
return p ? p->accError : SQLITE_NOMEM;
}
/* Return the current length of p in bytes */
SQLITE_API int sqlite3_str_length(sqlite3_str *p){
return p ? p->nChar : 0;
}
/* Truncate the text of the string to be no more than N bytes. */
SQLITE_API void sqlite3_str_truncate(sqlite3_str *p, int N){
if( p!=0 && N>=0 && (u32)N<p->nChar ){
p->nChar = N;
p->zText[p->nChar] = 0;
}
}
/* Return the current value for p */
SQLITE_API char *sqlite3_str_value(sqlite3_str *p){
if( p==0 || p->nChar==0 ) return 0;
p->zText[p->nChar] = 0;
return p->zText;
}
/*
** Reset an StrAccum string. Reclaim all malloced memory.
*/
SQLITE_API void sqlite3_str_reset(StrAccum *p){
if( isMalloced(p) ){
sqlite3DbFree(p->db, p->zText);
p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
}
p->nAlloc = 0;
p->nChar = 0;
p->zText = 0;
}
/*
** Destroy a dynamically allocate sqlite3_str object and all
** of its content, all in one call.
*/
SQLITE_API void sqlite3_str_free(sqlite3_str *p){
if( p ){
sqlite3_str_reset(p);
sqlite3_free(p);
}
}
/*
** Initialize a string accumulator.
**
** p: The accumulator to be initialized.
** db: Pointer to a database connection. May be NULL. Lookaside
** memory is used if not NULL. db->mallocFailed is set appropriately
|
| ︙ | ︙ | |||
37815 37816 37817 37818 37819 37820 37821 37822 37823 37824 37825 37826 37827 37828 |
pH->count++;
if( pH->count>=5 && pH->count > 2*pH->htsize ){
rehash(pH, pH->count*3);
}
insertElement(pH, pH->ht ? &pH->ht[new_elem->h % pH->htsize] : 0, new_elem);
return 0;
}
/************** End of hash.c ************************************************/
/************** Begin file opcodes.c *****************************************/
/* Automatically generated. Do not edit */
/* See the tool/mkopcodec.tcl script for details. */
#if !defined(SQLITE_OMIT_EXPLAIN) \
|| defined(VDBE_PROFILE) \
| > | 38059 38060 38061 38062 38063 38064 38065 38066 38067 38068 38069 38070 38071 38072 38073 |
pH->count++;
if( pH->count>=5 && pH->count > 2*pH->htsize ){
rehash(pH, pH->count*3);
}
insertElement(pH, pH->ht ? &pH->ht[new_elem->h % pH->htsize] : 0, new_elem);
return 0;
}
/************** End of hash.c ************************************************/
/************** Begin file opcodes.c *****************************************/
/* Automatically generated. Do not edit */
/* See the tool/mkopcodec.tcl script for details. */
#if !defined(SQLITE_OMIT_EXPLAIN) \
|| defined(VDBE_PROFILE) \
|
| ︙ | ︙ | |||
39608 39609 39610 39611 39612 39613 39614 39615 39616 39617 39618 39619 39620 39621 |
#else
{ "ioctl", (sqlite3_syscall_ptr)0, 0 },
#endif
}; /* End of the overrideable system calls */
/*
** On some systems, calls to fchown() will trigger a message in a security
** log if they come from non-root processes. So avoid calling fchown() if
** we are not running as root.
*/
static int robustFchown(int fd, uid_t uid, gid_t gid){
#if defined(HAVE_FCHOWN)
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 39853 39854 39855 39856 39857 39858 39859 39860 39861 39862 39863 39864 39865 39866 39867 39868 39869 39870 39871 39872 39873 39874 39875 39876 39877 39878 39879 39880 39881 39882 39883 39884 39885 39886 39887 39888 39889 39890 39891 39892 39893 39894 39895 39896 39897 39898 39899 39900 39901 39902 39903 39904 39905 39906 39907 39908 39909 39910 39911 39912 39913 39914 39915 39916 39917 39918 39919 39920 39921 39922 39923 39924 39925 39926 39927 39928 39929 39930 39931 39932 39933 39934 39935 39936 39937 39938 39939 39940 39941 39942 39943 39944 39945 39946 39947 39948 39949 39950 39951 39952 39953 39954 39955 39956 39957 39958 39959 39960 39961 39962 39963 39964 39965 39966 39967 39968 39969 39970 39971 39972 39973 39974 39975 39976 39977 39978 39979 |
#else
{ "ioctl", (sqlite3_syscall_ptr)0, 0 },
#endif
}; /* End of the overrideable system calls */
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
/*
** Extract Posix Advisory Locking information about file description fd
** from the /proc/PID/fdinfo/FD pseudo-file. Fill the string buffer a[16]
** with characters to indicate which SQLite-relevant locks are held.
** a[16] will be a 15-character zero-terminated string with the following
** schema:
**
** AAA/B.DDD.DDDDD
**
** Each of character A-D will be "w" or "r" or "-" to indicate either a
** write-lock, a read-lock, or no-lock, respectively. The "." and "/"
** characters are delimiters intended to make the string more easily
** readable by humans. Here are the meaning of the specific letters:
**
** AAA -> The main database locks. PENDING_BYTE, RESERVED_BYTE,
** and SHARED_FIRST, respectively.
**
** B -> The deadman switch lock. Offset 128 of the -shm file.
**
** CCC -> WAL locks: WRITE, CKPT, RECOVER
**
** DDDDD -> WAL read-locks 0 through 5
**
** Note that elements before the "/" apply to the main database file and
** elements after the "/" apply to the -shm file in WAL mode.
**
** Here is another way of thinking about the meaning of the result string:
**
** AAA/B.CCC.DDDDD
** ||| | ||| \___/
** PENDING--'|| | ||| `----- READ 0-5
** RESERVED--'| | ||`---- RECOVER
** SHARED ----' | |`----- CKPT
** DMS ------' `------ WRITE
**
** Return SQLITE_OK on success and SQLITE_ERROR_UNABLE if the /proc
** pseudo-filesystem is unavailable.
*/
static int unixPosixAdvisoryLocks(
int fd, /* The file descriptor to analyze */
char a[16] /* Write a text description of PALs here */
){
int in;
ssize_t n;
char *p, *pNext, *x;
char z[2000];
/* 1 */
/* 012 4 678 01234 */
memcpy(a, "---/-.---.-----", 16);
sqlite3_snprintf(sizeof(z), z, "/proc/%d/fdinfo/%d", getpid(), fd);
in = osOpen(z, O_RDONLY, 0);
if( in<0 ){
return SQLITE_ERROR_UNABLE;
}
n = osRead(in, z, sizeof(z)-1);
osClose(in);
if( n<=0 ) return SQLITE_ERROR_UNABLE;
z[n] = 0;
/* We are looking for lines that begin with "lock:\t". Examples:
**
** lock: 1: POSIX ADVISORY READ 494716 08:02:5277597 1073741826 1073742335
** lock: 1: POSIX ADVISORY WRITE 494716 08:02:5282282 120 120
** lock: 2: POSIX ADVISORY READ 494716 08:02:5282282 123 123
** lock: 3: POSIX ADVISORY READ 494716 08:02:5282282 128 128
*/
pNext = strstr(z, "lock:\t");
while( pNext ){
char cType = 0;
sqlite3_int64 iFirst, iLast;
p = pNext+6;
pNext = strstr(p, "lock:\t");
if( pNext ) pNext[-1] = 0;
if( (x = strstr(p, " READ "))!=0 ){
cType = 'r';
x += 6;
}else if( (x = strstr(p, " WRITE "))!=0 ){
cType = 'w';
x += 7;
}else{
continue;
}
x = strrchr(x, ' ');
if( x==0 ) continue;
iLast = strtoll(x+1, 0, 10);
*x = 0;
x = strrchr(p, ' ');
if( x==0 ) continue;
iFirst = strtoll(x+1, 0, 10);
if( iLast>=PENDING_BYTE ){
if( iFirst<=PENDING_BYTE && iLast>=PENDING_BYTE ) a[0] = cType;
if( iFirst<=PENDING_BYTE+1 && iLast>=PENDING_BYTE+1 ) a[1] = cType;
if( iFirst<=PENDING_BYTE+2 && iLast>=PENDING_BYTE+510 ) a[2] = cType;
}else if( iLast<=128 ){
if( iFirst<=128 && iLast>=128 ) a[4] = cType;
if( iFirst<=120 && iLast>=120 ) a[6] = cType;
if( iFirst<=121 && iLast>=121 ) a[7] = cType;
if( iFirst<=122 && iLast>=122 ) a[8] = cType;
if( iFirst<=123 && iLast>=123 ) a[10] = cType;
if( iFirst<=124 && iLast>=124 ) a[11] = cType;
if( iFirst<=125 && iLast>=125 ) a[12] = cType;
if( iFirst<=126 && iLast>=126 ) a[13] = cType;
if( iFirst<=127 && iLast>=127 ) a[14] = cType;
}
}
return SQLITE_OK;
}
#else
# define unixPosixAdvisoryLocks(A,B) SQLITE_ERROR_UNABLE
#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
/*
** On some systems, calls to fchown() will trigger a message in a security
** log if they come from non-root processes. So avoid calling fchown() if
** we are not running as root.
*/
static int robustFchown(int fd, uid_t uid, gid_t gid){
#if defined(HAVE_FCHOWN)
|
| ︙ | ︙ | |||
40731 40732 40733 40734 40735 40736 40737 40738 40739 40740 40741 40742 40743 40744 |
}else
#endif
rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile);
}
return rc;
}
/*
** Lock the file with the lock specified by parameter eFileLock - one
** of the following:
**
** (1) SHARED_LOCK
** (2) RESERVED_LOCK
** (3) PENDING_LOCK
| > > > > > > > | 41089 41090 41091 41092 41093 41094 41095 41096 41097 41098 41099 41100 41101 41102 41103 41104 41105 41106 41107 41108 41109 |
}else
#endif
rc = osSetPosixAdvisoryLock(pFile->h, pLock, pFile);
}
return rc;
}
#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL)
/* Forward reference */
static int unixIsSharingShmNode(unixFile*);
#else
#define unixIsSharingShmNode(pFile) (0)
#endif
/*
** Lock the file with the lock specified by parameter eFileLock - one
** of the following:
**
** (1) SHARED_LOCK
** (2) RESERVED_LOCK
** (3) PENDING_LOCK
|
| ︙ | ︙ | |||
40919 40920 40921 40922 40923 40924 40925 |
}
goto end_lock;
}else{
pFile->eFileLock = SHARED_LOCK;
pInode->nLock++;
pInode->nShared = 1;
}
| | > > | 41284 41285 41286 41287 41288 41289 41290 41291 41292 41293 41294 41295 41296 41297 41298 41299 41300 |
}
goto end_lock;
}else{
pFile->eFileLock = SHARED_LOCK;
pInode->nLock++;
pInode->nShared = 1;
}
}else if( (eFileLock==EXCLUSIVE_LOCK && pInode->nShared>1)
|| unixIsSharingShmNode(pFile)
){
/* We are trying for an exclusive lock but another thread in this
** same process is still holding a shared lock. */
rc = SQLITE_BUSY;
}else{
/* The request was for a RESERVED or EXCLUSIVE lock. It is
** assumed that there is a SHARED or greater lock on the file
** already.
|
| ︙ | ︙ | |||
43014 43015 43016 43017 43018 43019 43020 43021 43022 43023 43024 43025 43026 43027 |
}
/* Forward declaration */
static int unixGetTempname(int nBuf, char *zBuf);
#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL)
static int unixFcntlExternalReader(unixFile*, int*);
#endif
/*
** Information and control of an open file handle.
*/
static int unixFileControl(sqlite3_file *id, int op, void *pArg){
unixFile *pFile = (unixFile*)id;
switch( op ){
| > > > > | 43381 43382 43383 43384 43385 43386 43387 43388 43389 43390 43391 43392 43393 43394 43395 43396 43397 43398 |
}
/* Forward declaration */
static int unixGetTempname(int nBuf, char *zBuf);
#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL)
static int unixFcntlExternalReader(unixFile*, int*);
#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
static void unixDescribeShm(sqlite3_str*,unixShm*);
#endif
/*
** Information and control of an open file handle.
*/
static int unixFileControl(sqlite3_file *id, int op, void *pArg){
unixFile *pFile = (unixFile*)id;
switch( op ){
|
| ︙ | ︙ | |||
43156 43157 43158 43159 43160 43161 43162 43163 43164 43165 43166 43167 43168 43169 |
#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL)
return unixFcntlExternalReader((unixFile*)id, (int*)pArg);
#else
*(int*)pArg = 0;
return SQLITE_OK;
#endif
}
}
return SQLITE_NOTFOUND;
}
/*
** If pFd->sectorSize is non-zero when this function is called, it is a
** no-op. Otherwise, the values of pFd->sectorSize and
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 43527 43528 43529 43530 43531 43532 43533 43534 43535 43536 43537 43538 43539 43540 43541 43542 43543 43544 43545 43546 43547 43548 43549 43550 43551 43552 43553 43554 43555 43556 43557 43558 43559 43560 43561 43562 43563 43564 43565 43566 43567 43568 43569 43570 43571 43572 43573 43574 43575 43576 43577 43578 43579 43580 43581 43582 43583 43584 43585 43586 43587 43588 43589 43590 43591 43592 43593 43594 43595 43596 43597 43598 43599 43600 |
#if !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL)
return unixFcntlExternalReader((unixFile*)id, (int*)pArg);
#else
*(int*)pArg = 0;
return SQLITE_OK;
#endif
}
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
case SQLITE_FCNTL_FILESTAT: {
sqlite3_str *pStr = (sqlite3_str*)pArg;
char aLck[16];
unixInodeInfo *pInode;
static const char *azLock[] = { "SHARED", "RESERVED",
"PENDING", "EXCLUSIVE" };
sqlite3_str_appendf(pStr, "{\"h\":%d", pFile->h);
sqlite3_str_appendf(pStr, ",\"vfs\":\"%s\"", pFile->pVfs->zName);
if( pFile->eFileLock ){
sqlite3_str_appendf(pStr, ",\"eFileLock\":\"%s\"",
azLock[pFile->eFileLock-1]);
if( unixPosixAdvisoryLocks(pFile->h, aLck)==SQLITE_OK ){
sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
}
}
unixEnterMutex();
if( pFile->pShm ){
sqlite3_str_appendall(pStr, ",\"shm\":");
unixDescribeShm(pStr, pFile->pShm);
}
#if SQLITE_MAX_MMAP_SIZE>0
if( pFile->mmapSize ){
sqlite3_str_appendf(pStr, ",\"mmapSize\":%lld", pFile->mmapSize);
sqlite3_str_appendf(pStr, ",\"nFetchOut\":%d", pFile->nFetchOut);
}
#endif
if( (pInode = pFile->pInode)!=0 ){
sqlite3_str_appendf(pStr, ",\"inode\":{\"nRef\":%d",pInode->nRef);
sqlite3_mutex_enter(pInode->pLockMutex);
sqlite3_str_appendf(pStr, ",\"nShared\":%d", pInode->nShared);
if( pInode->eFileLock ){
sqlite3_str_appendf(pStr, ",\"eFileLock\":\"%s\"",
azLock[pInode->eFileLock-1]);
}
if( pInode->pUnused ){
char cSep = '[';
UnixUnusedFd *pUFd = pFile->pInode->pUnused;
sqlite3_str_appendall(pStr, ",\"unusedFd\":");
while( pUFd ){
sqlite3_str_appendf(pStr, "%c{\"fd\":%d,\"flags\":%d",
cSep, pUFd->fd, pUFd->flags);
cSep = ',';
if( unixPosixAdvisoryLocks(pUFd->fd, aLck)==SQLITE_OK ){
sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
}
sqlite3_str_append(pStr, "}", 1);
pUFd = pUFd->pNext;
}
sqlite3_str_append(pStr, "]", 1);
}
sqlite3_mutex_leave(pInode->pLockMutex);
sqlite3_str_append(pStr, "}", 1);
}
unixLeaveMutex();
sqlite3_str_append(pStr, "}", 1);
return SQLITE_OK;
}
#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
}
return SQLITE_NOTFOUND;
}
/*
** If pFd->sectorSize is non-zero when this function is called, it is a
** no-op. Otherwise, the values of pFd->sectorSize and
|
| ︙ | ︙ | |||
43422 43423 43424 43425 43426 43427 43428 43429 43430 43431 43432 43433 43434 43435 | /* ** Constants used for locking */ #define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */ #define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */ /* ** Use F_GETLK to check whether or not there are any readers with open ** wal-mode transactions in other processes on database file pFile. If ** no error occurs, return SQLITE_OK and set (*piOut) to 1 if there are ** such transactions, or 0 otherwise. If an error occurs, return an ** SQLite error code. The final value of *piOut is undefined in this ** case. | > > > > > > > > > > > > > > > > > > > > | 43853 43854 43855 43856 43857 43858 43859 43860 43861 43862 43863 43864 43865 43866 43867 43868 43869 43870 43871 43872 43873 43874 43875 43876 43877 43878 43879 43880 43881 43882 43883 43884 43885 43886 |
/*
** Constants used for locking
*/
#define UNIX_SHM_BASE ((22+SQLITE_SHM_NLOCK)*4) /* first lock byte */
#define UNIX_SHM_DMS (UNIX_SHM_BASE+SQLITE_SHM_NLOCK) /* deadman switch */
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
/*
** Describe the pShm object using JSON. Used for diagnostics only.
*/
static void unixDescribeShm(sqlite3_str *pStr, unixShm *pShm){
unixShmNode *pNode = pShm->pShmNode;
char aLck[16];
sqlite3_str_appendf(pStr, "{\"h\":%d", pNode->hShm);
assert( unixMutexHeld() );
sqlite3_str_appendf(pStr, ",\"nRef\":%d", pNode->nRef);
sqlite3_str_appendf(pStr, ",\"id\":%d", pShm->id);
sqlite3_str_appendf(pStr, ",\"sharedMask\":%d", pShm->sharedMask);
sqlite3_str_appendf(pStr, ",\"exclMask\":%d", pShm->exclMask);
if( unixPosixAdvisoryLocks(pNode->hShm, aLck)==SQLITE_OK ){
sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
}
sqlite3_str_append(pStr, "}", 1);
}
#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
/*
** Use F_GETLK to check whether or not there are any readers with open
** wal-mode transactions in other processes on database file pFile. If
** no error occurs, return SQLITE_OK and set (*piOut) to 1 if there are
** such transactions, or 0 otherwise. If an error occurs, return an
** SQLite error code. The final value of *piOut is undefined in this
** case.
|
| ︙ | ︙ | |||
43455 43456 43457 43458 43459 43460 43461 43462 43463 43464 43465 43466 43467 43468 |
}
sqlite3_mutex_leave(pShmNode->pShmMutex);
}
return rc;
}
/*
** Apply posix advisory locks for all bytes from ofst through ofst+n-1.
**
** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking
** otherwise.
*/
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 43906 43907 43908 43909 43910 43911 43912 43913 43914 43915 43916 43917 43918 43919 43920 43921 43922 43923 43924 43925 43926 43927 43928 43929 43930 43931 43932 43933 43934 43935 43936 43937 43938 43939 43940 43941 43942 43943 43944 43945 43946 43947 43948 43949 43950 43951 43952 43953 43954 43955 43956 43957 43958 43959 43960 43961 43962 |
}
sqlite3_mutex_leave(pShmNode->pShmMutex);
}
return rc;
}
/*
** If pFile has a -shm file open and it is sharing that file with some
** other connection, either in the same process or in a separate process,
** then return true. Return false if either pFile does not have a -shm
** file open or if it is the only connection to that -shm file across the
** entire system.
**
** This routine is not required for correct operation. It can always return
** false and SQLite will continue to operate according to spec. However,
** when this routine does its job, it adds extra robustness in cases
** where database file locks have been erroneously deleted in a WAL-mode
** database by doing close(open(DATABASE_PATHNAME)) or similar.
**
** With false negatives, SQLite still operates to spec, though with less
** robustness. With false positives, the last database connection on a
** WAL-mode database will fail to unlink the -wal and -shm files, which
** is annoying but harmless. False positives will also prevent a database
** connection from running "PRAGMA journal_mode=DELETE" in order to take
** the database out of WAL mode, which is perhaps more serious, but is
** still not a disaster.
*/
static int unixIsSharingShmNode(unixFile *pFile){
int rc;
unixShmNode *pShmNode;
if( pFile->pShm==0 ) return 0;
if( pFile->ctrlFlags & UNIXFILE_EXCL ) return 0;
pShmNode = pFile->pShm->pShmNode;
rc = 1;
unixEnterMutex();
if( ALWAYS(pShmNode->nRef==1) ){
struct flock lock;
lock.l_whence = SEEK_SET;
lock.l_start = UNIX_SHM_DMS;
lock.l_len = 1;
lock.l_type = F_WRLCK;
osFcntl(pShmNode->hShm, F_GETLK, &lock);
if( lock.l_type==F_UNLCK ){
rc = 0;
}
}
unixLeaveMutex();
return rc;
}
/*
** Apply posix advisory locks for all bytes from ofst through ofst+n-1.
**
** Locks block if the mask is exactly UNIX_SHM_C and are non-blocking
** otherwise.
*/
|
| ︙ | ︙ | |||
43500 43501 43502 43503 43504 43505 43506 | } /* Shared locks never span more than one byte */ assert( n==1 || lockType!=F_RDLCK ); /* Locks are within range */ assert( n>=1 && n<=SQLITE_SHM_NLOCK ); | | > | 43994 43995 43996 43997 43998 43999 44000 44001 44002 44003 44004 44005 44006 44007 44008 44009 |
}
/* Shared locks never span more than one byte */
assert( n==1 || lockType!=F_RDLCK );
/* Locks are within range */
assert( n>=1 && n<=SQLITE_SHM_NLOCK );
assert( ofst>=UNIX_SHM_BASE && ofst<=UNIX_SHM_DMS );
assert( ofst+n-1<=UNIX_SHM_DMS );
if( pShmNode->hShm>=0 ){
int res;
/* Initialize the locking parameters */
f.l_type = lockType;
f.l_whence = SEEK_SET;
f.l_start = ofst;
|
| ︙ | ︙ | |||
44032 44033 44034 44035 44036 44037 44038 |
}
}
assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) );
return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0);
#endif
}
| | | 44527 44528 44529 44530 44531 44532 44533 44534 44535 44536 44537 44538 44539 44540 44541 |
}
}
assert( 0==memcmp(pShmNode->aLock, aLock, sizeof(aLock)) );
return (memcmp(pShmNode->aLock, aLock, sizeof(aLock))==0);
#endif
}
#endif /* !defined(SQLITE_WASI) && !defined(SQLITE_OMIT_WAL) */
/*
** Change the lock state for a shared-memory segment.
**
** Note that the relationship between SHARED and EXCLUSIVE locks is a little
** different here than in posix. In xShmLock(), one can go from unlocked
** to shared and back or from unlocked to exclusive and back. But one may
|
| ︙ | ︙ | |||
50016 50017 50018 50019 50020 50021 50022 50023 50024 50025 50026 50027 50028 50029 |
return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
numBytesHigh);
#endif
}
#endif
}
/*
** Lock a region of nByte bytes starting at offset offset of file hFile.
** Take an EXCLUSIVE lock if parameter bExclusive is true, or a SHARED lock
** otherwise. If nMs is greater than zero and the lock cannot be obtained
** immediately, block for that many ms before giving up.
**
** This function returns SQLITE_OK if the lock is obtained successfully. If
| > | 50511 50512 50513 50514 50515 50516 50517 50518 50519 50520 50521 50522 50523 50524 50525 |
return osLockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
numBytesHigh);
#endif
}
#endif
}
#ifndef SQLITE_OMIT_WAL
/*
** Lock a region of nByte bytes starting at offset offset of file hFile.
** Take an EXCLUSIVE lock if parameter bExclusive is true, or a SHARED lock
** otherwise. If nMs is greater than zero and the lock cannot be obtained
** immediately, block for that many ms before giving up.
**
** This function returns SQLITE_OK if the lock is obtained successfully. If
|
| ︙ | ︙ | |||
50098 50099 50100 50101 50102 50103 50104 50105 50106 50107 50108 50109 50110 50111 |
}
if( rc==SQLITE_OK && !ret ){
rc = SQLITE_BUSY;
}
return rc;
}
/*
** Unlock a file region.
*/
static BOOL winUnlockFile(
LPHANDLE phFile,
DWORD offsetLow,
| > | 50594 50595 50596 50597 50598 50599 50600 50601 50602 50603 50604 50605 50606 50607 50608 |
}
if( rc==SQLITE_OK && !ret ){
rc = SQLITE_BUSY;
}
return rc;
}
#endif /* #ifndef SQLITE_OMIT_WAL */
/*
** Unlock a file region.
*/
static BOOL winUnlockFile(
LPHANDLE phFile,
DWORD offsetLow,
|
| ︙ | ︙ | |||
50132 50133 50134 50135 50136 50137 50138 50139 50140 50141 50142 50143 50144 50145 50146 50147 50148 50149 50150 50151 50152 |
return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
numBytesHigh);
#endif
}
#endif
}
/*
** Remove an nByte lock starting at offset iOff from HANDLE h.
*/
static int winHandleUnlock(HANDLE h, int iOff, int nByte){
BOOL ret = winUnlockFile(&h, iOff, 0, nByte, 0);
return (ret ? SQLITE_OK : SQLITE_IOERR_UNLOCK);
}
/*****************************************************************************
** The next group of routines implement the I/O methods specified
** by the sqlite3_io_methods object.
******************************************************************************/
/*
| > > | 50629 50630 50631 50632 50633 50634 50635 50636 50637 50638 50639 50640 50641 50642 50643 50644 50645 50646 50647 50648 50649 50650 50651 |
return osUnlockFile(*phFile, offsetLow, offsetHigh, numBytesLow,
numBytesHigh);
#endif
}
#endif
}
#ifndef SQLITE_OMIT_WAL
/*
** Remove an nByte lock starting at offset iOff from HANDLE h.
*/
static int winHandleUnlock(HANDLE h, int iOff, int nByte){
BOOL ret = winUnlockFile(&h, iOff, 0, nByte, 0);
return (ret ? SQLITE_OK : SQLITE_IOERR_UNLOCK);
}
#endif
/*****************************************************************************
** The next group of routines implement the I/O methods specified
** by the sqlite3_io_methods object.
******************************************************************************/
/*
|
| ︙ | ︙ | |||
50476 50477 50478 50479 50480 50481 50482 50483 50484 50485 50486 50487 50488 50489 |
winLogIoerr(nRetry, __LINE__);
}
OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_OK;
}
/*
** Truncate the file opened by handle h to nByte bytes in size.
*/
static int winHandleTruncate(HANDLE h, sqlite3_int64 nByte){
int rc = SQLITE_OK; /* Return code */
rc = winHandleSeek(h, nByte);
if( rc==SQLITE_OK ){
| > | 50975 50976 50977 50978 50979 50980 50981 50982 50983 50984 50985 50986 50987 50988 50989 |
winLogIoerr(nRetry, __LINE__);
}
OSTRACE(("WRITE pid=%lu, pFile=%p, file=%p, rc=SQLITE_OK\n",
osGetCurrentProcessId(), pFile, pFile->h));
return SQLITE_OK;
}
#ifndef SQLITE_OMIT_WAL
/*
** Truncate the file opened by handle h to nByte bytes in size.
*/
static int winHandleTruncate(HANDLE h, sqlite3_int64 nByte){
int rc = SQLITE_OK; /* Return code */
rc = winHandleSeek(h, nByte);
if( rc==SQLITE_OK ){
|
| ︙ | ︙ | |||
50529 50530 50531 50532 50533 50534 50535 50536 50537 50538 50539 50540 50541 50542 |
** Close the handle passed as the only argument.
*/
static void winHandleClose(HANDLE h){
if( h!=INVALID_HANDLE_VALUE ){
osCloseHandle(h);
}
}
/*
** Truncate an open file to a specified size
*/
static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
winFile *pFile = (winFile*)id; /* File handle object */
int rc = SQLITE_OK; /* Return code for this function */
| > | 51029 51030 51031 51032 51033 51034 51035 51036 51037 51038 51039 51040 51041 51042 51043 |
** Close the handle passed as the only argument.
*/
static void winHandleClose(HANDLE h){
if( h!=INVALID_HANDLE_VALUE ){
osCloseHandle(h);
}
}
#endif /* #ifndef SQLITE_OMIT_WAL */
/*
** Truncate an open file to a specified size
*/
static int winTruncate(sqlite3_file *id, sqlite3_int64 nByte){
winFile *pFile = (winFile*)id; /* File handle object */
int rc = SQLITE_OK; /* Return code for this function */
|
| ︙ | ︙ | |||
51305 51306 51307 51308 51309 51310 51311 51312 51313 51314 51315 51316 51317 51318 |
}
case SQLITE_FCNTL_BLOCK_ON_CONNECT: {
int iNew = *(int*)pArg;
pFile->bBlockOnConnect = iNew;
return SQLITE_OK;
}
#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
}
OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
return SQLITE_NOTFOUND;
}
/*
| > > > > > > > > > > > > > > > > > > > > > > | 51806 51807 51808 51809 51810 51811 51812 51813 51814 51815 51816 51817 51818 51819 51820 51821 51822 51823 51824 51825 51826 51827 51828 51829 51830 51831 51832 51833 51834 51835 51836 51837 51838 51839 51840 51841 |
}
case SQLITE_FCNTL_BLOCK_ON_CONNECT: {
int iNew = *(int*)pArg;
pFile->bBlockOnConnect = iNew;
return SQLITE_OK;
}
#endif /* SQLITE_ENABLE_SETLK_TIMEOUT */
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
case SQLITE_FCNTL_FILESTAT: {
sqlite3_str *pStr = (sqlite3_str*)pArg;
sqlite3_str_appendf(pStr, "{\"h\":%llu", (sqlite3_uint64)pFile->h);
sqlite3_str_appendf(pStr, ",\"vfs\":\"%s\"", pFile->pVfs->zName);
if( pFile->locktype ){
static const char *azLock[] = { "SHARED", "RESERVED",
"PENDING", "EXCLUSIVE" };
sqlite3_str_appendf(pStr, ",\"locktype\":\"%s\"",
azLock[pFile->locktype-1]);
}
#if SQLITE_MAX_MMAP_SIZE>0
if( pFile->mmapSize ){
sqlite3_str_appendf(pStr, ",\"mmapSize\":%lld", pFile->mmapSize);
sqlite3_str_appendf(pStr, ",\"nFetchOut\":%d", pFile->nFetchOut);
}
#endif
sqlite3_str_append(pStr, "}", 1);
return SQLITE_OK;
}
#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
}
OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h));
return SQLITE_NOTFOUND;
}
/*
|
| ︙ | ︙ | |||
59268 59269 59270 59271 59272 59273 59274 59275 59276 59277 59278 59279 59280 59281 |
if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */
#ifndef SQLITE_OMIT_WAL
if( pPager->pWal ){
u32 iRead = 0;
(void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
if( iRead ) return 0; /* Case (4) */
}
#endif
assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 );
if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd)
& SQLITE_IOCAP_SUBPAGE_READ)==0 ){
return 0; /* Case (2) */
}
return 1;
| > > | 59791 59792 59793 59794 59795 59796 59797 59798 59799 59800 59801 59802 59803 59804 59805 59806 |
if( sqlite3PCacheIsDirty(pPager->pPCache) ) return 0; /* Failed (3) */
#ifndef SQLITE_OMIT_WAL
if( pPager->pWal ){
u32 iRead = 0;
(void)sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
if( iRead ) return 0; /* Case (4) */
}
#else
UNUSED_PARAMETER(pgno);
#endif
assert( pPager->fd->pMethods->xDeviceCharacteristics!=0 );
if( (pPager->fd->pMethods->xDeviceCharacteristics(pPager->fd)
& SQLITE_IOCAP_SUBPAGE_READ)==0 ){
return 0; /* Case (2) */
}
return 1;
|
| ︙ | ︙ | |||
60311 60312 60313 60314 60315 60316 60317 |
if( pPager->eState==PAGER_ERROR ){
/* If an IO error occurs in wal.c while attempting to wrap the wal file,
** then the Wal object may be holding a write-lock but no read-lock.
** This call ensures that the write-lock is dropped as well. We cannot
** have sqlite3WalEndReadTransaction() drop the write-lock, as it once
** did, because this would break "BEGIN EXCLUSIVE" handling for
** SQLITE_ENABLE_SETLK_TIMEOUT builds. */
| | | 60836 60837 60838 60839 60840 60841 60842 60843 60844 60845 60846 60847 60848 60849 60850 |
if( pPager->eState==PAGER_ERROR ){
/* If an IO error occurs in wal.c while attempting to wrap the wal file,
** then the Wal object may be holding a write-lock but no read-lock.
** This call ensures that the write-lock is dropped as well. We cannot
** have sqlite3WalEndReadTransaction() drop the write-lock, as it once
** did, because this would break "BEGIN EXCLUSIVE" handling for
** SQLITE_ENABLE_SETLK_TIMEOUT builds. */
(void)sqlite3WalEndWriteTransaction(pPager->pWal);
}
sqlite3WalEndReadTransaction(pPager->pWal);
pPager->eState = PAGER_OPEN;
}else if( !pPager->exclusiveMode ){
int rc; /* Error code returned by pagerUnlockDb() */
int iDc = isOpen(pPager->fd)?sqlite3OsDeviceCharacteristics(pPager->fd):0;
|
| ︙ | ︙ | |||
62647 62648 62649 62650 62651 62652 62653 62654 62655 62656 62657 62658 62659 62660 |
&& SQLITE_OK==databaseIsUnmoved(pPager)
){
a = pTmp;
}
sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a);
pPager->pWal = 0;
}
#endif
pager_reset(pPager);
if( MEMDB ){
pager_unlock(pPager);
}else{
/* If it is open, sync the journal file before calling UnlockAndRollback.
** If this is not done, then an unsynced portion of the open journal
| > > | 63172 63173 63174 63175 63176 63177 63178 63179 63180 63181 63182 63183 63184 63185 63186 63187 |
&& SQLITE_OK==databaseIsUnmoved(pPager)
){
a = pTmp;
}
sqlite3WalClose(pPager->pWal, db, pPager->walSyncFlags, pPager->pageSize,a);
pPager->pWal = 0;
}
#else
UNUSED_PARAMETER(db);
#endif
pager_reset(pPager);
if( MEMDB ){
pager_unlock(pPager);
}else{
/* If it is open, sync the journal file before calling UnlockAndRollback.
** If this is not done, then an unsynced portion of the open journal
|
| ︙ | ︙ | |||
66890 66891 66892 66893 66894 66895 66896 |
int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */
int iZero; /* Frame number associated with aPgno[0] */
} aSegment[FLEXARRAY]; /* One for every 32KB page in the wal-index */
};
/* Size (in bytes) of a WalIterator object suitable for N or fewer segments */
#define SZ_WALITERATOR(N) \
| | | 67417 67418 67419 67420 67421 67422 67423 67424 67425 67426 67427 67428 67429 67430 67431 |
int nEntry; /* Nr. of entries in aPgno[] and aIndex[] */
int iZero; /* Frame number associated with aPgno[0] */
} aSegment[FLEXARRAY]; /* One for every 32KB page in the wal-index */
};
/* Size (in bytes) of a WalIterator object suitable for N or fewer segments */
#define SZ_WALITERATOR(N) \
(offsetof(WalIterator,aSegment)+(N)*sizeof(struct WalSegment))
/*
** Define the parameters of the hash tables in the wal-index file. There
** is a hash-table following every HASHTABLE_NPAGE page numbers in the
** wal-index.
**
** Changing any of these constants will alter the wal-index format and
|
| ︙ | ︙ | |||
69776 69777 69778 69779 69780 69781 69782 |
** read-lock.
*/
SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){
#ifndef SQLITE_ENABLE_SETLK_TIMEOUT
assert( pWal->writeLock==0 || pWal->readLock<0 );
#endif
if( pWal->readLock>=0 ){
| | | 70303 70304 70305 70306 70307 70308 70309 70310 70311 70312 70313 70314 70315 70316 70317 |
** read-lock.
*/
SQLITE_PRIVATE void sqlite3WalEndReadTransaction(Wal *pWal){
#ifndef SQLITE_ENABLE_SETLK_TIMEOUT
assert( pWal->writeLock==0 || pWal->readLock<0 );
#endif
if( pWal->readLock>=0 ){
(void)sqlite3WalEndWriteTransaction(pWal);
walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
pWal->readLock = -1;
}
}
/*
** Search the wal file for page pgno. If found, set *piRead to the frame that
|
| ︙ | ︙ | |||
70683 70684 70685 70686 70687 70688 70689 |
memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
}
walDisableBlocking(pWal);
sqlite3WalDb(pWal, 0);
/* Release the locks. */
| | | 71210 71211 71212 71213 71214 71215 71216 71217 71218 71219 71220 71221 71222 71223 71224 |
memset(&pWal->hdr, 0, sizeof(WalIndexHdr));
}
walDisableBlocking(pWal);
sqlite3WalDb(pWal, 0);
/* Release the locks. */
(void)sqlite3WalEndWriteTransaction(pWal);
if( pWal->ckptLock ){
walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1);
pWal->ckptLock = 0;
}
WALTRACE(("WAL%p: checkpoint %s\n", pWal, rc ? "failed" : "ok"));
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
if( rc==SQLITE_BUSY_TIMEOUT ) rc = SQLITE_BUSY;
|
| ︙ | ︙ | |||
75640 75641 75642 75643 75644 75645 75646 75647 75648 75649 75650 75651 75652 75653 |
** block for the WRITER lock first if possible. */
if( pBt->pPage1==0 && wrflag ){
assert( pBt->inTransaction==TRANS_NONE );
rc = sqlite3PagerWalWriteLock(pPager, 1);
if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break;
}
#endif
/* Call lockBtree() until either pBt->pPage1 is populated or
** lockBtree() returns something other than SQLITE_OK. lockBtree()
** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
** reading page 1 it discovers that the page-size of the database
** file is not pBt->pageSize. In this case lockBtree() will update
** pBt->pageSize to the page-size of the file on disk.
| > > > > > > > > > > > > > > > > > > > > > > > > | 76167 76168 76169 76170 76171 76172 76173 76174 76175 76176 76177 76178 76179 76180 76181 76182 76183 76184 76185 76186 76187 76188 76189 76190 76191 76192 76193 76194 76195 76196 76197 76198 76199 76200 76201 76202 76203 76204 |
** block for the WRITER lock first if possible. */
if( pBt->pPage1==0 && wrflag ){
assert( pBt->inTransaction==TRANS_NONE );
rc = sqlite3PagerWalWriteLock(pPager, 1);
if( rc!=SQLITE_BUSY && rc!=SQLITE_OK ) break;
}
#endif
#ifdef SQLITE_EXPERIMENTAL_PRAGMA_20251114
/* If both a read and write transaction will be opened by this call,
** then issue a file-control as if the following pragma command had
** been evaluated:
**
** PRAGMA experimental_pragma_20251114 = 1|2
**
** where the RHS is "1" if wrflag is 1 (RESERVED lock), or "2" if wrflag
** is 2 (EXCLUSIVE lock). Ignore any result or error returned by the VFS.
**
** WARNING: This code will likely remain part of SQLite only temporarily -
** it exists to allow users to experiment with certain types of blocking
** locks in custom VFS implementations. It MAY BE REMOVED AT ANY TIME. */
if( pBt->pPage1==0 && wrflag ){
sqlite3_file *fd = sqlite3PagerFile(pPager);
char *aFcntl[3] = {0,0,0};
aFcntl[1] = "experimental_pragma_20251114";
assert( wrflag==1 || wrflag==2 );
aFcntl[2] = (wrflag==1 ? "1" : "2");
sqlite3OsFileControlHint(fd, SQLITE_FCNTL_PRAGMA, (void*)aFcntl);
sqlite3_free(aFcntl[0]);
}
#endif
/* Call lockBtree() until either pBt->pPage1 is populated or
** lockBtree() returns something other than SQLITE_OK. lockBtree()
** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
** reading page 1 it discovers that the page-size of the database
** file is not pBt->pageSize. In this case lockBtree() will update
** pBt->pageSize to the page-size of the file on disk.
|
| ︙ | ︙ | |||
81726 81727 81728 81729 81730 81731 81732 |
aIn += 4;
nIn = pSrc->pBt->usableSize - 4;
}
}
}while( rc==SQLITE_OK && nOut>0 );
if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){
| | | 82277 82278 82279 82280 82281 82282 82283 82284 82285 82286 82287 82288 82289 82290 82291 |
aIn += 4;
nIn = pSrc->pBt->usableSize - 4;
}
}
}while( rc==SQLITE_OK && nOut>0 );
if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){
Pgno pgnoNew = 0; /* Prevent harmless static-analyzer warning */
MemPage *pNew = 0;
rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
put4byte(pPgnoOut, pgnoNew);
if( ISAUTOVACUUM(pBt) && pPageOut ){
ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc);
}
releasePage(pPageOut);
|
| ︙ | ︙ | |||
85511 85512 85513 85514 85515 85516 85517 85518 85519 85520 85521 85522 85523 85524 |
}
testcase( nAlloc==0 );
testcase( nAlloc==31 );
testcase( nAlloc==32 );
if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){
return SQLITE_NOMEM_BKPT;
}
memcpy(pMem->z, z, nAlloc);
}else{
sqlite3VdbeMemRelease(pMem);
pMem->z = (char *)z;
if( xDel==SQLITE_DYNAMIC ){
pMem->zMalloc = pMem->z;
pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
| > | 86062 86063 86064 86065 86066 86067 86068 86069 86070 86071 86072 86073 86074 86075 86076 |
}
testcase( nAlloc==0 );
testcase( nAlloc==31 );
testcase( nAlloc==32 );
if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){
return SQLITE_NOMEM_BKPT;
}
assert( pMem->z!=0 );
memcpy(pMem->z, z, nAlloc);
}else{
sqlite3VdbeMemRelease(pMem);
pMem->z = (char *)z;
if( xDel==SQLITE_DYNAMIC ){
pMem->zMalloc = pMem->z;
pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc);
|
| ︙ | ︙ | |||
91882 91883 91884 91885 91886 91887 91888 |
|| (pCsr->nField==nRealCol+1 && op==SQLITE_DELETE && iReg==-1)
);
preupdate.v = v;
preupdate.pCsr = pCsr;
preupdate.op = op;
preupdate.iNewReg = iReg;
| | | 92434 92435 92436 92437 92438 92439 92440 92441 92442 92443 92444 92445 92446 92447 92448 |
|| (pCsr->nField==nRealCol+1 && op==SQLITE_DELETE && iReg==-1)
);
preupdate.v = v;
preupdate.pCsr = pCsr;
preupdate.op = op;
preupdate.iNewReg = iReg;
preupdate.pKeyinfo = (KeyInfo*)&preupdate.uKey;
preupdate.pKeyinfo->db = db;
preupdate.pKeyinfo->enc = ENC(db);
preupdate.pKeyinfo->nKeyField = pTab->nCol;
preupdate.pKeyinfo->aSortFlags = 0; /* Indicate .aColl, .nAllField uninit */
preupdate.iKey1 = iKey1;
preupdate.iKey2 = iKey2;
preupdate.pTab = pTab;
|
| ︙ | ︙ | |||
91916 91917 91918 91919 91920 91921 91922 91923 91924 91925 91926 91927 91928 91929 |
sqlite3ValueFree(preupdate.apDflt[i]);
}
sqlite3DbFree(db, preupdate.apDflt);
}
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
/************** End of vdbeaux.c *********************************************/
/************** Begin file vdbeapi.c *****************************************/
/*
** 2004 May 26
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
| > > > > > > > > > > > | 92468 92469 92470 92471 92472 92473 92474 92475 92476 92477 92478 92479 92480 92481 92482 92483 92484 92485 92486 92487 92488 92489 92490 92491 92492 |
sqlite3ValueFree(preupdate.apDflt[i]);
}
sqlite3DbFree(db, preupdate.apDflt);
}
}
#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */
#ifdef SQLITE_ENABLE_PERCENTILE
/*
** Return the name of an SQL function associated with the sqlite3_context.
*/
SQLITE_PRIVATE const char *sqlite3VdbeFuncName(const sqlite3_context *pCtx){
assert( pCtx!=0 );
assert( pCtx->pFunc!=0 );
return pCtx->pFunc->zName;
}
#endif /* SQLITE_ENABLE_PERCENTILE */
/************** End of vdbeaux.c *********************************************/
/************** Begin file vdbeapi.c *****************************************/
/*
** 2004 May 26
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
|
| ︙ | ︙ | |||
92656 92657 92658 92659 92660 92661 92662 92663 92664 92665 92666 92667 92668 92669 |
nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
sqlite3BtreeLeave(pBt);
if( nEntry>0 && db->xWalCallback && rc==SQLITE_OK ){
rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry);
}
}
}
#endif
return rc;
}
/*
** Execute the statement pStmt, either until a row of data is ready, the
| > > | 93219 93220 93221 93222 93223 93224 93225 93226 93227 93228 93229 93230 93231 93232 93233 93234 |
nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt));
sqlite3BtreeLeave(pBt);
if( nEntry>0 && db->xWalCallback && rc==SQLITE_OK ){
rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zDbSName, nEntry);
}
}
}
#else
UNUSED_PARAMETER(db);
#endif
return rc;
}
/*
** Execute the statement pStmt, either until a row of data is ready, the
|
| ︙ | ︙ | |||
93613 93614 93615 93616 93617 93618 93619 |
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
if( zData!=0 ){
pVar = &p->aVar[i-1];
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
| | > > > | > | 94178 94179 94180 94181 94182 94183 94184 94185 94186 94187 94188 94189 94190 94191 94192 94193 94194 94195 94196 94197 |
rc = vdbeUnbind(p, (u32)(i-1));
if( rc==SQLITE_OK ){
assert( p!=0 && p->aVar!=0 && i>0 && i<=p->nVar ); /* tag-20240917-01 */
if( zData!=0 ){
pVar = &p->aVar[i-1];
rc = sqlite3VdbeMemSetStr(pVar, zData, nData, encoding, xDel);
if( rc==SQLITE_OK ){
if( encoding==0 ){
pVar->enc = ENC(p->db);
}else{
rc = sqlite3VdbeChangeEncoding(pVar, ENC(p->db));
}
}
if( rc ){
sqlite3Error(p->db, rc);
rc = sqlite3ApiExit(p->db, rc);
}
}
sqlite3_mutex_leave(p->db->mutex);
|
| ︙ | ︙ | |||
94547 94548 94549 94550 94551 94552 94553 | /* ** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of ** bytes in this text up to but excluding the first character in ** a host parameter. If the text contains no host parameters, return ** the total number of bytes in the text. */ | | | | | 95116 95117 95118 95119 95120 95121 95122 95123 95124 95125 95126 95127 95128 95129 95130 95131 95132 95133 |
/*
** zSql is a zero-terminated string of UTF-8 SQL text. Return the number of
** bytes in this text up to but excluding the first character in
** a host parameter. If the text contains no host parameters, return
** the total number of bytes in the text.
*/
static i64 findNextHostParameter(const char *zSql, i64 *pnToken){
int tokenType;
i64 nTotal = 0;
i64 n;
*pnToken = 0;
while( zSql[0] ){
n = sqlite3GetToken((u8*)zSql, &tokenType);
assert( n>0 && tokenType!=TK_ILLEGAL );
if( tokenType==TK_VARIABLE ){
*pnToken = n;
|
| ︙ | ︙ | |||
94597 94598 94599 94600 94601 94602 94603 |
SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
Vdbe *p, /* The prepared statement being evaluated */
const char *zRawSql /* Raw text of the SQL statement */
){
sqlite3 *db; /* The database connection */
int idx = 0; /* Index of a host parameter */
int nextIndex = 1; /* Index of next ? host parameter */
| | | | 95166 95167 95168 95169 95170 95171 95172 95173 95174 95175 95176 95177 95178 95179 95180 95181 |
SQLITE_PRIVATE char *sqlite3VdbeExpandSql(
Vdbe *p, /* The prepared statement being evaluated */
const char *zRawSql /* Raw text of the SQL statement */
){
sqlite3 *db; /* The database connection */
int idx = 0; /* Index of a host parameter */
int nextIndex = 1; /* Index of next ? host parameter */
i64 n; /* Length of a token prefix */
i64 nToken; /* Length of the parameter token */
int i; /* Loop counter */
Mem *pVar; /* Value of a host parameter */
StrAccum out; /* Accumulate the output here */
#ifndef SQLITE_OMIT_UTF16
Mem utf8; /* Used to convert UTF16 into UTF8 for display */
#endif
|
| ︙ | ︙ | |||
94763 94764 94765 94766 94767 94768 94769 | ** ** This file contains inline asm code for retrieving "high-performance" ** counters for x86 and x86_64 class CPUs. */ #ifndef SQLITE_HWTIME_H #define SQLITE_HWTIME_H | > | < | > | | > > > > | | < > > > > > | > < < < < < < < < < < < | | | | | 95332 95333 95334 95335 95336 95337 95338 95339 95340 95341 95342 95343 95344 95345 95346 95347 95348 95349 95350 95351 95352 95353 95354 95355 95356 95357 95358 95359 95360 95361 95362 95363 95364 95365 95366 95367 95368 95369 95370 95371 95372 95373 95374 95375 95376 95377 95378 95379 |
**
** This file contains inline asm code for retrieving "high-performance"
** counters for x86 and x86_64 class CPUs.
*/
#ifndef SQLITE_HWTIME_H
#define SQLITE_HWTIME_H
#if defined(_MSC_VER) && defined(_WIN32)
/* #include "windows.h" */
#include <profileapi.h>
__inline sqlite3_uint64 sqlite3Hwtime(void){
LARGE_INTEGER tm;
QueryPerformanceCounter(&tm);
return (sqlite3_uint64)tm.QuadPart;
}
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && \
(defined(i386) || defined(__i386__) || defined(_M_IX86))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned int lo, hi;
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
return (sqlite_uint64)hi << 32 | lo;
}
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__x86_64__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned int lo, hi;
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
return (sqlite_uint64)hi << 32 | lo;
}
#elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__aarch64__)
__inline__ sqlite_uint64 sqlite3Hwtime(void){
sqlite3_uint64 cnt;
__asm__ __volatile__ ("mrs %0, cntvct_el0" : "=r" (cnt));
return cnt;
}
#elif !defined(__STRICT_ANSI__) && (defined(__GNUC__) && defined(__ppc__))
__inline__ sqlite_uint64 sqlite3Hwtime(void){
unsigned long long retval;
unsigned long junk;
|
| ︙ | ︙ | |||
95522 95523 95524 95525 95526 95527 95528 | ** the common case where all content fits on the page. Factoring out ** the code reduces register pressure and helps the common case ** to run faster. */ static SQLITE_NOINLINE int vdbeColumnFromOverflow( VdbeCursor *pC, /* The BTree cursor from which we are reading */ int iCol, /* The column to read */ | | | 96090 96091 96092 96093 96094 96095 96096 96097 96098 96099 96100 96101 96102 96103 96104 |
** the common case where all content fits on the page. Factoring out
** the code reduces register pressure and helps the common case
** to run faster.
*/
static SQLITE_NOINLINE int vdbeColumnFromOverflow(
VdbeCursor *pC, /* The BTree cursor from which we are reading */
int iCol, /* The column to read */
u32 t, /* The serial-type code for the column value */
i64 iOffset, /* Offset to the start of the content value */
u32 cacheStatus, /* Current Vdbe.cacheCtr value */
u32 colCacheCtr, /* Current value of the column cache counter */
Mem *pDest /* Store the value into this register. */
){
int rc;
sqlite3 *db = pDest->db;
|
| ︙ | ︙ | |||
96623 96624 96625 96626 96627 96628 96629 |
if( (flags2 & (MEM_Str|MEM_Blob))==0 ){
if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem;
flags2 = pIn2->flags & ~MEM_Str;
}else if( (flags2 & MEM_Zero)!=0 ){
if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem;
flags2 = pIn2->flags & ~MEM_Str;
}
| | > > > > | 97191 97192 97193 97194 97195 97196 97197 97198 97199 97200 97201 97202 97203 97204 97205 97206 97207 97208 97209 97210 97211 97212 |
if( (flags2 & (MEM_Str|MEM_Blob))==0 ){
if( sqlite3VdbeMemStringify(pIn2,encoding,0) ) goto no_mem;
flags2 = pIn2->flags & ~MEM_Str;
}else if( (flags2 & MEM_Zero)!=0 ){
if( sqlite3VdbeMemExpandBlob(pIn2) ) goto no_mem;
flags2 = pIn2->flags & ~MEM_Str;
}
nByte = pIn1->n;
nByte += pIn2->n;
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
goto too_big;
}
#if SQLITE_MAX_LENGTH>2147483645
if( nByte>2147483645 ){ goto too_big; }
#endif
if( sqlite3VdbeMemGrow(pOut, (int)nByte+2, pOut==pIn2) ){
goto no_mem;
}
MemSetTypeFlag(pOut, MEM_Str);
if( pOut!=pIn2 ){
memcpy(pOut->z, pIn2->z, pIn2->n);
assert( (pIn2->flags & MEM_Dyn) == (flags2 & MEM_Dyn) );
|
| ︙ | ︙ | |||
98448 98449 98450 98451 98452 98453 98454 |
pRec->uTemp = 7;
}else{
assert( db->mallocFailed || pRec->flags&(MEM_Str|MEM_Blob) );
assert( pRec->n>=0 );
len = (u32)pRec->n;
serial_type = (len*2) + 12 + ((pRec->flags & MEM_Str)!=0);
if( pRec->flags & MEM_Zero ){
| | | 99020 99021 99022 99023 99024 99025 99026 99027 99028 99029 99030 99031 99032 99033 99034 |
pRec->uTemp = 7;
}else{
assert( db->mallocFailed || pRec->flags&(MEM_Str|MEM_Blob) );
assert( pRec->n>=0 );
len = (u32)pRec->n;
serial_type = (len*2) + 12 + ((pRec->flags & MEM_Str)!=0);
if( pRec->flags & MEM_Zero ){
serial_type += (u32)pRec->u.nZero*2;
if( nData ){
if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
len += pRec->u.nZero;
}else{
nZero += pRec->u.nZero;
}
}
|
| ︙ | ︙ | |||
104965 104966 104967 104968 104969 104970 104971 104972 104973 104974 104975 104976 104977 104978 | int nPMA; /* Number of PMAs currently in file */ VdbeSorter *pSorter; /* Sorter that owns this sub-task */ UnpackedRecord *pUnpacked; /* Space to unpack a record */ SorterList list; /* List for thread to write to a PMA */ SorterCompare xCompare; /* Compare function to use */ SorterFile file; /* Temp file for level-0 PMAs */ SorterFile file2; /* Space for other PMAs */ }; /* ** Main sorter structure. A single instance of this is allocated for each ** sorter cursor created by the VDBE. ** | > | 105537 105538 105539 105540 105541 105542 105543 105544 105545 105546 105547 105548 105549 105550 105551 | int nPMA; /* Number of PMAs currently in file */ VdbeSorter *pSorter; /* Sorter that owns this sub-task */ UnpackedRecord *pUnpacked; /* Space to unpack a record */ SorterList list; /* List for thread to write to a PMA */ SorterCompare xCompare; /* Compare function to use */ SorterFile file; /* Temp file for level-0 PMAs */ SorterFile file2; /* Space for other PMAs */ u64 nSpill; /* Total bytes written by this task */ }; /* ** Main sorter structure. A single instance of this is allocated for each ** sorter cursor created by the VDBE. ** |
| ︙ | ︙ | |||
105085 105086 105087 105088 105089 105090 105091 105092 105093 105094 105095 105096 105097 105098 | int eFWErr; /* Non-zero if in an error state */ u8 *aBuffer; /* Pointer to write buffer */ int nBuffer; /* Size of write buffer in bytes */ int iBufStart; /* First byte of buffer to write */ int iBufEnd; /* Last byte of buffer to write */ i64 iWriteOff; /* Offset of start of buffer in file */ sqlite3_file *pFd; /* File handle to write to */ }; /* ** This object is the header on a single record while that record is being ** held in memory and prior to being written out as part of a PMA. ** ** How the linked list is connected depends on how memory is being managed | > | 105658 105659 105660 105661 105662 105663 105664 105665 105666 105667 105668 105669 105670 105671 105672 | int eFWErr; /* Non-zero if in an error state */ u8 *aBuffer; /* Pointer to write buffer */ int nBuffer; /* Size of write buffer in bytes */ int iBufStart; /* First byte of buffer to write */ int iBufEnd; /* Last byte of buffer to write */ i64 iWriteOff; /* Offset of start of buffer in file */ sqlite3_file *pFd; /* File handle to write to */ u64 nPmaSpill; /* Total number of bytes written */ }; /* ** This object is the header on a single record while that record is being ** held in memory and prior to being written out as part of a PMA. ** ** How the linked list is connected depends on how memory is being managed |
| ︙ | ︙ | |||
105943 105944 105945 105946 105947 105948 105949 105950 105951 105952 105953 105954 105955 105956 |
** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
*/
SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){
VdbeSorter *pSorter;
assert( pCsr->eCurType==CURTYPE_SORTER );
pSorter = pCsr->uc.pSorter;
if( pSorter ){
sqlite3VdbeSorterReset(db, pSorter);
sqlite3_free(pSorter->list.aMemory);
sqlite3DbFree(db, pSorter);
pCsr->uc.pSorter = 0;
}
}
| > > > > > > | 106517 106518 106519 106520 106521 106522 106523 106524 106525 106526 106527 106528 106529 106530 106531 106532 106533 106534 106535 106536 |
** Free any cursor components allocated by sqlite3VdbeSorterXXX routines.
*/
SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *db, VdbeCursor *pCsr){
VdbeSorter *pSorter;
assert( pCsr->eCurType==CURTYPE_SORTER );
pSorter = pCsr->uc.pSorter;
if( pSorter ){
/* Increment db->nSpill by the total number of bytes of data written
** to temp files by this sort operation. */
int ii;
for(ii=0; ii<pSorter->nTask; ii++){
db->nSpill += pSorter->aTask[ii].nSpill;
}
sqlite3VdbeSorterReset(db, pSorter);
sqlite3_free(pSorter->list.aMemory);
sqlite3DbFree(db, pSorter);
pCsr->uc.pSorter = 0;
}
}
|
| ︙ | ︙ | |||
106168 106169 106170 106171 106172 106173 106174 106175 106176 106177 106178 106179 106180 106181 106182 106183 106184 106185 106186 106187 106188 106189 106190 |
memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy);
p->iBufEnd += nCopy;
if( p->iBufEnd==p->nBuffer ){
p->eFWErr = sqlite3OsWrite(p->pFd,
&p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart,
p->iWriteOff + p->iBufStart
);
p->iBufStart = p->iBufEnd = 0;
p->iWriteOff += p->nBuffer;
}
assert( p->iBufEnd<p->nBuffer );
nRem -= nCopy;
}
}
/*
** Flush any buffered data to disk and clean up the PMA-writer object.
** The results of using the PMA-writer after this call are undefined.
** Return SQLITE_OK if flushing the buffered data succeeds or is not
** required. Otherwise, return an SQLite error code.
**
** Before returning, set *piEof to the offset immediately following the
| > | > | > > | 106748 106749 106750 106751 106752 106753 106754 106755 106756 106757 106758 106759 106760 106761 106762 106763 106764 106765 106766 106767 106768 106769 106770 106771 106772 106773 106774 106775 106776 106777 106778 106779 106780 106781 106782 106783 106784 106785 106786 106787 106788 106789 106790 106791 106792 |
memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy);
p->iBufEnd += nCopy;
if( p->iBufEnd==p->nBuffer ){
p->eFWErr = sqlite3OsWrite(p->pFd,
&p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart,
p->iWriteOff + p->iBufStart
);
p->nPmaSpill += (p->iBufEnd - p->iBufStart);
p->iBufStart = p->iBufEnd = 0;
p->iWriteOff += p->nBuffer;
}
assert( p->iBufEnd<p->nBuffer );
nRem -= nCopy;
}
}
/*
** Flush any buffered data to disk and clean up the PMA-writer object.
** The results of using the PMA-writer after this call are undefined.
** Return SQLITE_OK if flushing the buffered data succeeds or is not
** required. Otherwise, return an SQLite error code.
**
** Before returning, set *piEof to the offset immediately following the
** last byte written to the file. Also, increment (*pnSpill) by the total
** number of bytes written to the file.
*/
static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof, u64 *pnSpill){
int rc;
if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){
p->eFWErr = sqlite3OsWrite(p->pFd,
&p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart,
p->iWriteOff + p->iBufStart
);
p->nPmaSpill += (p->iBufEnd - p->iBufStart);
}
*piEof = (p->iWriteOff + p->iBufEnd);
*pnSpill += p->nPmaSpill;
sqlite3_free(p->aBuffer);
rc = p->eFWErr;
memset(p, 0, sizeof(PmaWriter));
return rc;
}
/*
|
| ︙ | ︙ | |||
106274 106275 106276 106277 106278 106279 106280 |
for(p=pList->pList; p; p=pNext){
pNext = p->u.pNext;
vdbePmaWriteVarint(&writer, p->nVal);
vdbePmaWriteBlob(&writer, SRVAL(p), p->nVal);
if( pList->aMemory==0 ) sqlite3_free(p);
}
pList->pList = p;
| | | 106858 106859 106860 106861 106862 106863 106864 106865 106866 106867 106868 106869 106870 106871 106872 |
for(p=pList->pList; p; p=pNext){
pNext = p->u.pNext;
vdbePmaWriteVarint(&writer, p->nVal);
vdbePmaWriteBlob(&writer, SRVAL(p), p->nVal);
if( pList->aMemory==0 ) sqlite3_free(p);
}
pList->pList = p;
rc = vdbePmaWriterFinish(&writer, &pTask->file.iEof, &pTask->nSpill);
}
vdbeSorterWorkDebug(pTask, "exit");
assert( rc!=SQLITE_OK || pList->pList==0 );
assert( rc!=SQLITE_OK || pTask->file.iEof==iSz );
return rc;
}
|
| ︙ | ︙ | |||
106588 106589 106590 106591 106592 106593 106594 |
/* Write the next key to the output. */
vdbePmaWriteVarint(&writer, nKey);
vdbePmaWriteBlob(&writer, pReader->aKey, nKey);
assert( pIncr->pMerger->pTask==pTask );
rc = vdbeMergeEngineStep(pIncr->pMerger, &dummy);
}
| | | 107172 107173 107174 107175 107176 107177 107178 107179 107180 107181 107182 107183 107184 107185 107186 |
/* Write the next key to the output. */
vdbePmaWriteVarint(&writer, nKey);
vdbePmaWriteBlob(&writer, pReader->aKey, nKey);
assert( pIncr->pMerger->pTask==pTask );
rc = vdbeMergeEngineStep(pIncr->pMerger, &dummy);
}
rc2 = vdbePmaWriterFinish(&writer, &pOut->iEof, &pTask->nSpill);
if( rc==SQLITE_OK ) rc = rc2;
vdbeSorterPopulateDebug(pTask, "exit");
return rc;
}
#if SQLITE_MAX_WORKER_THREADS>0
/*
|
| ︙ | ︙ | |||
108979 108980 108981 108982 108983 108984 108985 108986 108987 |
if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, &bRowid) ){
continue;
}
if( bRowid==0 ){
if( cnt>0 ){
if( pItem->fg.isUsing==0
|| sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0
){
/* Two or more tables have the same column name which is
| > | > > | | 109563 109564 109565 109566 109567 109568 109569 109570 109571 109572 109573 109574 109575 109576 109577 109578 109579 109580 109581 109582 109583 |
if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, &bRowid) ){
continue;
}
if( bRowid==0 ){
if( cnt>0 ){
if( pItem->fg.isUsing==0
|| sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0
|| pMatch==pItem
){
/* Two or more tables have the same column name which is
** not joined by USING. Or, a single table has two columns
** that match a USING term (if pMatch==pItem). These are both
** "ambiguous column name" errors. Signal as much by clearing
** pFJMatch and letting cnt go above 1. */
sqlite3ExprListDelete(db, pFJMatch);
pFJMatch = 0;
}else
if( (pItem->fg.jointype & JT_RIGHT)==0 ){
/* An INNER or LEFT JOIN. Use the left-most table */
continue;
}else
|
| ︙ | ︙ | |||
115762 115763 115764 115765 115766 115767 115768 115769 115770 |
Vdbe *v; /* statement being coded */
assert( pExpr!=0 );
op = pExpr->op;
assert( op==TK_AND || op==TK_OR );
assert( TK_AND==OP_And ); testcase( op==TK_AND );
assert( TK_OR==OP_Or ); testcase( op==TK_OR );
pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
if( pAlt!=pExpr ){
| > > | > > < < | 116349 116350 116351 116352 116353 116354 116355 116356 116357 116358 116359 116360 116361 116362 116363 116364 116365 116366 116367 116368 116369 116370 |
Vdbe *v; /* statement being coded */
assert( pExpr!=0 );
op = pExpr->op;
assert( op==TK_AND || op==TK_OR );
assert( TK_AND==OP_And ); testcase( op==TK_AND );
assert( TK_OR==OP_Or ); testcase( op==TK_OR );
assert( pParse->pVdbe!=0 );
v = pParse->pVdbe;
pAlt = sqlite3ExprSimplifiedAndOr(pExpr);
if( pAlt!=pExpr ){
r1 = sqlite3ExprCodeTarget(pParse, pAlt, target);
sqlite3VdbeAddOp3(v, OP_And, r1, r1, target);
return target;
}
skipOp = op==TK_AND ? OP_IfNot : OP_If;
if( exprEvalRhsFirst(pExpr) ){
/* Compute the right operand first. Skip the computation of the left
** operand if the right operand fully determines the result */
r2 = regSS = sqlite3ExprCodeTarget(pParse, pExpr->pRight, target);
addrSkip = sqlite3VdbeAddOp1(v, skipOp, r2);
VdbeComment((v, "skip left operand"));
|
| ︙ | ︙ | |||
119083 119084 119085 119086 119087 119088 119089 | int i; int nAlloc; sqlite3 *db = pParse->db; /* Look up the table being altered. */ assert( pParse->pNewTable==0 ); assert( sqlite3BtreeHoldsAllMutexes(db) ); | | | 119672 119673 119674 119675 119676 119677 119678 119679 119680 119681 119682 119683 119684 119685 119686 |
int i;
int nAlloc;
sqlite3 *db = pParse->db;
/* Look up the table being altered. */
assert( pParse->pNewTable==0 );
assert( sqlite3BtreeHoldsAllMutexes(db) );
if( NEVER(db->mallocFailed) ) goto exit_begin_add_column;
pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
if( !pTab ) goto exit_begin_add_column;
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
sqlite3ErrorMsg(pParse, "virtual tables may not be altered");
goto exit_begin_add_column;
|
| ︙ | ︙ | |||
119155 119156 119157 119158 119159 119160 119161 | ** command. This function checks if the table is a view or virtual ** table (columns of views or virtual tables may not be renamed). If so, ** it loads an error message into pParse and returns non-zero. ** ** Or, if pTab is not a view or virtual table, zero is returned. */ #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) | | > > > > < | | 119744 119745 119746 119747 119748 119749 119750 119751 119752 119753 119754 119755 119756 119757 119758 119759 119760 119761 119762 119763 119764 119765 119766 119767 119768 119769 119770 119771 119772 119773 119774 119775 119776 |
** command. This function checks if the table is a view or virtual
** table (columns of views or virtual tables may not be renamed). If so,
** it loads an error message into pParse and returns non-zero.
**
** Or, if pTab is not a view or virtual table, zero is returned.
*/
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
static int isRealTable(Parse *pParse, Table *pTab, int iOp){
const char *zType = 0;
#ifndef SQLITE_OMIT_VIEW
if( IsView(pTab) ){
zType = "view";
}
#endif
#ifndef SQLITE_OMIT_VIRTUALTABLE
if( IsVirtual(pTab) ){
zType = "virtual table";
}
#endif
if( zType ){
const char *azMsg[] = {
"rename columns of", "drop column from", "edit constraints of"
};
assert( iOp>=0 && iOp<ArraySize(azMsg) );
sqlite3ErrorMsg(pParse, "cannot %s %s \"%s\"",
azMsg[iOp], zType, pTab->zName
);
return 1;
}
return 0;
}
#else /* !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE) */
# define isRealTable(x,y,z) (0)
|
| ︙ | ︙ | |||
119640 119641 119642 119643 119644 119645 119646 119647 119648 119649 119650 119651 119652 119653 |
if( pToken->t.z>pBest->t.z ) pBest = pToken;
}
for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext);
*pp = pBest->pNext;
return pBest;
}
/*
** An error occurred while parsing or otherwise processing a database
** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an
** ALTER TABLE RENAME COLUMN program. The error message emitted by the
** sub-routine is currently stored in pParse->zErrMsg. This function
** adds context to the error message and then stores it in pCtx.
| > > > > > > > > > > > > > > > > > > > | 120232 120233 120234 120235 120236 120237 120238 120239 120240 120241 120242 120243 120244 120245 120246 120247 120248 120249 120250 120251 120252 120253 120254 120255 120256 120257 120258 120259 120260 120261 120262 120263 120264 |
if( pToken->t.z>pBest->t.z ) pBest = pToken;
}
for(pp=&pCtx->pList; *pp!=pBest; pp=&(*pp)->pNext);
*pp = pBest->pNext;
return pBest;
}
/*
** Set the error message of the context passed as the first argument to
** the result of formatting zFmt using printf() style formatting.
*/
static void errorMPrintf(sqlite3_context *pCtx, const char *zFmt, ...){
sqlite3 *db = sqlite3_context_db_handle(pCtx);
char *zErr = 0;
va_list ap;
va_start(ap, zFmt);
zErr = sqlite3VMPrintf(db, zFmt, ap);
va_end(ap);
if( zErr ){
sqlite3_result_error(pCtx, zErr, -1);
sqlite3DbFree(db, zErr);
}else{
sqlite3_result_error_nomem(pCtx);
}
}
/*
** An error occurred while parsing or otherwise processing a database
** object (either pParse->pNewTable, pNewIndex or pNewTrigger) as part of an
** ALTER TABLE RENAME COLUMN program. The error message emitted by the
** sub-routine is currently stored in pParse->zErrMsg. This function
** adds context to the error message and then stores it in pCtx.
|
| ︙ | ︙ | |||
120904 120905 120906 120907 120908 120909 120910 120911 120912 120913 120914 120915 120916 120917 120918 120919 120920 120921 120922 120923 120924 120925 120926 120927 120928 |
sqlite3VdbeJumpHere(v, addr);
}
exit_drop_column:
sqlite3DbFree(db, zCol);
sqlite3SrcListDelete(db, pSrc);
}
/*
** Register built-in functions used to help implement ALTER TABLE
*/
SQLITE_PRIVATE void sqlite3AlterFunctions(void){
static FuncDef aAlterTableFuncs[] = {
INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc),
INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc),
INTERNAL_FUNCTION(sqlite_rename_test, 7, renameTableTest),
INTERNAL_FUNCTION(sqlite_drop_column, 3, dropColumnFunc),
INTERNAL_FUNCTION(sqlite_rename_quotefix,2, renameQuotefixFunc),
};
sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
}
#endif /* SQLITE_ALTER_TABLE */
/************** End of alter.c ***********************************************/
/************** Begin file analyze.c *****************************************/
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 121515 121516 121517 121518 121519 121520 121521 121522 121523 121524 121525 121526 121527 121528 121529 121530 121531 121532 121533 121534 121535 121536 121537 121538 121539 121540 121541 121542 121543 121544 121545 121546 121547 121548 121549 121550 121551 121552 121553 121554 121555 121556 121557 121558 121559 121560 121561 121562 121563 121564 121565 121566 121567 121568 121569 121570 121571 121572 121573 121574 121575 121576 121577 121578 121579 121580 121581 121582 121583 121584 121585 121586 121587 121588 121589 121590 121591 121592 121593 121594 121595 121596 121597 121598 121599 121600 121601 121602 121603 121604 121605 121606 121607 121608 121609 121610 121611 121612 121613 121614 121615 121616 121617 121618 121619 121620 121621 121622 121623 121624 121625 121626 121627 121628 121629 121630 121631 121632 121633 121634 121635 121636 121637 121638 121639 121640 121641 121642 121643 121644 121645 121646 121647 121648 121649 121650 121651 121652 121653 121654 121655 121656 121657 121658 121659 121660 121661 121662 121663 121664 121665 121666 121667 121668 121669 121670 121671 121672 121673 121674 121675 121676 121677 121678 121679 121680 121681 121682 121683 121684 121685 121686 121687 121688 121689 121690 121691 121692 121693 121694 121695 121696 121697 121698 121699 121700 121701 121702 121703 121704 121705 121706 121707 121708 121709 121710 121711 121712 121713 121714 121715 121716 121717 121718 121719 121720 121721 121722 121723 121724 121725 121726 121727 121728 121729 121730 121731 121732 121733 121734 121735 121736 121737 121738 121739 121740 121741 121742 121743 121744 121745 121746 121747 121748 121749 121750 121751 121752 121753 121754 121755 121756 121757 121758 121759 121760 121761 121762 121763 121764 121765 121766 121767 121768 121769 121770 121771 121772 121773 121774 121775 121776 121777 121778 121779 121780 121781 121782 121783 121784 121785 121786 121787 121788 121789 121790 121791 121792 121793 121794 121795 121796 121797 121798 121799 121800 121801 121802 121803 121804 121805 121806 121807 121808 121809 121810 121811 121812 121813 121814 121815 121816 121817 121818 121819 121820 121821 121822 121823 121824 121825 121826 121827 121828 121829 121830 121831 121832 121833 121834 121835 121836 121837 121838 121839 121840 121841 121842 121843 121844 121845 121846 121847 121848 121849 121850 121851 121852 121853 121854 121855 121856 121857 121858 121859 121860 121861 121862 121863 121864 121865 121866 121867 121868 121869 121870 121871 121872 121873 121874 121875 121876 121877 121878 121879 121880 121881 121882 121883 121884 121885 121886 121887 121888 121889 121890 121891 121892 121893 121894 121895 121896 121897 121898 121899 121900 121901 121902 121903 121904 121905 121906 121907 121908 121909 121910 121911 121912 121913 121914 121915 121916 121917 121918 121919 121920 121921 121922 121923 121924 121925 121926 121927 121928 121929 121930 121931 121932 121933 121934 121935 121936 121937 121938 121939 121940 121941 121942 121943 121944 121945 121946 121947 121948 121949 121950 121951 121952 121953 121954 121955 121956 121957 121958 121959 121960 121961 121962 121963 121964 121965 121966 121967 121968 121969 121970 121971 121972 121973 121974 121975 121976 121977 121978 121979 121980 121981 121982 121983 121984 121985 121986 121987 121988 121989 121990 121991 121992 121993 121994 121995 121996 121997 121998 121999 122000 122001 122002 122003 122004 122005 122006 122007 122008 122009 122010 122011 122012 122013 122014 122015 122016 122017 122018 122019 122020 122021 122022 122023 122024 122025 122026 122027 122028 122029 122030 122031 122032 122033 122034 122035 122036 122037 122038 122039 122040 122041 122042 122043 122044 122045 122046 122047 122048 122049 122050 122051 122052 122053 122054 122055 122056 122057 122058 122059 122060 122061 122062 122063 122064 122065 122066 122067 122068 122069 122070 122071 122072 122073 122074 122075 122076 122077 122078 122079 122080 122081 122082 122083 122084 122085 122086 122087 122088 122089 122090 122091 122092 122093 122094 122095 122096 122097 122098 122099 122100 122101 122102 122103 122104 122105 122106 122107 122108 122109 122110 122111 122112 122113 122114 122115 122116 122117 122118 122119 122120 122121 122122 122123 122124 122125 122126 122127 122128 122129 122130 122131 122132 122133 122134 122135 122136 122137 122138 122139 122140 122141 122142 122143 122144 122145 122146 122147 122148 122149 122150 122151 122152 122153 122154 122155 122156 122157 122158 122159 122160 122161 122162 122163 122164 122165 122166 122167 122168 122169 122170 122171 122172 122173 122174 122175 122176 122177 122178 122179 122180 122181 122182 122183 122184 122185 122186 122187 122188 122189 122190 122191 122192 122193 122194 122195 122196 122197 122198 122199 122200 122201 122202 122203 122204 122205 122206 122207 122208 122209 122210 122211 122212 122213 122214 122215 122216 122217 122218 122219 122220 122221 122222 122223 122224 122225 122226 122227 122228 122229 122230 122231 122232 122233 |
sqlite3VdbeJumpHere(v, addr);
}
exit_drop_column:
sqlite3DbFree(db, zCol);
sqlite3SrcListDelete(db, pSrc);
}
/*
** Return the number of bytes of leading whitespace/comments in string z[].
*/
static int getWhitespace(const u8 *z){
int nRet = 0;
while( 1 ){
int t = 0;
int n = sqlite3GetToken(&z[nRet], &t);
if( t!=TK_SPACE && t!=TK_COMMENT ) break;
nRet += n;
}
return nRet;
}
/*
** Return the number of bytes until the end of the next non-whitespace and
** non-comment token. For the purpose of this function, a "(" token includes
** all of the bytes through and including the matching ")", or until the
** first illegal token, whichever comes first.
**
** Write the token type into *piToken.
**
** The value returned is the number of bytes in the token itself plus
** the number of bytes of leading whitespace and comments skipped plus
** all bytes through the next matching ")" if the token is TK_LP.
**
** Example: (Note: '.' used in place of '*' in the example z[] text)
**
** ,--------- *piToken := TK_RP
** v
** z[] = " /.comment./ --comment\n (two three four) five"
** | |
** |<-------------------------------------->|
** |
** `--- return value
*/
static int getConstraintToken(const u8 *z, int *piToken){
int iOff = 0;
int t = 0;
do {
iOff += sqlite3GetToken(&z[iOff], &t);
}while( t==TK_SPACE || t==TK_COMMENT );
*piToken = t;
if( t==TK_LP ){
int nNest = 1;
while( nNest>0 ){
iOff += sqlite3GetToken(&z[iOff], &t);
if( t==TK_LP ){
nNest++;
}else if( t==TK_RP ){
t = TK_LP;
nNest--;
}else if( t==TK_ILLEGAL ){
break;
}
}
}
*piToken = t;
return iOff;
}
/*
** Argument z points into the body of a constraint - specifically the
** second token of the constraint definition. For a named constraint,
** z points to the first token past the CONSTRAINT keyword. For an
** unnamed NOT NULL constraint, z points to the first byte past the NOT
** keyword.
**
** Return the number of bytes until the end of the constraint.
*/
static int getConstraint(const u8 *z){
int iOff = 0;
int t = 0;
/* Now, the current constraint proceeds until the next occurence of one
** of the following tokens:
**
** CONSTRAINT, PRIMARY, NOT, UNIQUE, CHECK, DEFAULT,
** COLLATE, REFERENCES, FOREIGN, GENERATED, AS, RP, or COMMA
**
** Also exit the loop if ILLEGAL turns up.
*/
while( 1 ){
int n = getConstraintToken(&z[iOff], &t);
if( t==TK_CONSTRAINT || t==TK_PRIMARY || t==TK_NOT || t==TK_UNIQUE
|| t==TK_CHECK || t==TK_DEFAULT || t==TK_COLLATE || t==TK_REFERENCES
|| t==TK_FOREIGN || t==TK_RP || t==TK_COMMA || t==TK_ILLEGAL
|| t==TK_AS || t==TK_GENERATED
){
break;
}
iOff += n;
}
return iOff;
}
/*
** Compare two constraint names.
**
** Summary: *pRes := zQuote != zCmp
**
** Details:
** Compare the (possibly quoted) constraint name zQuote[0..nQuote-1]
** against zCmp[]. Write zero into *pRes if they are the same and
** non-zero if they differ. Normally return SQLITE_OK, except if there
** is an OOM, set the OOM error condition on ctx and return SQLITE_NOMEM.
*/
static int quotedCompare(
sqlite3_context *ctx, /* Function context on which to report errors */
const u8 *zQuote, /* Possibly quoted text. Not zero-terminated. */
int nQuote, /* Length of zQuote in bytes */
const u8 *zCmp, /* Zero-terminated, unquoted name to compare against */
int *pRes /* OUT: Set to 0 if equal, non-zero if unequal */
){
char *zCopy = 0; /* De-quoted, zero-terminated copy of zQuote[] */
zCopy = sqlite3MallocZero(nQuote+1);
if( zCopy==0 ){
sqlite3_result_error_nomem(ctx);
return SQLITE_NOMEM_BKPT;
}
memcpy(zCopy, zQuote, nQuote);
sqlite3Dequote(zCopy);
*pRes = sqlite3_stricmp((const char*)zCopy, (const char*)zCmp);
sqlite3_free(zCopy);
return SQLITE_OK;
}
/*
** zSql[] is a CREATE TABLE statement, supposedly. Find the offset
** into zSql[] of the first character past the first "(" and write
** that offset into *piOff and return SQLITE_OK. Or, if not found,
** set the SQLITE_CORRUPT error code and return SQLITE_ERROR.
*/
static int skipCreateTable(sqlite3_context *ctx, const u8 *zSql, int *piOff){
int iOff = 0;
if( zSql==0 ) return SQLITE_ERROR;
/* Jump past the "CREATE TABLE" bit. */
while( 1 ){
int t = 0;
iOff += sqlite3GetToken(&zSql[iOff], &t);
if( t==TK_LP ) break;
if( t==TK_ILLEGAL ){
sqlite3_result_error_code(ctx, SQLITE_CORRUPT_BKPT);
return SQLITE_ERROR;
}
}
*piOff = iOff;
return SQLITE_OK;
}
/*
** Internal SQL function sqlite3_drop_constraint(): Given an input
** CREATE TABLE statement, return a revised CREATE TABLE statement
** with a constraint removed. Two forms, depending on the datatype
** of argv[2]:
**
** sqlite_drop_constraint(SQL, INT) -- Omit NOT NULL from the INT-th column
** sqlite_drop_constraint(SQL, TEXT) -- OMIT constraint with name TEXT
**
** In the first case, the left-most column is 0.
*/
static void dropConstraintFunc(
sqlite3_context *ctx,
int NotUsed,
sqlite3_value **argv
){
const u8 *zSql = sqlite3_value_text(argv[0]);
const u8 *zCons = 0;
int iNotNull = -1;
int ii;
int iOff = 0;
int iStart = 0;
int iEnd = 0;
char *zNew = 0;
int t = 0;
sqlite3 *db;
UNUSED_PARAMETER(NotUsed);
if( zSql==0 ) return;
/* Jump past the "CREATE TABLE" bit. */
if( skipCreateTable(ctx, zSql, &iOff) ) return;
if( sqlite3_value_type(argv[1])==SQLITE_INTEGER ){
iNotNull = sqlite3_value_int(argv[1]);
}else{
zCons = sqlite3_value_text(argv[1]);
}
/* Search for the named constraint within column definitions. */
for(ii=0; iEnd==0; ii++){
/* Now parse the column or table constraint definition. Search
** for the token CONSTRAINT if this is a DROP CONSTRAINT command, or
** NOT in the right column if this is a DROP NOT NULL. */
while( 1 ){
iStart = iOff;
iOff += getConstraintToken(&zSql[iOff], &t);
if( t==TK_CONSTRAINT && (zCons || iNotNull==ii) ){
/* Check if this is the constraint we are searching for. */
int nTok = 0;
int cmp = 1;
/* Skip past any whitespace. */
iOff += getWhitespace(&zSql[iOff]);
/* Compare the next token - which may be quoted - with the name of
** the constraint being dropped. */
nTok = getConstraintToken(&zSql[iOff], &t);
if( zCons ){
if( quotedCompare(ctx, &zSql[iOff], nTok, zCons, &cmp) ) return;
}
iOff += nTok;
/* The next token is usually the first token of the constraint
** definition. This is enough to tell the type of the constraint -
** TK_NOT means it is a NOT NULL, TK_CHECK a CHECK constraint etc.
**
** There is also the chance that the next token is TK_CONSTRAINT
** (or TK_DEFAULT or TK_COLLATE), for example if a table has been
** created as follows:
**
** CREATE TABLE t1(cols, CONSTRAINT one CONSTRAINT two NOT NULL);
**
** In this case, allow the "CONSTRAINT one" bit to be dropped by
** this command if that is what is requested, or to advance to
** the next iteration of the loop with &zSql[iOff] still pointing
** to the CONSTRAINT keyword. */
nTok = getConstraintToken(&zSql[iOff], &t);
if( t==TK_CONSTRAINT || t==TK_DEFAULT || t==TK_COLLATE
|| t==TK_COMMA || t==TK_RP || t==TK_GENERATED || t==TK_AS
){
t = TK_CHECK;
}else{
iOff += nTok;
iOff += getConstraint(&zSql[iOff]);
}
if( cmp==0 || (iNotNull>=0 && t==TK_NOT) ){
if( t!=TK_NOT && t!=TK_CHECK ){
errorMPrintf(ctx, "constraint may not be dropped: %s", zCons);
return;
}
iEnd = iOff;
break;
}
}else if( t==TK_NOT && iNotNull==ii ){
iEnd = iOff + getConstraint(&zSql[iOff]);
break;
}else if( t==TK_RP || t==TK_ILLEGAL ){
iEnd = -1;
break;
}else if( t==TK_COMMA ){
break;
}
}
}
/* If the constraint has not been found it is an error. */
if( iEnd<=0 ){
if( zCons ){
errorMPrintf(ctx, "no such constraint: %s", zCons);
}else{
/* SQLite follows postgres in that a DROP NOT NULL on a column that is
** not NOT NULL is not an error. So just return the original SQL here. */
sqlite3_result_text(ctx, (const char*)zSql, -1, SQLITE_TRANSIENT);
}
}else{
/* Figure out if an extra space should be inserted after the constraint
** is removed. And if an additional comma preceding the constraint
** should be removed. */
const char *zSpace = " ";
iEnd += getWhitespace(&zSql[iEnd]);
sqlite3GetToken(&zSql[iEnd], &t);
if( t==TK_RP || t==TK_COMMA ){
zSpace = "";
if( zSql[iStart-1]==',' ) iStart--;
}
db = sqlite3_context_db_handle(ctx);
zNew = sqlite3MPrintf(db, "%.*s%s%s", iStart, zSql, zSpace, &zSql[iEnd]);
sqlite3_result_text(ctx, zNew, -1, SQLITE_DYNAMIC);
}
}
/*
** Internal SQL function:
**
** sqlite_add_constraint(SQL, CONSTRAINT-TEXT, ICOL)
**
** SQL is a CREATE TABLE statement. Return a modified version of
** SQL that adds CONSTRAINT-TEXT at the end of the ICOL-th column
** definition. (The left-most column defintion is 0.)
*/
static void addConstraintFunc(
sqlite3_context *ctx,
int NotUsed,
sqlite3_value **argv
){
const u8 *zSql = sqlite3_value_text(argv[0]);
const char *zCons = (const char*)sqlite3_value_text(argv[1]);
int iCol = sqlite3_value_int(argv[2]);
int iOff = 0;
int ii;
char *zNew = 0;
int t = 0;
sqlite3 *db;
UNUSED_PARAMETER(NotUsed);
if( skipCreateTable(ctx, zSql, &iOff) ) return;
for(ii=0; ii<=iCol || (iCol<0 && t!=TK_RP); ii++){
iOff += getConstraintToken(&zSql[iOff], &t);
while( 1 ){
int nTok = getConstraintToken(&zSql[iOff], &t);
if( t==TK_COMMA || t==TK_RP ) break;
if( t==TK_ILLEGAL ){
sqlite3_result_error_code(ctx, SQLITE_CORRUPT_BKPT);
return;
}
iOff += nTok;
}
}
iOff += getWhitespace(&zSql[iOff]);
db = sqlite3_context_db_handle(ctx);
if( iCol<0 ){
zNew = sqlite3MPrintf(db, "%.*s, %s%s", iOff, zSql, zCons, &zSql[iOff]);
}else{
zNew = sqlite3MPrintf(db, "%.*s %s%s", iOff, zSql, zCons, &zSql[iOff]);
}
sqlite3_result_text(ctx, zNew, -1, SQLITE_DYNAMIC);
}
/*
** Find a column named pCol in table pTab. If successful, set output
** parameter *piCol to the index of the column in the table and return
** SQLITE_OK. Otherwise, set *piCol to -1 and return an SQLite error
** code.
*/
static int alterFindCol(Parse *pParse, Table *pTab, Token *pCol, int *piCol){
sqlite3 *db = pParse->db;
char *zName = sqlite3NameFromToken(db, pCol);
int rc = SQLITE_NOMEM;
int iCol = -1;
if( zName ){
iCol = sqlite3ColumnIndex(pTab, zName);
if( iCol<0 ){
sqlite3ErrorMsg(pParse, "no such column: %s", zName);
rc = SQLITE_ERROR;
}else{
rc = SQLITE_OK;
}
}
#ifndef SQLITE_OMIT_AUTHORIZATION
if( rc==SQLITE_OK ){
const char *zDb = db->aDb[sqlite3SchemaToIndex(db, pTab->pSchema)].zDbSName;
const char *zCol = pTab->aCol[iCol].zCnName;
if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, zCol) ){
pTab = 0;
}
}
#endif
sqlite3DbFree(db, zName);
*piCol = iCol;
return rc;
}
/*
** Find the table named by the first entry in source list pSrc. If successful,
** return a pointer to the Table structure and set output variable (*pzDb)
** to point to the name of the database containin the table (i.e. "main",
** "temp" or the name of an attached database).
**
** If the table cannot be located, return NULL. The value of the two output
** parameters is undefined in this case.
*/
static Table *alterFindTable(
Parse *pParse, /* Parsing context */
SrcList *pSrc, /* Name of the table to look for */
int *piDb, /* OUT: write the iDb here */
const char **pzDb, /* OUT: write name of schema here */
int bAuth /* Do ALTER TABLE authorization checks if true */
){
sqlite3 *db = pParse->db;
Table *pTab = 0;
assert( sqlite3BtreeHoldsAllMutexes(db) );
pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
if( pTab ){
int iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
*pzDb = db->aDb[iDb].zDbSName;
*piDb = iDb;
if( SQLITE_OK!=isRealTable(pParse, pTab, 2)
|| SQLITE_OK!=isAlterableTable(pParse, pTab)
){
pTab = 0;
}
}
#ifndef SQLITE_OMIT_AUTHORIZATION
if( pTab && bAuth ){
if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, *pzDb, pTab->zName, 0) ){
pTab = 0;
}
}
#endif
sqlite3SrcListDelete(db, pSrc);
return pTab;
}
/*
** Generate bytecode for one of:
**
** (1) ALTER TABLE pSrc DROP CONSTRAINT pCons
** (2) ALTER TABLE pSrc ALTER pCol DROP NOT NULL
**
** One of pCons and pCol must be NULL and the other non-null.
*/
SQLITE_PRIVATE void sqlite3AlterDropConstraint(
Parse *pParse, /* Parsing context */
SrcList *pSrc, /* The table being altered */
Token *pCons, /* Name of the constraint to drop */
Token *pCol /* Name of the column from which to remove the NOT NULL */
){
sqlite3 *db = pParse->db;
Table *pTab = 0;
int iDb = 0;
const char *zDb = 0;
char *zArg = 0;
assert( (pCol==0)!=(pCons==0) );
assert( pSrc->nSrc==1 );
pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, pCons!=0);
if( !pTab ) return;
if( pCons ){
zArg = sqlite3MPrintf(db, "%.*Q", pCons->n, pCons->z);
}else{
int iCol;
if( alterFindCol(pParse, pTab, pCol, &iCol) ) return;
zArg = sqlite3MPrintf(db, "%d", iCol);
}
/* Edit the SQL for the named table. */
sqlite3NestedParse(pParse,
"UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
"sql = sqlite_drop_constraint(sql, %s) "
"WHERE type='table' AND tbl_name=%Q COLLATE nocase"
, zDb, zArg, pTab->zName
);
sqlite3DbFree(db, zArg);
/* Finally, reload the database schema. */
renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons);
}
/*
** The implementation of SQL function sqlite_fail(MSG). This takes a single
** argument, and returns it as an error message with the error code set to
** SQLITE_CONSTRAINT.
*/
static void failConstraintFunc(
sqlite3_context *ctx,
int NotUsed,
sqlite3_value **argv
){
const char *zText = (const char*)sqlite3_value_text(argv[0]);
int err = sqlite3_value_int(argv[1]);
(void)NotUsed;
sqlite3_result_error(ctx, zText, -1);
sqlite3_result_error_code(ctx, err);
}
/*
** Buffer pCons, which is nCons bytes in size, contains the text of a
** NOT NULL or CHECK constraint that will be inserted into a CREATE TABLE
** statement. If successful, this function returns the size of the buffer in
** bytes not including any trailing whitespace or "--" style comments. Or,
** if an OOM occurs, it returns 0 and sets db->mallocFailed to true.
**
** C-style comments at the end are preserved. "--" style comments are
** removed because the comment terminator might be \000, and we are about
** to insert the pCons[] text into the middle of a larger string, and that
** will have the effect of removing the comment terminator and messing up
** the syntax.
*/
static int alterRtrimConstraint(
sqlite3 *db, /* used to record OOM error */
const char *pCons, /* Buffer containing constraint */
int nCons /* Size of pCons in bytes */
){
u8 *zTmp = (u8*)sqlite3MPrintf(db, "%.*s", nCons, pCons);
int iOff = 0;
int iEnd = 0;
if( zTmp==0 ) return 0;
while( 1 ){
int t = 0;
int nToken = sqlite3GetToken(&zTmp[iOff], &t);
if( t==TK_ILLEGAL ) break;
if( t!=TK_SPACE && (t!=TK_COMMENT || zTmp[iOff]!='-') ){
iEnd = iOff+nToken;
}
iOff += nToken;
}
sqlite3DbFree(db, zTmp);
return iEnd;
}
/*
** Prepare a statement of the form:
**
** ALTER TABLE pSrc ALTER pCol SET NOT NULL
*/
SQLITE_PRIVATE void sqlite3AlterSetNotNull(
Parse *pParse, /* Parsing context */
SrcList *pSrc, /* Name of the table being altered */
Token *pCol, /* Name of the column to add a NOT NULL constraint to */
Token *pFirst /* The NOT token of the NOT NULL constraint text */
){
Table *pTab = 0;
int iCol = 0;
int iDb = 0;
const char *zDb = 0;
const char *pCons = 0;
int nCons = 0;
/* Look up the table being altered. */
assert( pSrc->nSrc==1 );
pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 0);
if( !pTab ) return;
/* Find the column being altered. */
if( alterFindCol(pParse, pTab, pCol, &iCol) ){
return;
}
/* Find the length in bytes of the constraint definition */
pCons = pFirst->z;
nCons = alterRtrimConstraint(pParse->db, pCons, pParse->sLastToken.z - pCons);
/* Search for a constraint violation. Throw an exception if one is found. */
sqlite3NestedParse(pParse,
"SELECT sqlite_fail('constraint failed', %d) "
"FROM %Q.%Q AS x WHERE x.%.*s IS NULL",
SQLITE_CONSTRAINT, zDb, pTab->zName, (int)pCol->n, pCol->z
);
/* Edit the SQL for the named table. */
sqlite3NestedParse(pParse,
"UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
"sql = sqlite_add_constraint(sqlite_drop_constraint(sql, %d), %.*Q, %d) "
"WHERE type='table' AND tbl_name=%Q COLLATE nocase"
, zDb, iCol, nCons, pCons, iCol, pTab->zName
);
/* Finally, reload the database schema. */
renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons);
}
/*
** Implementation of internal SQL function:
**
** sqlite_find_constraint(SQL, CONSTRAINT-NAME)
**
** This function returns true if the SQL passed as the first argument is a
** CREATE TABLE that contains a constraint with the name CONSTRAINT-NAME,
** or false otherwise.
*/
static void findConstraintFunc(
sqlite3_context *ctx,
int NotUsed,
sqlite3_value **argv
){
const u8 *zSql = 0;
const u8 *zCons = 0;
int iOff = 0;
int t = 0;
(void)NotUsed;
zSql = sqlite3_value_text(argv[0]);
zCons = sqlite3_value_text(argv[1]);
if( zSql==0 || zCons==0 ) return;
while( t!=TK_LP && t!=TK_ILLEGAL ){
iOff += sqlite3GetToken(&zSql[iOff], &t);
}
while( 1 ){
iOff += getConstraintToken(&zSql[iOff], &t);
if( t==TK_CONSTRAINT ){
int nTok = 0;
int cmp = 0;
iOff += getWhitespace(&zSql[iOff]);
nTok = getConstraintToken(&zSql[iOff], &t);
if( quotedCompare(ctx, &zSql[iOff], nTok, zCons, &cmp) ) return;
if( cmp==0 ){
sqlite3_result_int(ctx, 1);
return;
}
}else if( t==TK_ILLEGAL ){
break;
}
}
sqlite3_result_int(ctx, 0);
}
/*
** Generate bytecode to implement:
**
** ALTER TABLE pSrc ADD [CONSTRAINT pName] CHECK(pExpr)
**
** Any "ON CONFLICT" text that occurs after the "CHECK(...)", up
** until pParse->sLastToken, is included as part of the new constraint.
*/
SQLITE_PRIVATE void sqlite3AlterAddConstraint(
Parse *pParse, /* Parse context */
SrcList *pSrc, /* Table to add constraint to */
Token *pFirst, /* First token of new constraint */
Token *pName, /* Name of new constraint. NULL if name omitted. */
const char *pExpr, /* Text of CHECK expression */
int nExpr /* Size of pExpr in bytes */
){
Table *pTab = 0; /* Table identified by pSrc */
int iDb = 0; /* Which schema does pTab live in */
const char *zDb = 0; /* Name of the schema in which pTab lives */
const char *pCons = 0; /* Text of the constraint */
int nCons; /* Bytes of text to use from pCons[] */
/* Look up the table being altered. */
assert( pSrc->nSrc==1 );
pTab = alterFindTable(pParse, pSrc, &iDb, &zDb, 1);
if( !pTab ) return;
/* If this new constraint has a name, check that it is not a duplicate of
** an existing constraint. It is an error if it is. */
if( pName ){
char *zName = sqlite3NameFromToken(pParse->db, pName);
sqlite3NestedParse(pParse,
"SELECT sqlite_fail('constraint %q already exists', %d) "
"FROM \"%w\"." LEGACY_SCHEMA_TABLE " "
"WHERE type='table' AND tbl_name=%Q COLLATE nocase "
"AND sqlite_find_constraint(sql, %Q)",
zName, SQLITE_ERROR, zDb, pTab->zName, zName
);
sqlite3DbFree(pParse->db, zName);
}
/* Search for a constraint violation. Throw an exception if one is found. */
sqlite3NestedParse(pParse,
"SELECT sqlite_fail('constraint failed', %d) "
"FROM %Q.%Q WHERE (%.*s) IS NOT TRUE",
SQLITE_CONSTRAINT, zDb, pTab->zName, nExpr, pExpr
);
/* Edit the SQL for the named table. */
pCons = pFirst->z;
nCons = alterRtrimConstraint(pParse->db, pCons, pParse->sLastToken.z - pCons);
sqlite3NestedParse(pParse,
"UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET "
"sql = sqlite_add_constraint(sql, %.*Q, -1) "
"WHERE type='table' AND tbl_name=%Q COLLATE nocase"
, zDb, nCons, pCons, pTab->zName
);
/* Finally, reload the database schema. */
renameReloadSchema(pParse, iDb, INITFLAG_AlterDropCons);
}
/*
** Register built-in functions used to help implement ALTER TABLE
*/
SQLITE_PRIVATE void sqlite3AlterFunctions(void){
static FuncDef aAlterTableFuncs[] = {
INTERNAL_FUNCTION(sqlite_rename_column, 9, renameColumnFunc),
INTERNAL_FUNCTION(sqlite_rename_table, 7, renameTableFunc),
INTERNAL_FUNCTION(sqlite_rename_test, 7, renameTableTest),
INTERNAL_FUNCTION(sqlite_drop_column, 3, dropColumnFunc),
INTERNAL_FUNCTION(sqlite_rename_quotefix,2, renameQuotefixFunc),
INTERNAL_FUNCTION(sqlite_drop_constraint,2, dropConstraintFunc),
INTERNAL_FUNCTION(sqlite_fail, 2, failConstraintFunc),
INTERNAL_FUNCTION(sqlite_add_constraint, 3, addConstraintFunc),
INTERNAL_FUNCTION(sqlite_find_constraint,2, findConstraintFunc),
};
sqlite3InsertBuiltinFuncs(aAlterTableFuncs, ArraySize(aAlterTableFuncs));
}
#endif /* SQLITE_ALTER_TABLE */
/************** End of alter.c ***********************************************/
/************** Begin file analyze.c *****************************************/
|
| ︙ | ︙ | |||
124260 124261 124262 124263 124264 124265 124266 124267 124268 124269 124270 124271 124272 124273 |
** CREATE, then check to see if it is the name of an virtual table that
** can be an eponymous virtual table. */
if( (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)==0 && db->init.busy==0 ){
Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
pMod = sqlite3PragmaVtabRegister(db, zName);
}
if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
testcase( pMod->pEpoTab==0 );
return pMod->pEpoTab;
}
}
#endif
if( flags & LOCATE_NOERR ) return 0;
| > > > > > > > > > > | 125565 125566 125567 125568 125569 125570 125571 125572 125573 125574 125575 125576 125577 125578 125579 125580 125581 125582 125583 125584 125585 125586 125587 125588 |
** CREATE, then check to see if it is the name of an virtual table that
** can be an eponymous virtual table. */
if( (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)==0 && db->init.busy==0 ){
Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
pMod = sqlite3PragmaVtabRegister(db, zName);
}
#ifndef SQLITE_OMIT_JSON
if( pMod==0 && sqlite3_strnicmp(zName, "json", 4)==0 ){
pMod = sqlite3JsonVtabRegister(db, zName);
}
#endif
#ifdef SQLITE_ENABLE_CARRAY
if( pMod==0 && sqlite3_stricmp(zName, "carray")==0 ){
pMod = sqlite3CarrayRegister(db);
}
#endif
if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
testcase( pMod->pEpoTab==0 );
return pMod->pEpoTab;
}
}
#endif
if( flags & LOCATE_NOERR ) return 0;
|
| ︙ | ︙ | |||
125876 125877 125878 125879 125880 125881 125882 | ** Measure the number of characters needed to output the given ** identifier. The number returned includes any quotes used ** but does not include the null terminator. ** ** The estimate is conservative. It might be larger that what is ** really needed. */ | | | | 127191 127192 127193 127194 127195 127196 127197 127198 127199 127200 127201 127202 127203 127204 127205 127206 |
** Measure the number of characters needed to output the given
** identifier. The number returned includes any quotes used
** but does not include the null terminator.
**
** The estimate is conservative. It might be larger that what is
** really needed.
*/
static i64 identLength(const char *z){
i64 n;
for(n=0; *z; n++, z++){
if( *z=='"' ){ n++; }
}
return n + 2;
}
/*
|
| ︙ | ︙ | |||
130142 130143 130144 130145 130146 130147 130148 130149 130150 130151 130152 130153 130154 130155 |
temp1 = pSchema->tblHash;
temp2 = pSchema->trigHash;
sqlite3HashInit(&pSchema->trigHash);
sqlite3HashClear(&pSchema->idxHash);
for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem));
}
sqlite3HashClear(&temp2);
sqlite3HashInit(&pSchema->tblHash);
for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
Table *pTab = sqliteHashData(pElem);
sqlite3DeleteTable(&xdb, pTab);
}
sqlite3HashClear(&temp1);
| > | 131457 131458 131459 131460 131461 131462 131463 131464 131465 131466 131467 131468 131469 131470 131471 |
temp1 = pSchema->tblHash;
temp2 = pSchema->trigHash;
sqlite3HashInit(&pSchema->trigHash);
sqlite3HashClear(&pSchema->idxHash);
for(pElem=sqliteHashFirst(&temp2); pElem; pElem=sqliteHashNext(pElem)){
sqlite3DeleteTrigger(&xdb, (Trigger*)sqliteHashData(pElem));
}
sqlite3HashClear(&temp2);
sqlite3HashInit(&pSchema->tblHash);
for(pElem=sqliteHashFirst(&temp1); pElem; pElem=sqliteHashNext(pElem)){
Table *pTab = sqliteHashData(pElem);
sqlite3DeleteTable(&xdb, pTab);
}
sqlite3HashClear(&temp1);
|
| ︙ | ︙ | |||
131702 131703 131704 131705 131706 131707 131708 |
** raise an SQLITE_TOOBIG exception and return NULL.
*/
static void *contextMalloc(sqlite3_context *context, i64 nByte){
char *z;
sqlite3 *db = sqlite3_context_db_handle(context);
assert( nByte>0 );
testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] );
| | | 133018 133019 133020 133021 133022 133023 133024 133025 133026 133027 133028 133029 133030 133031 133032 |
** raise an SQLITE_TOOBIG exception and return NULL.
*/
static void *contextMalloc(sqlite3_context *context, i64 nByte){
char *z;
sqlite3 *db = sqlite3_context_db_handle(context);
assert( nByte>0 );
testcase( nByte==db->aLimit[SQLITE_LIMIT_LENGTH] );
testcase( nByte==(i64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
if( nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){
sqlite3_result_error_toobig(context);
z = 0;
}else{
z = sqlite3Malloc(nByte);
if( !z ){
sqlite3_result_error_nomem(context);
|
| ︙ | ︙ | |||
132373 132374 132375 132376 132377 132378 132379 |
/*
** Return true if z[] begins with N hexadecimal digits, and write
** a decoding of those digits into *pVal. Or return false if any
** one of the first N characters in z[] is not a hexadecimal digit.
*/
static int isNHex(const char *z, int N, u32 *pVal){
int i;
| | | 133689 133690 133691 133692 133693 133694 133695 133696 133697 133698 133699 133700 133701 133702 133703 |
/*
** Return true if z[] begins with N hexadecimal digits, and write
** a decoding of those digits into *pVal. Or return false if any
** one of the first N characters in z[] is not a hexadecimal digit.
*/
static int isNHex(const char *z, int N, u32 *pVal){
int i;
u32 v = 0;
for(i=0; i<N; i++){
if( !sqlite3Isxdigit(z[i]) ) return 0;
v = (v<<4) + sqlite3HexToInt(z[i]);
}
*pVal = v;
return 1;
}
|
| ︙ | ︙ | |||
132886 132887 132888 132889 132890 132891 132892 132893 132894 132895 132896 132897 132898 132899 132900 132901 132902 132903 132904 132905 132906 132907 132908 |
int argc,
sqlite3_value **argv,
int nSep,
const char *zSep
){
i64 j, n = 0;
int i;
char *z;
for(i=0; i<argc; i++){
n += sqlite3_value_bytes(argv[i]);
}
n += (argc-1)*(i64)nSep;
z = sqlite3_malloc64(n+1);
if( z==0 ){
sqlite3_result_error_nomem(context);
return;
}
j = 0;
for(i=0; i<argc; i++){
if( sqlite3_value_type(argv[i])!=SQLITE_NULL ){
int k = sqlite3_value_bytes(argv[i]);
const char *v = (const char*)sqlite3_value_text(argv[i]);
if( v!=0 ){
| > | > | 134202 134203 134204 134205 134206 134207 134208 134209 134210 134211 134212 134213 134214 134215 134216 134217 134218 134219 134220 134221 134222 134223 134224 134225 134226 134227 134228 134229 134230 134231 134232 134233 134234 134235 134236 134237 134238 134239 |
int argc,
sqlite3_value **argv,
int nSep,
const char *zSep
){
i64 j, n = 0;
int i;
int bNotNull = 0; /* True after at least NOT NULL argument seen */
char *z;
for(i=0; i<argc; i++){
n += sqlite3_value_bytes(argv[i]);
}
n += (argc-1)*(i64)nSep;
z = sqlite3_malloc64(n+1);
if( z==0 ){
sqlite3_result_error_nomem(context);
return;
}
j = 0;
for(i=0; i<argc; i++){
if( sqlite3_value_type(argv[i])!=SQLITE_NULL ){
int k = sqlite3_value_bytes(argv[i]);
const char *v = (const char*)sqlite3_value_text(argv[i]);
if( v!=0 ){
if( bNotNull && nSep>0 ){
memcpy(&z[j], zSep, nSep);
j += nSep;
}
memcpy(&z[j], v, k);
j += k;
bNotNull = 1;
}
}
}
z[j] = 0;
assert( j<=n );
sqlite3_result_text64(context, z, j, sqlite3_free, SQLITE_UTF8);
}
|
| ︙ | ︙ | |||
133853 133854 133855 133856 133857 133858 133859 133860 133861 133862 133863 133864 133865 133866 | assert( argc==1 ); type0 = sqlite3_value_numeric_type(argv[0]); if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return; x = sqlite3_value_double(argv[0]); sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0); } #ifdef SQLITE_DEBUG /* ** Implementation of fpdecode(x,y,z) function. ** ** x is a real number that is to be decoded. y is the precision. ** z is the maximum real precision. Return a string that shows the ** results of the sqlite3FpDecode() function. | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 135171 135172 135173 135174 135175 135176 135177 135178 135179 135180 135181 135182 135183 135184 135185 135186 135187 135188 135189 135190 135191 135192 135193 135194 135195 135196 135197 135198 135199 135200 135201 135202 135203 135204 135205 135206 135207 135208 135209 135210 135211 135212 135213 135214 135215 135216 135217 135218 135219 135220 135221 135222 135223 135224 135225 135226 135227 135228 135229 135230 135231 135232 135233 135234 135235 135236 135237 135238 135239 135240 135241 135242 135243 135244 135245 135246 135247 135248 135249 135250 135251 135252 135253 135254 135255 135256 135257 135258 135259 135260 135261 135262 135263 135264 135265 135266 135267 135268 135269 135270 135271 135272 135273 135274 135275 135276 135277 135278 135279 135280 135281 135282 135283 135284 135285 135286 135287 135288 135289 135290 135291 135292 135293 135294 135295 135296 135297 135298 135299 135300 135301 135302 135303 135304 135305 135306 135307 135308 135309 135310 135311 135312 135313 135314 135315 135316 135317 135318 135319 135320 135321 135322 135323 135324 135325 135326 135327 135328 135329 135330 135331 135332 135333 135334 135335 135336 135337 135338 135339 135340 135341 135342 135343 135344 135345 135346 135347 135348 135349 135350 135351 135352 135353 135354 135355 135356 135357 135358 135359 135360 135361 135362 135363 135364 135365 135366 135367 135368 135369 135370 135371 135372 135373 135374 135375 135376 135377 135378 135379 135380 135381 135382 135383 135384 135385 135386 135387 135388 135389 135390 135391 135392 135393 135394 135395 135396 135397 135398 135399 135400 135401 135402 135403 135404 135405 135406 135407 135408 135409 135410 135411 135412 135413 135414 135415 135416 135417 135418 135419 135420 135421 135422 135423 135424 135425 135426 135427 135428 135429 135430 135431 135432 135433 135434 135435 135436 135437 135438 135439 135440 135441 135442 135443 135444 135445 135446 135447 135448 135449 135450 135451 135452 135453 135454 135455 135456 135457 135458 135459 135460 135461 135462 135463 135464 135465 135466 135467 135468 135469 135470 135471 135472 135473 135474 135475 135476 135477 135478 135479 135480 135481 135482 135483 135484 135485 135486 135487 135488 135489 135490 135491 135492 135493 135494 135495 135496 135497 135498 135499 135500 135501 135502 135503 135504 135505 135506 135507 135508 135509 135510 135511 135512 135513 135514 135515 135516 135517 135518 135519 135520 135521 135522 135523 135524 135525 135526 135527 135528 135529 135530 135531 135532 135533 135534 135535 135536 135537 135538 135539 135540 135541 135542 135543 135544 135545 135546 135547 135548 135549 135550 135551 135552 135553 135554 135555 135556 135557 135558 135559 135560 135561 135562 135563 135564 135565 135566 135567 135568 135569 135570 135571 135572 135573 135574 135575 135576 135577 135578 135579 135580 135581 135582 135583 135584 135585 135586 135587 135588 135589 135590 135591 135592 135593 135594 135595 135596 135597 135598 135599 135600 135601 135602 135603 135604 135605 135606 135607 135608 135609 135610 135611 135612 135613 135614 135615 135616 135617 135618 135619 135620 135621 135622 135623 135624 135625 135626 135627 135628 135629 135630 135631 135632 135633 135634 135635 135636 135637 135638 135639 135640 135641 135642 135643 135644 135645 135646 135647 135648 135649 135650 135651 135652 135653 135654 135655 135656 135657 135658 135659 135660 135661 135662 135663 135664 135665 135666 135667 135668 135669 135670 135671 135672 135673 135674 135675 135676 135677 135678 135679 135680 |
assert( argc==1 );
type0 = sqlite3_value_numeric_type(argv[0]);
if( type0!=SQLITE_INTEGER && type0!=SQLITE_FLOAT ) return;
x = sqlite3_value_double(argv[0]);
sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0);
}
#if defined(SQLITE_ENABLE_PERCENTILE)
/***********************************************************************
** This section implements the percentile(Y,P) SQL function and similar.
** Requirements:
**
** (1) The percentile(Y,P) function is an aggregate function taking
** exactly two arguments.
**
** (2) If the P argument to percentile(Y,P) is not the same for every
** row in the aggregate then an error is thrown. The word "same"
** in the previous sentence means that the value differ by less
** than 0.001.
**
** (3) If the P argument to percentile(Y,P) evaluates to anything other
** than a number in the range of 0.0 to 100.0 inclusive then an
** error is thrown.
**
** (4) If any Y argument to percentile(Y,P) evaluates to a value that
** is not NULL and is not numeric then an error is thrown.
**
** (5) If any Y argument to percentile(Y,P) evaluates to plus or minus
** infinity then an error is thrown. (SQLite always interprets NaN
** values as NULL.)
**
** (6) Both Y and P in percentile(Y,P) can be arbitrary expressions,
** including CASE WHEN expressions.
**
** (7) The percentile(Y,P) aggregate is able to handle inputs of at least
** one million (1,000,000) rows.
**
** (8) If there are no non-NULL values for Y, then percentile(Y,P)
** returns NULL.
**
** (9) If there is exactly one non-NULL value for Y, the percentile(Y,P)
** returns the one Y value.
**
** (10) If there N non-NULL values of Y where N is two or more and
** the Y values are ordered from least to greatest and a graph is
** drawn from 0 to N-1 such that the height of the graph at J is
** the J-th Y value and such that straight lines are drawn between
** adjacent Y values, then the percentile(Y,P) function returns
** the height of the graph at P*(N-1)/100.
**
** (11) The percentile(Y,P) function always returns either a floating
** point number or NULL.
**
** (12) The percentile(Y,P) is implemented as a single C99 source-code
** file that compiles into a shared-library or DLL that can be loaded
** into SQLite using the sqlite3_load_extension() interface.
**
** (13) A separate median(Y) function is the equivalent percentile(Y,50).
**
** (14) A separate percentile_cont(Y,P) function is equivalent to
** percentile(Y,P/100.0). In other words, the fraction value in
** the second argument is in the range of 0 to 1 instead of 0 to 100.
**
** (15) A separate percentile_disc(Y,P) function is like
** percentile_cont(Y,P) except that instead of returning the weighted
** average of the nearest two input values, it returns the next lower
** value. So the percentile_disc(Y,P) will always return a value
** that was one of the inputs.
**
** (16) All of median(), percentile(Y,P), percentile_cont(Y,P) and
** percentile_disc(Y,P) can be used as window functions.
**
** Differences from standard SQL:
**
** * The percentile_cont(X,P) function is equivalent to the following in
** standard SQL:
**
** (percentile_cont(P) WITHIN GROUP (ORDER BY X))
**
** The SQLite syntax is much more compact. The standard SQL syntax
** is also supported if SQLite is compiled with the
** -DSQLITE_ENABLE_ORDERED_SET_AGGREGATES option.
**
** * No median(X) function exists in the SQL standard. App developers
** are expected to write "percentile_cont(0.5)WITHIN GROUP(ORDER BY X)".
**
** * No percentile(Y,P) function exists in the SQL standard. Instead of
** percential(Y,P), developers must write this:
** "percentile_cont(P/100.0) WITHIN GROUP (ORDER BY Y)". Note that
** the fraction parameter to percentile() goes from 0 to 100 whereas
** the fraction parameter in SQL standard percentile_cont() goes from
** 0 to 1.
**
** Implementation notes as of 2024-08-31:
**
** * The regular aggregate-function versions of these routines work
** by accumulating all values in an array of doubles, then sorting
** that array using quicksort before computing the answer. Thus
** the runtime is O(NlogN) where N is the number of rows of input.
**
** * For the window-function versions of these routines, the array of
** inputs is sorted as soon as the first value is computed. Thereafter,
** the array is kept in sorted order using an insert-sort. This
** results in O(N*K) performance where K is the size of the window.
** One can imagine alternative implementations that give O(N*logN*logK)
** performance, but they require more complex logic and data structures.
** The developers have elected to keep the asymptotically slower
** algorithm for now, for simplicity, under the theory that window
** functions are seldom used and when they are, the window size K is
** often small. The developers might revisit that decision later,
** should the need arise.
*/
/* The following object is the group context for a single percentile()
** aggregate. Remember all input Y values until the very end.
** Those values are accumulated in the Percentile.a[] array.
*/
typedef struct Percentile Percentile;
struct Percentile {
u64 nAlloc; /* Number of slots allocated for a[] */
u64 nUsed; /* Number of slots actually used in a[] */
char bSorted; /* True if a[] is already in sorted order */
char bKeepSorted; /* True if advantageous to keep a[] sorted */
char bPctValid; /* True if rPct is valid */
double rPct; /* Fraction. 0.0 to 1.0 */
double *a; /* Array of Y values */
};
/*
** Return TRUE if the input floating-point number is an infinity.
*/
static int percentIsInfinity(double r){
sqlite3_uint64 u;
assert( sizeof(u)==sizeof(r) );
memcpy(&u, &r, sizeof(u));
return ((u>>52)&0x7ff)==0x7ff;
}
/*
** Return TRUE if two doubles differ by 0.001 or less.
*/
static int percentSameValue(double a, double b){
a -= b;
return a>=-0.001 && a<=0.001;
}
/*
** Search p (which must have p->bSorted) looking for an entry with
** value y. Return the index of that entry.
**
** If bExact is true, return -1 if the entry is not found.
**
** If bExact is false, return the index at which a new entry with
** value y should be insert in order to keep the values in sorted
** order. The smallest return value in this case will be 0, and
** the largest return value will be p->nUsed.
*/
static i64 percentBinarySearch(Percentile *p, double y, int bExact){
i64 iFirst = 0; /* First element of search range */
i64 iLast = (i64)p->nUsed - 1; /* Last element of search range */
while( iLast>=iFirst ){
i64 iMid = (iFirst+iLast)/2;
double x = p->a[iMid];
if( x<y ){
iFirst = iMid + 1;
}else if( x>y ){
iLast = iMid - 1;
}else{
return iMid;
}
}
if( bExact ) return -1;
return iFirst;
}
/*
** Generate an error for a percentile function.
**
** The error format string must have exactly one occurrence of "%%s()"
** (with two '%' characters). That substring will be replaced by the name
** of the function.
*/
static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){
char *zMsg1;
char *zMsg2;
va_list ap;
va_start(ap, zFormat);
zMsg1 = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
zMsg2 = zMsg1 ? sqlite3_mprintf(zMsg1, sqlite3VdbeFuncName(pCtx)) : 0;
sqlite3_result_error(pCtx, zMsg2, -1);
sqlite3_free(zMsg1);
sqlite3_free(zMsg2);
}
/*
** The "step" function for percentile(Y,P) is called once for each
** input row.
*/
static void percentStep(sqlite3_context *pCtx, int argc, sqlite3_value **argv){
Percentile *p;
double rPct;
int eType;
double y;
assert( argc==2 || argc==1 );
if( argc==1 ){
/* Requirement 13: median(Y) is the same as percentile(Y,50). */
rPct = 0.5;
}else{
/* P must be a number between 0 and 100 for percentile() or between
** 0.0 and 1.0 for percentile_cont() and percentile_disc().
**
** The user-data is an integer which is 10 times the upper bound.
*/
double mxFrac = (SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx))&2)? 100.0 : 1.0;
eType = sqlite3_value_numeric_type(argv[1]);
rPct = sqlite3_value_double(argv[1])/mxFrac;
if( (eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT)
|| rPct<0.0 || rPct>1.0
){
percentError(pCtx, "the fraction argument to %%s()"
" is not between 0.0 and %.1f",
(double)mxFrac);
return;
}
}
/* Allocate the session context. */
p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p));
if( p==0 ) return;
/* Remember the P value. Throw an error if the P value is different
** from any prior row, per Requirement (2). */
if( !p->bPctValid ){
p->rPct = rPct;
p->bPctValid = 1;
}else if( !percentSameValue(p->rPct,rPct) ){
percentError(pCtx, "the fraction argument to %%s()"
" is not the same for all input rows");
return;
}
/* Ignore rows for which Y is NULL */
eType = sqlite3_value_type(argv[0]);
if( eType==SQLITE_NULL ) return;
/* If not NULL, then Y must be numeric. Otherwise throw an error.
** Requirement 4 */
if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){
percentError(pCtx, "input to %%s() is not numeric");
return;
}
/* Throw an error if the Y value is infinity or NaN */
y = sqlite3_value_double(argv[0]);
if( percentIsInfinity(y) ){
percentError(pCtx, "Inf input to %%s()");
return;
}
/* Allocate and store the Y */
if( p->nUsed>=p->nAlloc ){
u64 n = p->nAlloc*2 + 250;
double *a = sqlite3_realloc64(p->a, sizeof(double)*n);
if( a==0 ){
sqlite3_free(p->a);
memset(p, 0, sizeof(*p));
sqlite3_result_error_nomem(pCtx);
return;
}
p->nAlloc = n;
p->a = a;
}
if( p->nUsed==0 ){
p->a[p->nUsed++] = y;
p->bSorted = 1;
}else if( !p->bSorted || y>=p->a[p->nUsed-1] ){
p->a[p->nUsed++] = y;
}else if( p->bKeepSorted ){
i64 i;
i = percentBinarySearch(p, y, 0);
if( i<(int)p->nUsed ){
memmove(&p->a[i+1], &p->a[i], (p->nUsed-i)*sizeof(p->a[0]));
}
p->a[i] = y;
p->nUsed++;
}else{
p->a[p->nUsed++] = y;
p->bSorted = 0;
}
}
/*
** Interchange two doubles.
*/
#define SWAP_DOUBLE(X,Y) {double ttt=(X);(X)=(Y);(Y)=ttt;}
/*
** Sort an array of doubles.
**
** Algorithm: quicksort
**
** This is implemented separately rather than using the qsort() routine
** from the standard library because:
**
** (1) To avoid a dependency on qsort()
** (2) To avoid the function call to the comparison routine for each
** comparison.
*/
static void percentSort(double *a, unsigned int n){
int iLt; /* Entries before a[iLt] are less than rPivot */
int iGt; /* Entries at or after a[iGt] are greater than rPivot */
int i; /* Loop counter */
double rPivot; /* The pivot value */
assert( n>=2 );
if( a[0]>a[n-1] ){
SWAP_DOUBLE(a[0],a[n-1])
}
if( n==2 ) return;
iGt = n-1;
i = n/2;
if( a[0]>a[i] ){
SWAP_DOUBLE(a[0],a[i])
}else if( a[i]>a[iGt] ){
SWAP_DOUBLE(a[i],a[iGt])
}
if( n==3 ) return;
rPivot = a[i];
iLt = i = 1;
do{
if( a[i]<rPivot ){
if( i>iLt ) SWAP_DOUBLE(a[i],a[iLt])
iLt++;
i++;
}else if( a[i]>rPivot ){
do{
iGt--;
}while( iGt>i && a[iGt]>rPivot );
SWAP_DOUBLE(a[i],a[iGt])
}else{
i++;
}
}while( i<iGt );
if( iLt>=2 ) percentSort(a, iLt);
if( n-iGt>=2 ) percentSort(a+iGt, n-iGt);
/* Uncomment for testing */
#if 0
for(i=0; i<n-1; i++){
assert( a[i]<=a[i+1] );
}
#endif
}
/*
** The "inverse" function for percentile(Y,P) is called to remove a
** row that was previously inserted by "step".
*/
static void percentInverse(sqlite3_context *pCtx,int argc,sqlite3_value **argv){
Percentile *p;
int eType;
double y;
i64 i;
assert( argc==2 || argc==1 );
/* Allocate the session context. */
p = (Percentile*)sqlite3_aggregate_context(pCtx, sizeof(*p));
assert( p!=0 );
/* Ignore rows for which Y is NULL */
eType = sqlite3_value_type(argv[0]);
if( eType==SQLITE_NULL ) return;
/* If not NULL, then Y must be numeric. Otherwise throw an error.
** Requirement 4 */
if( eType!=SQLITE_INTEGER && eType!=SQLITE_FLOAT ){
return;
}
/* Ignore the Y value if it is infinity or NaN */
y = sqlite3_value_double(argv[0]);
if( percentIsInfinity(y) ){
return;
}
if( p->bSorted==0 ){
assert( p->nUsed>1 );
percentSort(p->a, p->nUsed);
p->bSorted = 1;
}
p->bKeepSorted = 1;
/* Find and remove the row */
i = percentBinarySearch(p, y, 1);
if( i>=0 ){
p->nUsed--;
if( i<(int)p->nUsed ){
memmove(&p->a[i], &p->a[i+1], (p->nUsed - i)*sizeof(p->a[0]));
}
}
}
/*
** Compute the final output of percentile(). Clean up all allocated
** memory if and only if bIsFinal is true.
*/
static void percentCompute(sqlite3_context *pCtx, int bIsFinal){
Percentile *p;
int settings = SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx))&1; /* Discrete? */
unsigned i1, i2;
double v1, v2;
double ix, vx;
p = (Percentile*)sqlite3_aggregate_context(pCtx, 0);
if( p==0 ) return;
if( p->a==0 ) return;
if( p->nUsed ){
if( p->bSorted==0 ){
assert( p->nUsed>1 );
percentSort(p->a, p->nUsed);
p->bSorted = 1;
}
ix = p->rPct*(p->nUsed-1);
i1 = (unsigned)ix;
if( settings & 1 ){
vx = p->a[i1];
}else{
i2 = ix==(double)i1 || i1==p->nUsed-1 ? i1 : i1+1;
v1 = p->a[i1];
v2 = p->a[i2];
vx = v1 + (v2-v1)*(ix-i1);
}
sqlite3_result_double(pCtx, vx);
}
if( bIsFinal ){
sqlite3_free(p->a);
memset(p, 0, sizeof(*p));
}else{
p->bKeepSorted = 1;
}
}
static void percentFinal(sqlite3_context *pCtx){
percentCompute(pCtx, 1);
}
static void percentValue(sqlite3_context *pCtx){
percentCompute(pCtx, 0);
}
/****** End of percentile family of functions ******/
#endif /* SQLITE_ENABLE_PERCENTILE */
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
/*
** Implementation of sqlite_filestat(SCHEMA).
**
** Return JSON text that describes low-level debug/diagnostic information
** about the sqlite3_file object associated with SCHEMA.
*/
static void filestatFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3 *db = sqlite3_context_db_handle(context);
const char *zDbName;
sqlite3_str *pStr;
Btree *pBtree;
zDbName = (const char*)sqlite3_value_text(argv[0]);
pBtree = sqlite3DbNameToBtree(db, zDbName);
if( pBtree ){
Pager *pPager;
sqlite3_file *fd;
int rc;
sqlite3BtreeEnter(pBtree);
pPager = sqlite3BtreePager(pBtree);
assert( pPager!=0 );
fd = sqlite3PagerFile(pPager);
pStr = sqlite3_str_new(db);
if( pStr==0 ){
sqlite3_result_error_nomem(context);
}else{
sqlite3_str_append(pStr, "{\"db\":", 6);
rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_FILESTAT, pStr);
if( rc ) sqlite3_str_append(pStr, "null", 4);
fd = sqlite3PagerJrnlFile(pPager);
if( fd && fd->pMethods!=0 ){
sqlite3_str_appendall(pStr, ",\"journal\":");
rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_FILESTAT, pStr);
if( rc ) sqlite3_str_append(pStr, "null", 4);
}
sqlite3_str_append(pStr, "}", 1);
sqlite3_result_text(context, sqlite3_str_finish(pStr), -1,
sqlite3_free);
}
sqlite3BtreeLeave(pBtree);
}else{
sqlite3_result_text(context, "{}", 2, SQLITE_STATIC);
}
}
#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILESTAT */
#ifdef SQLITE_DEBUG
/*
** Implementation of fpdecode(x,y,z) function.
**
** x is a real number that is to be decoded. y is the precision.
** z is the maximum real precision. Return a string that shows the
** results of the sqlite3FpDecode() function.
|
| ︙ | ︙ | |||
134011 134012 134013 134014 134015 134016 134017 134018 134019 134020 134021 134022 134023 134024 |
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
INLINE_FUNC(sqlite_offset, 1, INLINEFUNC_sqlite_offset, 0 ),
#endif
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
FUNCTION(rtrim, 2, 2, 0, trimFunc ),
FUNCTION(trim, 1, 3, 0, trimFunc ),
FUNCTION(trim, 2, 3, 0, trimFunc ),
FUNCTION(min, -3, 0, 1, minmaxFunc ),
| > > > | 135825 135826 135827 135828 135829 135830 135831 135832 135833 135834 135835 135836 135837 135838 135839 135840 135841 |
#endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */
INLINE_FUNC(unlikely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
INLINE_FUNC(likelihood, 2, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
INLINE_FUNC(likely, 1, INLINEFUNC_unlikely, SQLITE_FUNC_UNLIKELY),
#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
INLINE_FUNC(sqlite_offset, 1, INLINEFUNC_sqlite_offset, 0 ),
#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILESTAT)
FUNCTION(sqlite_filestat, 1, 0, 0, filestatFunc ),
#endif
FUNCTION(ltrim, 1, 1, 0, trimFunc ),
FUNCTION(ltrim, 2, 1, 0, trimFunc ),
FUNCTION(rtrim, 1, 2, 0, trimFunc ),
FUNCTION(rtrim, 2, 2, 0, trimFunc ),
FUNCTION(trim, 1, 3, 0, trimFunc ),
FUNCTION(trim, 2, 3, 0, trimFunc ),
FUNCTION(min, -3, 0, 1, minmaxFunc ),
|
| ︙ | ︙ | |||
134083 134084 134085 134086 134087 134088 134089 134090 134091 134092 134093 134094 134095 134096 |
WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep,
groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep,
groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
WAGGREGATE(string_agg, 2, 0, 0, groupConcatStep,
groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
#ifdef SQLITE_CASE_SENSITIVE_LIKE
LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
#else
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
| > > > > > > > > > > > > > > > | 135900 135901 135902 135903 135904 135905 135906 135907 135908 135909 135910 135911 135912 135913 135914 135915 135916 135917 135918 135919 135920 135921 135922 135923 135924 135925 135926 135927 135928 |
WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep,
groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep,
groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
WAGGREGATE(string_agg, 2, 0, 0, groupConcatStep,
groupConcatFinalize, groupConcatValue, groupConcatInverse, 0),
#ifdef SQLITE_ENABLE_PERCENTILE
WAGGREGATE(median, 1, 0,0, percentStep,
percentFinal, percentValue, percentInverse,
SQLITE_INNOCUOUS|SQLITE_SELFORDER1),
WAGGREGATE(percentile, 2, 0x2,0, percentStep,
percentFinal, percentValue, percentInverse,
SQLITE_INNOCUOUS|SQLITE_SELFORDER1),
WAGGREGATE(percentile_cont, 2, 0,0, percentStep,
percentFinal, percentValue, percentInverse,
SQLITE_INNOCUOUS|SQLITE_SELFORDER1),
WAGGREGATE(percentile_disc, 2, 0x1,0, percentStep,
percentFinal, percentValue, percentInverse,
SQLITE_INNOCUOUS|SQLITE_SELFORDER1),
#endif /* SQLITE_ENABLE_PERCENTILE */
LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
#ifdef SQLITE_CASE_SENSITIVE_LIKE
LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
LIKEFUNC(like, 3, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE),
#else
LIKEFUNC(like, 2, &likeInfoNorm, SQLITE_FUNC_LIKE),
LIKEFUNC(like, 3, &likeInfoNorm, SQLITE_FUNC_LIKE),
|
| ︙ | ︙ | |||
139582 139583 139584 139585 139586 139587 139588 139589 139590 139591 139592 139593 139594 139595 | /* Version 3.44.0 and later */ void *(*get_clientdata)(sqlite3*,const char*); int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); /* Version 3.50.0 and later */ int (*setlk_timeout)(sqlite3*,int,int); /* Version 3.51.0 and later */ int (*set_errmsg)(sqlite3*,int,const char*); }; /* ** This is the function signature used for all extension entry points. It ** is also defined in the file "loadext.c". */ typedef int (*sqlite3_loadext_entry)( | > > > > | 141414 141415 141416 141417 141418 141419 141420 141421 141422 141423 141424 141425 141426 141427 141428 141429 141430 141431 | /* Version 3.44.0 and later */ void *(*get_clientdata)(sqlite3*,const char*); int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); /* Version 3.50.0 and later */ int (*setlk_timeout)(sqlite3*,int,int); /* Version 3.51.0 and later */ int (*set_errmsg)(sqlite3*,int,const char*); int (*db_status64)(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int); /* Version 3.52.0 and later */ void (*str_truncate)(sqlite3_str*,int); void (*str_free)(sqlite3_str*); }; /* ** This is the function signature used for all extension entry points. It ** is also defined in the file "loadext.c". */ typedef int (*sqlite3_loadext_entry)( |
| ︙ | ︙ | |||
139919 139920 139921 139922 139923 139924 139925 139926 139927 139928 139929 139930 139931 139932 | /* Version 3.44.0 and later */ #define sqlite3_get_clientdata sqlite3_api->get_clientdata #define sqlite3_set_clientdata sqlite3_api->set_clientdata /* Version 3.50.0 and later */ #define sqlite3_setlk_timeout sqlite3_api->setlk_timeout /* Version 3.51.0 and later */ #define sqlite3_set_errmsg sqlite3_api->set_errmsg #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; | > > > > | 141755 141756 141757 141758 141759 141760 141761 141762 141763 141764 141765 141766 141767 141768 141769 141770 141771 141772 | /* Version 3.44.0 and later */ #define sqlite3_get_clientdata sqlite3_api->get_clientdata #define sqlite3_set_clientdata sqlite3_api->set_clientdata /* Version 3.50.0 and later */ #define sqlite3_setlk_timeout sqlite3_api->setlk_timeout /* Version 3.51.0 and later */ #define sqlite3_set_errmsg sqlite3_api->set_errmsg #define sqlite3_db_status64 sqlite3_api->db_status64 /* Version 3.52.0 and later */ #define sqlite3_str_truncate sqlite3_api->str_truncate #define sqlite3_str_free sqlite3_api->str_free #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) /* This case when the file really is being compiled as a loadable ** extension */ # define SQLITE_EXTENSION_INIT1 const sqlite3_api_routines *sqlite3_api=0; # define SQLITE_EXTENSION_INIT2(v) sqlite3_api=v; |
| ︙ | ︙ | |||
140444 140445 140446 140447 140448 140449 140450 | sqlite3_stmt_explain, /* Version 3.44.0 and later */ sqlite3_get_clientdata, sqlite3_set_clientdata, /* Version 3.50.0 and later */ sqlite3_setlk_timeout, /* Version 3.51.0 and later */ | | > > > > | 142284 142285 142286 142287 142288 142289 142290 142291 142292 142293 142294 142295 142296 142297 142298 142299 142300 142301 142302 | sqlite3_stmt_explain, /* Version 3.44.0 and later */ sqlite3_get_clientdata, sqlite3_set_clientdata, /* Version 3.50.0 and later */ sqlite3_setlk_timeout, /* Version 3.51.0 and later */ sqlite3_set_errmsg, sqlite3_db_status64, /* Version 3.52.0 and later */ sqlite3_str_truncate, sqlite3_str_free }; /* True if x is the directory separator character */ #if SQLITE_OS_WIN # define DirSep(X) ((X)=='/'||(X)=='\\') #else |
| ︙ | ︙ | |||
144644 144645 144646 144647 144648 144649 144650 |
pData->rc = SQLITE_NOMEM_BKPT;
}else if( pData->pzErrMsg[0]!=0 ){
/* A error message has already been generated. Do not overwrite it */
}else if( pData->mInitFlags & (INITFLAG_AlterMask) ){
static const char *azAlterType[] = {
"rename",
"drop column",
| | > | 146488 146489 146490 146491 146492 146493 146494 146495 146496 146497 146498 146499 146500 146501 146502 146503 |
pData->rc = SQLITE_NOMEM_BKPT;
}else if( pData->pzErrMsg[0]!=0 ){
/* A error message has already been generated. Do not overwrite it */
}else if( pData->mInitFlags & (INITFLAG_AlterMask) ){
static const char *azAlterType[] = {
"rename",
"drop column",
"add column",
"drop constraint"
};
*pData->pzErrMsg = sqlite3MPrintf(db,
"error in %s %s after %s: %s", azObj[0], azObj[1],
azAlterType[(pData->mInitFlags&INITFLAG_AlterMask)-1],
zExtra
);
pData->rc = SQLITE_ERROR;
|
| ︙ | ︙ | |||
148136 148137 148138 148139 148140 148141 148142 |
zType = sqlite3StdType[j];
break;
}
}
}
}
if( zType ){
| | | | 149981 149982 149983 149984 149985 149986 149987 149988 149989 149990 149991 149992 149993 149994 149995 149996 |
zType = sqlite3StdType[j];
break;
}
}
}
}
if( zType ){
const i64 k = strlen(zType);
n = strlen(pCol->zCnName);
pCol->zCnName = sqlite3DbReallocOrFree(db, pCol->zCnName, n+k+2);
pCol->colFlags &= ~(COLFLAG_HASTYPE|COLFLAG_HASCOLL);
if( pCol->zCnName ){
memcpy(&pCol->zCnName[n+1], zType, k+1);
pCol->colFlags |= COLFLAG_HASTYPE;
}
}
|
| ︙ | ︙ | |||
152529 152530 152531 152532 152533 152534 152535 152536 152537 152538 152539 152540 152541 152542 |
pOBList = pFunc->pFExpr->pLeft->x.pList;
if( !pFunc->bOBUnique ){
nExtra++; /* One extra column for the OP_Sequence */
}
if( pFunc->bOBPayload ){
/* extra columns for the function arguments */
assert( ExprUseXList(pFunc->pFExpr) );
nExtra += pFunc->pFExpr->x.pList->nExpr;
}
if( pFunc->bUseSubtype ){
nExtra += pFunc->pFExpr->x.pList->nExpr;
}
pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra);
if( !pFunc->bOBUnique && pParse->nErr==0 ){
| > | 154374 154375 154376 154377 154378 154379 154380 154381 154382 154383 154384 154385 154386 154387 154388 |
pOBList = pFunc->pFExpr->pLeft->x.pList;
if( !pFunc->bOBUnique ){
nExtra++; /* One extra column for the OP_Sequence */
}
if( pFunc->bOBPayload ){
/* extra columns for the function arguments */
assert( ExprUseXList(pFunc->pFExpr) );
assert( pFunc->pFExpr->x.pList!=0 );
nExtra += pFunc->pFExpr->x.pList->nExpr;
}
if( pFunc->bUseSubtype ){
nExtra += pFunc->pFExpr->x.pList->nExpr;
}
pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra);
if( !pFunc->bOBUnique && pParse->nErr==0 ){
|
| ︙ | ︙ | |||
159942 159943 159944 159945 159946 159947 159948 159949 159950 159951 159952 159953 159954 159955 159956 159957 159958 |
pTab->pSchema = db->aDb[0].pSchema;
assert( pTab->u.vtab.nArg==0 );
pTab->iPKey = -1;
pTab->tabFlags |= TF_Eponymous;
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
addModuleArgument(pParse, pTab, 0);
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
if( rc ){
sqlite3ErrorMsg(pParse, "%s", zErr);
sqlite3DbFree(db, zErr);
sqlite3VtabEponymousTableClear(db, pMod);
}
return 1;
}
/*
| > > > | 161788 161789 161790 161791 161792 161793 161794 161795 161796 161797 161798 161799 161800 161801 161802 161803 161804 161805 161806 161807 |
pTab->pSchema = db->aDb[0].pSchema;
assert( pTab->u.vtab.nArg==0 );
pTab->iPKey = -1;
pTab->tabFlags |= TF_Eponymous;
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
addModuleArgument(pParse, pTab, 0);
addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
db->nSchemaLock++;
rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
db->nSchemaLock--;
if( rc ){
sqlite3ErrorMsg(pParse, "%s", zErr);
pParse->rc = rc;
sqlite3DbFree(db, zErr);
sqlite3VtabEponymousTableClear(db, pMod);
}
return 1;
}
/*
|
| ︙ | ︙ | |||
171435 171436 171437 171438 171439 171440 171441 |
rUnsort -= 2; /* TUNING: Slight bias in favor of no-sort plans */
}
/* Check to see if pWLoop should be added to the set of
** mxChoice best-so-far paths.
**
** First look for an existing path among best-so-far paths
| > | > > > > > > | | | 173284 173285 173286 173287 173288 173289 173290 173291 173292 173293 173294 173295 173296 173297 173298 173299 173300 173301 173302 173303 173304 173305 173306 173307 173308 173309 173310 173311 173312 173313 173314 173315 |
rUnsort -= 2; /* TUNING: Slight bias in favor of no-sort plans */
}
/* Check to see if pWLoop should be added to the set of
** mxChoice best-so-far paths.
**
** First look for an existing path among best-so-far paths
** that:
** (1) covers the same set of loops, and
** (2) has a compatible isOrdered value.
**
** "Compatible isOrdered value" means either
** (A) both have isOrdered==-1, or
** (B) both have isOrder>=0, or
** (C) ordering does not matter because this is the last round
** of the solver.
**
** The term "((pTo->isOrdered^isOrdered)&0x80)==0" is equivalent
** to (pTo->isOrdered==(-1))==(isOrdered==(-1))" for the range
** of legal values for isOrdered, -1..64.
*/
testcase( nTo==0 );
for(jj=0, pTo=aTo; jj<nTo; jj++, pTo++){
if( pTo->maskLoop==maskNew
&& ( ((pTo->isOrdered^isOrdered)&0x80)==0 || iLoop==nLoop-1 )
){
testcase( jj==nTo-1 );
break;
}
}
if( jj>=nTo ){
/* None of the existing best-so-far paths match the candidate. */
|
| ︙ | ︙ | |||
171593 171594 171595 171596 171597 171598 171599 |
/* Swap the roles of aFrom and aTo for the next generation */
pFrom = aTo;
aTo = aFrom;
aFrom = pFrom;
nFrom = nTo;
}
| < > > > > | 173449 173450 173451 173452 173453 173454 173455 173456 173457 173458 173459 173460 173461 173462 173463 173464 173465 173466 173467 173468 173469 173470 173471 173472 173473 |
/* Swap the roles of aFrom and aTo for the next generation */
pFrom = aTo;
aTo = aFrom;
aFrom = pFrom;
nFrom = nTo;
}
if( nFrom==0 ){
sqlite3ErrorMsg(pParse, "no query solution");
sqlite3StackFreeNN(pParse->db, pSpace);
return SQLITE_ERROR;
}
/* Only one path is available, which is the best path */
assert( nFrom==1 );
pFrom = aFrom;
assert( pWInfo->nLevel==nLoop );
/* Load the lowest cost path into pWInfo */
for(iLoop=0; iLoop<nLoop; iLoop++){
WhereLevel *pLevel = pWInfo->a + iLoop;
pLevel->pWLoop = pWLoop = pFrom->aLoop[iLoop];
pLevel->iFrom = pWLoop->iTab;
pLevel->iTabCur = pWInfo->pTabList->a[pLevel->iFrom].iCursor;
|
| ︙ | ︙ | |||
172996 172997 172998 172999 173000 173001 173002 |
op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT;
addrSeek = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n);
VdbeCoverageIf(v, op==OP_SeekLT);
VdbeCoverageIf(v, op==OP_SeekGT);
sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
}
#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
| | > > > > > > > > > > > > > | > | 174855 174856 174857 174858 174859 174860 174861 174862 174863 174864 174865 174866 174867 174868 174869 174870 174871 174872 174873 174874 174875 174876 174877 174878 174879 174880 174881 174882 174883 174884 |
op = pLevel->op==OP_Prev ? OP_SeekLT : OP_SeekGT;
addrSeek = sqlite3VdbeAddOp4Int(v, op, pLevel->iIdxCur, 0, r1, n);
VdbeCoverageIf(v, op==OP_SeekLT);
VdbeCoverageIf(v, op==OP_SeekGT);
sqlite3VdbeAddOp2(v, OP_Goto, 1, pLevel->p2);
}
#endif /* SQLITE_DISABLE_SKIPAHEAD_DISTINCT */
if( pTabList->a[pLevel->iFrom].fg.fromExists && i==pWInfo->nLevel-1 ){
/* If the EXISTS-to-JOIN optimization was applied, then the EXISTS
** loop(s) will be the inner-most loops of the join. There might be
** multiple EXISTS loops, but they will all be nested, and the join
** order will not have been changed by the query planner. If the
** inner-most EXISTS loop sees a single successful row, it should
** break out of *all* EXISTS loops. But only the inner-most of the
** nested EXISTS loops should do this breakout. */
int nOuter = 0; /* Nr of outer EXISTS that this one is nested within */
while( nOuter<i ){
if( !pTabList->a[pLevel[-nOuter-1].iFrom].fg.fromExists ) break;
nOuter++;
}
testcase( nOuter>0 );
sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel[-nOuter].addrBrk);
VdbeComment((v, "EXISTS break"));
}
/* The common case: Advance to the next row */
if( pLevel->addrCont ) sqlite3VdbeResolveLabel(v, pLevel->addrCont);
sqlite3VdbeAddOp3(v, pLevel->op, pLevel->p1, pLevel->p2, pLevel->p3);
sqlite3VdbeChangeP5(v, pLevel->p5);
VdbeCoverage(v);
VdbeCoverageIf(v, pLevel->op==OP_Next);
|
| ︙ | ︙ | |||
176584 176585 176586 176587 176588 176589 176590 |
return pSelect;
}
/* Memory allocator for parser stack resizing. This is a thin wrapper around
** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate
** testing.
*/
| | > > > > | > > > > > > > > > > > | 178457 178458 178459 178460 178461 178462 178463 178464 178465 178466 178467 178468 178469 178470 178471 178472 178473 178474 178475 178476 178477 178478 178479 178480 178481 178482 178483 178484 178485 178486 178487 |
return pSelect;
}
/* Memory allocator for parser stack resizing. This is a thin wrapper around
** sqlite3_realloc() that includes a call to sqlite3FaultSim() to facilitate
** testing.
*/
static void *parserStackRealloc(
void *pOld, /* Prior allocation */
sqlite3_uint64 newSize, /* Requested new alloation size */
Parse *pParse /* Parsing context */
){
void *p = sqlite3FaultSim(700) ? 0 : sqlite3_realloc(pOld, newSize);
if( p==0 ) sqlite3OomFault(pParse->db);
return p;
}
static void parserStackFree(void *pOld, Parse *pParse){
(void)pParse;
sqlite3_free(pOld);
}
/* Return an integer that is the maximum allowed stack size */
static int parserStackSizeLimit(Parse *pParse){
return pParse->db->aLimit[SQLITE_LIMIT_PARSER_DEPTH];
}
/* Construct a new Expr object from a single token */
static Expr *tokenExpr(Parse *pParse, int op, Token t){
Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
if( p ){
|
| ︙ | ︙ | |||
176942 176943 176944 176945 176946 176947 176948 | Window* yy483; int yy502; SrcList* yy563; Expr* yy590; Select* yy637; } YYMINORTYPE; #ifndef YYSTACKDEPTH | | > > | > > > > > > > | | | | | | | | | | | | 178830 178831 178832 178833 178834 178835 178836 178837 178838 178839 178840 178841 178842 178843 178844 178845 178846 178847 178848 178849 178850 178851 178852 178853 178854 178855 178856 178857 178858 178859 178860 178861 178862 178863 178864 178865 178866 178867 178868 178869 178870 178871 178872 178873 178874 178875 178876 178877 178878 178879 178880 | Window* yy483; int yy502; SrcList* yy563; Expr* yy590; Select* yy637; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 50 #endif #define sqlite3ParserARG_SDECL #define sqlite3ParserARG_PDECL #define sqlite3ParserARG_PARAM #define sqlite3ParserARG_FETCH #define sqlite3ParserARG_STORE #undef YYREALLOC #define YYREALLOC parserStackRealloc #undef YYFREE #define YYFREE parserStackFree #undef YYDYNSTACK #define YYDYNSTACK 1 #undef YYSIZELIMIT #define YYSIZELIMIT parserStackSizeLimit #define sqlite3ParserCTX(P) ((P)->pParse) #define sqlite3ParserCTX_SDECL Parse *pParse; #define sqlite3ParserCTX_PDECL ,Parse *pParse #define sqlite3ParserCTX_PARAM ,pParse #define sqlite3ParserCTX_FETCH Parse *pParse=yypParser->pParse; #define sqlite3ParserCTX_STORE yypParser->pParse=pParse; #undef YYERRORSYMBOL #undef YYERRSYMDT #undef YYFALLBACK #define YYFALLBACK 1 #define YYNSTATE 602 #define YYNRULE 414 #define YYNRULE_WITH_ACTION 349 #define YYNTOKEN 187 #define YY_MAX_SHIFT 601 #define YY_MIN_SHIFTREDUCE 870 #define YY_MAX_SHIFTREDUCE 1283 #define YY_ERROR_ACTION 1284 #define YY_ACCEPT_ACTION 1285 #define YY_NO_ACTION 1286 #define YY_MIN_REDUCE 1287 #define YY_MAX_REDUCE 1700 #define YY_MIN_DSTRCTR 206 #define YY_MAX_DSTRCTR 320 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) /* Define the yytestcase() macro to be a no-op if is not already defined ** otherwise. |
| ︙ | ︙ | |||
177054 177055 177056 177057 177058 177059 177060 | ** yy_shift_ofst[] For each state, the offset into yy_action for ** shifting terminals. ** yy_reduce_ofst[] For each state, the offset into yy_action for ** shifting non-terminals after a reduce. ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > | < < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > < < < < < | | | | | | | | | | | | | | | | | | | | | > > > > > > > > > | < < < < < < < < < | | | | | | | | | | | | | | | | > > > > > > > > > > > > < < < < < < < < < < < < | | | | | | | | | | | | | | | | > > > > > > > > > > > > > > < < < < < < < < < < < < < < | | | | | | | | | | | | | | > > > > > > > > > > > > > > > > > > > | | > | | | | | | | | | | | | | | | | | | < < < < | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > | | > | | < > < | < < | | | | < < | | | | | | | | > > | | | | | < < | | | | | | | > > | | | | | | | | | | | | | | | | | > > > > | | | | | | | | | | | | | | | | | < | < | | | | > > > | | | | | | | | | | | | | | > | < | | | > | | > | < < > | < < < < | < | | | | | | < | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > | > > > | | | | > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > | 178951 178952 178953 178954 178955 178956 178957 178958 178959 178960 178961 178962 178963 178964 178965 178966 178967 178968 178969 178970 178971 178972 178973 178974 178975 178976 178977 178978 178979 178980 178981 178982 178983 178984 178985 178986 178987 178988 178989 178990 178991 178992 178993 178994 178995 178996 178997 178998 178999 179000 179001 179002 179003 179004 179005 179006 179007 179008 179009 179010 179011 179012 179013 179014 179015 179016 179017 179018 179019 179020 179021 179022 179023 179024 179025 179026 179027 179028 179029 179030 179031 179032 179033 179034 179035 179036 179037 179038 179039 179040 179041 179042 179043 179044 179045 179046 179047 179048 179049 179050 179051 179052 179053 179054 179055 179056 179057 179058 179059 179060 179061 179062 179063 179064 179065 179066 179067 179068 179069 179070 179071 179072 179073 179074 179075 179076 179077 179078 179079 179080 179081 179082 179083 179084 179085 179086 179087 179088 179089 179090 179091 179092 179093 179094 179095 179096 179097 179098 179099 179100 179101 179102 179103 179104 179105 179106 179107 179108 179109 179110 179111 179112 179113 179114 179115 179116 179117 179118 179119 179120 179121 179122 179123 179124 179125 179126 179127 179128 179129 179130 179131 179132 179133 179134 179135 179136 179137 179138 179139 179140 179141 179142 179143 179144 179145 179146 179147 179148 179149 179150 179151 179152 179153 179154 179155 179156 179157 179158 179159 179160 179161 179162 179163 179164 179165 179166 179167 179168 179169 179170 179171 179172 179173 179174 179175 179176 179177 179178 179179 179180 179181 179182 179183 179184 179185 179186 179187 179188 179189 179190 179191 179192 179193 179194 179195 179196 179197 179198 179199 179200 179201 179202 179203 179204 179205 179206 179207 179208 179209 179210 179211 179212 179213 179214 179215 179216 179217 179218 179219 179220 179221 179222 179223 179224 179225 179226 179227 179228 179229 179230 179231 179232 179233 179234 179235 179236 179237 179238 179239 179240 179241 179242 179243 179244 179245 179246 179247 179248 179249 179250 179251 179252 179253 179254 179255 179256 179257 179258 179259 179260 179261 179262 179263 179264 179265 179266 179267 179268 179269 179270 179271 179272 179273 179274 179275 179276 179277 179278 179279 179280 179281 179282 179283 179284 179285 179286 179287 179288 179289 179290 179291 179292 179293 179294 179295 179296 179297 179298 179299 179300 179301 179302 179303 179304 179305 179306 179307 179308 179309 179310 179311 179312 179313 179314 179315 179316 179317 179318 179319 179320 179321 179322 179323 179324 179325 179326 179327 179328 179329 179330 179331 179332 179333 179334 179335 179336 179337 179338 179339 179340 179341 179342 179343 179344 179345 179346 179347 179348 179349 179350 179351 179352 179353 179354 179355 179356 179357 179358 179359 179360 179361 179362 179363 179364 179365 179366 179367 179368 179369 179370 179371 179372 179373 179374 179375 179376 179377 179378 179379 179380 179381 179382 179383 179384 179385 179386 179387 179388 179389 179390 179391 179392 179393 179394 179395 179396 179397 179398 179399 179400 179401 179402 179403 179404 179405 179406 179407 179408 179409 179410 179411 179412 179413 179414 179415 179416 179417 179418 179419 179420 179421 179422 179423 179424 179425 179426 179427 179428 179429 179430 179431 179432 179433 179434 179435 179436 179437 179438 179439 179440 179441 179442 179443 179444 179445 179446 179447 179448 179449 179450 179451 179452 179453 179454 179455 179456 179457 179458 179459 179460 179461 179462 179463 179464 179465 179466 179467 179468 179469 179470 179471 179472 179473 179474 179475 179476 179477 179478 179479 179480 179481 179482 179483 179484 179485 179486 179487 179488 179489 179490 179491 179492 179493 179494 179495 179496 179497 179498 179499 179500 179501 179502 179503 179504 179505 179506 179507 179508 179509 179510 179511 179512 179513 179514 179515 179516 179517 179518 179519 179520 179521 179522 179523 179524 179525 179526 179527 179528 179529 179530 179531 179532 179533 179534 179535 179536 179537 179538 179539 179540 179541 179542 179543 179544 179545 179546 179547 179548 179549 179550 179551 179552 179553 179554 179555 179556 179557 179558 179559 179560 179561 179562 179563 179564 179565 179566 179567 179568 179569 179570 179571 179572 179573 179574 179575 179576 179577 179578 179579 179580 179581 179582 179583 179584 179585 179586 179587 179588 179589 179590 179591 179592 179593 179594 179595 179596 179597 179598 179599 179600 179601 179602 179603 179604 179605 179606 179607 179608 179609 179610 179611 179612 179613 179614 179615 179616 179617 179618 179619 179620 179621 179622 179623 179624 179625 179626 179627 179628 179629 179630 179631 179632 179633 179634 179635 179636 179637 179638 179639 179640 |
** yy_shift_ofst[] For each state, the offset into yy_action for
** shifting terminals.
** yy_reduce_ofst[] For each state, the offset into yy_action for
** shifting non-terminals after a reduce.
** yy_default[] Default action for each state.
**
*********** Begin parsing tables **********************************************/
#define YY_ACTTAB_COUNT (2379)
static const YYACTIONTYPE yy_action[] = {
/* 0 */ 134, 131, 238, 291, 291, 1358, 595, 1337, 479, 483,
/* 10 */ 595, 436, 595, 393, 595, 1358, 592, 595, 581, 425,
/* 20 */ 423, 1572, 134, 131, 238, 543, 479, 478, 577, 84,
/* 30 */ 84, 1008, 304, 51, 51, 51, 51, 63, 63, 1009,
/* 40 */ 84, 84, 1132, 141, 142, 93, 1132, 1258, 1258, 1088,
/* 50 */ 1091, 1078, 1078, 139, 139, 140, 140, 140, 140, 425,
/* 60 */ 297, 297, 1481, 297, 297, 569, 555, 297, 297, 134,
/* 70 */ 131, 238, 1130, 592, 544, 581, 592, 576, 581, 512,
/* 80 */ 592, 343, 581, 141, 142, 93, 578, 1258, 1258, 1088,
/* 90 */ 1091, 1078, 1078, 139, 139, 140, 140, 140, 140, 6,
/* 100 */ 479, 385, 1630, 138, 138, 138, 138, 137, 137, 136,
/* 110 */ 136, 136, 135, 132, 464, 1363, 1363, 595, 1044, 1603,
/* 120 */ 1285, 1, 1, 601, 2, 1289, 44, 1204, 231, 1204,
/* 130 */ 331, 425, 158, 1617, 392, 1617, 563, 116, 500, 1371,
/* 140 */ 84, 84, 569, 138, 138, 138, 138, 137, 137, 136,
/* 150 */ 136, 136, 135, 132, 464, 141, 142, 93, 517, 1258,
/* 160 */ 1258, 1088, 1091, 1078, 1078, 139, 139, 140, 140, 140,
/* 170 */ 140, 1234, 356, 212, 297, 297, 464, 576, 490, 1234,
/* 180 */ 570, 570, 143, 330, 586, 1320, 550, 592, 1199, 581,
/* 190 */ 491, 358, 45, 140, 140, 140, 140, 133, 394, 566,
/* 200 */ 1323, 1199, 253, 426, 1199, 137, 137, 136, 136, 136,
/* 210 */ 135, 132, 464, 292, 306, 138, 138, 138, 138, 137,
/* 220 */ 137, 136, 136, 136, 135, 132, 464, 1322, 1234, 1235,
/* 230 */ 1234, 1605, 413, 389, 468, 425, 1234, 1235, 1234, 491,
/* 240 */ 358, 138, 138, 138, 138, 137, 137, 136, 136, 136,
/* 250 */ 135, 132, 464, 113, 134, 131, 238, 557, 1606, 141,
/* 260 */ 142, 93, 595, 1258, 1258, 1088, 1091, 1078, 1078, 139,
/* 270 */ 139, 140, 140, 140, 140, 134, 131, 238, 1612, 425,
/* 280 */ 502, 185, 7, 334, 97, 19, 19, 994, 140, 140,
/* 290 */ 140, 140, 136, 136, 136, 135, 132, 464, 1179, 1692,
/* 300 */ 209, 1692, 1610, 141, 142, 93, 7, 1258, 1258, 1088,
/* 310 */ 1091, 1078, 1078, 139, 139, 140, 140, 140, 140, 138,
/* 320 */ 138, 138, 138, 137, 137, 136, 136, 136, 135, 132,
/* 330 */ 464, 1663, 1234, 589, 589, 589, 138, 138, 138, 138,
/* 340 */ 137, 137, 136, 136, 136, 135, 132, 464, 138, 138,
/* 350 */ 138, 138, 137, 137, 136, 136, 136, 135, 132, 464,
/* 360 */ 275, 595, 430, 138, 138, 138, 138, 137, 137, 136,
/* 370 */ 136, 136, 135, 132, 464, 400, 1234, 396, 1177, 461,
/* 380 */ 460, 237, 1611, 425, 51, 51, 7, 335, 1263, 1234,
/* 390 */ 1235, 1234, 1311, 1265, 549, 145, 1254, 283, 542, 542,
/* 400 */ 595, 1264, 597, 7, 597, 927, 994, 141, 142, 93,
/* 410 */ 506, 1258, 1258, 1088, 1091, 1078, 1078, 139, 139, 140,
/* 420 */ 140, 140, 140, 19, 19, 44, 1266, 425, 1266, 297,
/* 430 */ 297, 1234, 98, 1234, 1235, 1234, 265, 534, 439, 530,
/* 440 */ 527, 526, 592, 1633, 581, 928, 511, 272, 235, 525,
/* 450 */ 508, 141, 142, 93, 1254, 1258, 1258, 1088, 1091, 1078,
/* 460 */ 1078, 139, 139, 140, 140, 140, 140, 138, 138, 138,
/* 470 */ 138, 137, 137, 136, 136, 136, 135, 132, 464, 595,
/* 480 */ 422, 421, 330, 586, 1619, 517, 391, 517, 1234, 1235,
/* 490 */ 1234, 1274, 127, 587, 265, 4, 1311, 530, 527, 526,
/* 500 */ 595, 448, 84, 84, 594, 595, 572, 525, 1309, 590,
/* 510 */ 308, 138, 138, 138, 138, 137, 137, 136, 136, 136,
/* 520 */ 135, 132, 464, 19, 19, 161, 1234, 390, 19, 19,
/* 530 */ 1571, 425, 1535, 465, 1637, 601, 2, 1289, 444, 576,
/* 540 */ 330, 586, 331, 446, 158, 584, 1274, 481, 575, 595,
/* 550 */ 240, 1371, 506, 551, 1234, 141, 142, 93, 313, 1258,
/* 560 */ 1258, 1088, 1091, 1078, 1078, 139, 139, 140, 140, 140,
/* 570 */ 140, 160, 83, 83, 1065, 974, 135, 132, 464, 595,
/* 580 */ 125, 125, 973, 1234, 1235, 1234, 297, 297, 126, 517,
/* 590 */ 465, 596, 465, 297, 297, 1053, 1234, 1369, 387, 592,
/* 600 */ 1234, 581, 84, 84, 517, 242, 592, 1465, 581, 46,
/* 610 */ 473, 1234, 1235, 1234, 253, 138, 138, 138, 138, 137,
/* 620 */ 137, 136, 136, 136, 135, 132, 464, 1053, 1053, 1055,
/* 630 */ 1056, 35, 297, 297, 1370, 399, 425, 445, 996, 576,
/* 640 */ 372, 415, 233, 541, 413, 592, 468, 581, 452, 1366,
/* 650 */ 112, 552, 355, 1234, 1235, 1234, 1218, 1234, 1235, 1234,
/* 660 */ 141, 142, 93, 223, 1258, 1258, 1088, 1091, 1078, 1078,
/* 670 */ 139, 139, 140, 140, 140, 140, 297, 297, 441, 553,
/* 680 */ 425, 298, 298, 1375, 531, 330, 586, 1199, 115, 592,
/* 690 */ 1465, 581, 100, 1480, 592, 592, 581, 581, 559, 1307,
/* 700 */ 1199, 907, 545, 1199, 141, 142, 93, 498, 1258, 1258,
/* 710 */ 1088, 1091, 1078, 1078, 139, 139, 140, 140, 140, 140,
/* 720 */ 138, 138, 138, 138, 137, 137, 136, 136, 136, 135,
/* 730 */ 132, 464, 385, 1630, 297, 297, 470, 297, 297, 472,
/* 740 */ 200, 579, 1065, 201, 44, 127, 587, 592, 4, 581,
/* 750 */ 592, 1044, 581, 482, 40, 500, 558, 482, 907, 1054,
/* 760 */ 1479, 442, 590, 1053, 138, 138, 138, 138, 137, 137,
/* 770 */ 136, 136, 136, 135, 132, 464, 297, 297, 1234, 1657,
/* 780 */ 492, 1234, 1603, 480, 425, 506, 465, 1330, 911, 592,
/* 790 */ 918, 581, 1234, 1361, 1361, 1053, 1053, 1055, 584, 385,
/* 800 */ 1630, 330, 586, 353, 5, 356, 486, 344, 141, 142,
/* 810 */ 93, 185, 1258, 1258, 1088, 1091, 1078, 1078, 139, 139,
/* 820 */ 140, 140, 140, 140, 1218, 1694, 411, 1065, 425, 1234,
/* 830 */ 48, 309, 904, 125, 125, 1234, 1235, 1234, 1234, 1235,
/* 840 */ 1234, 126, 1234, 465, 596, 465, 348, 517, 1053, 1234,
/* 850 */ 1235, 1234, 141, 142, 93, 3, 1258, 1258, 1088, 1091,
/* 860 */ 1078, 1078, 139, 139, 140, 140, 140, 140, 138, 138,
/* 870 */ 138, 138, 137, 137, 136, 136, 136, 135, 132, 464,
/* 880 */ 1053, 1053, 1055, 1056, 35, 315, 1234, 1235, 1234, 1234,
/* 890 */ 1065, 1237, 363, 1234, 1604, 887, 389, 341, 500, 1234,
/* 900 */ 1235, 1234, 595, 1075, 1075, 1089, 1092, 1054, 345, 1218,
/* 910 */ 347, 1053, 138, 138, 138, 138, 137, 137, 136, 136,
/* 920 */ 136, 135, 132, 464, 436, 19, 19, 370, 567, 567,
/* 930 */ 595, 554, 425, 7, 1398, 325, 1217, 462, 462, 462,
/* 940 */ 316, 1582, 432, 1053, 1053, 1055, 1234, 1235, 1234, 1237,
/* 950 */ 1234, 1235, 1234, 84, 84, 489, 141, 142, 93, 595,
/* 960 */ 1258, 1258, 1088, 1091, 1078, 1078, 139, 139, 140, 140,
/* 970 */ 140, 140, 1218, 995, 312, 383, 425, 600, 1079, 1289,
/* 980 */ 1066, 115, 19, 19, 331, 382, 158, 1603, 1536, 365,
/* 990 */ 326, 368, 346, 1371, 216, 461, 460, 451, 1110, 236,
/* 1000 */ 141, 142, 93, 1465, 1258, 1258, 1088, 1091, 1078, 1078,
/* 1010 */ 139, 139, 140, 140, 140, 140, 138, 138, 138, 138,
/* 1020 */ 137, 137, 136, 136, 136, 135, 132, 464, 297, 297,
/* 1030 */ 595, 500, 1008, 1199, 595, 50, 1528, 398, 218, 218,
/* 1040 */ 1009, 592, 1266, 581, 1266, 450, 1199, 404, 522, 1199,
/* 1050 */ 376, 424, 418, 84, 84, 595, 253, 19, 19, 548,
/* 1060 */ 138, 138, 138, 138, 137, 137, 136, 136, 136, 135,
/* 1070 */ 132, 464, 210, 317, 443, 317, 269, 307, 19, 19,
/* 1080 */ 425, 307, 22, 22, 1049, 294, 413, 994, 468, 593,
/* 1090 */ 327, 961, 961, 571, 269, 1603, 1603, 595, 231, 1604,
/* 1100 */ 425, 389, 410, 1279, 141, 142, 93, 314, 1258, 1258,
/* 1110 */ 1088, 1091, 1078, 1078, 139, 139, 140, 140, 140, 140,
/* 1120 */ 84, 84, 533, 387, 141, 142, 93, 434, 1258, 1258,
/* 1130 */ 1088, 1091, 1078, 1078, 139, 139, 140, 140, 140, 140,
/* 1140 */ 447, 1541, 1585, 47, 49, 431, 282, 300, 384, 536,
/* 1150 */ 379, 535, 270, 595, 436, 595, 1465, 458, 375, 1541,
/* 1160 */ 1543, 375, 455, 431, 138, 138, 138, 138, 137, 137,
/* 1170 */ 136, 136, 136, 135, 132, 464, 84, 84, 84, 84,
/* 1180 */ 595, 237, 1280, 1583, 138, 138, 138, 138, 137, 137,
/* 1190 */ 136, 136, 136, 135, 132, 464, 1179, 1693, 10, 1693,
/* 1200 */ 275, 565, 1151, 149, 149, 475, 994, 1604, 1604, 389,
/* 1210 */ 389, 1465, 1199, 459, 425, 463, 226, 1152, 1150, 1609,
/* 1220 */ 564, 303, 1608, 7, 217, 1199, 7, 513, 1199, 1210,
/* 1230 */ 1312, 432, 1153, 1541, 425, 1662, 1254, 936, 141, 142,
/* 1240 */ 93, 119, 1258, 1258, 1088, 1091, 1078, 1078, 139, 139,
/* 1250 */ 140, 140, 140, 140, 583, 302, 538, 1396, 141, 142,
/* 1260 */ 93, 6, 1258, 1258, 1088, 1091, 1078, 1078, 139, 139,
/* 1270 */ 140, 140, 140, 140, 588, 432, 1177, 1135, 1135, 514,
/* 1280 */ 1151, 1210, 456, 969, 333, 288, 433, 187, 968, 595,
/* 1290 */ 129, 595, 547, 595, 1254, 1152, 1341, 551, 138, 138,
/* 1300 */ 138, 138, 137, 137, 136, 136, 136, 135, 132, 464,
/* 1310 */ 1153, 595, 151, 151, 53, 53, 54, 54, 138, 138,
/* 1320 */ 138, 138, 137, 137, 136, 136, 136, 135, 132, 464,
/* 1330 */ 504, 595, 947, 595, 68, 68, 595, 296, 235, 595,
/* 1340 */ 507, 595, 948, 595, 101, 222, 595, 484, 425, 875,
/* 1350 */ 876, 877, 215, 219, 69, 69, 21, 21, 423, 55,
/* 1360 */ 55, 1584, 70, 70, 56, 56, 71, 71, 425, 72,
/* 1370 */ 72, 1183, 141, 142, 93, 123, 1258, 1258, 1088, 1091,
/* 1380 */ 1078, 1078, 139, 139, 140, 140, 140, 140, 425, 268,
/* 1390 */ 267, 266, 141, 142, 93, 552, 1258, 1258, 1088, 1091,
/* 1400 */ 1078, 1078, 139, 139, 140, 140, 140, 140, 23, 163,
/* 1410 */ 496, 572, 141, 130, 93, 476, 1258, 1258, 1088, 1091,
/* 1420 */ 1078, 1078, 139, 139, 140, 140, 140, 140, 505, 124,
/* 1430 */ 1580, 121, 138, 138, 138, 138, 137, 137, 136, 136,
/* 1440 */ 136, 135, 132, 464, 595, 225, 595, 899, 437, 246,
/* 1450 */ 336, 1253, 138, 138, 138, 138, 137, 137, 136, 136,
/* 1460 */ 136, 135, 132, 464, 595, 1340, 595, 73, 73, 74,
/* 1470 */ 74, 337, 138, 138, 138, 138, 137, 137, 136, 136,
/* 1480 */ 136, 135, 132, 464, 38, 595, 493, 75, 75, 57,
/* 1490 */ 57, 595, 425, 410, 1178, 1274, 497, 423, 250, 969,
/* 1500 */ 329, 164, 914, 16, 968, 899, 1117, 423, 58, 58,
/* 1510 */ 595, 423, 425, 595, 59, 59, 39, 142, 93, 340,
/* 1520 */ 1258, 1258, 1088, 1091, 1078, 1078, 139, 139, 140, 140,
/* 1530 */ 140, 140, 595, 61, 61, 595, 62, 62, 93, 595,
/* 1540 */ 1258, 1258, 1088, 1091, 1078, 1078, 139, 139, 140, 140,
/* 1550 */ 140, 140, 1410, 926, 925, 76, 76, 1409, 77, 77,
/* 1560 */ 914, 485, 78, 78, 1117, 1174, 595, 412, 595, 226,
/* 1570 */ 595, 127, 587, 1280, 4, 1592, 138, 138, 138, 138,
/* 1580 */ 137, 137, 136, 136, 136, 135, 132, 464, 590, 20,
/* 1590 */ 20, 79, 79, 147, 147, 595, 138, 138, 138, 138,
/* 1600 */ 137, 137, 136, 136, 136, 135, 132, 464, 595, 354,
/* 1610 */ 169, 115, 465, 595, 349, 595, 252, 595, 148, 148,
/* 1620 */ 595, 1046, 595, 274, 584, 494, 112, 499, 595, 274,
/* 1630 */ 1560, 80, 80, 595, 44, 1559, 64, 64, 81, 81,
/* 1640 */ 65, 65, 595, 82, 82, 66, 66, 509, 310, 595,
/* 1650 */ 360, 173, 173, 1065, 595, 553, 174, 174, 595, 125,
/* 1660 */ 125, 501, 595, 274, 1406, 89, 89, 126, 299, 465,
/* 1670 */ 596, 465, 67, 67, 1053, 595, 364, 85, 85, 595,
/* 1680 */ 1057, 150, 150, 933, 934, 86, 86, 127, 587, 367,
/* 1690 */ 4, 330, 586, 359, 523, 115, 271, 369, 171, 171,
/* 1700 */ 1011, 1012, 152, 152, 590, 1339, 1053, 1053, 1055, 1056,
/* 1710 */ 35, 371, 373, 595, 115, 1354, 1338, 9, 595, 168,
/* 1720 */ 595, 115, 595, 1113, 595, 271, 595, 378, 465, 595,
/* 1730 */ 388, 1419, 595, 539, 595, 1218, 146, 146, 1057, 1464,
/* 1740 */ 584, 172, 172, 165, 165, 156, 156, 155, 155, 153,
/* 1750 */ 153, 1392, 154, 154, 561, 88, 88, 90, 90, 560,
/* 1760 */ 127, 587, 1129, 4, 1129, 999, 208, 274, 595, 1065,
/* 1770 */ 595, 967, 595, 129, 1404, 125, 125, 590, 964, 1128,
/* 1780 */ 129, 1128, 897, 126, 162, 465, 596, 465, 1651, 582,
/* 1790 */ 1053, 87, 87, 52, 52, 60, 60, 966, 1624, 129,
/* 1800 */ 1469, 465, 1319, 243, 1310, 1298, 1297, 1299, 1644, 170,
/* 1810 */ 518, 1389, 289, 584, 12, 322, 323, 324, 228, 409,
/* 1820 */ 1451, 305, 1053, 1053, 1055, 1056, 35, 561, 241, 351,
/* 1830 */ 245, 1446, 562, 127, 587, 357, 4, 1439, 352, 311,
/* 1840 */ 1456, 503, 1065, 528, 1455, 416, 232, 1401, 125, 125,
/* 1850 */ 590, 1218, 381, 1532, 1337, 1531, 126, 1402, 465, 596,
/* 1860 */ 465, 1400, 1399, 1053, 585, 213, 403, 227, 214, 537,
/* 1870 */ 1647, 1587, 1274, 1589, 465, 1588, 239, 278, 1271, 1579,
/* 1880 */ 1577, 96, 435, 100, 224, 198, 584, 1537, 183, 99,
/* 1890 */ 191, 487, 488, 1452, 521, 1053, 1053, 1055, 1056, 35,
/* 1900 */ 561, 13, 193, 194, 195, 560, 196, 255, 113, 414,
/* 1910 */ 1458, 1457, 14, 510, 495, 1065, 259, 1460, 202, 106,
/* 1920 */ 516, 125, 125, 417, 1218, 290, 1548, 1526, 261, 126,
/* 1930 */ 206, 465, 596, 465, 362, 519, 1053, 419, 366, 262,
/* 1940 */ 1357, 1300, 1356, 449, 263, 1355, 1348, 108, 918, 1327,
/* 1950 */ 1661, 420, 1660, 233, 1326, 453, 1629, 380, 546, 1347,
/* 1960 */ 1325, 454, 277, 276, 1659, 1615, 1614, 457, 1053, 1053,
/* 1970 */ 1055, 1056, 35, 1636, 1222, 467, 320, 321, 301, 386,
/* 1980 */ 144, 1424, 572, 408, 408, 407, 285, 405, 11, 1423,
/* 1990 */ 884, 397, 120, 127, 587, 220, 4, 1218, 1380, 1513,
/* 2000 */ 395, 114, 1379, 247, 42, 339, 556, 598, 1228, 284,
/* 2010 */ 590, 401, 402, 338, 286, 287, 328, 599, 1295, 1290,
/* 2020 */ 1564, 175, 428, 1565, 429, 1563, 176, 871, 159, 177,
/* 2030 */ 1562, 318, 229, 466, 465, 230, 221, 91, 332, 469,
/* 2040 */ 1169, 471, 474, 94, 249, 189, 584, 95, 244, 1127,
/* 2050 */ 188, 1125, 178, 342, 190, 43, 1253, 179, 251, 950,
/* 2060 */ 254, 350, 192, 1141, 197, 180, 181, 438, 182, 440,
/* 2070 */ 102, 103, 248, 104, 199, 1065, 1144, 256, 105, 1140,
/* 2080 */ 257, 125, 125, 24, 166, 258, 361, 1133, 274, 126,
/* 2090 */ 515, 465, 596, 465, 260, 15, 1053, 204, 264, 382,
/* 2100 */ 886, 92, 587, 1268, 4, 203, 520, 427, 205, 524,
/* 2110 */ 107, 25, 330, 586, 374, 574, 26, 916, 590, 529,
/* 2120 */ 377, 929, 109, 319, 167, 110, 27, 184, 1053, 1053,
/* 2130 */ 1055, 1056, 35, 540, 532, 1215, 477, 1094, 111, 1185,
/* 2140 */ 17, 234, 465, 293, 1184, 295, 207, 997, 129, 273,
/* 2150 */ 1205, 28, 1003, 29, 584, 30, 1201, 1218, 1208, 31,
/* 2160 */ 1203, 1209, 32, 1190, 41, 568, 33, 34, 211, 115,
/* 2170 */ 8, 1108, 1095, 1093, 1097, 1098, 279, 580, 122, 1149,
/* 2180 */ 36, 117, 18, 1065, 1058, 118, 898, 128, 37, 125,
/* 2190 */ 125, 406, 591, 186, 960, 280, 281, 126, 1652, 465,
/* 2200 */ 596, 465, 1222, 467, 1053, 157, 301, 1224, 1223, 1286,
/* 2210 */ 1286, 408, 408, 407, 285, 405, 1286, 1286, 884, 1286,
/* 2220 */ 301, 1286, 1286, 573, 1286, 408, 408, 407, 285, 405,
/* 2230 */ 1286, 247, 884, 339, 1286, 1286, 1053, 1053, 1055, 1056,
/* 2240 */ 35, 338, 1286, 1286, 1286, 247, 1286, 339, 1286, 1286,
/* 2250 */ 1286, 1286, 1286, 1286, 1286, 338, 1286, 1286, 1286, 1286,
/* 2260 */ 1286, 1286, 1286, 1286, 1286, 1218, 1286, 1286, 1286, 1286,
/* 2270 */ 1286, 1286, 249, 1286, 1286, 1286, 1286, 1286, 1286, 1286,
/* 2280 */ 178, 1286, 1286, 43, 1286, 1286, 249, 1286, 1286, 1286,
/* 2290 */ 1286, 1286, 1286, 1286, 178, 1286, 1286, 43, 1286, 1286,
/* 2300 */ 248, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286,
/* 2310 */ 1286, 1286, 1286, 1286, 248, 1286, 1286, 1286, 1286, 1286,
/* 2320 */ 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286,
/* 2330 */ 1286, 1286, 1286, 1286, 1286, 427, 1286, 1286, 1286, 1286,
/* 2340 */ 330, 586, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 427,
/* 2350 */ 1286, 1286, 1286, 1286, 330, 586, 1286, 1286, 1286, 1286,
/* 2360 */ 1286, 1286, 1286, 1286, 477, 1286, 1286, 1286, 1286, 1286,
/* 2370 */ 1286, 1286, 1286, 1286, 1286, 1286, 1286, 1286, 477,
};
static const YYCODETYPE yy_lookahead[] = {
/* 0 */ 277, 278, 279, 241, 242, 225, 195, 227, 195, 246,
/* 10 */ 195, 195, 195, 221, 195, 235, 254, 195, 256, 19,
/* 20 */ 257, 298, 277, 278, 279, 206, 213, 214, 206, 218,
/* 30 */ 219, 31, 206, 218, 219, 218, 219, 218, 219, 39,
/* 40 */ 218, 219, 29, 43, 44, 45, 33, 47, 48, 49,
/* 50 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 19,
/* 60 */ 241, 242, 276, 241, 242, 195, 255, 241, 242, 277,
/* 70 */ 278, 279, 11, 254, 255, 256, 254, 255, 256, 66,
/* 80 */ 254, 265, 256, 43, 44, 45, 264, 47, 48, 49,
/* 90 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 215,
/* 100 */ 287, 315, 316, 103, 104, 105, 106, 107, 108, 109,
/* 110 */ 110, 111, 112, 113, 114, 237, 238, 195, 74, 195,
/* 120 */ 187, 188, 189, 190, 191, 192, 82, 87, 25, 89,
/* 130 */ 197, 19, 199, 318, 319, 318, 319, 25, 195, 206,
/* 140 */ 218, 219, 195, 103, 104, 105, 106, 107, 108, 109,
/* 150 */ 110, 111, 112, 113, 114, 43, 44, 45, 195, 47,
/* 160 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
/* 170 */ 58, 60, 128, 289, 241, 242, 114, 255, 294, 60,
/* 180 */ 310, 311, 70, 139, 140, 218, 264, 254, 77, 256,
/* 190 */ 129, 130, 73, 55, 56, 57, 58, 59, 221, 88,
/* 200 */ 218, 90, 269, 240, 93, 107, 108, 109, 110, 111,
/* 210 */ 112, 113, 114, 215, 271, 103, 104, 105, 106, 107,
/* 220 */ 108, 109, 110, 111, 112, 113, 114, 218, 117, 118,
/* 230 */ 119, 307, 299, 309, 301, 19, 117, 118, 119, 129,
/* 240 */ 130, 103, 104, 105, 106, 107, 108, 109, 110, 111,
/* 250 */ 112, 113, 114, 150, 277, 278, 279, 146, 311, 43,
/* 260 */ 44, 45, 195, 47, 48, 49, 50, 51, 52, 53,
/* 270 */ 54, 55, 56, 57, 58, 277, 278, 279, 313, 19,
/* 280 */ 195, 195, 317, 23, 68, 218, 219, 25, 55, 56,
/* 290 */ 57, 58, 109, 110, 111, 112, 113, 114, 22, 23,
/* 300 */ 233, 25, 313, 43, 44, 45, 317, 47, 48, 49,
/* 310 */ 50, 51, 52, 53, 54, 55, 56, 57, 58, 103,
/* 320 */ 104, 105, 106, 107, 108, 109, 110, 111, 112, 113,
/* 330 */ 114, 232, 60, 212, 213, 214, 103, 104, 105, 106,
/* 340 */ 107, 108, 109, 110, 111, 112, 113, 114, 103, 104,
/* 350 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
/* 360 */ 24, 195, 200, 103, 104, 105, 106, 107, 108, 109,
/* 370 */ 110, 111, 112, 113, 114, 251, 60, 253, 102, 107,
/* 380 */ 108, 119, 313, 19, 218, 219, 317, 23, 116, 117,
/* 390 */ 118, 119, 195, 121, 206, 22, 60, 26, 312, 313,
/* 400 */ 195, 129, 205, 317, 207, 35, 144, 43, 44, 45,
/* 410 */ 195, 47, 48, 49, 50, 51, 52, 53, 54, 55,
/* 420 */ 56, 57, 58, 218, 219, 82, 154, 19, 156, 241,
/* 430 */ 242, 60, 24, 117, 118, 119, 120, 67, 233, 123,
/* 440 */ 124, 125, 254, 195, 256, 75, 284, 259, 260, 133,
/* 450 */ 288, 43, 44, 45, 118, 47, 48, 49, 50, 51,
/* 460 */ 52, 53, 54, 55, 56, 57, 58, 103, 104, 105,
/* 470 */ 106, 107, 108, 109, 110, 111, 112, 113, 114, 195,
/* 480 */ 107, 108, 139, 140, 318, 195, 320, 195, 117, 118,
/* 490 */ 119, 61, 19, 20, 120, 22, 195, 123, 124, 125,
/* 500 */ 195, 131, 218, 219, 195, 195, 146, 133, 207, 36,
/* 510 */ 295, 103, 104, 105, 106, 107, 108, 109, 110, 111,
/* 520 */ 112, 113, 114, 218, 219, 165, 60, 195, 218, 219,
/* 530 */ 240, 19, 240, 60, 189, 190, 191, 192, 233, 255,
/* 540 */ 139, 140, 197, 233, 199, 72, 61, 272, 264, 195,
/* 550 */ 120, 206, 195, 19, 60, 43, 44, 45, 206, 47,
/* 560 */ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
/* 570 */ 58, 25, 218, 219, 101, 109, 112, 113, 114, 195,
/* 580 */ 107, 108, 109, 117, 118, 119, 241, 242, 115, 195,
/* 590 */ 117, 118, 119, 241, 242, 122, 60, 206, 195, 254,
/* 600 */ 60, 256, 218, 219, 195, 120, 254, 195, 256, 73,
/* 610 */ 125, 117, 118, 119, 269, 103, 104, 105, 106, 107,
/* 620 */ 108, 109, 110, 111, 112, 113, 114, 154, 155, 156,
/* 630 */ 157, 158, 241, 242, 240, 281, 19, 234, 144, 255,
/* 640 */ 23, 206, 166, 167, 299, 254, 301, 256, 264, 240,
/* 650 */ 116, 117, 295, 117, 118, 119, 183, 117, 118, 119,
/* 660 */ 43, 44, 45, 151, 47, 48, 49, 50, 51, 52,
/* 670 */ 53, 54, 55, 56, 57, 58, 241, 242, 266, 145,
/* 680 */ 19, 241, 242, 242, 23, 139, 140, 77, 25, 254,
/* 690 */ 195, 256, 152, 276, 254, 254, 256, 256, 88, 206,
/* 700 */ 90, 60, 206, 93, 43, 44, 45, 272, 47, 48,
/* 710 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
/* 720 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
/* 730 */ 113, 114, 315, 316, 241, 242, 131, 241, 242, 134,
/* 740 */ 22, 206, 101, 22, 82, 19, 20, 254, 22, 256,
/* 750 */ 254, 74, 256, 263, 22, 195, 146, 267, 117, 118,
/* 760 */ 276, 266, 36, 122, 103, 104, 105, 106, 107, 108,
/* 770 */ 109, 110, 111, 112, 113, 114, 241, 242, 60, 217,
/* 780 */ 130, 60, 195, 121, 19, 195, 60, 225, 23, 254,
/* 790 */ 127, 256, 60, 237, 238, 154, 155, 156, 72, 315,
/* 800 */ 316, 139, 140, 153, 22, 128, 129, 130, 43, 44,
/* 810 */ 45, 195, 47, 48, 49, 50, 51, 52, 53, 54,
/* 820 */ 55, 56, 57, 58, 183, 304, 305, 101, 19, 60,
/* 830 */ 243, 271, 23, 107, 108, 117, 118, 119, 117, 118,
/* 840 */ 119, 115, 60, 117, 118, 119, 16, 195, 122, 117,
/* 850 */ 118, 119, 43, 44, 45, 22, 47, 48, 49, 50,
/* 860 */ 51, 52, 53, 54, 55, 56, 57, 58, 103, 104,
/* 870 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
/* 880 */ 154, 155, 156, 157, 158, 295, 117, 118, 119, 60,
/* 890 */ 101, 60, 240, 60, 307, 21, 309, 195, 195, 117,
/* 900 */ 118, 119, 195, 47, 48, 49, 50, 118, 78, 183,
/* 910 */ 80, 122, 103, 104, 105, 106, 107, 108, 109, 110,
/* 920 */ 111, 112, 113, 114, 195, 218, 219, 16, 312, 313,
/* 930 */ 195, 195, 19, 317, 262, 263, 23, 212, 213, 214,
/* 940 */ 233, 210, 211, 154, 155, 156, 117, 118, 119, 118,
/* 950 */ 117, 118, 119, 218, 219, 81, 43, 44, 45, 195,
/* 960 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
/* 970 */ 57, 58, 183, 144, 271, 122, 19, 190, 122, 192,
/* 980 */ 23, 25, 218, 219, 197, 132, 199, 195, 286, 78,
/* 990 */ 255, 80, 162, 206, 265, 107, 108, 233, 124, 195,
/* 1000 */ 43, 44, 45, 195, 47, 48, 49, 50, 51, 52,
/* 1010 */ 53, 54, 55, 56, 57, 58, 103, 104, 105, 106,
/* 1020 */ 107, 108, 109, 110, 111, 112, 113, 114, 241, 242,
/* 1030 */ 195, 195, 31, 77, 195, 243, 162, 195, 195, 195,
/* 1040 */ 39, 254, 154, 256, 156, 19, 90, 203, 19, 93,
/* 1050 */ 24, 208, 208, 218, 219, 195, 269, 218, 219, 195,
/* 1060 */ 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
/* 1070 */ 113, 114, 233, 230, 266, 232, 47, 263, 218, 219,
/* 1080 */ 19, 267, 218, 219, 23, 23, 299, 25, 301, 135,
/* 1090 */ 255, 137, 138, 233, 47, 195, 195, 195, 25, 307,
/* 1100 */ 19, 309, 22, 23, 43, 44, 45, 271, 47, 48,
/* 1110 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
/* 1120 */ 218, 219, 96, 195, 43, 44, 45, 195, 47, 48,
/* 1130 */ 49, 50, 51, 52, 53, 54, 55, 56, 57, 58,
/* 1140 */ 114, 195, 195, 243, 243, 116, 120, 121, 122, 123,
/* 1150 */ 124, 125, 126, 195, 195, 195, 195, 255, 132, 213,
/* 1160 */ 214, 132, 234, 116, 103, 104, 105, 106, 107, 108,
/* 1170 */ 109, 110, 111, 112, 113, 114, 218, 219, 218, 219,
/* 1180 */ 195, 119, 102, 195, 103, 104, 105, 106, 107, 108,
/* 1190 */ 109, 110, 111, 112, 113, 114, 22, 23, 22, 25,
/* 1200 */ 24, 67, 12, 218, 219, 195, 144, 307, 307, 309,
/* 1210 */ 309, 195, 77, 255, 19, 255, 143, 27, 23, 313,
/* 1220 */ 86, 100, 313, 317, 265, 90, 317, 266, 93, 95,
/* 1230 */ 210, 211, 42, 287, 19, 23, 60, 25, 43, 44,
/* 1240 */ 45, 160, 47, 48, 49, 50, 51, 52, 53, 54,
/* 1250 */ 55, 56, 57, 58, 64, 134, 109, 261, 43, 44,
/* 1260 */ 45, 215, 47, 48, 49, 50, 51, 52, 53, 54,
/* 1270 */ 55, 56, 57, 58, 210, 211, 102, 128, 129, 130,
/* 1280 */ 12, 147, 266, 136, 163, 164, 302, 303, 141, 195,
/* 1290 */ 25, 195, 19, 195, 118, 27, 228, 19, 103, 104,
/* 1300 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
/* 1310 */ 42, 195, 218, 219, 218, 219, 218, 219, 103, 104,
/* 1320 */ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
/* 1330 */ 19, 195, 64, 195, 218, 219, 195, 259, 260, 195,
/* 1340 */ 294, 195, 74, 195, 150, 151, 195, 246, 19, 7,
/* 1350 */ 8, 9, 195, 24, 218, 219, 218, 219, 257, 218,
/* 1360 */ 219, 195, 218, 219, 218, 219, 218, 219, 19, 218,
/* 1370 */ 219, 98, 43, 44, 45, 160, 47, 48, 49, 50,
/* 1380 */ 51, 52, 53, 54, 55, 56, 57, 58, 19, 128,
/* 1390 */ 129, 130, 43, 44, 45, 117, 47, 48, 49, 50,
/* 1400 */ 51, 52, 53, 54, 55, 56, 57, 58, 22, 22,
/* 1410 */ 116, 146, 43, 44, 45, 195, 47, 48, 49, 50,
/* 1420 */ 51, 52, 53, 54, 55, 56, 57, 58, 117, 159,
/* 1430 */ 195, 161, 103, 104, 105, 106, 107, 108, 109, 110,
/* 1440 */ 111, 112, 113, 114, 195, 151, 195, 60, 62, 15,
/* 1450 */ 195, 25, 103, 104, 105, 106, 107, 108, 109, 110,
/* 1460 */ 111, 112, 113, 114, 195, 228, 195, 218, 219, 218,
/* 1470 */ 219, 195, 103, 104, 105, 106, 107, 108, 109, 110,
/* 1480 */ 111, 112, 113, 114, 22, 195, 246, 218, 219, 218,
/* 1490 */ 219, 195, 19, 22, 23, 61, 246, 257, 24, 136,
/* 1500 */ 246, 22, 60, 24, 141, 118, 60, 257, 218, 219,
/* 1510 */ 195, 257, 19, 195, 218, 219, 54, 44, 45, 195,
/* 1520 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
/* 1530 */ 57, 58, 195, 218, 219, 195, 218, 219, 45, 195,
/* 1540 */ 47, 48, 49, 50, 51, 52, 53, 54, 55, 56,
/* 1550 */ 57, 58, 195, 121, 122, 218, 219, 195, 218, 219,
/* 1560 */ 118, 195, 218, 219, 118, 23, 195, 25, 195, 143,
/* 1570 */ 195, 19, 20, 102, 22, 195, 103, 104, 105, 106,
/* 1580 */ 107, 108, 109, 110, 111, 112, 113, 114, 36, 218,
/* 1590 */ 219, 218, 219, 218, 219, 195, 103, 104, 105, 106,
/* 1600 */ 107, 108, 109, 110, 111, 112, 113, 114, 195, 23,
/* 1610 */ 23, 25, 60, 195, 195, 195, 142, 195, 218, 219,
/* 1620 */ 195, 23, 195, 25, 72, 130, 116, 23, 195, 25,
/* 1630 */ 195, 218, 219, 195, 82, 195, 218, 219, 218, 219,
/* 1640 */ 218, 219, 195, 218, 219, 218, 219, 195, 153, 195,
/* 1650 */ 195, 218, 219, 101, 195, 145, 218, 219, 195, 107,
/* 1660 */ 108, 23, 195, 25, 195, 218, 219, 115, 22, 117,
/* 1670 */ 118, 119, 218, 219, 122, 195, 195, 218, 219, 195,
/* 1680 */ 60, 218, 219, 7, 8, 218, 219, 19, 20, 195,
/* 1690 */ 22, 139, 140, 23, 23, 25, 25, 195, 218, 219,
/* 1700 */ 84, 85, 218, 219, 36, 228, 154, 155, 156, 157,
/* 1710 */ 158, 195, 23, 195, 25, 195, 195, 49, 195, 23,
/* 1720 */ 195, 25, 195, 23, 195, 25, 195, 195, 60, 195,
/* 1730 */ 195, 195, 195, 146, 195, 183, 218, 219, 118, 195,
/* 1740 */ 72, 218, 219, 218, 219, 218, 219, 218, 219, 218,
/* 1750 */ 219, 195, 218, 219, 86, 218, 219, 218, 219, 91,
/* 1760 */ 19, 20, 154, 22, 156, 23, 258, 25, 195, 101,
/* 1770 */ 195, 23, 195, 25, 195, 107, 108, 36, 23, 154,
/* 1780 */ 25, 156, 23, 115, 25, 117, 118, 119, 142, 238,
/* 1790 */ 122, 218, 219, 218, 219, 218, 219, 23, 322, 25,
/* 1800 */ 195, 60, 195, 300, 195, 195, 195, 195, 195, 244,
/* 1810 */ 291, 258, 290, 72, 245, 258, 258, 258, 216, 193,
/* 1820 */ 274, 247, 154, 155, 156, 157, 158, 86, 300, 296,
/* 1830 */ 300, 270, 91, 19, 20, 247, 22, 270, 248, 248,
/* 1840 */ 274, 296, 101, 222, 274, 274, 231, 262, 107, 108,
/* 1850 */ 36, 183, 221, 221, 227, 221, 115, 262, 117, 118,
/* 1860 */ 119, 262, 262, 122, 283, 251, 247, 245, 251, 116,
/* 1870 */ 198, 220, 61, 220, 60, 220, 300, 142, 38, 202,
/* 1880 */ 202, 297, 202, 152, 151, 22, 72, 286, 43, 297,
/* 1890 */ 236, 18, 202, 275, 18, 154, 155, 156, 157, 158,
/* 1900 */ 86, 273, 239, 239, 239, 91, 239, 201, 150, 248,
/* 1910 */ 275, 275, 273, 202, 248, 101, 201, 236, 236, 159,
/* 1920 */ 63, 107, 108, 248, 183, 202, 293, 248, 201, 115,
/* 1930 */ 22, 117, 118, 119, 292, 223, 122, 223, 202, 201,
/* 1940 */ 220, 202, 220, 65, 201, 220, 229, 22, 127, 220,
/* 1950 */ 226, 223, 226, 166, 222, 24, 316, 220, 308, 229,
/* 1960 */ 220, 114, 92, 202, 220, 321, 321, 83, 154, 155,
/* 1970 */ 156, 157, 158, 0, 1, 2, 285, 285, 5, 223,
/* 1980 */ 149, 268, 146, 10, 11, 12, 13, 14, 22, 268,
/* 1990 */ 17, 202, 159, 19, 20, 250, 22, 183, 252, 280,
/* 2000 */ 251, 148, 252, 30, 25, 32, 147, 204, 13, 196,
/* 2010 */ 36, 249, 248, 40, 196, 6, 282, 194, 194, 194,
/* 2020 */ 215, 209, 306, 215, 306, 215, 209, 4, 224, 209,
/* 2030 */ 215, 224, 216, 3, 60, 216, 22, 215, 122, 19,
/* 2040 */ 122, 19, 125, 22, 71, 16, 72, 22, 15, 23,
/* 2050 */ 303, 23, 79, 140, 152, 82, 25, 131, 24, 20,
/* 2060 */ 145, 16, 143, 1, 143, 131, 131, 62, 131, 37,
/* 2070 */ 54, 54, 99, 54, 152, 101, 117, 34, 54, 1,
/* 2080 */ 142, 107, 108, 22, 5, 116, 162, 69, 25, 115,
/* 2090 */ 41, 117, 118, 119, 142, 24, 122, 116, 126, 132,
/* 2100 */ 20, 19, 20, 76, 22, 69, 19, 134, 22, 68,
/* 2110 */ 22, 22, 139, 140, 23, 141, 22, 60, 36, 68,
/* 2120 */ 24, 28, 22, 68, 23, 150, 34, 37, 154, 155,
/* 2130 */ 156, 157, 158, 22, 97, 23, 163, 23, 25, 23,
/* 2140 */ 22, 142, 60, 23, 98, 23, 22, 144, 25, 34,
/* 2150 */ 76, 34, 117, 34, 72, 34, 89, 183, 94, 34,
/* 2160 */ 87, 76, 34, 23, 22, 24, 34, 22, 25, 25,
/* 2170 */ 44, 23, 23, 23, 23, 11, 22, 25, 25, 23,
/* 2180 */ 22, 143, 22, 101, 23, 143, 23, 22, 22, 107,
/* 2190 */ 108, 15, 25, 25, 136, 142, 142, 115, 142, 117,
/* 2200 */ 118, 119, 1, 2, 122, 23, 5, 1, 1, 323,
/* 2210 */ 323, 10, 11, 12, 13, 14, 323, 323, 17, 323,
/* 2220 */ 5, 323, 323, 141, 323, 10, 11, 12, 13, 14,
/* 2230 */ 323, 30, 17, 32, 323, 323, 154, 155, 156, 157,
/* 2240 */ 158, 40, 323, 323, 323, 30, 323, 32, 323, 323,
/* 2250 */ 323, 323, 323, 323, 323, 40, 323, 323, 323, 323,
/* 2260 */ 323, 323, 323, 323, 323, 183, 323, 323, 323, 323,
/* 2270 */ 323, 323, 71, 323, 323, 323, 323, 323, 323, 323,
/* 2280 */ 79, 323, 323, 82, 323, 323, 71, 323, 323, 323,
/* 2290 */ 323, 323, 323, 323, 79, 323, 323, 82, 323, 323,
/* 2300 */ 99, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2310 */ 323, 323, 323, 323, 99, 323, 323, 323, 323, 323,
/* 2320 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2330 */ 323, 323, 323, 323, 323, 134, 323, 323, 323, 323,
/* 2340 */ 139, 140, 323, 323, 323, 323, 323, 323, 323, 134,
/* 2350 */ 323, 323, 323, 323, 139, 140, 323, 323, 323, 323,
/* 2360 */ 323, 323, 323, 323, 163, 323, 323, 323, 323, 323,
/* 2370 */ 323, 323, 323, 323, 323, 323, 323, 323, 163, 323,
/* 2380 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2390 */ 323, 323, 323, 323, 323, 323, 323, 323, 323, 323,
/* 2400 */ 323, 323, 323, 323, 323, 323, 323, 323, 187, 187,
/* 2410 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2420 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2430 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2440 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2450 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2460 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2470 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2480 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2490 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2500 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2510 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2520 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2530 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2540 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2550 */ 187, 187, 187, 187, 187, 187, 187, 187, 187, 187,
/* 2560 */ 187, 187, 187, 187, 187, 187,
};
#define YY_SHIFT_COUNT (601)
#define YY_SHIFT_MIN (0)
#define YY_SHIFT_MAX (2215)
static const unsigned short int yy_shift_ofst[] = {
/* 0 */ 2201, 1973, 2215, 1552, 1552, 343, 44, 1668, 1741, 1814,
/* 10 */ 726, 726, 726, 662, 343, 343, 343, 343, 343, 0,
/* 20 */ 0, 216, 1349, 726, 726, 726, 726, 726, 726, 726,
/* 30 */ 726, 726, 726, 726, 726, 726, 726, 726, 272, 272,
/* 40 */ 111, 111, 316, 119, 536, 769, 769, 546, 546, 546,
/* 50 */ 546, 40, 112, 260, 364, 408, 512, 617, 661, 765,
/* 60 */ 809, 913, 957, 1061, 1081, 1195, 1215, 1329, 1349, 1349,
/* 70 */ 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349, 1349,
/* 80 */ 1349, 1349, 1349, 1349, 1349, 1349, 1369, 1349, 1473, 1493,
/* 90 */ 1493, 473, 1974, 2082, 726, 726, 726, 726, 726, 726,
/* 100 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726,
/* 110 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726,
/* 120 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726,
/* 130 */ 726, 726, 726, 726, 726, 726, 726, 726, 726, 726,
/* 140 */ 726, 726, 726, 726, 726, 726, 138, 233, 233, 233,
/* 150 */ 233, 233, 233, 233, 245, 98, 183, 371, 874, 1029,
/* 160 */ 769, 769, 888, 888, 769, 464, 110, 476, 476, 476,
/* 170 */ 401, 62, 62, 2379, 2379, 1026, 1026, 1026, 540, 718,
/* 180 */ 718, 718, 718, 1268, 1268, 610, 371, 276, 1174, 769,
/* 190 */ 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
/* 200 */ 769, 769, 769, 769, 769, 769, 769, 769, 534, 956,
/* 210 */ 956, 769, 61, 1135, 1135, 831, 1278, 1278, 831, 831,
/* 220 */ 360, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 641, 789,
/* 230 */ 789, 721, 374, 732, 466, 782, 494, 829, 833, 769,
/* 240 */ 769, 769, 769, 769, 769, 769, 769, 769, 769, 769,
/* 250 */ 769, 769, 769, 677, 769, 769, 769, 769, 769, 769,
/* 260 */ 769, 769, 769, 769, 769, 769, 370, 370, 370, 769,
/* 270 */ 769, 769, 1062, 769, 769, 769, 1176, 1134, 769, 1190,
/* 280 */ 769, 769, 769, 769, 769, 769, 769, 769, 485, 1149,
/* 290 */ 13, 954, 336, 336, 336, 336, 262, 954, 954, 1147,
/* 300 */ 373, 1342, 430, 1434, 1294, 1194, 1073, 1194, 1311, 103,
/* 310 */ 1294, 1294, 103, 1294, 1073, 1311, 663, 1212, 1047, 1001,
/* 320 */ 1001, 1001, 1510, 1510, 1510, 1510, 1265, 1265, 1270, 1426,
/* 330 */ 1363, 1479, 1753, 1811, 1753, 1753, 1735, 1735, 1840, 1840,
/* 340 */ 1735, 1731, 1733, 1863, 1845, 1873, 1873, 1873, 1873, 1735,
/* 350 */ 1876, 1758, 1733, 1733, 1758, 1863, 1845, 1758, 1845, 1758,
/* 360 */ 1735, 1876, 1760, 1857, 1735, 1876, 1908, 1735, 1876, 1735,
/* 370 */ 1876, 1908, 1753, 1753, 1753, 1878, 1925, 1925, 1908, 1753,
/* 380 */ 1821, 1753, 1878, 1753, 1753, 1787, 1931, 1847, 1847, 1908,
/* 390 */ 1735, 1870, 1870, 1884, 1884, 1831, 1836, 1966, 1735, 1833,
/* 400 */ 1831, 1853, 1859, 1758, 1979, 1995, 1995, 2009, 2009, 2009,
/* 410 */ 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379, 2379,
/* 420 */ 2379, 2379, 2379, 2379, 2379, 856, 1121, 830, 1080, 1471,
/* 430 */ 911, 1261, 1387, 1542, 605, 1462, 1474, 650, 1495, 1586,
/* 440 */ 1386, 1598, 1604, 1638, 1670, 1671, 1689, 1442, 1432, 1676,
/* 450 */ 853, 1696, 1587, 1273, 1446, 1700, 1742, 1616, 1748, 1755,
/* 460 */ 1608, 1625, 1759, 1774, 1620, 1646, 2023, 2030, 2014, 1916,
/* 470 */ 2020, 1918, 2022, 2021, 2025, 1917, 2033, 2029, 2026, 2028,
/* 480 */ 1913, 1902, 1926, 2031, 2031, 2034, 1919, 2039, 1915, 2045,
/* 490 */ 2062, 1921, 1934, 2031, 1935, 2005, 2032, 2031, 1922, 2016,
/* 500 */ 2017, 2019, 2024, 1937, 1959, 2043, 1938, 2078, 2079, 2061,
/* 510 */ 1969, 1924, 2018, 2063, 2036, 2027, 2049, 1952, 1981, 2071,
/* 520 */ 2080, 2087, 1967, 1972, 2086, 2041, 2088, 2089, 2091, 2094,
/* 530 */ 2051, 2057, 2096, 2037, 2093, 2100, 2055, 2090, 2101, 2092,
/* 540 */ 1975, 2111, 2112, 2114, 2113, 2116, 2118, 2046, 1999, 2120,
/* 550 */ 2122, 2035, 2115, 2124, 2003, 2123, 2117, 2119, 2121, 2125,
/* 560 */ 2067, 2074, 2073, 2126, 2085, 2064, 2128, 2140, 2142, 2141,
/* 570 */ 2143, 2144, 2132, 2038, 2042, 2148, 2123, 2149, 2150, 2151,
/* 580 */ 2145, 2152, 2153, 2156, 2154, 2164, 2158, 2160, 2161, 2163,
/* 590 */ 2165, 2166, 2167, 2058, 2053, 2054, 2056, 2168, 2182, 2176,
/* 600 */ 2206, 2207,
};
#define YY_REDUCE_COUNT (424)
#define YY_REDUCE_MIN (-277)
#define YY_REDUCE_MAX (1825)
static const short yy_reduce_ofst[] = {
/* 0 */ -67, 345, 787, -178, -181, 188, 435, -185, 166, -183,
/* 10 */ -78, 284, 384, -174, 352, 391, 493, 496, 535, -208,
/* 20 */ -23, -277, -2, 205, 305, 310, 707, 764, -189, 67,
/* 30 */ 839, 735, 835, 860, 902, 354, 958, 960, -187, 946,
/* 40 */ 86, 616, 843, 587, 792, 900, 901, -238, 440, -238,
/* 50 */ 440, -255, -255, -255, -255, -255, -255, -255, -255, -255,
/* 60 */ -255, -255, -255, -255, -255, -255, -255, -255, -255, -255,
/* 70 */ -255, -255, -255, -255, -255, -255, -255, -255, -255, -255,
/* 80 */ -255, -255, -255, -255, -255, -255, -255, -255, -255, -255,
/* 90 */ -255, 864, 985, 1094, 1096, 1098, 1116, 1136, 1138, 1141,
/* 100 */ 1144, 1146, 1148, 1151, 1249, 1251, 1269, 1271, 1290, 1296,
/* 110 */ 1315, 1318, 1337, 1340, 1344, 1371, 1373, 1375, 1400, 1413,
/* 120 */ 1418, 1420, 1422, 1425, 1427, 1433, 1438, 1447, 1454, 1459,
/* 130 */ 1463, 1467, 1480, 1484, 1518, 1523, 1525, 1527, 1529, 1531,
/* 140 */ 1534, 1537, 1539, 1573, 1575, 1577, -255, -255, -255, -255,
/* 150 */ -255, -255, -255, -255, -255, -255, -255, 197, 162, -220,
/* 160 */ -76, -130, 121, 725, 844, -255, -116, -214, 417, 484,
/* 170 */ 441, -255, -255, -255, -255, 562, 562, 562, 702, -57,
/* 180 */ 560, 703, 836, -122, 556, -35, 301, 521, 521, -37,
/* 190 */ -184, 729, 959, 290, 292, 394, 409, 215, 412, 357,
/* 200 */ 495, 808, 590, 961, 652, 403, 928, 1016, 672, -11,
/* 210 */ 69, -53, 1046, 906, 909, 731, 490, 814, 1020, 1064,
/* 220 */ 124, 984, -237, 1101, 1240, 1250, 1078, 1254, -33, -18,
/* 230 */ 9, 85, 99, 248, 309, 332, 736, 804, 842, 932,
/* 240 */ 947, 988, 1010, 1157, 1166, 1220, 1235, 1255, 1276, 1324,
/* 250 */ 1357, 1362, 1366, 275, 1380, 1419, 1435, 1440, 1452, 1455,
/* 260 */ 1469, 1481, 1494, 1502, 1516, 1520, 1068, 1237, 1477, 1521,
/* 270 */ 1532, 1535, 996, 1536, 1544, 1556, 1508, 1476, 1579, 1551,
/* 280 */ 1605, 309, 1607, 1609, 1610, 1611, 1612, 1613, 1503, 1519,
/* 290 */ 1522, 1565, 1553, 1557, 1558, 1559, 996, 1565, 1565, 1569,
/* 300 */ 1602, 1626, 1528, 1530, 1546, 1561, 1574, 1567, 1533, 1590,
/* 310 */ 1566, 1570, 1591, 1571, 1588, 1545, 1621, 1615, 1627, 1631,
/* 320 */ 1632, 1634, 1585, 1595, 1599, 1600, 1614, 1617, 1581, 1619,
/* 330 */ 1622, 1672, 1651, 1576, 1653, 1655, 1677, 1678, 1584, 1592,
/* 340 */ 1680, 1601, 1618, 1628, 1654, 1663, 1664, 1665, 1667, 1690,
/* 350 */ 1706, 1661, 1635, 1636, 1666, 1639, 1681, 1675, 1682, 1679,
/* 360 */ 1711, 1715, 1633, 1642, 1723, 1727, 1712, 1736, 1738, 1739,
/* 370 */ 1743, 1714, 1720, 1722, 1725, 1717, 1724, 1726, 1728, 1729,
/* 380 */ 1732, 1737, 1730, 1740, 1744, 1640, 1650, 1691, 1692, 1756,
/* 390 */ 1761, 1644, 1645, 1713, 1721, 1746, 1749, 1719, 1789, 1734,
/* 400 */ 1750, 1745, 1762, 1764, 1803, 1813, 1818, 1823, 1824, 1825,
/* 410 */ 1716, 1718, 1747, 1812, 1805, 1808, 1810, 1815, 1817, 1804,
/* 420 */ 1807, 1816, 1819, 1822, 1820,
};
static const YYACTIONTYPE yy_default[] = {
/* 0 */ 1698, 1698, 1698, 1521, 1284, 1397, 1284, 1284, 1284, 1284,
/* 10 */ 1521, 1521, 1521, 1284, 1284, 1284, 1284, 1284, 1284, 1427,
/* 20 */ 1427, 1574, 1317, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 30 */ 1284, 1284, 1284, 1284, 1284, 1520, 1284, 1284, 1284, 1284,
/* 40 */ 1613, 1613, 1284, 1284, 1284, 1284, 1284, 1598, 1597, 1284,
/* 50 */ 1284, 1284, 1436, 1284, 1284, 1284, 1443, 1284, 1284, 1284,
/* 60 */ 1284, 1284, 1522, 1523, 1284, 1284, 1284, 1284, 1573, 1575,
/* 70 */ 1538, 1450, 1449, 1448, 1447, 1556, 1415, 1441, 1434, 1438,
/* 80 */ 1517, 1518, 1516, 1676, 1523, 1522, 1284, 1437, 1485, 1501,
/* 90 */ 1484, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 100 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 110 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 120 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 130 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 140 */ 1284, 1284, 1284, 1284, 1284, 1284, 1493, 1500, 1499, 1498,
/* 150 */ 1507, 1497, 1494, 1487, 1486, 1488, 1489, 1308, 1305, 1359,
/* 160 */ 1284, 1284, 1284, 1284, 1284, 1490, 1317, 1478, 1477, 1476,
/* 170 */ 1284, 1504, 1491, 1503, 1502, 1581, 1650, 1649, 1539, 1284,
/* 180 */ 1284, 1284, 1284, 1284, 1284, 1613, 1284, 1284, 1284, 1284,
/* 190 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 200 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1417, 1613,
/* 210 */ 1613, 1284, 1317, 1613, 1613, 1313, 1418, 1418, 1313, 1313,
/* 220 */ 1421, 1593, 1388, 1388, 1388, 1388, 1397, 1388, 1284, 1284,
/* 230 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 240 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1578, 1576, 1284,
/* 250 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 260 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 270 */ 1284, 1284, 1284, 1284, 1284, 1284, 1393, 1284, 1284, 1284,
/* 280 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1643, 1690, 1284,
/* 290 */ 1551, 1373, 1393, 1393, 1393, 1393, 1395, 1374, 1372, 1387,
/* 300 */ 1318, 1291, 1690, 1690, 1453, 1442, 1394, 1442, 1687, 1440,
/* 310 */ 1453, 1453, 1440, 1453, 1394, 1687, 1334, 1665, 1329, 1427,
/* 320 */ 1427, 1427, 1417, 1417, 1417, 1417, 1421, 1421, 1519, 1394,
/* 330 */ 1387, 1284, 1360, 1690, 1360, 1360, 1403, 1403, 1689, 1689,
/* 340 */ 1403, 1539, 1673, 1462, 1362, 1368, 1368, 1368, 1368, 1403,
/* 350 */ 1302, 1440, 1673, 1673, 1440, 1462, 1362, 1440, 1362, 1440,
/* 360 */ 1403, 1302, 1555, 1684, 1403, 1302, 1529, 1403, 1302, 1403,
/* 370 */ 1302, 1529, 1360, 1360, 1360, 1349, 1284, 1284, 1529, 1360,
/* 380 */ 1334, 1360, 1349, 1360, 1360, 1631, 1284, 1533, 1533, 1529,
/* 390 */ 1403, 1623, 1623, 1430, 1430, 1435, 1421, 1524, 1403, 1284,
/* 400 */ 1435, 1433, 1431, 1440, 1352, 1646, 1646, 1642, 1642, 1642,
/* 410 */ 1695, 1695, 1593, 1658, 1317, 1317, 1317, 1317, 1658, 1336,
/* 420 */ 1336, 1318, 1318, 1317, 1658, 1284, 1284, 1284, 1284, 1284,
/* 430 */ 1284, 1284, 1653, 1284, 1284, 1540, 1407, 1284, 1284, 1284,
/* 440 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 450 */ 1284, 1284, 1284, 1599, 1284, 1284, 1284, 1284, 1284, 1284,
/* 460 */ 1284, 1284, 1284, 1284, 1284, 1467, 1284, 1287, 1590, 1284,
/* 470 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 480 */ 1284, 1284, 1284, 1444, 1445, 1408, 1284, 1284, 1284, 1284,
/* 490 */ 1284, 1284, 1284, 1459, 1284, 1284, 1284, 1454, 1284, 1284,
/* 500 */ 1284, 1284, 1284, 1284, 1284, 1284, 1686, 1284, 1284, 1284,
/* 510 */ 1284, 1284, 1284, 1554, 1553, 1284, 1284, 1405, 1284, 1284,
/* 520 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 530 */ 1284, 1332, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 540 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 550 */ 1284, 1284, 1284, 1284, 1284, 1432, 1284, 1284, 1284, 1284,
/* 560 */ 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 570 */ 1628, 1422, 1284, 1284, 1284, 1284, 1677, 1284, 1284, 1284,
/* 580 */ 1284, 1382, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284,
/* 590 */ 1284, 1284, 1669, 1376, 1468, 1284, 1471, 1306, 1284, 1296,
/* 600 */ 1284, 1284,
};
/********** End of lemon-generated parsing tables *****************************/
/* The next table maps tokens (terminal symbols) into fallback tokens.
** If a construct like the following:
**
** %fallback ID X Y Z.
|
| ︙ | ︙ | |||
178279 178280 178281 178282 178283 178284 178285 | /* 292 */ "foreach_clause", /* 293 */ "when_clause", /* 294 */ "trigger_cmd", /* 295 */ "trnm", /* 296 */ "tridxby", /* 297 */ "database_kw_opt", /* 298 */ "key_opt", | | | 180215 180216 180217 180218 180219 180220 180221 180222 180223 180224 180225 180226 180227 180228 180229 | /* 292 */ "foreach_clause", /* 293 */ "when_clause", /* 294 */ "trigger_cmd", /* 295 */ "trnm", /* 296 */ "tridxby", /* 297 */ "database_kw_opt", /* 298 */ "key_opt", /* 299 */ "alter_add", /* 300 */ "kwcolumn_opt", /* 301 */ "create_vtab", /* 302 */ "vtabarglist", /* 303 */ "vtabarg", /* 304 */ "vtabargtoken", /* 305 */ "lp", /* 306 */ "anylist", |
| ︙ | ︙ | |||
178604 178605 178606 178607 178608 178609 178610 | /* 287 */ "key_opt ::=", /* 288 */ "key_opt ::= KEY expr", /* 289 */ "cmd ::= REINDEX", /* 290 */ "cmd ::= REINDEX nm dbnm", /* 291 */ "cmd ::= ANALYZE", /* 292 */ "cmd ::= ANALYZE nm dbnm", /* 293 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", | > | | < > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > > > > > > > > > | | | 180540 180541 180542 180543 180544 180545 180546 180547 180548 180549 180550 180551 180552 180553 180554 180555 180556 180557 180558 180559 180560 180561 180562 180563 180564 180565 180566 180567 180568 180569 180570 180571 180572 180573 180574 180575 180576 180577 180578 180579 180580 180581 180582 180583 180584 180585 180586 180587 180588 180589 180590 180591 180592 180593 180594 180595 180596 180597 180598 180599 180600 180601 180602 180603 180604 180605 180606 180607 180608 180609 180610 180611 180612 180613 180614 180615 180616 180617 180618 180619 180620 180621 180622 180623 180624 180625 180626 180627 180628 180629 180630 180631 180632 180633 180634 180635 180636 180637 180638 180639 180640 180641 180642 180643 180644 180645 180646 180647 180648 180649 180650 180651 180652 180653 180654 180655 180656 180657 180658 180659 180660 180661 180662 180663 180664 180665 180666 180667 180668 180669 180670 180671 180672 180673 180674 180675 180676 180677 180678 180679 180680 180681 180682 180683 180684 180685 180686 180687 180688 180689 180690 180691 180692 180693 180694 180695 180696 180697 180698 180699 180700 180701 180702 180703 180704 180705 |
/* 287 */ "key_opt ::=",
/* 288 */ "key_opt ::= KEY expr",
/* 289 */ "cmd ::= REINDEX",
/* 290 */ "cmd ::= REINDEX nm dbnm",
/* 291 */ "cmd ::= ANALYZE",
/* 292 */ "cmd ::= ANALYZE nm dbnm",
/* 293 */ "cmd ::= ALTER TABLE fullname RENAME TO nm",
/* 294 */ "cmd ::= alter_add carglist",
/* 295 */ "alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken",
/* 296 */ "cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm",
/* 297 */ "cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm",
/* 298 */ "cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm",
/* 299 */ "cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL",
/* 300 */ "cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf",
/* 301 */ "cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf",
/* 302 */ "cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf",
/* 303 */ "cmd ::= create_vtab",
/* 304 */ "cmd ::= create_vtab LP vtabarglist RP",
/* 305 */ "create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm",
/* 306 */ "vtabarg ::=",
/* 307 */ "vtabargtoken ::= ANY",
/* 308 */ "vtabargtoken ::= lp anylist RP",
/* 309 */ "lp ::= LP",
/* 310 */ "with ::= WITH wqlist",
/* 311 */ "with ::= WITH RECURSIVE wqlist",
/* 312 */ "wqas ::= AS",
/* 313 */ "wqas ::= AS MATERIALIZED",
/* 314 */ "wqas ::= AS NOT MATERIALIZED",
/* 315 */ "wqitem ::= withnm eidlist_opt wqas LP select RP",
/* 316 */ "withnm ::= nm",
/* 317 */ "wqlist ::= wqitem",
/* 318 */ "wqlist ::= wqlist COMMA wqitem",
/* 319 */ "windowdefn_list ::= windowdefn_list COMMA windowdefn",
/* 320 */ "windowdefn ::= nm AS LP window RP",
/* 321 */ "window ::= PARTITION BY nexprlist orderby_opt frame_opt",
/* 322 */ "window ::= nm PARTITION BY nexprlist orderby_opt frame_opt",
/* 323 */ "window ::= ORDER BY sortlist frame_opt",
/* 324 */ "window ::= nm ORDER BY sortlist frame_opt",
/* 325 */ "window ::= nm frame_opt",
/* 326 */ "frame_opt ::=",
/* 327 */ "frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt",
/* 328 */ "frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt",
/* 329 */ "range_or_rows ::= RANGE|ROWS|GROUPS",
/* 330 */ "frame_bound_s ::= frame_bound",
/* 331 */ "frame_bound_s ::= UNBOUNDED PRECEDING",
/* 332 */ "frame_bound_e ::= frame_bound",
/* 333 */ "frame_bound_e ::= UNBOUNDED FOLLOWING",
/* 334 */ "frame_bound ::= expr PRECEDING|FOLLOWING",
/* 335 */ "frame_bound ::= CURRENT ROW",
/* 336 */ "frame_exclude_opt ::=",
/* 337 */ "frame_exclude_opt ::= EXCLUDE frame_exclude",
/* 338 */ "frame_exclude ::= NO OTHERS",
/* 339 */ "frame_exclude ::= CURRENT ROW",
/* 340 */ "frame_exclude ::= GROUP|TIES",
/* 341 */ "window_clause ::= WINDOW windowdefn_list",
/* 342 */ "filter_over ::= filter_clause over_clause",
/* 343 */ "filter_over ::= over_clause",
/* 344 */ "filter_over ::= filter_clause",
/* 345 */ "over_clause ::= OVER LP window RP",
/* 346 */ "over_clause ::= OVER nm",
/* 347 */ "filter_clause ::= FILTER LP WHERE expr RP",
/* 348 */ "term ::= QNUMBER",
/* 349 */ "input ::= cmdlist",
/* 350 */ "cmdlist ::= cmdlist ecmd",
/* 351 */ "cmdlist ::= ecmd",
/* 352 */ "ecmd ::= SEMI",
/* 353 */ "ecmd ::= cmdx SEMI",
/* 354 */ "ecmd ::= explain cmdx SEMI",
/* 355 */ "trans_opt ::=",
/* 356 */ "trans_opt ::= TRANSACTION",
/* 357 */ "trans_opt ::= TRANSACTION nm",
/* 358 */ "savepoint_opt ::= SAVEPOINT",
/* 359 */ "savepoint_opt ::=",
/* 360 */ "cmd ::= create_table create_table_args",
/* 361 */ "table_option_set ::= table_option",
/* 362 */ "columnlist ::= columnlist COMMA columnname carglist",
/* 363 */ "columnlist ::= columnname carglist",
/* 364 */ "nm ::= ID|INDEXED|JOIN_KW",
/* 365 */ "nm ::= STRING",
/* 366 */ "typetoken ::= typename",
/* 367 */ "typename ::= ID|STRING",
/* 368 */ "signed ::= plus_num",
/* 369 */ "signed ::= minus_num",
/* 370 */ "carglist ::= carglist ccons",
/* 371 */ "carglist ::=",
/* 372 */ "ccons ::= NULL onconf",
/* 373 */ "ccons ::= GENERATED ALWAYS AS generated",
/* 374 */ "ccons ::= AS generated",
/* 375 */ "conslist_opt ::= COMMA conslist",
/* 376 */ "conslist ::= conslist tconscomma tcons",
/* 377 */ "conslist ::= tcons",
/* 378 */ "tconscomma ::=",
/* 379 */ "defer_subclause_opt ::= defer_subclause",
/* 380 */ "resolvetype ::= raisetype",
/* 381 */ "selectnowith ::= oneselect",
/* 382 */ "oneselect ::= values",
/* 383 */ "sclp ::= selcollist COMMA",
/* 384 */ "as ::= ID|STRING",
/* 385 */ "indexed_opt ::= indexed_by",
/* 386 */ "returning ::=",
/* 387 */ "expr ::= term",
/* 388 */ "likeop ::= LIKE_KW|MATCH",
/* 389 */ "case_operand ::= expr",
/* 390 */ "exprlist ::= nexprlist",
/* 391 */ "nmnum ::= plus_num",
/* 392 */ "nmnum ::= nm",
/* 393 */ "nmnum ::= ON",
/* 394 */ "nmnum ::= DELETE",
/* 395 */ "nmnum ::= DEFAULT",
/* 396 */ "plus_num ::= INTEGER|FLOAT",
/* 397 */ "foreach_clause ::=",
/* 398 */ "foreach_clause ::= FOR EACH ROW",
/* 399 */ "trnm ::= nm",
/* 400 */ "tridxby ::=",
/* 401 */ "database_kw_opt ::= DATABASE",
/* 402 */ "database_kw_opt ::=",
/* 403 */ "kwcolumn_opt ::=",
/* 404 */ "kwcolumn_opt ::= COLUMNKW",
/* 405 */ "vtabarglist ::= vtabarg",
/* 406 */ "vtabarglist ::= vtabarglist COMMA vtabarg",
/* 407 */ "vtabarg ::= vtabarg vtabargtoken",
/* 408 */ "anylist ::=",
/* 409 */ "anylist ::= anylist LP anylist RP",
/* 410 */ "anylist ::= anylist ANY",
/* 411 */ "with ::=",
/* 412 */ "windowdefn_list ::= windowdefn",
/* 413 */ "window ::= frame_opt",
};
#endif /* NDEBUG */
#if YYGROWABLESTACK
/*
** Try to increase the size of the parser stack. Return the number
** of errors. Return 0 on success.
*/
static int yyGrowStack(yyParser *p){
int oldSize = 1 + (int)(p->yystackEnd - p->yystack);
int newSize;
int idx;
yyStackEntry *pNew;
#ifdef YYSIZELIMIT
int nLimit = YYSIZELIMIT(sqlite3ParserCTX(p));
#endif
newSize = oldSize*2 + 100;
#ifdef YYSIZELIMIT
if( newSize>nLimit ){
newSize = nLimit;
if( newSize<=oldSize ) return 1;
}
#endif
idx = (int)(p->yytos - p->yystack);
if( p->yystack==p->yystk0 ){
pNew = YYREALLOC(0, newSize*sizeof(pNew[0]), sqlite3ParserCTX(p));
if( pNew==0 ) return 1;
memcpy(pNew, p->yystack, oldSize*sizeof(pNew[0]));
}else{
pNew = YYREALLOC(p->yystack, newSize*sizeof(pNew[0]), sqlite3ParserCTX(p));
if( pNew==0 ) return 1;
}
p->yystack = pNew;
p->yytos = &p->yystack[idx];
#ifndef NDEBUG
if( yyTraceFILE ){
fprintf(yyTraceFILE,"%sStack grows from %d to %d entries.\n",
|
| ︙ | ︙ | |||
178986 178987 178988 178989 178990 178991 178992 |
if( yytos->major>=YY_MIN_DSTRCTR ){
yy_destructor(pParser, yytos->major, &yytos->minor);
}
yytos--;
}
#if YYGROWABLESTACK
| | > > | 180936 180937 180938 180939 180940 180941 180942 180943 180944 180945 180946 180947 180948 180949 180950 180951 180952 |
if( yytos->major>=YY_MIN_DSTRCTR ){
yy_destructor(pParser, yytos->major, &yytos->minor);
}
yytos--;
}
#if YYGROWABLESTACK
if( pParser->yystack!=pParser->yystk0 ){
YYFREE(pParser->yystack, sqlite3ParserCTX(pParser));
}
#endif
}
#ifndef sqlite3Parser_ENGINEALWAYSONSTACK
/*
** Deallocate and destroy a parser. Destructors are called for
** all stack elements before shutting the parser down.
|
| ︙ | ︙ | |||
179169 179170 179171 179172 179173 179174 179175 | } #endif while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will execute if the parser ** stack every overflows */ /******** Begin %stack_overflow code ******************************************/ | | | 181121 181122 181123 181124 181125 181126 181127 181128 181129 181130 181131 181132 181133 181134 181135 | } #endif while( yypParser->yytos>yypParser->yystack ) yy_pop_parser_stack(yypParser); /* Here code is inserted which will execute if the parser ** stack every overflows */ /******** Begin %stack_overflow code ******************************************/ if( pParse->nErr==0 ) sqlite3ErrorMsg(pParse, "Recursion limit"); /******** End %stack_overflow code ********************************************/ sqlite3ParserARG_STORE /* Suppress warning about unused %extra_argument var */ sqlite3ParserCTX_STORE } /* ** Print tracing information for a SHIFT action |
| ︙ | ︙ | |||
179529 179530 179531 179532 179533 179534 179535 | 298, /* (287) key_opt ::= */ 298, /* (288) key_opt ::= KEY expr */ 192, /* (289) cmd ::= REINDEX */ 192, /* (290) cmd ::= REINDEX nm dbnm */ 192, /* (291) cmd ::= ANALYZE */ 192, /* (292) cmd ::= ANALYZE nm dbnm */ 192, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */ | | > | < | > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 181481 181482 181483 181484 181485 181486 181487 181488 181489 181490 181491 181492 181493 181494 181495 181496 181497 181498 181499 181500 181501 181502 181503 181504 181505 181506 181507 181508 181509 181510 181511 181512 181513 181514 181515 181516 181517 181518 181519 181520 181521 181522 181523 181524 181525 181526 181527 181528 181529 181530 181531 181532 181533 181534 181535 181536 181537 181538 181539 181540 181541 181542 181543 181544 181545 181546 181547 181548 181549 181550 181551 181552 181553 181554 181555 181556 181557 181558 181559 181560 181561 181562 181563 181564 181565 181566 181567 181568 181569 181570 181571 181572 181573 181574 181575 181576 181577 181578 181579 181580 181581 181582 181583 181584 181585 181586 181587 181588 181589 181590 181591 181592 181593 181594 181595 181596 181597 181598 181599 181600 181601 181602 181603 181604 181605 181606 181607 181608 181609 181610 181611 181612 181613 181614 |
298, /* (287) key_opt ::= */
298, /* (288) key_opt ::= KEY expr */
192, /* (289) cmd ::= REINDEX */
192, /* (290) cmd ::= REINDEX nm dbnm */
192, /* (291) cmd ::= ANALYZE */
192, /* (292) cmd ::= ANALYZE nm dbnm */
192, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */
192, /* (294) cmd ::= alter_add carglist */
299, /* (295) alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken */
192, /* (296) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
192, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
192, /* (298) cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm */
192, /* (299) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL */
192, /* (300) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf */
192, /* (301) cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */
192, /* (302) cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */
192, /* (303) cmd ::= create_vtab */
192, /* (304) cmd ::= create_vtab LP vtabarglist RP */
301, /* (305) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
303, /* (306) vtabarg ::= */
304, /* (307) vtabargtoken ::= ANY */
304, /* (308) vtabargtoken ::= lp anylist RP */
305, /* (309) lp ::= LP */
269, /* (310) with ::= WITH wqlist */
269, /* (311) with ::= WITH RECURSIVE wqlist */
308, /* (312) wqas ::= AS */
308, /* (313) wqas ::= AS MATERIALIZED */
308, /* (314) wqas ::= AS NOT MATERIALIZED */
307, /* (315) wqitem ::= withnm eidlist_opt wqas LP select RP */
309, /* (316) withnm ::= nm */
243, /* (317) wqlist ::= wqitem */
243, /* (318) wqlist ::= wqlist COMMA wqitem */
310, /* (319) windowdefn_list ::= windowdefn_list COMMA windowdefn */
311, /* (320) windowdefn ::= nm AS LP window RP */
312, /* (321) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
312, /* (322) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
312, /* (323) window ::= ORDER BY sortlist frame_opt */
312, /* (324) window ::= nm ORDER BY sortlist frame_opt */
312, /* (325) window ::= nm frame_opt */
313, /* (326) frame_opt ::= */
313, /* (327) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
313, /* (328) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
317, /* (329) range_or_rows ::= RANGE|ROWS|GROUPS */
319, /* (330) frame_bound_s ::= frame_bound */
319, /* (331) frame_bound_s ::= UNBOUNDED PRECEDING */
320, /* (332) frame_bound_e ::= frame_bound */
320, /* (333) frame_bound_e ::= UNBOUNDED FOLLOWING */
318, /* (334) frame_bound ::= expr PRECEDING|FOLLOWING */
318, /* (335) frame_bound ::= CURRENT ROW */
321, /* (336) frame_exclude_opt ::= */
321, /* (337) frame_exclude_opt ::= EXCLUDE frame_exclude */
322, /* (338) frame_exclude ::= NO OTHERS */
322, /* (339) frame_exclude ::= CURRENT ROW */
322, /* (340) frame_exclude ::= GROUP|TIES */
253, /* (341) window_clause ::= WINDOW windowdefn_list */
276, /* (342) filter_over ::= filter_clause over_clause */
276, /* (343) filter_over ::= over_clause */
276, /* (344) filter_over ::= filter_clause */
316, /* (345) over_clause ::= OVER LP window RP */
316, /* (346) over_clause ::= OVER nm */
315, /* (347) filter_clause ::= FILTER LP WHERE expr RP */
218, /* (348) term ::= QNUMBER */
187, /* (349) input ::= cmdlist */
188, /* (350) cmdlist ::= cmdlist ecmd */
188, /* (351) cmdlist ::= ecmd */
189, /* (352) ecmd ::= SEMI */
189, /* (353) ecmd ::= cmdx SEMI */
189, /* (354) ecmd ::= explain cmdx SEMI */
194, /* (355) trans_opt ::= */
194, /* (356) trans_opt ::= TRANSACTION */
194, /* (357) trans_opt ::= TRANSACTION nm */
196, /* (358) savepoint_opt ::= SAVEPOINT */
196, /* (359) savepoint_opt ::= */
192, /* (360) cmd ::= create_table create_table_args */
205, /* (361) table_option_set ::= table_option */
203, /* (362) columnlist ::= columnlist COMMA columnname carglist */
203, /* (363) columnlist ::= columnname carglist */
195, /* (364) nm ::= ID|INDEXED|JOIN_KW */
195, /* (365) nm ::= STRING */
210, /* (366) typetoken ::= typename */
211, /* (367) typename ::= ID|STRING */
212, /* (368) signed ::= plus_num */
212, /* (369) signed ::= minus_num */
209, /* (370) carglist ::= carglist ccons */
209, /* (371) carglist ::= */
217, /* (372) ccons ::= NULL onconf */
217, /* (373) ccons ::= GENERATED ALWAYS AS generated */
217, /* (374) ccons ::= AS generated */
204, /* (375) conslist_opt ::= COMMA conslist */
230, /* (376) conslist ::= conslist tconscomma tcons */
230, /* (377) conslist ::= tcons */
231, /* (378) tconscomma ::= */
235, /* (379) defer_subclause_opt ::= defer_subclause */
237, /* (380) resolvetype ::= raisetype */
241, /* (381) selectnowith ::= oneselect */
242, /* (382) oneselect ::= values */
257, /* (383) sclp ::= selcollist COMMA */
258, /* (384) as ::= ID|STRING */
267, /* (385) indexed_opt ::= indexed_by */
275, /* (386) returning ::= */
219, /* (387) expr ::= term */
277, /* (388) likeop ::= LIKE_KW|MATCH */
281, /* (389) case_operand ::= expr */
264, /* (390) exprlist ::= nexprlist */
287, /* (391) nmnum ::= plus_num */
287, /* (392) nmnum ::= nm */
287, /* (393) nmnum ::= ON */
287, /* (394) nmnum ::= DELETE */
287, /* (395) nmnum ::= DEFAULT */
213, /* (396) plus_num ::= INTEGER|FLOAT */
292, /* (397) foreach_clause ::= */
292, /* (398) foreach_clause ::= FOR EACH ROW */
295, /* (399) trnm ::= nm */
296, /* (400) tridxby ::= */
297, /* (401) database_kw_opt ::= DATABASE */
297, /* (402) database_kw_opt ::= */
300, /* (403) kwcolumn_opt ::= */
300, /* (404) kwcolumn_opt ::= COLUMNKW */
302, /* (405) vtabarglist ::= vtabarg */
302, /* (406) vtabarglist ::= vtabarglist COMMA vtabarg */
303, /* (407) vtabarg ::= vtabarg vtabargtoken */
306, /* (408) anylist ::= */
306, /* (409) anylist ::= anylist LP anylist RP */
306, /* (410) anylist ::= anylist ANY */
269, /* (411) with ::= */
310, /* (412) windowdefn_list ::= windowdefn */
312, /* (413) window ::= frame_opt */
};
/* For rule J, yyRuleInfoNRhs[J] contains the negative of the number
** of symbols on the right-hand side of that rule. */
static const signed char yyRuleInfoNRhs[] = {
-1, /* (0) explain ::= EXPLAIN */
-3, /* (1) explain ::= EXPLAIN QUERY PLAN */
|
| ︙ | ︙ | |||
179943 179944 179945 179946 179947 179948 179949 |
0, /* (287) key_opt ::= */
-2, /* (288) key_opt ::= KEY expr */
-1, /* (289) cmd ::= REINDEX */
-3, /* (290) cmd ::= REINDEX nm dbnm */
-1, /* (291) cmd ::= ANALYZE */
-3, /* (292) cmd ::= ANALYZE nm dbnm */
-6, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */
| > | | < > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 181900 181901 181902 181903 181904 181905 181906 181907 181908 181909 181910 181911 181912 181913 181914 181915 181916 181917 181918 181919 181920 181921 181922 181923 181924 181925 181926 181927 181928 181929 181930 181931 181932 181933 181934 181935 181936 181937 181938 181939 181940 181941 181942 181943 181944 181945 181946 181947 181948 181949 181950 181951 181952 181953 181954 181955 181956 181957 181958 181959 181960 181961 181962 181963 181964 181965 181966 181967 181968 181969 181970 181971 181972 181973 181974 181975 181976 181977 181978 181979 181980 181981 181982 181983 181984 181985 181986 181987 181988 181989 181990 181991 181992 181993 181994 181995 181996 181997 181998 181999 182000 182001 182002 182003 182004 182005 182006 182007 182008 182009 182010 182011 182012 182013 182014 182015 182016 182017 182018 182019 182020 182021 182022 182023 182024 182025 182026 182027 182028 182029 182030 182031 182032 182033 |
0, /* (287) key_opt ::= */
-2, /* (288) key_opt ::= KEY expr */
-1, /* (289) cmd ::= REINDEX */
-3, /* (290) cmd ::= REINDEX nm dbnm */
-1, /* (291) cmd ::= ANALYZE */
-3, /* (292) cmd ::= ANALYZE nm dbnm */
-6, /* (293) cmd ::= ALTER TABLE fullname RENAME TO nm */
-2, /* (294) cmd ::= alter_add carglist */
-7, /* (295) alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken */
-6, /* (296) cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
-8, /* (297) cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
-6, /* (298) cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm */
-9, /* (299) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL */
-10, /* (300) cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf */
-11, /* (301) cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */
-9, /* (302) cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */
-1, /* (303) cmd ::= create_vtab */
-4, /* (304) cmd ::= create_vtab LP vtabarglist RP */
-8, /* (305) create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
0, /* (306) vtabarg ::= */
-1, /* (307) vtabargtoken ::= ANY */
-3, /* (308) vtabargtoken ::= lp anylist RP */
-1, /* (309) lp ::= LP */
-2, /* (310) with ::= WITH wqlist */
-3, /* (311) with ::= WITH RECURSIVE wqlist */
-1, /* (312) wqas ::= AS */
-2, /* (313) wqas ::= AS MATERIALIZED */
-3, /* (314) wqas ::= AS NOT MATERIALIZED */
-6, /* (315) wqitem ::= withnm eidlist_opt wqas LP select RP */
-1, /* (316) withnm ::= nm */
-1, /* (317) wqlist ::= wqitem */
-3, /* (318) wqlist ::= wqlist COMMA wqitem */
-3, /* (319) windowdefn_list ::= windowdefn_list COMMA windowdefn */
-5, /* (320) windowdefn ::= nm AS LP window RP */
-5, /* (321) window ::= PARTITION BY nexprlist orderby_opt frame_opt */
-6, /* (322) window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
-4, /* (323) window ::= ORDER BY sortlist frame_opt */
-5, /* (324) window ::= nm ORDER BY sortlist frame_opt */
-2, /* (325) window ::= nm frame_opt */
0, /* (326) frame_opt ::= */
-3, /* (327) frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
-6, /* (328) frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
-1, /* (329) range_or_rows ::= RANGE|ROWS|GROUPS */
-1, /* (330) frame_bound_s ::= frame_bound */
-2, /* (331) frame_bound_s ::= UNBOUNDED PRECEDING */
-1, /* (332) frame_bound_e ::= frame_bound */
-2, /* (333) frame_bound_e ::= UNBOUNDED FOLLOWING */
-2, /* (334) frame_bound ::= expr PRECEDING|FOLLOWING */
-2, /* (335) frame_bound ::= CURRENT ROW */
0, /* (336) frame_exclude_opt ::= */
-2, /* (337) frame_exclude_opt ::= EXCLUDE frame_exclude */
-2, /* (338) frame_exclude ::= NO OTHERS */
-2, /* (339) frame_exclude ::= CURRENT ROW */
-1, /* (340) frame_exclude ::= GROUP|TIES */
-2, /* (341) window_clause ::= WINDOW windowdefn_list */
-2, /* (342) filter_over ::= filter_clause over_clause */
-1, /* (343) filter_over ::= over_clause */
-1, /* (344) filter_over ::= filter_clause */
-4, /* (345) over_clause ::= OVER LP window RP */
-2, /* (346) over_clause ::= OVER nm */
-5, /* (347) filter_clause ::= FILTER LP WHERE expr RP */
-1, /* (348) term ::= QNUMBER */
-1, /* (349) input ::= cmdlist */
-2, /* (350) cmdlist ::= cmdlist ecmd */
-1, /* (351) cmdlist ::= ecmd */
-1, /* (352) ecmd ::= SEMI */
-2, /* (353) ecmd ::= cmdx SEMI */
-3, /* (354) ecmd ::= explain cmdx SEMI */
0, /* (355) trans_opt ::= */
-1, /* (356) trans_opt ::= TRANSACTION */
-2, /* (357) trans_opt ::= TRANSACTION nm */
-1, /* (358) savepoint_opt ::= SAVEPOINT */
0, /* (359) savepoint_opt ::= */
-2, /* (360) cmd ::= create_table create_table_args */
-1, /* (361) table_option_set ::= table_option */
-4, /* (362) columnlist ::= columnlist COMMA columnname carglist */
-2, /* (363) columnlist ::= columnname carglist */
-1, /* (364) nm ::= ID|INDEXED|JOIN_KW */
-1, /* (365) nm ::= STRING */
-1, /* (366) typetoken ::= typename */
-1, /* (367) typename ::= ID|STRING */
-1, /* (368) signed ::= plus_num */
-1, /* (369) signed ::= minus_num */
-2, /* (370) carglist ::= carglist ccons */
0, /* (371) carglist ::= */
-2, /* (372) ccons ::= NULL onconf */
-4, /* (373) ccons ::= GENERATED ALWAYS AS generated */
-2, /* (374) ccons ::= AS generated */
-2, /* (375) conslist_opt ::= COMMA conslist */
-3, /* (376) conslist ::= conslist tconscomma tcons */
-1, /* (377) conslist ::= tcons */
0, /* (378) tconscomma ::= */
-1, /* (379) defer_subclause_opt ::= defer_subclause */
-1, /* (380) resolvetype ::= raisetype */
-1, /* (381) selectnowith ::= oneselect */
-1, /* (382) oneselect ::= values */
-2, /* (383) sclp ::= selcollist COMMA */
-1, /* (384) as ::= ID|STRING */
-1, /* (385) indexed_opt ::= indexed_by */
0, /* (386) returning ::= */
-1, /* (387) expr ::= term */
-1, /* (388) likeop ::= LIKE_KW|MATCH */
-1, /* (389) case_operand ::= expr */
-1, /* (390) exprlist ::= nexprlist */
-1, /* (391) nmnum ::= plus_num */
-1, /* (392) nmnum ::= nm */
-1, /* (393) nmnum ::= ON */
-1, /* (394) nmnum ::= DELETE */
-1, /* (395) nmnum ::= DEFAULT */
-1, /* (396) plus_num ::= INTEGER|FLOAT */
0, /* (397) foreach_clause ::= */
-3, /* (398) foreach_clause ::= FOR EACH ROW */
-1, /* (399) trnm ::= nm */
0, /* (400) tridxby ::= */
-1, /* (401) database_kw_opt ::= DATABASE */
0, /* (402) database_kw_opt ::= */
0, /* (403) kwcolumn_opt ::= */
-1, /* (404) kwcolumn_opt ::= COLUMNKW */
-1, /* (405) vtabarglist ::= vtabarg */
-3, /* (406) vtabarglist ::= vtabarglist COMMA vtabarg */
-2, /* (407) vtabarg ::= vtabarg vtabargtoken */
0, /* (408) anylist ::= */
-4, /* (409) anylist ::= anylist LP anylist RP */
-2, /* (410) anylist ::= anylist ANY */
0, /* (411) with ::= */
-1, /* (412) windowdefn_list ::= windowdefn */
-1, /* (413) window ::= frame_opt */
};
static void yy_accept(yyParser*); /* Forward Declaration */
/*
** Perform a reduce action and the shift that must immediately
** follow the reduce.
|
| ︙ | ︙ | |||
180117 180118 180119 180120 180121 180122 180123 |
break;
case 4: /* transtype ::= */
{yymsp[1].minor.yy502 = TK_DEFERRED;}
break;
case 5: /* transtype ::= DEFERRED */
case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
| | | 182079 182080 182081 182082 182083 182084 182085 182086 182087 182088 182089 182090 182091 182092 182093 |
break;
case 4: /* transtype ::= */
{yymsp[1].minor.yy502 = TK_DEFERRED;}
break;
case 5: /* transtype ::= DEFERRED */
case 6: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==6);
case 7: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==7);
case 329: /* range_or_rows ::= RANGE|ROWS|GROUPS */ yytestcase(yyruleno==329);
{yymsp[0].minor.yy502 = yymsp[0].major; /*A-overwrites-X*/}
break;
case 8: /* cmd ::= COMMIT|END trans_opt */
case 9: /* cmd ::= ROLLBACK trans_opt */ yytestcase(yyruleno==9);
{sqlite3EndTransaction(pParse,yymsp[-1].major);}
break;
case 10: /* cmd ::= SAVEPOINT nm */
|
| ︙ | ︙ | |||
181388 181389 181390 181391 181392 181393 181394 |
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
case 293: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy563,&yymsp[0].minor.yy0);
}
break;
| | | > | > > | < | > > > > > > > > > > > > > > > > > > > > > > > > > > > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 183350 183351 183352 183353 183354 183355 183356 183357 183358 183359 183360 183361 183362 183363 183364 183365 183366 183367 183368 183369 183370 183371 183372 183373 183374 183375 183376 183377 183378 183379 183380 183381 183382 183383 183384 183385 183386 183387 183388 183389 183390 183391 183392 183393 183394 183395 183396 183397 183398 183399 183400 183401 183402 183403 183404 183405 183406 183407 183408 183409 183410 183411 183412 183413 183414 183415 183416 183417 183418 183419 183420 183421 183422 183423 183424 183425 183426 183427 183428 183429 183430 183431 183432 183433 183434 183435 183436 183437 183438 183439 183440 183441 183442 183443 183444 183445 183446 183447 183448 183449 183450 183451 183452 183453 183454 183455 183456 183457 183458 183459 183460 183461 183462 183463 183464 183465 183466 183467 183468 183469 183470 183471 183472 183473 183474 183475 183476 183477 183478 183479 183480 183481 183482 183483 183484 183485 183486 183487 183488 183489 183490 183491 183492 183493 183494 183495 183496 183497 183498 183499 183500 183501 183502 183503 183504 183505 183506 183507 183508 183509 183510 183511 183512 183513 183514 183515 183516 183517 183518 183519 183520 183521 183522 183523 183524 183525 183526 183527 183528 183529 183530 183531 183532 183533 183534 183535 183536 183537 183538 183539 183540 183541 183542 183543 183544 183545 183546 183547 183548 183549 183550 183551 183552 183553 183554 183555 183556 183557 183558 183559 183560 183561 183562 183563 183564 183565 183566 183567 183568 183569 183570 183571 183572 183573 183574 183575 183576 183577 183578 183579 183580 183581 183582 183583 183584 183585 183586 183587 183588 183589 183590 183591 183592 183593 183594 183595 183596 183597 183598 183599 183600 183601 183602 183603 183604 183605 183606 183607 183608 183609 183610 183611 183612 183613 183614 183615 183616 183617 183618 183619 183620 183621 183622 183623 183624 183625 183626 183627 183628 183629 183630 183631 183632 183633 183634 183635 183636 183637 183638 183639 183640 183641 183642 183643 183644 183645 183646 183647 183648 183649 183650 183651 183652 183653 183654 183655 183656 183657 183658 183659 183660 183661 183662 183663 183664 183665 183666 183667 183668 183669 183670 183671 183672 183673 183674 183675 183676 183677 |
{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
break;
case 293: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
{
sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy563,&yymsp[0].minor.yy0);
}
break;
case 294: /* cmd ::= alter_add carglist */
{
yymsp[-1].minor.yy0.n = (int)(pParse->sLastToken.z-yymsp[-1].minor.yy0.z) + pParse->sLastToken.n;
sqlite3AlterFinishAddColumn(pParse, &yymsp[-1].minor.yy0);
}
break;
case 295: /* alter_add ::= ALTER TABLE fullname ADD kwcolumn_opt nm typetoken */
{
disableLookaside(pParse);
sqlite3AlterBeginAddColumn(pParse, yymsp[-4].minor.yy563);
sqlite3AddColumn(pParse, yymsp[-1].minor.yy0, yymsp[0].minor.yy0);
yymsp[-6].minor.yy0 = yymsp[-1].minor.yy0;
}
break;
case 296: /* cmd ::= ALTER TABLE fullname DROP kwcolumn_opt nm */
{
sqlite3AlterDropColumn(pParse, yymsp[-3].minor.yy563, &yymsp[0].minor.yy0);
}
break;
case 297: /* cmd ::= ALTER TABLE fullname RENAME kwcolumn_opt nm TO nm */
{
sqlite3AlterRenameColumn(pParse, yymsp[-5].minor.yy563, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
}
break;
case 298: /* cmd ::= ALTER TABLE fullname DROP CONSTRAINT nm */
{
sqlite3AlterDropConstraint(pParse, yymsp[-3].minor.yy563, &yymsp[0].minor.yy0, 0);
}
break;
case 299: /* cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm DROP NOT NULL */
{
sqlite3AlterDropConstraint(pParse, yymsp[-6].minor.yy563, 0, &yymsp[-3].minor.yy0);
}
break;
case 300: /* cmd ::= ALTER TABLE fullname ALTER kwcolumn_opt nm SET NOT NULL onconf */
{
sqlite3AlterSetNotNull(pParse, yymsp[-7].minor.yy563, &yymsp[-4].minor.yy0, &yymsp[-2].minor.yy0);
}
break;
case 301: /* cmd ::= ALTER TABLE fullname ADD CONSTRAINT nm CHECK LP expr RP onconf */
{
sqlite3AlterAddConstraint(pParse, yymsp[-8].minor.yy563, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1));
}
yy_destructor(yypParser,219,&yymsp[-2].minor);
break;
case 302: /* cmd ::= ALTER TABLE fullname ADD CHECK LP expr RP onconf */
{
sqlite3AlterAddConstraint(pParse, yymsp[-6].minor.yy563, &yymsp[-4].minor.yy0, 0, yymsp[-3].minor.yy0.z+1, (yymsp[-1].minor.yy0.z-yymsp[-3].minor.yy0.z-1));
}
yy_destructor(yypParser,219,&yymsp[-2].minor);
break;
case 303: /* cmd ::= create_vtab */
{sqlite3VtabFinishParse(pParse,0);}
break;
case 304: /* cmd ::= create_vtab LP vtabarglist RP */
{sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);}
break;
case 305: /* create_vtab ::= createkw VIRTUAL TABLE ifnotexists nm dbnm USING nm */
{
sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-4].minor.yy502);
}
break;
case 306: /* vtabarg ::= */
{sqlite3VtabArgInit(pParse);}
break;
case 307: /* vtabargtoken ::= ANY */
case 308: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==308);
case 309: /* lp ::= LP */ yytestcase(yyruleno==309);
{sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);}
break;
case 310: /* with ::= WITH wqlist */
case 311: /* with ::= WITH RECURSIVE wqlist */ yytestcase(yyruleno==311);
{ sqlite3WithPush(pParse, yymsp[0].minor.yy125, 1); }
break;
case 312: /* wqas ::= AS */
{yymsp[0].minor.yy444 = M10d_Any;}
break;
case 313: /* wqas ::= AS MATERIALIZED */
{yymsp[-1].minor.yy444 = M10d_Yes;}
break;
case 314: /* wqas ::= AS NOT MATERIALIZED */
{yymsp[-2].minor.yy444 = M10d_No;}
break;
case 315: /* wqitem ::= withnm eidlist_opt wqas LP select RP */
{
yymsp[-5].minor.yy361 = sqlite3CteNew(pParse, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy402, yymsp[-1].minor.yy637, yymsp[-3].minor.yy444); /*A-overwrites-X*/
}
break;
case 316: /* withnm ::= nm */
{pParse->bHasWith = 1;}
break;
case 317: /* wqlist ::= wqitem */
{
yymsp[0].minor.yy125 = sqlite3WithAdd(pParse, 0, yymsp[0].minor.yy361); /*A-overwrites-X*/
}
break;
case 318: /* wqlist ::= wqlist COMMA wqitem */
{
yymsp[-2].minor.yy125 = sqlite3WithAdd(pParse, yymsp[-2].minor.yy125, yymsp[0].minor.yy361);
}
break;
case 319: /* windowdefn_list ::= windowdefn_list COMMA windowdefn */
{
assert( yymsp[0].minor.yy483!=0 );
sqlite3WindowChain(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy483);
yymsp[0].minor.yy483->pNextWin = yymsp[-2].minor.yy483;
yylhsminor.yy483 = yymsp[0].minor.yy483;
}
yymsp[-2].minor.yy483 = yylhsminor.yy483;
break;
case 320: /* windowdefn ::= nm AS LP window RP */
{
if( ALWAYS(yymsp[-1].minor.yy483) ){
yymsp[-1].minor.yy483->zName = sqlite3DbStrNDup(pParse->db, yymsp[-4].minor.yy0.z, yymsp[-4].minor.yy0.n);
}
yylhsminor.yy483 = yymsp[-1].minor.yy483;
}
yymsp[-4].minor.yy483 = yylhsminor.yy483;
break;
case 321: /* window ::= PARTITION BY nexprlist orderby_opt frame_opt */
{
yymsp[-4].minor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy402, yymsp[-1].minor.yy402, 0);
}
break;
case 322: /* window ::= nm PARTITION BY nexprlist orderby_opt frame_opt */
{
yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, yymsp[-2].minor.yy402, yymsp[-1].minor.yy402, &yymsp[-5].minor.yy0);
}
yymsp[-5].minor.yy483 = yylhsminor.yy483;
break;
case 323: /* window ::= ORDER BY sortlist frame_opt */
{
yymsp[-3].minor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, yymsp[-1].minor.yy402, 0);
}
break;
case 324: /* window ::= nm ORDER BY sortlist frame_opt */
{
yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, yymsp[-1].minor.yy402, &yymsp[-4].minor.yy0);
}
yymsp[-4].minor.yy483 = yylhsminor.yy483;
break;
case 325: /* window ::= nm frame_opt */
{
yylhsminor.yy483 = sqlite3WindowAssemble(pParse, yymsp[0].minor.yy483, 0, 0, &yymsp[-1].minor.yy0);
}
yymsp[-1].minor.yy483 = yylhsminor.yy483;
break;
case 326: /* frame_opt ::= */
{
yymsp[1].minor.yy483 = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
}
break;
case 327: /* frame_opt ::= range_or_rows frame_bound_s frame_exclude_opt */
{
yylhsminor.yy483 = sqlite3WindowAlloc(pParse, yymsp[-2].minor.yy502, yymsp[-1].minor.yy205.eType, yymsp[-1].minor.yy205.pExpr, TK_CURRENT, 0, yymsp[0].minor.yy444);
}
yymsp[-2].minor.yy483 = yylhsminor.yy483;
break;
case 328: /* frame_opt ::= range_or_rows BETWEEN frame_bound_s AND frame_bound_e frame_exclude_opt */
{
yylhsminor.yy483 = sqlite3WindowAlloc(pParse, yymsp[-5].minor.yy502, yymsp[-3].minor.yy205.eType, yymsp[-3].minor.yy205.pExpr, yymsp[-1].minor.yy205.eType, yymsp[-1].minor.yy205.pExpr, yymsp[0].minor.yy444);
}
yymsp[-5].minor.yy483 = yylhsminor.yy483;
break;
case 330: /* frame_bound_s ::= frame_bound */
case 332: /* frame_bound_e ::= frame_bound */ yytestcase(yyruleno==332);
{yylhsminor.yy205 = yymsp[0].minor.yy205;}
yymsp[0].minor.yy205 = yylhsminor.yy205;
break;
case 331: /* frame_bound_s ::= UNBOUNDED PRECEDING */
case 333: /* frame_bound_e ::= UNBOUNDED FOLLOWING */ yytestcase(yyruleno==333);
case 335: /* frame_bound ::= CURRENT ROW */ yytestcase(yyruleno==335);
{yylhsminor.yy205.eType = yymsp[-1].major; yylhsminor.yy205.pExpr = 0;}
yymsp[-1].minor.yy205 = yylhsminor.yy205;
break;
case 334: /* frame_bound ::= expr PRECEDING|FOLLOWING */
{yylhsminor.yy205.eType = yymsp[0].major; yylhsminor.yy205.pExpr = yymsp[-1].minor.yy590;}
yymsp[-1].minor.yy205 = yylhsminor.yy205;
break;
case 336: /* frame_exclude_opt ::= */
{yymsp[1].minor.yy444 = 0;}
break;
case 337: /* frame_exclude_opt ::= EXCLUDE frame_exclude */
{yymsp[-1].minor.yy444 = yymsp[0].minor.yy444;}
break;
case 338: /* frame_exclude ::= NO OTHERS */
case 339: /* frame_exclude ::= CURRENT ROW */ yytestcase(yyruleno==339);
{yymsp[-1].minor.yy444 = yymsp[-1].major; /*A-overwrites-X*/}
break;
case 340: /* frame_exclude ::= GROUP|TIES */
{yymsp[0].minor.yy444 = yymsp[0].major; /*A-overwrites-X*/}
break;
case 341: /* window_clause ::= WINDOW windowdefn_list */
{ yymsp[-1].minor.yy483 = yymsp[0].minor.yy483; }
break;
case 342: /* filter_over ::= filter_clause over_clause */
{
if( yymsp[0].minor.yy483 ){
yymsp[0].minor.yy483->pFilter = yymsp[-1].minor.yy590;
}else{
sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy590);
}
yylhsminor.yy483 = yymsp[0].minor.yy483;
}
yymsp[-1].minor.yy483 = yylhsminor.yy483;
break;
case 343: /* filter_over ::= over_clause */
{
yylhsminor.yy483 = yymsp[0].minor.yy483;
}
yymsp[0].minor.yy483 = yylhsminor.yy483;
break;
case 344: /* filter_over ::= filter_clause */
{
yylhsminor.yy483 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
if( yylhsminor.yy483 ){
yylhsminor.yy483->eFrmType = TK_FILTER;
yylhsminor.yy483->pFilter = yymsp[0].minor.yy590;
}else{
sqlite3ExprDelete(pParse->db, yymsp[0].minor.yy590);
}
}
yymsp[0].minor.yy483 = yylhsminor.yy483;
break;
case 345: /* over_clause ::= OVER LP window RP */
{
yymsp[-3].minor.yy483 = yymsp[-1].minor.yy483;
assert( yymsp[-3].minor.yy483!=0 );
}
break;
case 346: /* over_clause ::= OVER nm */
{
yymsp[-1].minor.yy483 = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
if( yymsp[-1].minor.yy483 ){
yymsp[-1].minor.yy483->zName = sqlite3DbStrNDup(pParse->db, yymsp[0].minor.yy0.z, yymsp[0].minor.yy0.n);
}
}
break;
case 347: /* filter_clause ::= FILTER LP WHERE expr RP */
{ yymsp[-4].minor.yy590 = yymsp[-1].minor.yy590; }
break;
case 348: /* term ::= QNUMBER */
{
yylhsminor.yy590=tokenExpr(pParse,yymsp[0].major,yymsp[0].minor.yy0);
sqlite3DequoteNumber(pParse, yylhsminor.yy590);
}
yymsp[0].minor.yy590 = yylhsminor.yy590;
break;
default:
/* (349) input ::= cmdlist */ yytestcase(yyruleno==349);
/* (350) cmdlist ::= cmdlist ecmd */ yytestcase(yyruleno==350);
/* (351) cmdlist ::= ecmd (OPTIMIZED OUT) */ assert(yyruleno!=351);
/* (352) ecmd ::= SEMI */ yytestcase(yyruleno==352);
/* (353) ecmd ::= cmdx SEMI */ yytestcase(yyruleno==353);
/* (354) ecmd ::= explain cmdx SEMI (NEVER REDUCES) */ assert(yyruleno!=354);
/* (355) trans_opt ::= */ yytestcase(yyruleno==355);
/* (356) trans_opt ::= TRANSACTION */ yytestcase(yyruleno==356);
/* (357) trans_opt ::= TRANSACTION nm */ yytestcase(yyruleno==357);
/* (358) savepoint_opt ::= SAVEPOINT */ yytestcase(yyruleno==358);
/* (359) savepoint_opt ::= */ yytestcase(yyruleno==359);
/* (360) cmd ::= create_table create_table_args */ yytestcase(yyruleno==360);
/* (361) table_option_set ::= table_option (OPTIMIZED OUT) */ assert(yyruleno!=361);
/* (362) columnlist ::= columnlist COMMA columnname carglist */ yytestcase(yyruleno==362);
/* (363) columnlist ::= columnname carglist */ yytestcase(yyruleno==363);
/* (364) nm ::= ID|INDEXED|JOIN_KW */ yytestcase(yyruleno==364);
/* (365) nm ::= STRING */ yytestcase(yyruleno==365);
/* (366) typetoken ::= typename */ yytestcase(yyruleno==366);
/* (367) typename ::= ID|STRING */ yytestcase(yyruleno==367);
/* (368) signed ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=368);
/* (369) signed ::= minus_num (OPTIMIZED OUT) */ assert(yyruleno!=369);
/* (370) carglist ::= carglist ccons */ yytestcase(yyruleno==370);
/* (371) carglist ::= */ yytestcase(yyruleno==371);
/* (372) ccons ::= NULL onconf */ yytestcase(yyruleno==372);
/* (373) ccons ::= GENERATED ALWAYS AS generated */ yytestcase(yyruleno==373);
/* (374) ccons ::= AS generated */ yytestcase(yyruleno==374);
/* (375) conslist_opt ::= COMMA conslist */ yytestcase(yyruleno==375);
/* (376) conslist ::= conslist tconscomma tcons */ yytestcase(yyruleno==376);
/* (377) conslist ::= tcons (OPTIMIZED OUT) */ assert(yyruleno!=377);
/* (378) tconscomma ::= */ yytestcase(yyruleno==378);
/* (379) defer_subclause_opt ::= defer_subclause (OPTIMIZED OUT) */ assert(yyruleno!=379);
/* (380) resolvetype ::= raisetype (OPTIMIZED OUT) */ assert(yyruleno!=380);
/* (381) selectnowith ::= oneselect (OPTIMIZED OUT) */ assert(yyruleno!=381);
/* (382) oneselect ::= values */ yytestcase(yyruleno==382);
/* (383) sclp ::= selcollist COMMA */ yytestcase(yyruleno==383);
/* (384) as ::= ID|STRING */ yytestcase(yyruleno==384);
/* (385) indexed_opt ::= indexed_by (OPTIMIZED OUT) */ assert(yyruleno!=385);
/* (386) returning ::= */ yytestcase(yyruleno==386);
/* (387) expr ::= term (OPTIMIZED OUT) */ assert(yyruleno!=387);
/* (388) likeop ::= LIKE_KW|MATCH */ yytestcase(yyruleno==388);
/* (389) case_operand ::= expr */ yytestcase(yyruleno==389);
/* (390) exprlist ::= nexprlist */ yytestcase(yyruleno==390);
/* (391) nmnum ::= plus_num (OPTIMIZED OUT) */ assert(yyruleno!=391);
/* (392) nmnum ::= nm (OPTIMIZED OUT) */ assert(yyruleno!=392);
/* (393) nmnum ::= ON */ yytestcase(yyruleno==393);
/* (394) nmnum ::= DELETE */ yytestcase(yyruleno==394);
/* (395) nmnum ::= DEFAULT */ yytestcase(yyruleno==395);
/* (396) plus_num ::= INTEGER|FLOAT */ yytestcase(yyruleno==396);
/* (397) foreach_clause ::= */ yytestcase(yyruleno==397);
/* (398) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==398);
/* (399) trnm ::= nm */ yytestcase(yyruleno==399);
/* (400) tridxby ::= */ yytestcase(yyruleno==400);
/* (401) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==401);
/* (402) database_kw_opt ::= */ yytestcase(yyruleno==402);
/* (403) kwcolumn_opt ::= */ yytestcase(yyruleno==403);
/* (404) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==404);
/* (405) vtabarglist ::= vtabarg */ yytestcase(yyruleno==405);
/* (406) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==406);
/* (407) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==407);
/* (408) anylist ::= */ yytestcase(yyruleno==408);
/* (409) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==409);
/* (410) anylist ::= anylist ANY */ yytestcase(yyruleno==410);
/* (411) with ::= */ yytestcase(yyruleno==411);
/* (412) windowdefn_list ::= windowdefn (OPTIMIZED OUT) */ assert(yyruleno!=412);
/* (413) window ::= frame_opt (OPTIMIZED OUT) */ assert(yyruleno!=413);
break;
/********** End reduce actions ************************************************/
};
assert( yyruleno<sizeof(yyRuleInfoLhs)/sizeof(yyRuleInfoLhs[0]) );
yygoto = yyRuleInfoLhs[yyruleno];
yysize = yyRuleInfoNRhs[yyruleno];
yyact = yy_find_reduce_action(yymsp[yysize].stateno,(YYCODETYPE)yygoto);
|
| ︙ | ︙ | |||
182768 182769 182770 182771 182772 182773 182774 | } #endif /* SQLITE_OMIT_WINDOWFUNC */ /* ** Return the length (in bytes) of the token that begins at z[0]. ** Store the token type in *tokenType before returning. */ | | > | | 184759 184760 184761 184762 184763 184764 184765 184766 184767 184768 184769 184770 184771 184772 184773 184774 184775 |
}
#endif /* SQLITE_OMIT_WINDOWFUNC */
/*
** Return the length (in bytes) of the token that begins at z[0].
** Store the token type in *tokenType before returning.
*/
SQLITE_PRIVATE i64 sqlite3GetToken(const unsigned char *z, int *tokenType){
i64 i;
int c;
switch( aiClass[*z] ){ /* Switch on the character-class of the first byte
** of the token. See the comment on the CC_ defines
** above. */
case CC_SPACE: {
testcase( z[0]==' ' );
testcase( z[0]=='\t' );
testcase( z[0]=='\n' );
|
| ︙ | ︙ | |||
183097 183098 183099 183100 183101 183102 183103 |
/*
** Run the parser on the given SQL string.
*/
SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){
int nErr = 0; /* Number of errors encountered */
void *pEngine; /* The LEMON-generated LALR(1) parser */
| | | 185089 185090 185091 185092 185093 185094 185095 185096 185097 185098 185099 185100 185101 185102 185103 |
/*
** Run the parser on the given SQL string.
*/
SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql){
int nErr = 0; /* Number of errors encountered */
void *pEngine; /* The LEMON-generated LALR(1) parser */
i64 n = 0; /* Length of the next token token */
int tokenType; /* type of the next token */
int lastTokenParsed = -1; /* type of the previous token */
sqlite3 *db = pParse->db; /* The database connection */
int mxSqlLen; /* Max length of an SQL string */
Parse *pParentParse = 0; /* Outer parse context, if any */
#ifdef sqlite3Parser_ENGINEALWAYSONSTACK
yyParser sEngine; /* Space to hold the Lemon-generated Parser object */
|
| ︙ | ︙ | |||
183200 183201 183202 183203 183204 183205 183206 |
/* Ignore SQL comments if either (1) we are reparsing the schema or
** (2) SQLITE_DBCONFIG_ENABLE_COMMENTS is turned on (the default). */
zSql += n;
continue;
}else if( tokenType!=TK_QNUMBER ){
Token x;
x.z = zSql;
| | | | 185192 185193 185194 185195 185196 185197 185198 185199 185200 185201 185202 185203 185204 185205 185206 185207 185208 185209 185210 185211 185212 |
/* Ignore SQL comments if either (1) we are reparsing the schema or
** (2) SQLITE_DBCONFIG_ENABLE_COMMENTS is turned on (the default). */
zSql += n;
continue;
}else if( tokenType!=TK_QNUMBER ){
Token x;
x.z = zSql;
x.n = (u32)n;
sqlite3ErrorMsg(pParse, "unrecognized token: \"%T\"", &x);
break;
}
}
pParse->sLastToken.z = zSql;
pParse->sLastToken.n = (u32)n;
sqlite3Parser(pEngine, tokenType, pParse->sLastToken);
lastTokenParsed = tokenType;
zSql += n;
assert( db->mallocFailed==0 || pParse->rc!=SQLITE_OK || startedWithOom );
if( pParse->rc!=SQLITE_OK ) break;
}
assert( nErr==0 );
|
| ︙ | ︙ | |||
183282 183283 183284 183285 183286 183287 183288 |
*/
SQLITE_PRIVATE char *sqlite3Normalize(
Vdbe *pVdbe, /* VM being reprepared */
const char *zSql /* The original SQL string */
){
sqlite3 *db; /* The database connection */
int i; /* Next unread byte of zSql[] */
| | | 185274 185275 185276 185277 185278 185279 185280 185281 185282 185283 185284 185285 185286 185287 185288 |
*/
SQLITE_PRIVATE char *sqlite3Normalize(
Vdbe *pVdbe, /* VM being reprepared */
const char *zSql /* The original SQL string */
){
sqlite3 *db; /* The database connection */
int i; /* Next unread byte of zSql[] */
i64 n; /* length of current token */
int tokenType; /* type of current token */
int prevType = 0; /* Previous non-whitespace token */
int nParen; /* Number of nested levels of parentheses */
int iStartIN; /* Start of RHS of IN operator in z[] */
int nParenAtIN; /* Value of nParent at start of RHS of IN operator */
u32 j; /* Bytes of normalized SQL generated so far */
sqlite3_str *pStr; /* The normalized SQL string under construction */
|
| ︙ | ︙ | |||
183860 183861 183862 183863 183864 183865 183866 | #ifdef SQLITE_ENABLE_DBPAGE_VTAB sqlite3DbpageRegister, #endif #ifdef SQLITE_ENABLE_DBSTAT_VTAB sqlite3DbstatRegister, #endif sqlite3TestExtInit, | < < < | 185852 185853 185854 185855 185856 185857 185858 185859 185860 185861 185862 185863 185864 185865 | #ifdef SQLITE_ENABLE_DBPAGE_VTAB sqlite3DbpageRegister, #endif #ifdef SQLITE_ENABLE_DBSTAT_VTAB sqlite3DbstatRegister, #endif sqlite3TestExtInit, #ifdef SQLITE_ENABLE_STMTVTAB sqlite3StmtVtabInit, #endif #ifdef SQLITE_ENABLE_BYTECODE_VTAB sqlite3VdbeBytecodeVtabInit, #endif #ifdef SQLITE_EXTRA_AUTOEXT |
| ︙ | ︙ | |||
185183 185184 185185 185186 185187 185188 185189 185190 185191 185192 185193 185194 185195 185196 |
pDb->pSchema = 0;
}
}
}
/* Clear the TEMP schema separately and last */
if( db->aDb[1].pSchema ){
sqlite3SchemaClear(db->aDb[1].pSchema);
}
sqlite3VtabUnlockList(db);
/* Free up the array of auxiliary databases */
sqlite3CollapseDatabaseArray(db);
assert( db->nDb<=2 );
assert( db->aDb==db->aDbStatic );
| > | 187172 187173 187174 187175 187176 187177 187178 187179 187180 187181 187182 187183 187184 187185 187186 |
pDb->pSchema = 0;
}
}
}
/* Clear the TEMP schema separately and last */
if( db->aDb[1].pSchema ){
sqlite3SchemaClear(db->aDb[1].pSchema);
assert( db->aDb[1].pSchema->trigHash.count==0 );
}
sqlite3VtabUnlockList(db);
/* Free up the array of auxiliary databases */
sqlite3CollapseDatabaseArray(db);
assert( db->nDb<=2 );
assert( db->aDb==db->aDbStatic );
|
| ︙ | ︙ | |||
186314 186315 186316 186317 186318 186319 186320 186321 186322 186323 186324 186325 186326 186327 186328 186329 186330 186331 186332 186333 186334 186335 186336 186337 186338 186339 186340 186341 186342 |
sqlite3_mutex_enter(db->mutex);
pRet = db->pWalArg;
db->xWalCallback = xCallback;
db->pWalArg = pArg;
sqlite3_mutex_leave(db->mutex);
return pRet;
#else
return 0;
#endif
}
/*
** Checkpoint database zDb.
*/
SQLITE_API int sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
int *pnLog, /* OUT: Size of WAL log in frames */
int *pnCkpt /* OUT: Total number of frames checkpointed */
){
#ifdef SQLITE_OMIT_WAL
return SQLITE_OK;
#else
int rc; /* Return code */
int iDb; /* Schema to checkpoint */
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
| > > > > > > > > | 188304 188305 188306 188307 188308 188309 188310 188311 188312 188313 188314 188315 188316 188317 188318 188319 188320 188321 188322 188323 188324 188325 188326 188327 188328 188329 188330 188331 188332 188333 188334 188335 188336 188337 188338 188339 188340 |
sqlite3_mutex_enter(db->mutex);
pRet = db->pWalArg;
db->xWalCallback = xCallback;
db->pWalArg = pArg;
sqlite3_mutex_leave(db->mutex);
return pRet;
#else
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(xCallback);
UNUSED_PARAMETER(pArg);
return 0;
#endif
}
/*
** Checkpoint database zDb.
*/
SQLITE_API int sqlite3_wal_checkpoint_v2(
sqlite3 *db, /* Database handle */
const char *zDb, /* Name of attached database (or NULL) */
int eMode, /* SQLITE_CHECKPOINT_* value */
int *pnLog, /* OUT: Size of WAL log in frames */
int *pnCkpt /* OUT: Total number of frames checkpointed */
){
#ifdef SQLITE_OMIT_WAL
UNUSED_PARAMETER(db);
UNUSED_PARAMETER(zDb);
UNUSED_PARAMETER(eMode);
UNUSED_PARAMETER(pnLog);
UNUSED_PARAMETER(pnCkpt);
return SQLITE_OK;
#else
int rc; /* Return code */
int iDb; /* Schema to checkpoint */
#ifdef SQLITE_ENABLE_API_ARMOR
if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT;
|
| ︙ | ︙ | |||
186511 186512 186513 186514 186515 186516 186517 |
**
** This routine is intended to be called by outside extensions (ex: the
** Session extension). Internal logic should invoke sqlite3Error() or
** sqlite3ErrorWithMsg() directly.
*/
SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zMsg){
int rc = SQLITE_OK;
| | | 188509 188510 188511 188512 188513 188514 188515 188516 188517 188518 188519 188520 188521 188522 188523 |
**
** This routine is intended to be called by outside extensions (ex: the
** Session extension). Internal logic should invoke sqlite3Error() or
** sqlite3ErrorWithMsg() directly.
*/
SQLITE_API int sqlite3_set_errmsg(sqlite3 *db, int errcode, const char *zMsg){
int rc = SQLITE_OK;
if( !sqlite3SafetyCheckOk(db) ){
return SQLITE_MISUSE_BKPT;
}
sqlite3_mutex_enter(db->mutex);
if( zMsg ){
sqlite3ErrorWithMsg(db, errcode, "%s", zMsg);
}else{
sqlite3Error(db, errcode);
|
| ︙ | ︙ | |||
186710 186711 186712 186713 186714 186715 186716 186717 186718 186719 186720 186721 186722 186723 | SQLITE_MAX_VDBE_OP, SQLITE_MAX_FUNCTION_ARG, SQLITE_MAX_ATTACHED, SQLITE_MAX_LIKE_PATTERN_LENGTH, SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */ SQLITE_MAX_TRIGGER_DEPTH, SQLITE_MAX_WORKER_THREADS, }; /* ** Make sure the hard limits are set to reasonable values */ #if SQLITE_MAX_LENGTH<100 # error SQLITE_MAX_LENGTH must be at least 100 | > | 188708 188709 188710 188711 188712 188713 188714 188715 188716 188717 188718 188719 188720 188721 188722 | SQLITE_MAX_VDBE_OP, SQLITE_MAX_FUNCTION_ARG, SQLITE_MAX_ATTACHED, SQLITE_MAX_LIKE_PATTERN_LENGTH, SQLITE_MAX_VARIABLE_NUMBER, /* IMP: R-38091-32352 */ SQLITE_MAX_TRIGGER_DEPTH, SQLITE_MAX_WORKER_THREADS, SQLITE_MAX_PARSER_DEPTH, }; /* ** Make sure the hard limits are set to reasonable values */ #if SQLITE_MAX_LENGTH<100 # error SQLITE_MAX_LENGTH must be at least 100 |
| ︙ | ︙ | |||
186779 186780 186781 186782 186783 186784 186785 186786 186787 186788 186789 186790 186791 186792 186793 186794 |
** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to
** "_MAX_".)
*/
assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH );
assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH );
assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN );
assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH );
assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT);
assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP );
assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG );
assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED );
assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]==
SQLITE_MAX_LIKE_PATTERN_LENGTH );
assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS );
| > | | 188778 188779 188780 188781 188782 188783 188784 188785 188786 188787 188788 188789 188790 188791 188792 188793 188794 188795 188796 188797 188798 188799 188800 188801 188802 |
** macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to
** "_MAX_".)
*/
assert( aHardLimit[SQLITE_LIMIT_LENGTH]==SQLITE_MAX_LENGTH );
assert( aHardLimit[SQLITE_LIMIT_SQL_LENGTH]==SQLITE_MAX_SQL_LENGTH );
assert( aHardLimit[SQLITE_LIMIT_COLUMN]==SQLITE_MAX_COLUMN );
assert( aHardLimit[SQLITE_LIMIT_EXPR_DEPTH]==SQLITE_MAX_EXPR_DEPTH );
assert( aHardLimit[SQLITE_LIMIT_PARSER_DEPTH]==SQLITE_MAX_PARSER_DEPTH );
assert( aHardLimit[SQLITE_LIMIT_COMPOUND_SELECT]==SQLITE_MAX_COMPOUND_SELECT);
assert( aHardLimit[SQLITE_LIMIT_VDBE_OP]==SQLITE_MAX_VDBE_OP );
assert( aHardLimit[SQLITE_LIMIT_FUNCTION_ARG]==SQLITE_MAX_FUNCTION_ARG );
assert( aHardLimit[SQLITE_LIMIT_ATTACHED]==SQLITE_MAX_ATTACHED );
assert( aHardLimit[SQLITE_LIMIT_LIKE_PATTERN_LENGTH]==
SQLITE_MAX_LIKE_PATTERN_LENGTH );
assert( aHardLimit[SQLITE_LIMIT_VARIABLE_NUMBER]==SQLITE_MAX_VARIABLE_NUMBER);
assert( aHardLimit[SQLITE_LIMIT_TRIGGER_DEPTH]==SQLITE_MAX_TRIGGER_DEPTH );
assert( aHardLimit[SQLITE_LIMIT_WORKER_THREADS]==SQLITE_MAX_WORKER_THREADS );
assert( SQLITE_LIMIT_PARSER_DEPTH==(SQLITE_N_LIMIT-1) );
if( limitId<0 || limitId>=SQLITE_N_LIMIT ){
return -1;
}
oldLimit = db->aLimit[limitId];
if( newLimit>=0 ){ /* IMP: R-52476-28732 */
|
| ︙ | ︙ | |||
188691 188692 188693 188694 188695 188696 188697 188698 188699 188700 188701 188702 188703 188704 |
zFilename += sqlite3Strlen30(zFilename) + 1;
zFilename += sqlite3Strlen30(zFilename) + 1;
}
return zFilename + 1;
}
SQLITE_API const char *sqlite3_filename_wal(const char *zFilename){
#ifdef SQLITE_OMIT_WAL
return 0;
#else
zFilename = sqlite3_filename_journal(zFilename);
if( zFilename ) zFilename += sqlite3Strlen30(zFilename) + 1;
return zFilename;
#endif
}
| > | 190691 190692 190693 190694 190695 190696 190697 190698 190699 190700 190701 190702 190703 190704 190705 |
zFilename += sqlite3Strlen30(zFilename) + 1;
zFilename += sqlite3Strlen30(zFilename) + 1;
}
return zFilename + 1;
}
SQLITE_API const char *sqlite3_filename_wal(const char *zFilename){
#ifdef SQLITE_OMIT_WAL
UNUSED_PARAMETER(zFilename);
return 0;
#else
zFilename = sqlite3_filename_journal(zFilename);
if( zFilename ) zFilename += sqlite3Strlen30(zFilename) + 1;
return zFilename;
#endif
}
|
| ︙ | ︙ | |||
200708 200709 200710 200711 200712 200713 200714 |
typedef struct SegmentWriter SegmentWriter;
/*
** An instance of the following data structure is used to build doclists
** incrementally. See function fts3PendingListAppend() for details.
*/
struct PendingList {
| | | | 202709 202710 202711 202712 202713 202714 202715 202716 202717 202718 202719 202720 202721 202722 202723 202724 202725 |
typedef struct SegmentWriter SegmentWriter;
/*
** An instance of the following data structure is used to build doclists
** incrementally. See function fts3PendingListAppend() for details.
*/
struct PendingList {
sqlite3_int64 nData;
char *aData;
sqlite3_int64 nSpace;
sqlite3_int64 iLastDocid;
sqlite3_int64 iLastCol;
sqlite3_int64 iLastPos;
};
/*
|
| ︙ | ︙ | |||
206067 206068 206069 206070 206071 206072 206073 |
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
else{
int v;
if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){
v = atoi(&zVal[9]);
if( v>=24 && v<=p->nPgsz-35 ) p->nNodeSize = v;
rc = SQLITE_OK;
| | | 208068 208069 208070 208071 208072 208073 208074 208075 208076 208077 208078 208079 208080 208081 208082 |
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
else{
int v;
if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){
v = atoi(&zVal[9]);
if( v>=24 && v<=p->nPgsz-35 ) p->nNodeSize = v;
rc = SQLITE_OK;
}else if( nVal>11 && 0==sqlite3_strnicmp(zVal, "maxpending=", 11) ){
v = atoi(&zVal[11]);
if( v>=64 && v<=FTS3_MAX_PENDING_DATA ) p->nMaxPendingData = v;
rc = SQLITE_OK;
}else if( nVal>21 && 0==sqlite3_strnicmp(zVal,"test-no-incr-doclist=",21) ){
p->bNoIncrDoclist = atoi(&zVal[21]);
rc = SQLITE_OK;
}else if( nVal>11 && 0==sqlite3_strnicmp(zVal,"mergecount=",11) ){
|
| ︙ | ︙ | |||
206464 206465 206466 206467 206468 206469 206470 | /* #include "fts3Int.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <string.h> */ /* #include <assert.h> */ | < < < < | 208465 208466 208467 208468 208469 208470 208471 208472 208473 208474 208475 208476 208477 208478 | /* #include "fts3Int.h" */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) /* #include <string.h> */ /* #include <assert.h> */ /* ** Characters that may appear in the second argument to matchinfo(). */ #define FTS3_MATCHINFO_NPHRASE 'p' /* 1 value */ #define FTS3_MATCHINFO_NCOL 'c' /* 1 value */ #define FTS3_MATCHINFO_NDOC 'n' /* 1 value */ #define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */ |
| ︙ | ︙ | |||
211321 211322 211323 211324 211325 211326 211327 |
break;
}
switch( (u8)zIn[1] ){
case '\'':
jsonAppendChar(pOut, '\'');
break;
case 'v':
| | | 213318 213319 213320 213321 213322 213323 213324 213325 213326 213327 213328 213329 213330 213331 213332 |
break;
}
switch( (u8)zIn[1] ){
case '\'':
jsonAppendChar(pOut, '\'');
break;
case 'v':
jsonAppendRawNZ(pOut, "\\u000b", 6);
break;
case 'x':
if( sz2<4 ){
pOut->eErr |= JSTRING_MALFORMED;
sz2 = 2;
break;
}
|
| ︙ | ︙ | |||
212171 212172 212173 212174 212175 212176 212177 | /* ** Return the value of the BLOB node at index i. ** ** If the value is a primitive, return it as an SQL value. ** If the value is an array or object, return it as either | | > > > | > > > > | > | 214168 214169 214170 214171 214172 214173 214174 214175 214176 214177 214178 214179 214180 214181 214182 214183 214184 214185 214186 214187 214188 214189 214190 214191 214192 214193 214194 214195 214196 214197 214198 214199 214200 214201 214202 |
/*
** Return the value of the BLOB node at index i.
**
** If the value is a primitive, return it as an SQL value.
** If the value is an array or object, return it as either
** JSON text or the BLOB encoding, depending on the eMode flag
** as follows:
**
** eMode==0 JSONB if the JSON_B flag is set in userdata or
** text if the JSON_B flag is omitted from userdata.
**
** eMode==1 Text
**
** eMode==2 JSONB
*/
static void jsonReturnFromBlob(
JsonParse *pParse, /* Complete JSON parse tree */
u32 i, /* Index of the node */
sqlite3_context *pCtx, /* Return value for this function */
int eMode /* Format of return: text of JSONB */
){
u32 n, sz;
int rc;
sqlite3 *db = sqlite3_context_db_handle(pCtx);
assert( eMode>=0 && eMode<=2 );
n = jsonbPayloadSize(pParse, i, &sz);
if( n==0 ){
sqlite3_result_error(pCtx, "malformed JSON", -1);
return;
}
switch( pParse->aBlob[i] & 0x0f ){
case JSONB_NULL: {
|
| ︙ | ︙ | |||
212224 212225 212226 212227 212228 212229 212230 |
bNeg = 1;
}
z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz);
if( z==0 ) goto returnfromblob_oom;
rc = sqlite3DecOrHexToI64(z, &iRes);
sqlite3DbFree(db, z);
if( rc==0 ){
| > > > > > > > > > > > | > | 214229 214230 214231 214232 214233 214234 214235 214236 214237 214238 214239 214240 214241 214242 214243 214244 214245 214246 214247 214248 214249 214250 214251 214252 214253 214254 214255 |
bNeg = 1;
}
z = sqlite3DbStrNDup(db, (const char*)&pParse->aBlob[i+n], (int)sz);
if( z==0 ) goto returnfromblob_oom;
rc = sqlite3DecOrHexToI64(z, &iRes);
sqlite3DbFree(db, z);
if( rc==0 ){
if( iRes<0 ){
/* A hexadecimal literal with 16 significant digits and with the
** high-order bit set is a negative integer in SQLite (and hence
** iRes comes back as negative) but should be interpreted as a
** positive value if it occurs within JSON. The value is too
** large to appear as an SQLite integer so it must be converted
** into floating point. */
double r;
r = (double)*(sqlite3_uint64*)&iRes;
sqlite3_result_double(pCtx, bNeg ? -r : r);
}else{
sqlite3_result_int64(pCtx, bNeg ? -iRes : iRes);
}
}else if( rc==3 && bNeg ){
sqlite3_result_int64(pCtx, SMALLEST_INT64);
}else if( rc==1 ){
goto returnfromblob_malformed;
}else{
if( bNeg ){ n--; sz++; }
goto to_double;
|
| ︙ | ︙ | |||
212302 212303 212304 212305 212306 212307 212308 |
assert( iOut<=nOut );
zOut[iOut] = 0;
sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC);
break;
}
case JSONB_ARRAY:
case JSONB_OBJECT: {
| > | > > > > > | | 214319 214320 214321 214322 214323 214324 214325 214326 214327 214328 214329 214330 214331 214332 214333 214334 214335 214336 214337 214338 214339 214340 |
assert( iOut<=nOut );
zOut[iOut] = 0;
sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC);
break;
}
case JSONB_ARRAY:
case JSONB_OBJECT: {
if( eMode==0 ){
if( (SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx)) & JSON_BLOB)!=0 ){
eMode = 2;
}else{
eMode = 1;
}
}
if( eMode==2 ){
sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT);
}else{
jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n);
}
break;
}
default: {
|
| ︙ | ︙ | |||
213950 213951 213952 213953 213954 213955 213956 213957 213958 213959 213960 213961 213962 213963 213964 213965 213966 213967 213968 213969 213970 213971 213972 213973 213974 |
sqlite3_vtab_cursor base; /* Base class - must be first */
u32 iRowid; /* The rowid */
u32 i; /* Index in sParse.aBlob[] of current row */
u32 iEnd; /* EOF when i equals or exceeds this value */
u32 nRoot; /* Size of the root path in bytes */
u8 eType; /* Type of the container for element i */
u8 bRecursive; /* True for json_tree(). False for json_each() */
u32 nParent; /* Current nesting depth */
u32 nParentAlloc; /* Space allocated for aParent[] */
JsonParent *aParent; /* Parent elements of i */
sqlite3 *db; /* Database connection */
JsonString path; /* Current path */
JsonParse sParse; /* Parse of the input JSON */
};
typedef struct JsonEachConnection JsonEachConnection;
struct JsonEachConnection {
sqlite3_vtab base; /* Base class - must be first */
sqlite3 *db; /* Database connection */
};
/* Constructor for the json_each virtual table */
static int jsonEachConnect(
sqlite3 *db,
void *pAux,
| > > > | 215973 215974 215975 215976 215977 215978 215979 215980 215981 215982 215983 215984 215985 215986 215987 215988 215989 215990 215991 215992 215993 215994 215995 215996 215997 215998 215999 216000 |
sqlite3_vtab_cursor base; /* Base class - must be first */
u32 iRowid; /* The rowid */
u32 i; /* Index in sParse.aBlob[] of current row */
u32 iEnd; /* EOF when i equals or exceeds this value */
u32 nRoot; /* Size of the root path in bytes */
u8 eType; /* Type of the container for element i */
u8 bRecursive; /* True for json_tree(). False for json_each() */
u8 eMode; /* 1 for json_each(). 2 for jsonb_each() */
u32 nParent; /* Current nesting depth */
u32 nParentAlloc; /* Space allocated for aParent[] */
JsonParent *aParent; /* Parent elements of i */
sqlite3 *db; /* Database connection */
JsonString path; /* Current path */
JsonParse sParse; /* Parse of the input JSON */
};
typedef struct JsonEachConnection JsonEachConnection;
struct JsonEachConnection {
sqlite3_vtab base; /* Base class - must be first */
sqlite3 *db; /* Database connection */
u8 eMode; /* 1 for json_each(). 2 for jsonb_each() */
u8 bRecursive; /* True for json_tree(). False for json_each() */
};
/* Constructor for the json_each virtual table */
static int jsonEachConnect(
sqlite3 *db,
void *pAux,
|
| ︙ | ︙ | |||
214003 214004 214005 214006 214007 214008 214009 214010 214011 214012 214013 214014 214015 214016 214017 214018 214019 214020 |
"json HIDDEN,root HIDDEN)");
if( rc==SQLITE_OK ){
pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew));
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
pNew->db = db;
}
return rc;
}
/* destructor for json_each virtual table */
static int jsonEachDisconnect(sqlite3_vtab *pVtab){
JsonEachConnection *p = (JsonEachConnection*)pVtab;
sqlite3DbFree(p->db, pVtab);
return SQLITE_OK;
}
| > > | | > > < < < < < < < < < < | 216029 216030 216031 216032 216033 216034 216035 216036 216037 216038 216039 216040 216041 216042 216043 216044 216045 216046 216047 216048 216049 216050 216051 216052 216053 216054 216055 216056 216057 216058 216059 216060 216061 216062 216063 216064 216065 216066 216067 216068 216069 216070 216071 |
"json HIDDEN,root HIDDEN)");
if( rc==SQLITE_OK ){
pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew));
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
pNew->db = db;
pNew->eMode = argv[0][4]=='b' ? 2 : 1;
pNew->bRecursive = argv[0][4+pNew->eMode]=='t';
}
return rc;
}
/* destructor for json_each virtual table */
static int jsonEachDisconnect(sqlite3_vtab *pVtab){
JsonEachConnection *p = (JsonEachConnection*)pVtab;
sqlite3DbFree(p->db, pVtab);
return SQLITE_OK;
}
/* constructor for a JsonEachCursor object for json_each()/json_tree(). */
static int jsonEachOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
JsonEachConnection *pVtab = (JsonEachConnection*)p;
JsonEachCursor *pCur;
UNUSED_PARAMETER(p);
pCur = sqlite3DbMallocZero(pVtab->db, sizeof(*pCur));
if( pCur==0 ) return SQLITE_NOMEM;
pCur->db = pVtab->db;
pCur->eMode = pVtab->eMode;
pCur->bRecursive = pVtab->bRecursive;
jsonStringZero(&pCur->path);
*ppCursor = &pCur->base;
return SQLITE_OK;
}
/* Reset a JsonEachCursor back to its original state. Free any memory
** held. */
static void jsonEachCursorReset(JsonEachCursor *p){
jsonParseReset(&p->sParse);
jsonStringReset(&p->path);
sqlite3DbFree(p->db, p->aParent);
p->iRowid = 0;
|
| ︙ | ︙ | |||
214242 214243 214244 214245 214246 214247 214248 |
assert( p->eType==JSONB_ARRAY );
sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iKey);
}
break;
}
case JEACH_VALUE: {
u32 i = jsonSkipLabel(p);
| | | 216262 216263 216264 216265 216266 216267 216268 216269 216270 216271 216272 216273 216274 216275 216276 |
assert( p->eType==JSONB_ARRAY );
sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iKey);
}
break;
}
case JEACH_VALUE: {
u32 i = jsonSkipLabel(p);
jsonReturnFromBlob(&p->sParse, i, ctx, p->eMode);
if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){
sqlite3_result_subtype(ctx, JSON_SUBTYPE);
}
break;
}
case JEACH_TYPE: {
u32 i = jsonSkipLabel(p);
|
| ︙ | ︙ | |||
214486 214487 214488 214489 214490 214491 214492 |
static sqlite3_module jsonEachModule = {
0, /* iVersion */
0, /* xCreate */
jsonEachConnect, /* xConnect */
jsonEachBestIndex, /* xBestIndex */
jsonEachDisconnect, /* xDisconnect */
0, /* xDestroy */
| | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 216506 216507 216508 216509 216510 216511 216512 216513 216514 216515 216516 216517 216518 216519 216520 |
static sqlite3_module jsonEachModule = {
0, /* iVersion */
0, /* xCreate */
jsonEachConnect, /* xConnect */
jsonEachBestIndex, /* xBestIndex */
jsonEachDisconnect, /* xDisconnect */
0, /* xDestroy */
jsonEachOpen, /* xOpen - open a cursor */
jsonEachClose, /* xClose - close a cursor */
jsonEachFilter, /* xFilter - configure scan constraints */
jsonEachNext, /* xNext - advance a cursor */
jsonEachEof, /* xEof - check for end of scan */
jsonEachColumn, /* xColumn - read data */
jsonEachRowid, /* xRowid - read data */
0, /* xUpdate */
|
| ︙ | ︙ | |||
214604 214605 214606 214607 214608 214609 214610 | }; sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc)); #endif } #if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) /* | | > | | | < < < < | < > | > | | > | | 216595 216596 216597 216598 216599 216600 216601 216602 216603 216604 216605 216606 216607 216608 216609 216610 216611 216612 216613 216614 216615 216616 216617 216618 216619 216620 216621 216622 216623 |
};
sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));
#endif
}
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
/*
** Register the JSON table-valued function named zName and return a
** pointer to its Module object. Return NULL if something goes wrong.
*/
SQLITE_PRIVATE Module *sqlite3JsonVtabRegister(sqlite3 *db, const char *zName){
unsigned int i;
static const char *azModule[] = {
"json_each", "json_tree", "jsonb_each", "jsonb_tree"
};
assert( sqlite3HashFind(&db->aModule, zName)==0 );
for(i=0; i<sizeof(azModule)/sizeof(azModule[0]); i++){
if( sqlite3StrICmp(azModule[i],zName)==0 ){
return sqlite3VtabCreateModule(db, azModule[i], &jsonEachModule, 0, 0);
}
}
return 0;
}
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) */
/************** End of json.c ************************************************/
/************** Begin file rtree.c *******************************************/
/*
** 2001 September 15
|
| ︙ | ︙ | |||
214689 214690 214691 214692 214693 214694 214695 | #ifndef SQLITE_CORE /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 #else /* #include "sqlite3.h" */ #endif | | | 216679 216680 216681 216682 216683 216684 216685 216686 216687 216688 216689 216690 216691 216692 216693 | #ifndef SQLITE_CORE /* #include "sqlite3ext.h" */ SQLITE_EXTENSION_INIT1 #else /* #include "sqlite3.h" */ #endif SQLITE_PRIVATE sqlite3_int64 sqlite3GetToken(const unsigned char*,int*); /* In SQLite core */ /* #include <stddef.h> */ /* ** If building separately, we will need some setup that is normally ** found in sqliteInt.h */ |
| ︙ | ︙ | |||
229228 229229 229230 229231 229232 229233 229234 |
if( rc==SQLITE_OK ){
const void *pData = sqlite3_value_blob(argv[3]);
if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
unsigned char *aPage = sqlite3PagerGetData(pDbPage);
memcpy(aPage, pData, szPage);
pTab->pgnoTrunc = 0;
}
| < > > | 231218 231219 231220 231221 231222 231223 231224 231225 231226 231227 231228 231229 231230 231231 231232 231233 |
if( rc==SQLITE_OK ){
const void *pData = sqlite3_value_blob(argv[3]);
if( (rc = sqlite3PagerWrite(pDbPage))==SQLITE_OK && pData ){
unsigned char *aPage = sqlite3PagerGetData(pDbPage);
memcpy(aPage, pData, szPage);
pTab->pgnoTrunc = 0;
}
}
if( rc!=SQLITE_OK ){
pTab->pgnoTrunc = 0;
}
sqlite3PagerUnref(pDbPage);
return rc;
update_fail:
pTab->pgnoTrunc = 0;
|
| ︙ | ︙ | |||
229311 229312 229313 229314 229315 229316 229317 229318 229319 229320 229321 229322 229323 229324 |
return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
}
#elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
/************** End of dbpage.c **********************************************/
/************** Begin file sqlite3session.c **********************************/
#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
/* #include "sqlite3session.h" */
/* #include <assert.h> */
/* #include <string.h> */
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 231302 231303 231304 231305 231306 231307 231308 231309 231310 231311 231312 231313 231314 231315 231316 231317 231318 231319 231320 231321 231322 231323 231324 231325 231326 231327 231328 231329 231330 231331 231332 231333 231334 231335 231336 231337 231338 231339 231340 231341 231342 231343 231344 231345 231346 231347 231348 231349 231350 231351 231352 231353 231354 231355 231356 231357 231358 231359 231360 231361 231362 231363 231364 231365 231366 231367 231368 231369 231370 231371 231372 231373 231374 231375 231376 231377 231378 231379 231380 231381 231382 231383 231384 231385 231386 231387 231388 231389 231390 231391 231392 231393 231394 231395 231396 231397 231398 231399 231400 231401 231402 231403 231404 231405 231406 231407 231408 231409 231410 231411 231412 231413 231414 231415 231416 231417 231418 231419 231420 231421 231422 231423 231424 231425 231426 231427 231428 231429 231430 231431 231432 231433 231434 231435 231436 231437 231438 231439 231440 231441 231442 231443 231444 231445 231446 231447 231448 231449 231450 231451 231452 231453 231454 231455 231456 231457 231458 231459 231460 231461 231462 231463 231464 231465 231466 231467 231468 231469 231470 231471 231472 231473 231474 231475 231476 231477 231478 231479 231480 231481 231482 231483 231484 231485 231486 231487 231488 231489 231490 231491 231492 231493 231494 231495 231496 231497 231498 231499 231500 231501 231502 231503 231504 231505 231506 231507 231508 231509 231510 231511 231512 231513 231514 231515 231516 231517 231518 231519 231520 231521 231522 231523 231524 231525 231526 231527 231528 231529 231530 231531 231532 231533 231534 231535 231536 231537 231538 231539 231540 231541 231542 231543 231544 231545 231546 231547 231548 231549 231550 231551 231552 231553 231554 231555 231556 231557 231558 231559 231560 231561 231562 231563 231564 231565 231566 231567 231568 231569 231570 231571 231572 231573 231574 231575 231576 231577 231578 231579 231580 231581 231582 231583 231584 231585 231586 231587 231588 231589 231590 231591 231592 231593 231594 231595 231596 231597 231598 231599 231600 231601 231602 231603 231604 231605 231606 231607 231608 231609 231610 231611 231612 231613 231614 231615 231616 231617 231618 231619 231620 231621 231622 231623 231624 231625 231626 231627 231628 231629 231630 231631 231632 231633 231634 231635 231636 231637 231638 231639 231640 231641 231642 231643 231644 231645 231646 231647 231648 231649 231650 231651 231652 231653 231654 231655 231656 231657 231658 231659 231660 231661 231662 231663 231664 231665 231666 231667 231668 231669 231670 231671 231672 231673 231674 231675 231676 231677 231678 231679 231680 231681 231682 231683 231684 231685 231686 231687 231688 231689 231690 231691 231692 231693 231694 231695 231696 231697 231698 231699 231700 231701 231702 231703 231704 231705 231706 231707 231708 231709 231710 231711 231712 231713 231714 231715 231716 231717 231718 231719 231720 231721 231722 231723 231724 231725 231726 231727 231728 231729 231730 231731 231732 231733 231734 231735 231736 231737 231738 231739 231740 231741 231742 231743 231744 231745 231746 231747 231748 231749 231750 231751 231752 231753 231754 231755 231756 231757 231758 231759 231760 231761 231762 231763 231764 231765 231766 231767 231768 231769 231770 231771 231772 231773 231774 231775 231776 231777 231778 231779 231780 231781 231782 231783 231784 231785 231786 231787 231788 231789 231790 231791 231792 231793 231794 231795 231796 231797 231798 231799 231800 231801 231802 231803 231804 231805 231806 231807 231808 231809 231810 231811 231812 231813 231814 231815 231816 231817 231818 231819 231820 231821 231822 231823 231824 231825 231826 231827 231828 231829 231830 231831 231832 231833 231834 231835 231836 231837 231838 231839 231840 231841 231842 231843 231844 231845 |
return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
}
#elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
SQLITE_PRIVATE int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */
/************** End of dbpage.c **********************************************/
/************** Begin file carray.c ******************************************/
/*
** 2016-06-29
**
** The author disclaims copyright to this source code. In place of
** a legal notice, here is a blessing:
**
** May you do good and not evil.
** May you find forgiveness for yourself and forgive others.
** May you share freely, never taking more than you give.
**
*************************************************************************
**
** This file implements a table-valued-function that
** returns the values in a C-language array.
** Examples:
**
** SELECT * FROM carray($ptr,5)
**
** The query above returns 5 integers contained in a C-language array
** at the address $ptr. $ptr is a pointer to the array of integers.
** The pointer value must be assigned to $ptr using the
** sqlite3_bind_pointer() interface with a pointer type of "carray".
** For example:
**
** static int aX[] = { 53, 9, 17, 2231, 4, 99 };
** int i = sqlite3_bind_parameter_index(pStmt, "$ptr");
** sqlite3_bind_pointer(pStmt, i, aX, "carray", 0);
**
** There is an optional third parameter to determine the datatype of
** the C-language array. Allowed values of the third parameter are
** 'int32', 'int64', 'double', 'char*', 'struct iovec'. Example:
**
** SELECT * FROM carray($ptr,10,'char*');
**
** The default value of the third parameter is 'int32'.
**
** HOW IT WORKS
**
** The carray "function" is really a virtual table with the
** following schema:
**
** CREATE TABLE carray(
** value,
** pointer HIDDEN,
** count HIDDEN,
** ctype TEXT HIDDEN
** );
**
** If the hidden columns "pointer" and "count" are unconstrained, then
** the virtual table has no rows. Otherwise, the virtual table interprets
** the integer value of "pointer" as a pointer to the array and "count"
** as the number of elements in the array. The virtual table steps through
** the array, element by element.
*/
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_CARRAY)
/* #include "sqliteInt.h" */
#if defined(_WIN32) || defined(__RTP__) || defined(_WRS_KERNEL)
struct iovec {
void *iov_base;
size_t iov_len;
};
#else
# include <sys/uio.h>
#endif
/*
** Names of allowed datatypes
*/
static const char *azCarrayType[] = {
"int32", "int64", "double", "char*", "struct iovec"
};
/*
** Structure used to hold the sqlite3_carray_bind() information
*/
typedef struct carray_bind carray_bind;
struct carray_bind {
void *aData; /* The data */
int nData; /* Number of elements */
int mFlags; /* Control flags */
void (*xDel)(void*); /* Destructor for aData */
};
/* carray_cursor is a subclass of sqlite3_vtab_cursor which will
** serve as the underlying representation of a cursor that scans
** over rows of the result
*/
typedef struct carray_cursor carray_cursor;
struct carray_cursor {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3_int64 iRowid; /* The rowid */
void *pPtr; /* Pointer to the array of values */
sqlite3_int64 iCnt; /* Number of integers in the array */
unsigned char eType; /* One of the CARRAY_type values */
};
/*
** The carrayConnect() method is invoked to create a new
** carray_vtab that describes the carray virtual table.
**
** Think of this routine as the constructor for carray_vtab objects.
**
** All this routine needs to do is:
**
** (1) Allocate the carray_vtab object and initialize all fields.
**
** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
** result set of queries against carray will look like.
*/
static int carrayConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
sqlite3_vtab *pNew;
int rc;
/* Column numbers */
#define CARRAY_COLUMN_VALUE 0
#define CARRAY_COLUMN_POINTER 1
#define CARRAY_COLUMN_COUNT 2
#define CARRAY_COLUMN_CTYPE 3
rc = sqlite3_declare_vtab(db,
"CREATE TABLE x(value,pointer hidden,count hidden,ctype hidden)");
if( rc==SQLITE_OK ){
pNew = *ppVtab = sqlite3_malloc( sizeof(*pNew) );
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
}
return rc;
}
/*
** This method is the destructor for carray_cursor objects.
*/
static int carrayDisconnect(sqlite3_vtab *pVtab){
sqlite3_free(pVtab);
return SQLITE_OK;
}
/*
** Constructor for a new carray_cursor object.
*/
static int carrayOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
carray_cursor *pCur;
pCur = sqlite3_malloc( sizeof(*pCur) );
if( pCur==0 ) return SQLITE_NOMEM;
memset(pCur, 0, sizeof(*pCur));
*ppCursor = &pCur->base;
return SQLITE_OK;
}
/*
** Destructor for a carray_cursor.
*/
static int carrayClose(sqlite3_vtab_cursor *cur){
sqlite3_free(cur);
return SQLITE_OK;
}
/*
** Advance a carray_cursor to its next row of output.
*/
static int carrayNext(sqlite3_vtab_cursor *cur){
carray_cursor *pCur = (carray_cursor*)cur;
pCur->iRowid++;
return SQLITE_OK;
}
/*
** Return values of columns for the row at which the carray_cursor
** is currently pointing.
*/
static int carrayColumn(
sqlite3_vtab_cursor *cur, /* The cursor */
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
int i /* Which column to return */
){
carray_cursor *pCur = (carray_cursor*)cur;
sqlite3_int64 x = 0;
switch( i ){
case CARRAY_COLUMN_POINTER: return SQLITE_OK;
case CARRAY_COLUMN_COUNT: x = pCur->iCnt; break;
case CARRAY_COLUMN_CTYPE: {
sqlite3_result_text(ctx, azCarrayType[pCur->eType], -1, SQLITE_STATIC);
return SQLITE_OK;
}
default: {
switch( pCur->eType ){
case CARRAY_INT32: {
int *p = (int*)pCur->pPtr;
sqlite3_result_int(ctx, p[pCur->iRowid-1]);
return SQLITE_OK;
}
case CARRAY_INT64: {
sqlite3_int64 *p = (sqlite3_int64*)pCur->pPtr;
sqlite3_result_int64(ctx, p[pCur->iRowid-1]);
return SQLITE_OK;
}
case CARRAY_DOUBLE: {
double *p = (double*)pCur->pPtr;
sqlite3_result_double(ctx, p[pCur->iRowid-1]);
return SQLITE_OK;
}
case CARRAY_TEXT: {
const char **p = (const char**)pCur->pPtr;
sqlite3_result_text(ctx, p[pCur->iRowid-1], -1, SQLITE_TRANSIENT);
return SQLITE_OK;
}
default: {
const struct iovec *p = (struct iovec*)pCur->pPtr;
assert( pCur->eType==CARRAY_BLOB );
sqlite3_result_blob(ctx, p[pCur->iRowid-1].iov_base,
(int)p[pCur->iRowid-1].iov_len, SQLITE_TRANSIENT);
return SQLITE_OK;
}
}
}
}
sqlite3_result_int64(ctx, x);
return SQLITE_OK;
}
/*
** Return the rowid for the current row. In this implementation, the
** rowid is the same as the output value.
*/
static int carrayRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
carray_cursor *pCur = (carray_cursor*)cur;
*pRowid = pCur->iRowid;
return SQLITE_OK;
}
/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int carrayEof(sqlite3_vtab_cursor *cur){
carray_cursor *pCur = (carray_cursor*)cur;
return pCur->iRowid>pCur->iCnt;
}
/*
** This method is called to "rewind" the carray_cursor object back
** to the first row of output.
*/
static int carrayFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
carray_cursor *pCur = (carray_cursor *)pVtabCursor;
pCur->pPtr = 0;
pCur->iCnt = 0;
switch( idxNum ){
case 1: {
carray_bind *pBind = sqlite3_value_pointer(argv[0], "carray-bind");
if( pBind==0 ) break;
pCur->pPtr = pBind->aData;
pCur->iCnt = pBind->nData;
pCur->eType = pBind->mFlags & 0x07;
break;
}
case 2:
case 3: {
pCur->pPtr = sqlite3_value_pointer(argv[0], "carray");
pCur->iCnt = pCur->pPtr ? sqlite3_value_int64(argv[1]) : 0;
if( idxNum<3 ){
pCur->eType = CARRAY_INT32;
}else{
unsigned char i;
const char *zType = (const char*)sqlite3_value_text(argv[2]);
for(i=0; i<sizeof(azCarrayType)/sizeof(azCarrayType[0]); i++){
if( sqlite3_stricmp(zType, azCarrayType[i])==0 ) break;
}
if( i>=sizeof(azCarrayType)/sizeof(azCarrayType[0]) ){
pVtabCursor->pVtab->zErrMsg = sqlite3_mprintf(
"unknown datatype: %Q", zType);
return SQLITE_ERROR;
}else{
pCur->eType = i;
}
}
break;
}
}
pCur->iRowid = 1;
return SQLITE_OK;
}
/*
** SQLite will invoke this method one or more times while planning a query
** that uses the carray virtual table. This routine needs to create
** a query plan for each invocation and compute an estimated cost for that
** plan.
**
** In this implementation idxNum is used to represent the
** query plan. idxStr is unused.
**
** idxNum is:
**
** 1 If only the pointer= constraint exists. In this case, the
** parameter must be bound using sqlite3_carray_bind().
**
** 2 if the pointer= and count= constraints exist.
**
** 3 if the ctype= constraint also exists.
**
** idxNum is 0 otherwise and carray becomes an empty table.
*/
static int carrayBestIndex(
sqlite3_vtab *tab,
sqlite3_index_info *pIdxInfo
){
int i; /* Loop over constraints */
int ptrIdx = -1; /* Index of the pointer= constraint, or -1 if none */
int cntIdx = -1; /* Index of the count= constraint, or -1 if none */
int ctypeIdx = -1; /* Index of the ctype= constraint, or -1 if none */
unsigned seen = 0; /* Bitmask of == constrainted columns */
const struct sqlite3_index_constraint *pConstraint;
pConstraint = pIdxInfo->aConstraint;
for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
if( pConstraint->iColumn>=0 ) seen |= 1 << pConstraint->iColumn;
if( pConstraint->usable==0 ) continue;
switch( pConstraint->iColumn ){
case CARRAY_COLUMN_POINTER:
ptrIdx = i;
break;
case CARRAY_COLUMN_COUNT:
cntIdx = i;
break;
case CARRAY_COLUMN_CTYPE:
ctypeIdx = i;
break;
}
}
if( ptrIdx>=0 ){
pIdxInfo->aConstraintUsage[ptrIdx].argvIndex = 1;
pIdxInfo->aConstraintUsage[ptrIdx].omit = 1;
pIdxInfo->estimatedCost = (double)1;
pIdxInfo->estimatedRows = 100;
pIdxInfo->idxNum = 1;
if( cntIdx>=0 ){
pIdxInfo->aConstraintUsage[cntIdx].argvIndex = 2;
pIdxInfo->aConstraintUsage[cntIdx].omit = 1;
pIdxInfo->idxNum = 2;
if( ctypeIdx>=0 ){
pIdxInfo->aConstraintUsage[ctypeIdx].argvIndex = 3;
pIdxInfo->aConstraintUsage[ctypeIdx].omit = 1;
pIdxInfo->idxNum = 3;
}else if( seen & (1<<CARRAY_COLUMN_CTYPE) ){
/* In a three-argument carray(), we need to know the value of all
** three arguments */
return SQLITE_CONSTRAINT;
}
}else if( seen & (1<<CARRAY_COLUMN_COUNT) ){
/* In a two-argument carray(), we need to know the value of both
** arguments */
return SQLITE_CONSTRAINT;
}
}else{
pIdxInfo->estimatedCost = (double)2147483647;
pIdxInfo->estimatedRows = 2147483647;
pIdxInfo->idxNum = 0;
}
return SQLITE_OK;
}
/*
** This following structure defines all the methods for the
** carray virtual table.
*/
static sqlite3_module carrayModule = {
0, /* iVersion */
0, /* xCreate */
carrayConnect, /* xConnect */
carrayBestIndex, /* xBestIndex */
carrayDisconnect, /* xDisconnect */
0, /* xDestroy */
carrayOpen, /* xOpen - open a cursor */
carrayClose, /* xClose - close a cursor */
carrayFilter, /* xFilter - configure scan constraints */
carrayNext, /* xNext - advance a cursor */
carrayEof, /* xEof - check for end of scan */
carrayColumn, /* xColumn - read data */
carrayRowid, /* xRowid - read data */
0, /* xUpdate */
0, /* xBegin */
0, /* xSync */
0, /* xCommit */
0, /* xRollback */
0, /* xFindMethod */
0, /* xRename */
0, /* xSavepoint */
0, /* xRelease */
0, /* xRollbackTo */
0, /* xShadow */
0 /* xIntegrity */
};
/*
** Destructor for the carray_bind object
*/
static void carrayBindDel(void *pPtr){
carray_bind *p = (carray_bind*)pPtr;
if( p->xDel!=SQLITE_STATIC ){
p->xDel(p->aData);
}
sqlite3_free(p);
}
/*
** Invoke this interface in order to bind to the single-argument
** version of CARRAY().
*/
SQLITE_API int sqlite3_carray_bind(
sqlite3_stmt *pStmt,
int idx,
void *aData,
int nData,
int mFlags,
void (*xDestroy)(void*)
){
carray_bind *pNew = 0;
int i;
int rc = SQLITE_OK;
/* Ensure that the mFlags value is acceptable. */
assert( CARRAY_INT32==0 && CARRAY_INT64==1 && CARRAY_DOUBLE==2 );
assert( CARRAY_TEXT==3 && CARRAY_BLOB==4 );
if( mFlags<CARRAY_INT32 || mFlags>CARRAY_BLOB ){
rc = SQLITE_ERROR;
goto carray_bind_error;
}
pNew = sqlite3_malloc64(sizeof(*pNew));
if( pNew==0 ){
rc = SQLITE_NOMEM;
goto carray_bind_error;
}
pNew->nData = nData;
pNew->mFlags = mFlags;
if( xDestroy==SQLITE_TRANSIENT ){
sqlite3_int64 sz = nData;
switch( mFlags ){
case CARRAY_INT32: sz *= 4; break;
case CARRAY_INT64: sz *= 8; break;
case CARRAY_DOUBLE: sz *= 8; break;
case CARRAY_TEXT: sz *= sizeof(char*); break;
default: sz *= sizeof(struct iovec); break;
}
if( mFlags==CARRAY_TEXT ){
for(i=0; i<nData; i++){
const char *z = ((char**)aData)[i];
if( z ) sz += strlen(z) + 1;
}
}else if( mFlags==CARRAY_BLOB ){
for(i=0; i<nData; i++){
sz += ((struct iovec*)aData)[i].iov_len;
}
}
pNew->aData = sqlite3_malloc64( sz );
if( pNew->aData==0 ){
rc = SQLITE_NOMEM;
goto carray_bind_error;
}
if( mFlags==CARRAY_TEXT ){
char **az = (char**)pNew->aData;
char *z = (char*)&az[nData];
for(i=0; i<nData; i++){
const char *zData = ((char**)aData)[i];
sqlite3_int64 n;
if( zData==0 ){
az[i] = 0;
continue;
}
az[i] = z;
n = strlen(zData);
memcpy(z, zData, n+1);
z += n+1;
}
}else if( mFlags==CARRAY_BLOB ){
struct iovec *p = (struct iovec*)pNew->aData;
unsigned char *z = (unsigned char*)&p[nData];
for(i=0; i<nData; i++){
size_t n = ((struct iovec*)aData)[i].iov_len;
p[i].iov_len = n;
p[i].iov_base = z;
z += n;
memcpy(p[i].iov_base, ((struct iovec*)aData)[i].iov_base, n);
}
}else{
memcpy(pNew->aData, aData, sz);
}
pNew->xDel = sqlite3_free;
}else{
pNew->aData = aData;
pNew->xDel = xDestroy;
}
return sqlite3_bind_pointer(pStmt, idx, pNew, "carray-bind", carrayBindDel);
carray_bind_error:
if( xDestroy!=SQLITE_STATIC && xDestroy!=SQLITE_TRANSIENT ){
xDestroy(aData);
}
sqlite3_free(pNew);
return rc;
}
/*
** Invoke this routine to register the carray() function.
*/
SQLITE_PRIVATE Module *sqlite3CarrayRegister(sqlite3 *db){
return sqlite3VtabCreateModule(db, "carray", &carrayModule, 0, 0);
}
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_CARRAY) */
/************** End of carray.c **********************************************/
/************** Begin file sqlite3session.c **********************************/
#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
/* #include "sqlite3session.h" */
/* #include <assert.h> */
/* #include <string.h> */
|
| ︙ | ︙ | |||
234699 234700 234701 234702 234703 234704 234705 234706 234707 234708 234709 234710 234711 234712 |
sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
}
}
assert( sApply.bRebase || sApply.rebase.nBuf==0 );
if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
*ppRebase = (void*)sApply.rebase.aBuf;
*pnRebase = sApply.rebase.nBuf;
sApply.rebase.aBuf = 0;
}
sessionUpdateFree(&sApply);
sqlite3_finalize(sApply.pInsert);
sqlite3_finalize(sApply.pDelete);
| > | 237220 237221 237222 237223 237224 237225 237226 237227 237228 237229 237230 237231 237232 237233 237234 |
sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
}
}
assert( sApply.bRebase || sApply.rebase.nBuf==0 );
if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
assert( ppRebase!=0 && pnRebase!=0 );
*ppRebase = (void*)sApply.rebase.aBuf;
*pnRebase = sApply.rebase.nBuf;
sApply.rebase.aBuf = 0;
}
sessionUpdateFree(&sApply);
sqlite3_finalize(sApply.pInsert);
sqlite3_finalize(sApply.pDelete);
|
| ︙ | ︙ | |||
237996 237997 237998 237999 238000 238001 238002 238003 238004 238005 238006 238007 238008 238009 238010 238011 238012 238013 238014 238015 238016 238017 | #define fts5YYSTACKDEPTH 100 #endif #define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse; #define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse #define sqlite3Fts5ParserARG_PARAM ,pParse #define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse; #define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse; #define fts5YYREALLOC realloc #define fts5YYFREE free #define fts5YYDYNSTACK 0 #define sqlite3Fts5ParserCTX_SDECL #define sqlite3Fts5ParserCTX_PDECL #define sqlite3Fts5ParserCTX_PARAM #define sqlite3Fts5ParserCTX_FETCH #define sqlite3Fts5ParserCTX_STORE #define fts5YYNSTATE 35 #define fts5YYNRULE 28 #define fts5YYNRULE_WITH_ACTION 28 #define fts5YYNFTS5TOKEN 16 #define fts5YY_MAX_SHIFT 34 #define fts5YY_MIN_SHIFTREDUCE 52 #define fts5YY_MAX_SHIFTREDUCE 79 | > > > > > > > > | 240518 240519 240520 240521 240522 240523 240524 240525 240526 240527 240528 240529 240530 240531 240532 240533 240534 240535 240536 240537 240538 240539 240540 240541 240542 240543 240544 240545 240546 240547 | #define fts5YYSTACKDEPTH 100 #endif #define sqlite3Fts5ParserARG_SDECL Fts5Parse *pParse; #define sqlite3Fts5ParserARG_PDECL ,Fts5Parse *pParse #define sqlite3Fts5ParserARG_PARAM ,pParse #define sqlite3Fts5ParserARG_FETCH Fts5Parse *pParse=fts5yypParser->pParse; #define sqlite3Fts5ParserARG_STORE fts5yypParser->pParse=pParse; #undef fts5YYREALLOC #define fts5YYREALLOC realloc #undef fts5YYFREE #define fts5YYFREE free #undef fts5YYDYNSTACK #define fts5YYDYNSTACK 0 #undef fts5YYSIZELIMIT #define sqlite3Fts5ParserCTX(P) 0 #define sqlite3Fts5ParserCTX_SDECL #define sqlite3Fts5ParserCTX_PDECL #define sqlite3Fts5ParserCTX_PARAM #define sqlite3Fts5ParserCTX_FETCH #define sqlite3Fts5ParserCTX_STORE #undef fts5YYERRORSYMBOL #undef fts5YYERRSYMDT #undef fts5YYFALLBACK #define fts5YYNSTATE 35 #define fts5YYNRULE 28 #define fts5YYNRULE_WITH_ACTION 28 #define fts5YYNFTS5TOKEN 16 #define fts5YY_MAX_SHIFT 34 #define fts5YY_MIN_SHIFTREDUCE 52 #define fts5YY_MAX_SHIFTREDUCE 79 |
| ︙ | ︙ | |||
238328 238329 238330 238331 238332 238333 238334 238335 238336 238337 238338 |
** of errors. Return 0 on success.
*/
static int fts5yyGrowStack(fts5yyParser *p){
int oldSize = 1 + (int)(p->fts5yystackEnd - p->fts5yystack);
int newSize;
int idx;
fts5yyStackEntry *pNew;
newSize = oldSize*2 + 100;
idx = (int)(p->fts5yytos - p->fts5yystack);
if( p->fts5yystack==p->fts5yystk0 ){
| > > > > > > > > > | | | 240858 240859 240860 240861 240862 240863 240864 240865 240866 240867 240868 240869 240870 240871 240872 240873 240874 240875 240876 240877 240878 240879 240880 240881 240882 240883 240884 240885 240886 240887 240888 240889 |
** of errors. Return 0 on success.
*/
static int fts5yyGrowStack(fts5yyParser *p){
int oldSize = 1 + (int)(p->fts5yystackEnd - p->fts5yystack);
int newSize;
int idx;
fts5yyStackEntry *pNew;
#ifdef fts5YYSIZELIMIT
int nLimit = fts5YYSIZELIMIT(sqlite3Fts5ParserCTX(p));
#endif
newSize = oldSize*2 + 100;
#ifdef fts5YYSIZELIMIT
if( newSize>nLimit ){
newSize = nLimit;
if( newSize<=oldSize ) return 1;
}
#endif
idx = (int)(p->fts5yytos - p->fts5yystack);
if( p->fts5yystack==p->fts5yystk0 ){
pNew = fts5YYREALLOC(0, newSize*sizeof(pNew[0]), sqlite3Fts5ParserCTX(p));
if( pNew==0 ) return 1;
memcpy(pNew, p->fts5yystack, oldSize*sizeof(pNew[0]));
}else{
pNew = fts5YYREALLOC(p->fts5yystack, newSize*sizeof(pNew[0]), sqlite3Fts5ParserCTX(p));
if( pNew==0 ) return 1;
}
p->fts5yystack = pNew;
p->fts5yytos = &p->fts5yystack[idx];
#ifndef NDEBUG
if( fts5yyTraceFILE ){
fprintf(fts5yyTraceFILE,"%sStack grows from %d to %d entries.\n",
|
| ︙ | ︙ | |||
238516 238517 238518 238519 238520 238521 238522 |
if( fts5yytos->major>=fts5YY_MIN_DSTRCTR ){
fts5yy_destructor(pParser, fts5yytos->major, &fts5yytos->minor);
}
fts5yytos--;
}
#if fts5YYGROWABLESTACK
| | > > | 241055 241056 241057 241058 241059 241060 241061 241062 241063 241064 241065 241066 241067 241068 241069 241070 241071 |
if( fts5yytos->major>=fts5YY_MIN_DSTRCTR ){
fts5yy_destructor(pParser, fts5yytos->major, &fts5yytos->minor);
}
fts5yytos--;
}
#if fts5YYGROWABLESTACK
if( pParser->fts5yystack!=pParser->fts5yystk0 ){
fts5YYFREE(pParser->fts5yystack, sqlite3Fts5ParserCTX(pParser));
}
#endif
}
#ifndef sqlite3Fts5Parser_ENGINEALWAYSONSTACK
/*
** Deallocate and destroy a parser. Destructors are called for
** all stack elements before shutting the parser down.
|
| ︙ | ︙ | |||
246460 246461 246462 246463 246464 246465 246466 |
** All the reasons those functions might return SQLITE_ERROR - missing
** table, missing row, non-blob/text in block column - indicate
** backing store corruption. */
if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT_ROWID(p, iRowid);
if( rc==SQLITE_OK ){
u8 *aOut = 0; /* Read blob data into this buffer */
| | | | | 249001 249002 249003 249004 249005 249006 249007 249008 249009 249010 249011 249012 249013 249014 249015 249016 249017 |
** All the reasons those functions might return SQLITE_ERROR - missing
** table, missing row, non-blob/text in block column - indicate
** backing store corruption. */
if( rc==SQLITE_ERROR ) rc = FTS5_CORRUPT_ROWID(p, iRowid);
if( rc==SQLITE_OK ){
u8 *aOut = 0; /* Read blob data into this buffer */
i64 nByte = sqlite3_blob_bytes(p->pReader);
i64 szData = (sizeof(Fts5Data) + 7) & ~7;
i64 nAlloc = szData + nByte + FTS5_DATA_PADDING;
pRet = (Fts5Data*)sqlite3_malloc64(nAlloc);
if( pRet ){
pRet->nn = nByte;
aOut = pRet->p = (u8*)pRet + szData;
}else{
rc = SQLITE_NOMEM;
}
|
| ︙ | ︙ | |||
252412 252413 252414 252415 252416 252417 252418 |
union {
Fts5Structure sFts;
u8 tmpSpace[SZ_FTS5STRUCTURE(1)];
} uFts;
fts5StructureInvalidate(p);
fts5IndexDiscardData(p);
pTmp = &uFts.sFts;
| | | 254953 254954 254955 254956 254957 254958 254959 254960 254961 254962 254963 254964 254965 254966 254967 |
union {
Fts5Structure sFts;
u8 tmpSpace[SZ_FTS5STRUCTURE(1)];
} uFts;
fts5StructureInvalidate(p);
fts5IndexDiscardData(p);
pTmp = &uFts.sFts;
memset(uFts.tmpSpace, 0, sizeof(uFts.tmpSpace));
if( p->pConfig->bContentlessDelete ){
pTmp->nOriginCntr = 1;
}
fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
fts5StructureWrite(p, pTmp);
return fts5IndexReturn(p);
}
|
| ︙ | ︙ | |||
258720 258721 258722 258723 258724 258725 258726 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
| | | 261261 261262 261263 261264 261265 261266 261267 261268 261269 261270 261271 261272 261273 261274 261275 |
static void fts5SourceIdFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apUnused /* Function arguments */
){
assert( nArg==0 );
UNUSED_PARAM2(nArg, apUnused);
sqlite3_result_text(pCtx, "fts5: 2025-11-25 18:20:33 5804ba4874cc41b11e8bb559d5533283c2895d2b13316830955663575567f911", -1, SQLITE_TRANSIENT);
}
/*
** Implementation of fts5_locale(LOCALE, TEXT) function.
**
** If parameter LOCALE is NULL, or a zero-length string, then a copy of
** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as
|
| ︙ | ︙ | |||
258743 258744 258745 258746 258747 258748 258749 |
*/
static void fts5LocaleFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apArg /* Function arguments */
){
const char *zLocale = 0;
| | | | | | 261284 261285 261286 261287 261288 261289 261290 261291 261292 261293 261294 261295 261296 261297 261298 261299 261300 261301 261302 261303 261304 261305 261306 261307 261308 261309 261310 261311 261312 261313 261314 261315 261316 261317 261318 261319 261320 |
*/
static void fts5LocaleFunc(
sqlite3_context *pCtx, /* Function call context */
int nArg, /* Number of args */
sqlite3_value **apArg /* Function arguments */
){
const char *zLocale = 0;
i64 nLocale = 0;
const char *zText = 0;
i64 nText = 0;
assert( nArg==2 );
UNUSED_PARAM(nArg);
zLocale = (const char*)sqlite3_value_text(apArg[0]);
nLocale = sqlite3_value_bytes(apArg[0]);
zText = (const char*)sqlite3_value_text(apArg[1]);
nText = sqlite3_value_bytes(apArg[1]);
if( zLocale==0 || zLocale[0]=='\0' ){
sqlite3_result_text(pCtx, zText, nText, SQLITE_TRANSIENT);
}else{
Fts5Global *p = (Fts5Global*)sqlite3_user_data(pCtx);
u8 *pBlob = 0;
u8 *pCsr = 0;
i64 nBlob = 0;
nBlob = FTS5_LOCALE_HDR_SIZE + nLocale + 1 + nText;
pBlob = (u8*)sqlite3_malloc64(nBlob);
if( pBlob==0 ){
sqlite3_result_error_nomem(pCtx);
return;
}
pCsr = pBlob;
memcpy(pCsr, (const u8*)p->aLocaleHdr, FTS5_LOCALE_HDR_SIZE);
|
| ︙ | ︙ |
Changes to extsrc/sqlite3.h.
| ︙ | ︙ | |||
142 143 144 145 146 147 148 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ | | | | | | 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 | ** been edited in any way since it was last checked in, then the last ** four hexadecimal digits of the hash may be modified. ** ** See also: [sqlite3_libversion()], ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */ #define SQLITE_VERSION "3.52.0" #define SQLITE_VERSION_NUMBER 3052000 #define SQLITE_SOURCE_ID "2025-11-25 18:20:33 5804ba4874cc41b11e8bb559d5533283c2895d2b13316830955663575567f911" #define SQLITE_SCM_BRANCH "trunk" #define SQLITE_SCM_TAGS "" #define SQLITE_SCM_DATETIME "2025-11-25T18:20:33.534Z" /* ** CAPI3REF: Run-Time Library Version Numbers ** KEYWORDS: sqlite3_version sqlite3_sourceid ** ** These interfaces provide the same information as the [SQLITE_VERSION], ** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros |
| ︙ | ︙ | |||
928 929 930 931 932 933 934 | ** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]] ** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer ** to the [sqlite3_file] object associated with the journal file (either ** the [rollback journal] or the [write-ahead log]) for a particular database ** connection. See also [SQLITE_FCNTL_FILE_POINTER]. ** ** <li>[[SQLITE_FCNTL_SYNC_OMITTED]] | | | 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 | ** <li>[[SQLITE_FCNTL_JOURNAL_POINTER]] ** The [SQLITE_FCNTL_JOURNAL_POINTER] opcode is used to obtain a pointer ** to the [sqlite3_file] object associated with the journal file (either ** the [rollback journal] or the [write-ahead log]) for a particular database ** connection. See also [SQLITE_FCNTL_FILE_POINTER]. ** ** <li>[[SQLITE_FCNTL_SYNC_OMITTED]] ** The SQLITE_FCNTL_SYNC_OMITTED file-control is no longer used. ** ** <li>[[SQLITE_FCNTL_SYNC]] ** The [SQLITE_FCNTL_SYNC] opcode is generated internally by SQLite and ** sent to the VFS immediately before the xSync method is invoked on a ** database file descriptor. Or, if the xSync method is not invoked ** because the user has configured SQLite with ** [PRAGMA synchronous | PRAGMA synchronous=OFF] it is invoked in place |
| ︙ | ︙ | |||
1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 | ** [checksum VFS shim] only. ** ** <li>[[SQLITE_FCNTL_RESET_CACHE]] ** If there is currently no transaction open on the database, and the ** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control ** purges the contents of the in-memory page cache. If there is an open ** transaction, or if the db is a temp-db, this opcode is a no-op, not an error. ** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 #define SQLITE_FCNTL_LAST_ERRNO 4 #define SQLITE_FCNTL_SIZE_HINT 5 | > > > > > > > > > | 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 | ** [checksum VFS shim] only. ** ** <li>[[SQLITE_FCNTL_RESET_CACHE]] ** If there is currently no transaction open on the database, and the ** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control ** purges the contents of the in-memory page cache. If there is an open ** transaction, or if the db is a temp-db, this opcode is a no-op, not an error. ** ** <li>[[SQLITE_FCNTL_FILESTAT]] ** The [SQLITE_FCNTL_FILESTAT] opcode returns low-level diagnostic information ** about the [sqlite3_file] objects used access the database and journal files ** for the given schema. The fourth parameter to [sqlite3_file_control()] ** should be an initialized [sqlite3_str] pointer. JSON text describing ** various aspects of the sqlite3_file object is appended to the sqlite3_str. ** The SQLITE_FCNTL_FILESTAT opcode is usually a no-op, unless compile-time ** options are used to enable it. ** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1 #define SQLITE_FCNTL_GET_LOCKPROXYFILE 2 #define SQLITE_FCNTL_SET_LOCKPROXYFILE 3 #define SQLITE_FCNTL_LAST_ERRNO 4 #define SQLITE_FCNTL_SIZE_HINT 5 |
| ︙ | ︙ | |||
1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 | #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 #define SQLITE_FCNTL_NULL_IO 43 #define SQLITE_FCNTL_BLOCK_ON_CONNECT 44 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO | > | 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 | #define SQLITE_FCNTL_RESERVE_BYTES 38 #define SQLITE_FCNTL_CKPT_START 39 #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 #define SQLITE_FCNTL_RESET_CACHE 42 #define SQLITE_FCNTL_NULL_IO 43 #define SQLITE_FCNTL_BLOCK_ON_CONNECT 44 #define SQLITE_FCNTL_FILESTAT 45 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE #define SQLITE_SET_LOCKPROXYFILE SQLITE_FCNTL_SET_LOCKPROXYFILE #define SQLITE_LAST_ERRNO SQLITE_FCNTL_LAST_ERRNO |
| ︙ | ︙ | |||
2553 2554 2555 2556 2557 2558 2559 | ** not considered a bug since SQLite versions 3.3.0 and earlier do not support ** either generated columns or descending indexes. ** </dd> ** ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] ** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt> ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in | | | > > | | > | | | 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 | ** not considered a bug since SQLite versions 3.3.0 and earlier do not support ** either generated columns or descending indexes. ** </dd> ** ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] ** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt> ** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in ** [SQLITE_ENABLE_STMT_SCANSTATUS] builds. In this case, it sets or clears ** a flag that enables collection of run-time performance statistics ** used by [sqlite3_stmt_scanstatus_v2()] and the [nexec and ncycle] ** columns of the [bytecode virtual table]. ** For statistics to be collected, the flag must be set on ** the database handle both when the SQL statement is ** [sqlite3_prepare|prepared] and when it is [sqlite3_step|stepped]. ** The flag is set (collection of statistics is enabled) by default. ** <p>This option takes two arguments: an integer and a pointer to ** an integer. The first argument is 1, 0, or -1 to enable, disable, or ** leave unchanged the statement scanstatus option. If the second argument ** is not NULL, then the value of the statement scanstatus setting after ** processing the first argument is written into the integer that the second ** argument points to. ** </dd> ** |
| ︙ | ︙ | |||
4203 4204 4205 4206 4207 4208 4209 | SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); SQLITE_API const char *sqlite3_errmsg(sqlite3*); SQLITE_API const void *sqlite3_errmsg16(sqlite3*); SQLITE_API const char *sqlite3_errstr(int); SQLITE_API int sqlite3_error_offset(sqlite3 *db); /* | | | 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 | SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); SQLITE_API const char *sqlite3_errmsg(sqlite3*); SQLITE_API const void *sqlite3_errmsg16(sqlite3*); SQLITE_API const char *sqlite3_errstr(int); SQLITE_API int sqlite3_error_offset(sqlite3 *db); /* ** CAPI3REF: Set Error Code And Message ** METHOD: sqlite3 ** ** Set the error code of the database handle passed as the first argument ** to errcode, and the error message to a copy of nul-terminated string ** zErrMsg. If zErrMsg is passed NULL, then the error message is set to ** the default message associated with the supplied error code. Subsequent ** calls to [sqlite3_errcode()] and [sqlite3_errmsg()] and similar will |
| ︙ | ︙ | |||
4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 | ** [[SQLITE_LIMIT_COLUMN]] ^(<dt>SQLITE_LIMIT_COLUMN</dt> ** <dd>The maximum number of columns in a table definition or in the ** result set of a [SELECT] or the maximum number of columns in an index ** or in an ORDER BY or GROUP BY clause.</dd>)^ ** ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt> ** <dd>The maximum depth of the parse tree on any expression.</dd>)^ ** ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt> ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^ ** ** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt> ** <dd>The maximum number of instructions in a virtual machine program ** used to implement an SQL statement. If [sqlite3_prepare_v2()] or | > > > > | 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 | ** [[SQLITE_LIMIT_COLUMN]] ^(<dt>SQLITE_LIMIT_COLUMN</dt> ** <dd>The maximum number of columns in a table definition or in the ** result set of a [SELECT] or the maximum number of columns in an index ** or in an ORDER BY or GROUP BY clause.</dd>)^ ** ** [[SQLITE_LIMIT_EXPR_DEPTH]] ^(<dt>SQLITE_LIMIT_EXPR_DEPTH</dt> ** <dd>The maximum depth of the parse tree on any expression.</dd>)^ ** ** [[SQLITE_LIMIT_PARSER_DEPTH]] ^(<dt>SQLITE_LIMIT_PARSER_DEPTH</dt> ** <dd>The maximum depth of the LALR(1) parser stack used to analyze ** input SQL statements.</dd>)^ ** ** [[SQLITE_LIMIT_COMPOUND_SELECT]] ^(<dt>SQLITE_LIMIT_COMPOUND_SELECT</dt> ** <dd>The maximum number of terms in a compound SELECT statement.</dd>)^ ** ** [[SQLITE_LIMIT_VDBE_OP]] ^(<dt>SQLITE_LIMIT_VDBE_OP</dt> ** <dd>The maximum number of instructions in a virtual machine program ** used to implement an SQL statement. If [sqlite3_prepare_v2()] or |
| ︙ | ︙ | |||
4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 | #define SQLITE_LIMIT_VDBE_OP 5 #define SQLITE_LIMIT_FUNCTION_ARG 6 #define SQLITE_LIMIT_ATTACHED 7 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 #define SQLITE_LIMIT_VARIABLE_NUMBER 9 #define SQLITE_LIMIT_TRIGGER_DEPTH 10 #define SQLITE_LIMIT_WORKER_THREADS 11 /* ** CAPI3REF: Prepare Flags ** ** These constants define various flags that can be passed into the ** "prepFlags" parameter of the [sqlite3_prepare_v3()] and ** [sqlite3_prepare16_v3()] interfaces. | > | 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 | #define SQLITE_LIMIT_VDBE_OP 5 #define SQLITE_LIMIT_FUNCTION_ARG 6 #define SQLITE_LIMIT_ATTACHED 7 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 #define SQLITE_LIMIT_VARIABLE_NUMBER 9 #define SQLITE_LIMIT_TRIGGER_DEPTH 10 #define SQLITE_LIMIT_WORKER_THREADS 11 #define SQLITE_LIMIT_PARSER_DEPTH 12 /* ** CAPI3REF: Prepare Flags ** ** These constants define various flags that can be passed into the ** "prepFlags" parameter of the [sqlite3_prepare_v3()] and ** [sqlite3_prepare16_v3()] interfaces. |
| ︙ | ︙ | |||
4903 4904 4905 4906 4907 4908 4909 | ** ^A negative value for the zeroblob results in a zero-length BLOB. ** ** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in ** [prepared statement] S to have an SQL value of NULL, but to also be ** associated with the pointer P of type T. ^D is either a NULL pointer or ** a pointer to a destructor function for P. ^SQLite will invoke the ** destructor D with a single argument of P when it is finished using | > > | | | | 4921 4922 4923 4924 4925 4926 4927 4928 4929 4930 4931 4932 4933 4934 4935 4936 4937 4938 4939 | ** ^A negative value for the zeroblob results in a zero-length BLOB. ** ** ^The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in ** [prepared statement] S to have an SQL value of NULL, but to also be ** associated with the pointer P of type T. ^D is either a NULL pointer or ** a pointer to a destructor function for P. ^SQLite will invoke the ** destructor D with a single argument of P when it is finished using ** P, even if the call to sqlite3_bind_pointer() fails. Due to a ** historical design quirk, results are undefined if D is ** SQLITE_TRANSIENT. The T parameter should be a static string, ** preferably a string literal. The sqlite3_bind_pointer() routine is ** part of the [pointer passing interface] added for SQLite 3.20.0. ** ** ^If any of the sqlite3_bind_*() routines are called with a NULL pointer ** for the [prepared statement] or with a prepared statement for which ** [sqlite3_step()] has been called more recently than [sqlite3_reset()], ** then the call will return [SQLITE_MISUSE]. If any sqlite3_bind_() ** routine is passed a [prepared statement] that has been finalized, the ** result is undefined and probably harmful. |
| ︙ | ︙ | |||
8708 8709 8710 8711 8712 8713 8714 8715 8716 8717 8718 8719 8720 8721 | ** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()] ** that contains the constructed string. The calling application should ** pass the returned value to [sqlite3_free()] to avoid a memory leak. ** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any ** errors were encountered during construction of the string. ^The ** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the ** string in [sqlite3_str] object X is zero bytes long. */ SQLITE_API char *sqlite3_str_finish(sqlite3_str*); /* ** CAPI3REF: Add Content To A Dynamic String ** METHOD: sqlite3_str ** | > > > > > | | | 8728 8729 8730 8731 8732 8733 8734 8735 8736 8737 8738 8739 8740 8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 | ** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()] ** that contains the constructed string. The calling application should ** pass the returned value to [sqlite3_free()] to avoid a memory leak. ** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any ** errors were encountered during construction of the string. ^The ** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the ** string in [sqlite3_str] object X is zero bytes long. ** ** ^The [sqlite3_str_free(X)] interface destroys both the sqlite3_str object ** X and the string content it contains. Calling sqlite3_str_free(X) is ** the equivalent of calling [sqlite3_free](sqlite3_str_finish(X)). */ SQLITE_API char *sqlite3_str_finish(sqlite3_str*); SQLITE_API void sqlite3_str_free(sqlite3_str*); /* ** CAPI3REF: Add Content To A Dynamic String ** METHOD: sqlite3_str ** ** These interfaces add or remove content to an sqlite3_str object ** previously obtained from [sqlite3_str_new()]. ** ** ^The [sqlite3_str_appendf(X,F,...)] and ** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] ** functionality of SQLite to append formatted text onto the end of ** [sqlite3_str] object X. ** ** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S |
| ︙ | ︙ | |||
8738 8739 8740 8741 8742 8743 8744 8745 8746 8747 8748 8749 8750 8751 8752 8753 8754 8755 8756 8757 8758 8759 8760 8761 8762 | ** ** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the ** single-byte character C onto the end of [sqlite3_str] object X. ** ^This method can be used, for example, to add whitespace indentation. ** ** ^The [sqlite3_str_reset(X)] method resets the string under construction ** inside [sqlite3_str] object X back to zero bytes in length. ** ** These methods do not return a result code. ^If an error occurs, that fact ** is recorded in the [sqlite3_str] object and can be recovered by a ** subsequent call to [sqlite3_str_errcode(X)]. */ SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...); SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list); SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn); SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C); SQLITE_API void sqlite3_str_reset(sqlite3_str*); /* ** CAPI3REF: Status Of A Dynamic String ** METHOD: sqlite3_str ** ** These interfaces return the current status of an [sqlite3_str] object. ** | > > > > > | 8763 8764 8765 8766 8767 8768 8769 8770 8771 8772 8773 8774 8775 8776 8777 8778 8779 8780 8781 8782 8783 8784 8785 8786 8787 8788 8789 8790 8791 8792 | ** ** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the ** single-byte character C onto the end of [sqlite3_str] object X. ** ^This method can be used, for example, to add whitespace indentation. ** ** ^The [sqlite3_str_reset(X)] method resets the string under construction ** inside [sqlite3_str] object X back to zero bytes in length. ** ** ^The [sqlite3_str_truncate(X,N)] method changes the length of the string ** under construction to be N bytes are less. This routine is a no-op if ** N is negative or if the string is already N bytes or smaller in size. ** ** These methods do not return a result code. ^If an error occurs, that fact ** is recorded in the [sqlite3_str] object and can be recovered by a ** subsequent call to [sqlite3_str_errcode(X)]. */ SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...); SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list); SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N); SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn); SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C); SQLITE_API void sqlite3_str_reset(sqlite3_str*); SQLITE_API void sqlite3_str_truncate(sqlite3_str*,int N); /* ** CAPI3REF: Status Of A Dynamic String ** METHOD: sqlite3_str ** ** These interfaces return the current status of an [sqlite3_str] object. ** |
| ︙ | ︙ | |||
8916 8917 8918 8919 8920 8921 8922 8923 8924 8925 8926 8927 8928 8929 8930 8931 8932 8933 |
** ^The current value of the requested parameter is written into *pCur
** and the highest instantaneous value is written into *pHiwtr. ^If
** the resetFlg is true, then the highest instantaneous value is
** reset back down to the current value.
**
** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
** non-zero [error code] on failure.
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
/*
** CAPI3REF: Status Parameters for database connections
** KEYWORDS: {SQLITE_DBSTATUS options}
**
** These constants are the available integer "verbs" that can be passed as
** the second argument to the [sqlite3_db_status()] interface.
| > > > > > > > > > | 8946 8947 8948 8949 8950 8951 8952 8953 8954 8955 8956 8957 8958 8959 8960 8961 8962 8963 8964 8965 8966 8967 8968 8969 8970 8971 8972 |
** ^The current value of the requested parameter is written into *pCur
** and the highest instantaneous value is written into *pHiwtr. ^If
** the resetFlg is true, then the highest instantaneous value is
** reset back down to the current value.
**
** ^The sqlite3_db_status() routine returns SQLITE_OK on success and a
** non-zero [error code] on failure.
**
** ^The sqlite3_db_status64(D,O,C,H,R) routine works exactly the same
** way as sqlite3_db_status(D,O,C,H,R) routine except that the C and H
** parameters are pointer to 64-bit integers (type: sqlite3_int64) instead
** of pointers to 32-bit integers, which allows larger status values
** to be returned. If a status value exceeds 2,147,483,647 then
** sqlite3_db_status() will truncate the value whereas sqlite3_db_status64()
** will return the full value.
**
** See also: [sqlite3_status()] and [sqlite3_stmt_status()].
*/
SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg);
SQLITE_API int sqlite3_db_status64(sqlite3*,int,sqlite3_int64*,sqlite3_int64*,int);
/*
** CAPI3REF: Status Parameters for database connections
** KEYWORDS: {SQLITE_DBSTATUS options}
**
** These constants are the available integer "verbs" that can be passed as
** the second argument to the [sqlite3_db_status()] interface.
|
| ︙ | ︙ | |||
9016 9017 9018 9019 9020 9021 9022 9023 9024 9025 9026 9027 9028 9029 9030 9031 9032 9033 9034 9035 9036 9037 9038 9039 9040 9041 9042 9043 9044 9045 9046 9047 9048 9049 9050 9051 9052 9053 | ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk in the middle of a transaction due to the page ** cache overflowing. Transactions are more efficient if they are written ** to disk all at once. When pages spill mid-transaction, that introduces ** additional overhead. This parameter can be used to help identify ** inefficiencies that can be resolved by increasing the cache size. ** </dd> ** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> ** <dd>This parameter returns zero for the current value if and only if ** all foreign key constraints (deferred or immediate) have been ** resolved.)^ ^The highwater mark is always 0. ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 #define SQLITE_DBSTATUS_STMT_USED 3 #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 #define SQLITE_DBSTATUS_CACHE_HIT 7 #define SQLITE_DBSTATUS_CACHE_MISS 8 #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_DEFERRED_FKS 10 #define SQLITE_DBSTATUS_CACHE_USED_SHARED 11 #define SQLITE_DBSTATUS_CACHE_SPILL 12 | > > > > > > > > > > > > > > > > > | | 9055 9056 9057 9058 9059 9060 9061 9062 9063 9064 9065 9066 9067 9068 9069 9070 9071 9072 9073 9074 9075 9076 9077 9078 9079 9080 9081 9082 9083 9084 9085 9086 9087 9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 9114 9115 9116 9117 | ** been written to disk. Specifically, the number of pages written to the ** wal file in wal mode databases, or the number of pages written to the ** database file in rollback mode databases. Any pages written as part of ** transaction rollback or database recovery operations are not included. ** If an IO or other error occurs while writing a page to disk, the effect ** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** <p> ** ^(There is overlap between the quantities measured by this parameter ** (SQLITE_DBSTATUS_CACHE_WRITE) and SQLITE_DBSTATUS_TEMPBUF_SPILL. ** Resetting one will reduce the other.)^ ** </dd> ** ** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt> ** <dd>This parameter returns the number of dirty cache entries that have ** been written to disk in the middle of a transaction due to the page ** cache overflowing. Transactions are more efficient if they are written ** to disk all at once. When pages spill mid-transaction, that introduces ** additional overhead. This parameter can be used to help identify ** inefficiencies that can be resolved by increasing the cache size. ** </dd> ** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> ** <dd>This parameter returns zero for the current value if and only if ** all foreign key constraints (deferred or immediate) have been ** resolved.)^ ^The highwater mark is always 0. ** ** [[SQLITE_DBSTATUS_TEMPBUF_SPILL] ^(<dt>SQLITE_DBSTATUS_TEMPBUF_SPILL</dt> ** <dd>^(This parameter returns the number of bytes written to temporary ** files on disk that could have been kept in memory had sufficient memory ** been available. This value includes writes to intermediate tables that ** are part of complex queries, external sorts that spill to disk, and ** writes to TEMP tables.)^ ** ^The highwater mark is always 0. ** <p> ** ^(There is overlap between the quantities measured by this parameter ** (SQLITE_DBSTATUS_TEMPBUF_SPILL) and SQLITE_DBSTATUS_CACHE_WRITE. ** Resetting one will reduce the other.)^ ** </dd> ** </dl> */ #define SQLITE_DBSTATUS_LOOKASIDE_USED 0 #define SQLITE_DBSTATUS_CACHE_USED 1 #define SQLITE_DBSTATUS_SCHEMA_USED 2 #define SQLITE_DBSTATUS_STMT_USED 3 #define SQLITE_DBSTATUS_LOOKASIDE_HIT 4 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5 #define SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6 #define SQLITE_DBSTATUS_CACHE_HIT 7 #define SQLITE_DBSTATUS_CACHE_MISS 8 #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_DEFERRED_FKS 10 #define SQLITE_DBSTATUS_CACHE_USED_SHARED 11 #define SQLITE_DBSTATUS_CACHE_SPILL 12 #define SQLITE_DBSTATUS_TEMPBUF_SPILL 13 #define SQLITE_DBSTATUS_MAX 13 /* Largest defined DBSTATUS */ /* ** CAPI3REF: Prepared Statement Status ** METHOD: sqlite3_stmt ** ** ^(Each prepared statement maintains various |
| ︙ | ︙ | |||
10384 10385 10386 10387 10388 10389 10390 |
** <blockquote><pre>
** for(rc=sqlite3_vtab_in_first(pList, &pVal);
** rc==SQLITE_OK && pVal;
** rc=sqlite3_vtab_in_next(pList, &pVal)
** ){
** // do something with pVal
** }
| | | 10440 10441 10442 10443 10444 10445 10446 10447 10448 10449 10450 10451 10452 10453 10454 |
** <blockquote><pre>
** for(rc=sqlite3_vtab_in_first(pList, &pVal);
** rc==SQLITE_OK && pVal;
** rc=sqlite3_vtab_in_next(pList, &pVal)
** ){
** // do something with pVal
** }
** if( rc!=SQLITE_DONE ){
** // an error has occurred
** }
** </pre></blockquote>)^
**
** ^On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P)
** routines return SQLITE_OK and set *P to point to the first or next value
** on the RHS of the IN constraint. ^If there are no more values on the
|
| ︙ | ︙ | |||
10556 10557 10558 10559 10560 10561 10562 | ** ** The "iScanStatusOp" parameter determines which status information to return. ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior ** of this interface is undefined. ^The requested measurement is written into ** a variable pointed to by the "pOut" parameter. ** ** The "flags" parameter must be passed a mask of flags. At present only | | | | > | 10612 10613 10614 10615 10616 10617 10618 10619 10620 10621 10622 10623 10624 10625 10626 10627 10628 10629 10630 10631 10632 10633 10634 10635 10636 10637 10638 10639 10640 10641 10642 10643 | ** ** The "iScanStatusOp" parameter determines which status information to return. ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior ** of this interface is undefined. ^The requested measurement is written into ** a variable pointed to by the "pOut" parameter. ** ** The "flags" parameter must be passed a mask of flags. At present only ** one flag is defined - [SQLITE_SCANSTAT_COMPLEX]. If SQLITE_SCANSTAT_COMPLEX ** is specified, then status information is available for all elements ** of a query plan that are reported by "[EXPLAIN QUERY PLAN]" output. If ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of ** the EXPLAIN QUERY PLAN output) are available. Invoking API ** sqlite3_stmt_scanstatus() is equivalent to calling ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. ** ** Parameter "idx" identifies the specific query element to retrieve statistics ** for. Query elements are numbered starting from zero. A value of -1 may ** retrieve statistics for the entire query. ^If idx is out of range ** - less than -1 or greater than or equal to the total number of query ** elements used to implement the statement - a non-zero value is returned and ** the variable that pOut points to is unchanged. ** ** See also: [sqlite3_stmt_scanstatus_reset()] and the ** [nexec and ncycle] columnes of the [bytecode virtual table]. */ SQLITE_API int sqlite3_stmt_scanstatus( sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ void *pOut /* Result written here */ ); |
| ︙ | ︙ | |||
11111 11112 11113 11114 11115 11116 11117 11118 11119 11120 11121 11122 11123 11124 | ** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database ** should be treated as read-only. */ #define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */ #define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */ #define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 11168 11169 11170 11171 11172 11173 11174 11175 11176 11177 11178 11179 11180 11181 11182 11183 11184 11185 11186 11187 11188 11189 11190 11191 11192 11193 11194 11195 11196 11197 11198 11199 11200 11201 11202 11203 11204 11205 11206 11207 11208 11209 11210 11211 11212 11213 11214 11215 11216 11217 11218 11219 11220 11221 11222 11223 11224 11225 11226 11227 11228 11229 | ** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database ** should be treated as read-only. */ #define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */ #define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */ #define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */ /* ** CAPI3REF: Bind array values to the CARRAY table-valued function ** ** The sqlite3_carray_bind(S,I,P,N,F,X) interface binds an array value to ** one of the first argument of the [carray() table-valued function]. The ** S parameter is a pointer to the [prepared statement] that uses the carray() ** functions. I is the parameter index to be bound. P is a pointer to the ** array to be bound, and N is the number of eements in the array. The ** F argument is one of constants [SQLITE_CARRAY_INT32], [SQLITE_CARRAY_INT64], ** [SQLITE_CARRAY_DOUBLE], [SQLITE_CARRAY_TEXT], or [SQLITE_CARRAY_BLOB] to ** indicate the datatype of the array being bound. The X argument is not a ** NULL pointer, then SQLite will invoke the function X on the P parameter ** after it has finished using P, even if the call to ** sqlite3_carray_bind() fails. The special-case finalizer ** SQLITE_TRANSIENT has no effect here. */ SQLITE_API int sqlite3_carray_bind( sqlite3_stmt *pStmt, /* Statement to be bound */ int i, /* Parameter index */ void *aData, /* Pointer to array data */ int nData, /* Number of data elements */ int mFlags, /* CARRAY flags */ void (*xDel)(void*) /* Destructor for aData */ ); /* ** CAPI3REF: Datatypes for the CARRAY table-valued function ** ** The fifth argument to the [sqlite3_carray_bind()] interface musts be ** one of the following constants, to specify the datatype of the array ** that is being bound into the [carray table-valued function]. */ #define SQLITE_CARRAY_INT32 0 /* Data is 32-bit signed integers */ #define SQLITE_CARRAY_INT64 1 /* Data is 64-bit signed integers */ #define SQLITE_CARRAY_DOUBLE 2 /* Data is doubles */ #define SQLITE_CARRAY_TEXT 3 /* Data is char* */ #define SQLITE_CARRAY_BLOB 4 /* Data is struct iovec */ /* ** Versions of the above #defines that omit the initial SQLITE_, for ** legacy compatibility. */ #define CARRAY_INT32 0 /* Data is 32-bit signed integers */ #define CARRAY_INT64 1 /* Data is 64-bit signed integers */ #define CARRAY_DOUBLE 2 /* Data is doubles */ #define CARRAY_TEXT 3 /* Data is char* */ #define CARRAY_BLOB 4 /* Data is struct iovec */ /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */ #ifdef SQLITE_OMIT_FLOATING_POINT # undef double #endif |
| ︙ | ︙ |
Changes to src/accordion.js.
| ︙ | ︙ | |||
39 40 41 42 43 44 45 |
img.src = acc_svgdata[0]+acc_svgdata[2]+acc_svgdata[1];
img.className = "accordion_btn accordion_btn_plus";
a[i].insertBefore(img,a[i].firstChild);
img = document.createElement("img");
img.src = acc_svgdata[0]+acc_svgdata[3]+acc_svgdata[1];
img.className = "accordion_btn accordion_btn_minus";
a[i].insertBefore(img,a[i].firstChild);
| | > > > > > | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
img.src = acc_svgdata[0]+acc_svgdata[2]+acc_svgdata[1];
img.className = "accordion_btn accordion_btn_plus";
a[i].insertBefore(img,a[i].firstChild);
img = document.createElement("img");
img.src = acc_svgdata[0]+acc_svgdata[3]+acc_svgdata[1];
img.className = "accordion_btn accordion_btn_minus";
a[i].insertBefore(img,a[i].firstChild);
a[i].addEventListener("click",function(evt){
/* Ignore clicks to hyperlinks and other "click-responsive" HTML elements in
** ".accordion" headers (for which Fossil uses <DIV> elements that represent
** section headers). */
var xClickyHTML = /^(?:A|AREA|BUTTON|INPUT|LABEL|SELECT|TEXTAREA|DETAILS)$/;
if( xClickyHTML.test(evt.target.tagName) ) return;
var x = this.nextElementSibling;
if( this.classList.contains("accordion_closed") ){
x.style.maxHeight = x.scrollHeight + "px";
setTimeout(function(){
x.style.maxHeight = "";
},250); // default.css: .accordion_panel { transition-duration }
}else{
|
| ︙ | ︙ |
Changes to src/add.c.
| ︙ | ︙ | |||
1004 1005 1006 1007 1008 1009 1010 | } } /* ** COMMAND: mv ** COMMAND: rename* ** | | | | 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 | } } /* ** COMMAND: mv ** COMMAND: rename* ** ** Usage: %fossil mv|rename ?OPTIONS? OLDNAME NEWNAME ** or: %fossil mv|rename ?OPTIONS? OLDNAME... DIR ** ** Move or rename one or more files or directories within the repository tree. ** You can either rename a file or directory or move it to another subdirectory. ** ** The 'mv' command does NOT normally rename or move the files on disk. ** This command merely records the fact that file names have changed so ** that appropriate notations can be made at the next [[commit]]. |
| ︙ | ︙ |
Changes to src/alerts.c.
| ︙ | ︙ | |||
361 362 363 364 365 366 367 |
@ can handle bounces. (Property: "email-self")</p>
@ <hr>
entry_attribute("List-ID", 40, "email-listid",
"elistid", "", 0);
@ <p>
@ If this is not an empty string, then it becomes the argument to
| | > | 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 |
@ can handle bounces. (Property: "email-self")</p>
@ <hr>
entry_attribute("List-ID", 40, "email-listid",
"elistid", "", 0);
@ <p>
@ If this is not an empty string, then it becomes the argument to
@ a "List-ID:" header on all out-bound notification emails. A list ID
@ is required for the generation of unsubscribe links in notifications.
@ (Property: "email-listid")</p>
@ <hr>
entry_attribute("Repository Nickname", 16, "email-subname",
"enn", "", 0);
@ <p><b>Required.</b>
@ This is short name used to identifies the repository in the
|
| ︙ | ︙ | |||
1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 | ** This is the email address for the repository. Outbound emails add ** this email address as the "From:" field. */ /* ** SETTING: email-listid width=40 ** If this setting is not an empty string, then it becomes the argument to ** a "List-ID:" header that is added to all out-bound notification emails. */ /* ** SETTING: email-send-relayhost width=40 sensitive default=127.0.0.1 ** This is the hostname and TCP port to which output email messages ** are sent when email-send-method is "relay". There should be an ** SMTP server configured as a Mail Submission Agent listening on the ** designated host and port and all times. | > > | 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 | ** This is the email address for the repository. Outbound emails add ** this email address as the "From:" field. */ /* ** SETTING: email-listid width=40 ** If this setting is not an empty string, then it becomes the argument to ** a "List-ID:" header that is added to all out-bound notification emails. ** A list ID is required for the generation of unsubscribe links in ** notifications. */ /* ** SETTING: email-send-relayhost width=40 sensitive default=127.0.0.1 ** This is the hostname and TCP port to which output email messages ** are sent when email-send-method is "relay". There should be an ** SMTP server configured as a Mail Submission Agent listening on the ** designated host and port and all times. |
| ︙ | ︙ |
Changes to src/branch.c.
| ︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
*******************************************************************************
**
** This file contains code used to create new branches within a repository.
*/
#include "config.h"
#include "branch.h"
#include <assert.h>
/*
** Return true if zBr is the branch name associated with check-in with
** blob.uuid value of zUuid
*/
int branch_includes_uuid(const char *zBr, const char *zUuid){
return db_exists(
| > > > > > > > > > > > > | 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 |
*******************************************************************************
**
** This file contains code used to create new branches within a repository.
*/
#include "config.h"
#include "branch.h"
#include <assert.h>
/*
** Return the name of the main branch. Cache the result.
**
** This is the current value of the "main-branch" setting, or its default
** value (historically, and as of 2025-10-28: "trunk") if not set.
*/
const char *db_main_branch(void){
static char *zMainBranch = 0;
if( zMainBranch==0 ) zMainBranch = db_get("main-branch", 0);
return zMainBranch;
}
/*
** Return true if zBr is the branch name associated with check-in with
** blob.uuid value of zUuid
*/
int branch_includes_uuid(const char *zBr, const char *zUuid){
return db_exists(
|
| ︙ | ︙ | |||
51 52 53 54 55 56 57 |
" AND tagtype>0", TAG_BRANCH);
db_bind_int(&q, "$rid", rid);
if( db_step(&q)==SQLITE_ROW ){
zBr = fossil_strdup(db_column_text(&q,0));
}
db_reset(&q);
if( zBr==0 ){
| < < | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
" AND tagtype>0", TAG_BRANCH);
db_bind_int(&q, "$rid", rid);
if( db_step(&q)==SQLITE_ROW ){
zBr = fossil_strdup(db_column_text(&q,0));
}
db_reset(&q);
if( zBr==0 ){
zBr = fossil_strdup(db_main_branch());
}
return zBr;
}
/*
** fossil branch new NAME BASIS ?OPTIONS?
** argv0 argv1 argv2 argv3 argv4
|
| ︙ | ︙ | |||
835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 |
** Control jumps to this routine from brlist_page() (the /brlist handler)
** if there are no query parameters.
*/
static void new_brlist_page(void){
Stmt q;
double rNow;
int show_colors = PB("colors");
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_set_current_feature("branch");
style_header("Branches");
style_adunit_config(ADUNIT_RIGHT_OK);
style_submenu_checkbox("colors", "Use Branch Colors", 0, 0);
login_anonymous_available();
brlist_create_temp_table();
db_prepare(&q, "SELECT * FROM tmp_brlist ORDER BY mtime DESC");
rNow = db_double(0.0, "SELECT julianday('now')");
@ <script id="brlist-data" type="application/json">\
@ {"timelineUrl":"%R/timeline"}</script>
@ <div class="brlist">
| > > > | 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 |
** Control jumps to this routine from brlist_page() (the /brlist handler)
** if there are no query parameters.
*/
static void new_brlist_page(void){
Stmt q;
double rNow;
int show_colors = PB("colors");
const char *zMainBranch;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
style_set_current_feature("branch");
style_header("Branches");
style_adunit_config(ADUNIT_RIGHT_OK);
style_submenu_checkbox("colors", "Use Branch Colors", 0, 0);
login_anonymous_available();
zMainBranch = db_main_branch();
brlist_create_temp_table();
db_prepare(&q, "SELECT * FROM tmp_brlist ORDER BY mtime DESC");
rNow = db_double(0.0, "SELECT julianday('now')");
@ <script id="brlist-data" type="application/json">\
@ {"timelineUrl":"%R/timeline"}</script>
@ <div class="brlist">
|
| ︙ | ︙ | |||
870 871 872 873 874 875 876 |
const char *zLastCkin = db_column_text(&q, 5);
const char *zBgClr = db_column_text(&q, 6);
char *zAge = human_readable_age(rNow - rMtime);
sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0);
if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0;
if( zBgClr ) zBgClr = reasonable_bg_color(zBgClr, 0);
if( zBgClr==0 ){
| | | 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 |
const char *zLastCkin = db_column_text(&q, 5);
const char *zBgClr = db_column_text(&q, 6);
char *zAge = human_readable_age(rNow - rMtime);
sqlite3_int64 iMtime = (sqlite3_int64)(rMtime*86400.0);
if( zMergeTo && zMergeTo[0]==0 ) zMergeTo = 0;
if( zBgClr ) zBgClr = reasonable_bg_color(zBgClr, 0);
if( zBgClr==0 ){
if( zBranch==0 || strcmp(zBranch, zMainBranch)==0 ){
zBgClr = 0;
}else{
zBgClr = hash_color(zBranch);
}
}
if( zBgClr && zBgClr[0] && show_colors ){
@ <tr style="background-color:%s(zBgClr)">
|
| ︙ | ︙ | |||
1017 1018 1019 1020 1021 1022 1023 | } /* ** This routine is called while for each check-in that is rendered by ** the timeline of a "brlist" page. Add some additional hyperlinks ** to the end of the line. */ | | | | | < | < < < > | > > | > > > > > > > | > | > > | > > < > | < < < < | > | | | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 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 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 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 |
}
/*
** This routine is called while for each check-in that is rendered by
** the timeline of a "brlist" page. Add some additional hyperlinks
** to the end of the line.
*/
static void brtimeline_extra(
Stmt *pQuery, /* Current row of the timeline query */
int tmFlags, /* Flags to www_print_timeline() */
const char *zThisUser, /* Suppress links to this user */
const char *zThisTag /* Suppress links to this tag */
){
int rid;
int tmFlagsNew;
char *zBrName;
if( (tmFlags & TIMELINE_INLINE)!=0 ){
tmFlagsNew = (tmFlags & ~TIMELINE_VIEWS) | TIMELINE_MODERN;
cgi_printf("(");
}else{
tmFlagsNew = tmFlags;
}
timeline_extra(pQuery,tmFlagsNew,zThisUser,zThisTag);
if( !g.perm.Hyperlink ) return;
rid = db_column_int(pQuery,0);
zBrName = branch_of_rid(rid);
@ branch: <span class='timelineHash'>\
@ %z(href("%R/timeline?r=%T",zBrName))%h(zBrName)</a></span>
if( (tmFlags & TIMELINE_INLINE)!=0 ){
cgi_printf(")");
}
}
/*
** WEBPAGE: brtimeline
**
** List the first check of every branch, starting with the most recent
** and going backwards in time.
**
** Query parameters:
**
** ubg Color the graph by user, not by branch.
*/
void brtimeline_page(void){
Blob sql = empty_blob;
Stmt q;
int tmFlags; /* Timeline display flags */
int fNoHidden = PB("nohidden")!=0; /* The "nohidden" query parameter */
int fOnlyHidden = PB("onlyhidden")!=0; /* The "onlyhidden" query parameter */
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
if( robot_restrict("timelineX") ) return;
style_set_current_feature("branch");
style_header("Branches");
style_submenu_element("Branch List", "brlist");
login_anonymous_available();
timeline_ss_submenu();
cgi_check_for_malice();
@ <h2>The initial check-in for each branch:</h2>
blob_append(&sql, timeline_query_for_www(), -1);
blob_append_sql(&sql,
"AND blob.rid IN (SELECT rid FROM tagxref"
" WHERE tagtype>0 AND tagid=%d AND srcid!=0)", TAG_BRANCH);
if( fNoHidden || fOnlyHidden ){
const char* zUnaryOp = fNoHidden ? "NOT" : "";
blob_append_sql(&sql,
" AND %s EXISTS(SELECT 1 FROM tagxref"
" WHERE tagid=%d AND tagtype>0 AND rid=blob.rid)\n",
zUnaryOp/*safe-for-%s*/, TAG_HIDDEN);
}
db_prepare(&q, "%s ORDER BY event.mtime DESC", blob_sql_text(&sql));
blob_reset(&sql);
/* Always specify TIMELINE_DISJOINT, or graph_finish() may fail because of too
** many descenders to (off-screen) parents. */
tmFlags = TIMELINE_DISJOINT | TIMELINE_NOSCROLL;
if( PB("ubg")!=0 ){
tmFlags |= TIMELINE_UCOLOR;
}else{
tmFlags |= TIMELINE_BRCOLOR;
}
www_print_timeline(&q, tmFlags, 0, 0, 0, 0, 0, brtimeline_extra);
db_finalize(&q);
style_finish_page();
}
/*
** Generate a multichoice submenu for the few recent active branches. zName is
** the query parameter used to select the current checkin. zCI is optional and
** represent the currently selected checkin, so if it is a checkin hash
** instead of a branch, it can be part of the multichoice menu.
*/
void generate_branch_submenu_multichoice(
const char* zName, /* Query parameter name */
const char* zCI /* Current checkin */
){
Stmt q;
const int brFlags = BRL_ORDERBY_MTIME | BRL_OPEN_ONLY;
static const char *zBranchMenuList[32*2]; /* 2 per entries */
const int nLimit = count(zBranchMenuList)/2;
int i = 0;
if( zName == 0 ) zName = "ci";
branch_prepare_list_query(&q, brFlags, 0, nLimit, 0);
zBranchMenuList[i++] = "";
zBranchMenuList[i++] = "All Checkins";
if( zCI ){
zCI = fossil_strdup(zCI);
zBranchMenuList[i++] = zCI;
zBranchMenuList[i++] = zCI;
}
/* If current checkin is not "tip", add it to the list */
if( zCI==0 || strcmp(zCI, "tip") ){
zBranchMenuList[i++] = "tip";
zBranchMenuList[i++] = "tip";
}
while( i/2 < nLimit && db_step(&q)==SQLITE_ROW ){
const char* zBr = fossil_strdup(db_column_text(&q, 0));
/* zCI is already in the list, don't add it twice */
if( zCI==0 || strcmp(zBr, zCI) ){
zBranchMenuList[i++] = zBr;
zBranchMenuList[i++] = zBr;
}
}
db_finalize(&q);
style_submenu_multichoice(zName, i/2, zBranchMenuList, 0);
}
|
Changes to src/browse.c.
| ︙ | ︙ | |||
125 126 127 128 129 130 131 | ** source tree. This works similarly to /dir but with the following ** differences: ** ** * Links to files go to /doc (showing the file content directly, ** depending on mimetype) rather than to /file (which always shows ** the file embedded in a standard Fossil page frame). ** | | | 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | ** source tree. This works similarly to /dir but with the following ** differences: ** ** * Links to files go to /doc (showing the file content directly, ** depending on mimetype) rather than to /file (which always shows ** the file embedded in a standard Fossil page frame). ** ** * The submenu and the page title is not shown. The page is plain. ** ** The /docdir page is a shorthand for /dir with the "dx" query parameter. ** ** Query parameters: ** ** ci=LABEL Show only files in this check-in. If omitted, the ** "trunk" directory is used. |
| ︙ | ︙ | |||
169 170 171 172 173 174 175 |
char *zPrefix;
Stmt q;
const char *zCI = P("ci");
int rid = 0;
char *zUuid = 0;
Manifest *pM = 0;
const char *zSubdirLink;
| < < | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
char *zPrefix;
Stmt q;
const char *zCI = P("ci");
int rid = 0;
char *zUuid = 0;
Manifest *pM = 0;
const char *zSubdirLink;
HQuery sURI;
int isSymbolicCI = 0; /* ci= is symbolic name, not a hash prefix */
int isBranchCI = 0; /* True if ci= refers to a branch name */
char *zHeader = 0;
const char *zRegexp; /* The re= query parameter */
char *zMatch; /* Extra title text describing the match */
int bDocDir = PB("dx") || strncmp(g.zPath, "docdir", 6)==0;
|
| ︙ | ︙ | |||
192 193 194 195 196 197 198 |
/* If the name= parameter is an empty string, make it a NULL pointer */
if( zD && strlen(zD)==0 ){ zD = 0; }
/* If a specific check-in is requested, fetch and parse it. If the
** specific check-in does not exist, clear zCI. zCI==0 will cause all
** files from all check-ins to be displayed.
*/
| | < < < | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
/* If the name= parameter is an empty string, make it a NULL pointer */
if( zD && strlen(zD)==0 ){ zD = 0; }
/* If a specific check-in is requested, fetch and parse it. If the
** specific check-in does not exist, clear zCI. zCI==0 will cause all
** files from all check-ins to be displayed.
*/
if( bDocDir && zCI==0 ) zCI = db_main_branch();
if( zCI ){
pM = manifest_get_by_name(zCI, &rid);
if( pM ){
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
isSymbolicCI = (sqlite3_strnicmp(zUuid, zCI, strlen(zCI))!=0);
isBranchCI = branch_includes_uuid(zCI, zUuid);
if( bDocDir ) zCI = mprintf("%S", zUuid);
Th_StoreUnsafe("current_checkin", zCI);
}else{
zCI = 0;
|
| ︙ | ︙ | |||
232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
zHeader = mprintf("%z matching \"%s\"", zHeader, zRegexp);
zMatch = mprintf(" matching \"%h\"", zRegexp);
}else{
zMatch = "";
}
style_header("%s", zHeader);
fossil_free(zHeader);
style_adunit_config(ADUNIT_RIGHT_OK);
sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
pathelementFunc, 0, 0);
url_initialize(&sURI, "dir");
cgi_check_for_malice();
cgi_query_parameters_to_url(&sURI);
| > > > | 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
zHeader = mprintf("%z matching \"%s\"", zHeader, zRegexp);
zMatch = mprintf(" matching \"%h\"", zRegexp);
}else{
zMatch = "";
}
style_header("%s", zHeader);
fossil_free(zHeader);
if( rid && zD==0 && zMatch[0]==0 && g.perm.Zip ){
style_submenu_element("Download","%R/rchvdwnld/%!S",zUuid);
}
style_adunit_config(ADUNIT_RIGHT_OK);
sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
pathelementFunc, 0, 0);
url_initialize(&sURI, "dir");
cgi_check_for_malice();
cgi_query_parameters_to_url(&sURI);
|
| ︙ | ︙ | |||
281 282 283 284 285 286 287 |
if( nD==0 && !bDocDir ){
style_submenu_element("File Ages", "%R/fileage?name=%T", zCI);
}
}else{
@ in any check-in</h2>
zSubdirLink = mprintf("%R/dir?name=%T", zPrefix);
}
| < < < < < < < < > > > > > | 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 |
if( nD==0 && !bDocDir ){
style_submenu_element("File Ages", "%R/fileage?name=%T", zCI);
}
}else{
@ in any check-in</h2>
zSubdirLink = mprintf("%R/dir?name=%T", zPrefix);
}
if( zD && !bDocDir ){
style_submenu_element("History","%R/timeline?chng=%T/*", zD);
}
if( !bDocDir ){
style_submenu_element("Tree-View", "%s",
url_render(&sURI, "type", "tree", 0, 0));
}
if( !bDocDir ){
/* Generate the Branch list submenu */
generate_branch_submenu_multichoice("ci", zCI);
}
/* Compute the temporary table "localfiles" containing the names
** of all files and subdirectories in the zD[] directory.
**
** Subdirectory names begin with "/". This causes them to sort
** first and it also gives us an easy way to distinguish files
** from directories in the loop that follows.
|
| ︙ | ︙ | |||
703 704 705 706 707 708 709 |
char *zUuid = 0;
Blob dirname;
Manifest *pM = 0;
double rNow = 0;
char *zNow = 0;
int useMtime = atoi(PD("mtime","0"));
int sortOrder = atoi(PD("sort",useMtime?"1":"0"));
| < < | 698 699 700 701 702 703 704 705 706 707 708 709 710 711 |
char *zUuid = 0;
Blob dirname;
Manifest *pM = 0;
double rNow = 0;
char *zNow = 0;
int useMtime = atoi(PD("mtime","0"));
int sortOrder = atoi(PD("sort",useMtime?"1":"0"));
const char *zRE; /* the value for the re=REGEXP query parameter */
const char *zObjType; /* "files" by default or "folders" for "nofiles" */
char *zREx = ""; /* Extra parameters for path hyperlinks */
ReCompiled *pRE = 0; /* Compiled regular expression */
FileTreeNode *p; /* One line of the tree */
FileTree sTree; /* The complete tree of files */
HQuery sURI; /* Hyperlink */
|
| ︙ | ︙ | |||
745 746 747 748 749 750 751 |
}else{
startExpanded = 0;
}
/* If a regular expression is specified, compile it */
zRE = P("re");
if( zRE ){
| | < < < > > > | 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 |
}else{
startExpanded = 0;
}
/* If a regular expression is specified, compile it */
zRE = P("re");
if( zRE ){
fossil_re_compile(&pRE, zRE, 0);
zREx = mprintf("&re=%T", zRE);
}
cgi_check_for_malice();
/* If the name= parameter is an empty string, make it a NULL pointer */
if( zD && strlen(zD)==0 ){ zD = 0; }
/* If a specific check-in is requested, fetch and parse it. If the
** specific check-in does not exist, clear zCI. zCI==0 will cause all
** files from all check-ins to be displayed.
*/
if( zCI ){
pM = manifest_get_by_name(zCI, &rid);
if( pM ){
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
rNow = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
zNow = db_text("", "SELECT datetime(mtime,toLocal())"
" FROM event WHERE objid=%d", rid);
isSymbolicCI = (sqlite3_strnicmp(zUuid, zCI, strlen(zCI)) != 0);
isBranchCI = branch_includes_uuid(zCI, zUuid);
Th_StoreUnsafe("current_checkin", zCI);
}else{
zCI = 0;
}
}
if( zCI==0 ){
rNow = db_double(0.0, "SELECT max(mtime) FROM event");
zNow = db_text("", "SELECT datetime(max(mtime),toLocal()) FROM event");
}
/* Generate the Branch list submenu */
generate_branch_submenu_multichoice("ci", zCI);
assert( isSymbolicCI==0 || (zCI!=0 && zCI[0]!=0) );
if( zD==0 ){
if( zCI ){
zHeader = mprintf("Top-level Files of %s", zCI);
}else{
zHeader = mprintf("All Top-level Files");
}
|
| ︙ | ︙ | |||
816 817 818 819 820 821 822 |
"0", "Sort By Filename",
"1", "Sort By Age",
"2", "Sort By Size"
};
style_submenu_multichoice("sort", 3, sort_orders, 0);
}
if( zCI ){
| < < | | < | | < < | 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 |
"0", "Sort By Filename",
"1", "Sort By Age",
"2", "Sort By Size"
};
style_submenu_multichoice("sort", 3, sort_orders, 0);
}
if( zCI ){
if( nD==0 && !showDirOnly ){
style_submenu_element("File Ages", "%R/fileage?name=%T", zCI);
}
}
style_submenu_element("Flat-View", "%s",
url_render(&sURI, "type", "flat", 0, 0));
if( rid && zD==0 && zRE==0 && !showDirOnly && g.perm.Zip ){
style_submenu_element("Download","%R/rchvdwnld/%!S", zUuid);
}
/* Compute the file hierarchy.
*/
if( zCI ){
Stmt q;
compute_fileage(rid, 0);
db_prepare(&q,
|
| ︙ | ︙ | |||
1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 |
}
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
isBranchCI = branch_includes_uuid(zName,zUuid);
baseTime = db_double(0.0,"SELECT mtime FROM event WHERE objid=%d", rid);
zNow = db_text("", "SELECT datetime(mtime,toLocal()) FROM event"
" WHERE objid=%d", rid);
style_submenu_element("Tree-View", "%R/tree?ci=%T&mtime=1&type=tree", zName);
style_header("File Ages");
zGlob = P("glob");
cgi_check_for_malice();
compute_fileage(rid,zGlob);
db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
if( fossil_strcmp(zName,"tip")==0 ){
| > > > > | 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 |
}
zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
isBranchCI = branch_includes_uuid(zName,zUuid);
baseTime = db_double(0.0,"SELECT mtime FROM event WHERE objid=%d", rid);
zNow = db_text("", "SELECT datetime(mtime,toLocal()) FROM event"
" WHERE objid=%d", rid);
style_submenu_element("Tree-View", "%R/tree?ci=%T&mtime=1&type=tree", zName);
/* Generate the Branch list submenu */
generate_branch_submenu_multichoice("name", zName);
style_header("File Ages");
zGlob = P("glob");
cgi_check_for_malice();
compute_fileage(rid,zGlob);
db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");
if( fossil_strcmp(zName,"tip")==0 ){
|
| ︙ | ︙ |
Changes to src/cgi.c.
| ︙ | ︙ | |||
2288 2289 2290 2291 2292 2293 2294 |
**
** It is called in a loop so some variables will need to be replaced
*/
void cgi_handle_ssh_http_request(const char *zIpAddr){
static int nCycles = 0;
static char *zCmd = 0;
char *z, *zToken;
| | | > | 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 |
**
** It is called in a loop so some variables will need to be replaced
*/
void cgi_handle_ssh_http_request(const char *zIpAddr){
static int nCycles = 0;
static char *zCmd = 0;
char *z, *zToken;
char *zMethod;
int i;
size_t n;
char zLine[2000]; /* A single line of input. */
assert( !g.httpUseSSL );
#ifdef FOSSIL_ENABLE_JSON
if( nCycles==0 ){ json_bootstrap_early(); }
#endif
if( zIpAddr ){
|
| ︙ | ︙ | |||
2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 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 |
cgi_trace(zLine);
zToken = extract_token(zLine, &z);
if( zToken==0 ){
malformed_request("malformed HTTP header");
}
}
if( fossil_strcmp(zToken,"GET")!=0 && fossil_strcmp(zToken,"POST")!=0
&& fossil_strcmp(zToken,"HEAD")!=0 ){
malformed_request("unsupported HTTP method");
}
if( nCycles==0 ){
cgi_setenv("GATEWAY_INTERFACE","CGI/1.0");
cgi_setenv("REQUEST_METHOD",zToken);
}
zToken = extract_token(z, &z);
if( zToken==0 ){
malformed_request("malformed URL in HTTP header");
}
if( nCycles==0 ){
cgi_setenv("REQUEST_URI", zToken);
cgi_setenv("SCRIPT_NAME", "");
}
for(i=0; zToken[i] && zToken[i]!='?'; i++){}
if( zToken[i] ) zToken[i++] = 0;
if( nCycles==0 ){
cgi_setenv("PATH_INFO", zToken);
}else{
cgi_replace_parameter("PATH_INFO", fossil_strdup(zToken));
}
/* Get all the optional fields that follow the first line.
*/
while( fgets(zLine,sizeof(zLine),g.httpIn) ){
char *zFieldName;
char *zVal;
cgi_trace(zLine);
zFieldName = extract_token(zLine,&zVal);
if( zFieldName==0 || *zFieldName==0 ) break;
while( fossil_isspace(*zVal) ){ zVal++; }
i = strlen(zVal);
while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; }
zVal[i] = 0;
for(i=0; zFieldName[i]; i++){
zFieldName[i] = fossil_tolower(zFieldName[i]);
}
if( fossil_strcmp(zFieldName,"content-length:")==0 ){
| > > > > > > > > > > > > > > | > > > > | > | 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 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 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 |
cgi_trace(zLine);
zToken = extract_token(zLine, &z);
if( zToken==0 ){
malformed_request("malformed HTTP header");
}
}
zMethod = fossil_strdup(zToken);
if( fossil_strcmp(zToken,"GET")!=0 && fossil_strcmp(zToken,"POST")!=0
&& fossil_strcmp(zToken,"HEAD")!=0 ){
malformed_request("unsupported HTTP method");
}
if( nCycles==0 ){
cgi_setenv("GATEWAY_INTERFACE","CGI/1.0");
cgi_setenv("REQUEST_METHOD",zToken);
}
zToken = extract_token(z, &z);
if( zToken==0 ){
malformed_request("malformed URL in HTTP header");
}
n = strlen(g.zRepositoryName);
if( fossil_strncmp(g.zRepositoryName, zToken, n)==0
&& (zToken[n]=='/' || zToken[n]==0)
&& fossil_strcmp(zMethod,"GET")==0
){
zToken += n;
if( zToken && strlen(zToken)==0 ){
malformed_request("malformed URL in HTTP header");
}
}
if( nCycles==0 ){
cgi_setenv("REQUEST_URI", zToken);
cgi_setenv("SCRIPT_NAME", "");
}
for(i=0; zToken[i] && zToken[i]!='?'; i++){}
if( zToken[i] ) zToken[i++] = 0;
if( nCycles==0 ){
cgi_setenv("PATH_INFO", zToken);
cgi_setenv("QUERY_STRING",&zToken[i]);
}else{
cgi_replace_parameter("PATH_INFO", fossil_strdup(zToken));
cgi_replace_parameter("QUERY_STRING",fossil_strdup(&zToken[i]));
}
/* Get all the optional fields that follow the first line.
*/
while( fgets(zLine,sizeof(zLine),g.httpIn) ){
char *zFieldName;
char *zVal;
cgi_trace(zLine);
zFieldName = extract_token(zLine,&zVal);
if( zFieldName==0 || *zFieldName==0 ) break;
while( fossil_isspace(*zVal) ){ zVal++; }
i = strlen(zVal);
while( i>0 && fossil_isspace(zVal[i-1]) ){ i--; }
zVal[i] = 0;
for(i=0; zFieldName[i]; i++){
zFieldName[i] = fossil_tolower(zFieldName[i]);
}
if( fossil_strcmp(zFieldName,"content-length:")==0 ){
if( nCycles==0 ){
cgi_setenv("CONTENT_LENGTH", zVal);
}else{
cgi_replace_parameter("CONTENT_LENGTH", zVal);
}
}else if( fossil_strcmp(zFieldName,"content-type:")==0 ){
if( nCycles==0 ){
cgi_setenv("CONTENT_TYPE", zVal);
}
}else if( fossil_strcmp(zFieldName,"host:")==0 ){
if( nCycles==0 ){
cgi_setenv("HTTP_HOST", zVal);
}
}else if( fossil_strcmp(zFieldName,"user-agent:")==0 ){
if( nCycles==0 ){
cgi_setenv("HTTP_USER_AGENT", zVal);
|
| ︙ | ︙ | |||
2415 2416 2417 2418 2419 2420 2421 |
cgi_replace_parameter("REMOTE_ADDR", "127.0.0.1");
}
}
cgi_reset_content();
cgi_destination(CGI_BODY);
| < | < < < < < < < < < | 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 |
cgi_replace_parameter("REMOTE_ADDR", "127.0.0.1");
}
}
cgi_reset_content();
cgi_destination(CGI_BODY);
cgi_init();
cgi_trace(0);
nCycles++;
}
/*
** This routine handles the old fossil SSH probes
*/
|
| ︙ | ︙ | |||
2950 2951 2952 2953 2954 2955 2956 |
}else{
return mprintf("%04d-%02d-%02d %02d:%02d:%02d",
pTm->tm_year+1900, pTm->tm_mon+1, pTm->tm_mday,
pTm->tm_hour, pTm->tm_min, pTm->tm_sec);
}
}
| < < < < < < < < < < | 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 |
}else{
return mprintf("%04d-%02d-%02d %02d:%02d:%02d",
pTm->tm_year+1900, pTm->tm_mon+1, pTm->tm_mday,
pTm->tm_hour, pTm->tm_min, pTm->tm_sec);
}
}
/*
** Parse an RFC822-formatted timestamp as we'd expect from HTTP and return
** a Unix epoch time. <= zero is returned on failure.
**
** Note that this won't handle all the _allowed_ HTTP formats, just the
** most popular one (the one generated by cgi_rfc822_datestamp(), actually).
*/
|
| ︙ | ︙ |
Changes to src/checkin.c.
| ︙ | ︙ | |||
777 778 779 780 781 782 783 |
while( db_step(&q)==SQLITE_ROW ){
const char *zTime = db_column_text(&q,0);
const char *zFile = db_column_text(&q,1);
int size = db_column_int(&q,2);
if( treeFmt ){
blob_appendf(&out, "%s\n", zFile);
}else if( verboseFlag ){
| > | > > | > | 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 |
while( db_step(&q)==SQLITE_ROW ){
const char *zTime = db_column_text(&q,0);
const char *zFile = db_column_text(&q,1);
int size = db_column_int(&q,2);
if( treeFmt ){
blob_appendf(&out, "%s\n", zFile);
}else if( verboseFlag ){
if( showHash ){
const char *zUuid = db_column_text(&q,3);
fossil_print("%s %7d [%S] %s\n", zTime, size, zUuid, zFile);
}else{
fossil_print("%s %7d %s\n", zTime, size, zFile);
}
}else if( showAge ){
fossil_print("%s %s\n", zTime, zFile);
}else{
fossil_print("%s\n", zFile);
}
}
db_finalize(&q);
|
| ︙ | ︙ | |||
1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 |
int parent_rid, /* parent check-in */
Blob *pComment, /* Check-in comment */
int dryRunFlag /* True for a dry-run only */
){
Blob *pDesc;
char *zTags;
char *zFilename;
Blob desc;
blob_init(&desc, 0, 0);
pDesc = &desc;
blob_appendf(pDesc, "checkout %s\n", g.zLocalRoot);
blob_appendf(pDesc, "repository %s\n", g.zRepositoryName);
blob_appendf(pDesc, "user %s\n",
p->zUserOvrd ? p->zUserOvrd : login_name());
blob_appendf(pDesc, "branch %s\n",
| > | | 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 |
int parent_rid, /* parent check-in */
Blob *pComment, /* Check-in comment */
int dryRunFlag /* True for a dry-run only */
){
Blob *pDesc;
char *zTags;
char *zFilename;
const char *zMainBranch = db_main_branch();
Blob desc;
blob_init(&desc, 0, 0);
pDesc = &desc;
blob_appendf(pDesc, "checkout %s\n", g.zLocalRoot);
blob_appendf(pDesc, "repository %s\n", g.zRepositoryName);
blob_appendf(pDesc, "user %s\n",
p->zUserOvrd ? p->zUserOvrd : login_name());
blob_appendf(pDesc, "branch %s\n",
(p->zBranch && p->zBranch[0]) ? p->zBranch : zMainBranch);
zTags = info_tags_of_checkin(parent_rid, 1);
if( zTags || p->azTag ){
blob_append(pDesc, "tags ", -1);
if(zTags){
blob_appendf(pDesc, "%z%s", zTags, p->azTag ? ", " : "");
}
if(p->azTag){
|
| ︙ | ︙ | |||
2618 2619 2620 2621 2622 2623 2624 |
}
/* Get the ID of the parent manifest artifact */
vid = db_lget_int("checkout", 0);
if( vid==0 ){
useCksum = 1;
if( privateFlag==0 && sCiInfo.zBranch==0 ) {
| | | 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 |
}
/* Get the ID of the parent manifest artifact */
vid = db_lget_int("checkout", 0);
if( vid==0 ){
useCksum = 1;
if( privateFlag==0 && sCiInfo.zBranch==0 ) {
sCiInfo.zBranch = db_main_branch();
}
}else{
privateParent = content_is_private(vid);
}
user_select();
/*
|
| ︙ | ︙ |
Changes to src/checkout.c.
| ︙ | ︙ | |||
17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ** ** This file contains code used to check-out versions of the project ** from the local repository. */ #include "config.h" #include "checkout.h" #include <assert.h> /* ** Check to see if there is an existing check-out that has been ** modified. Return values: ** ** 0: There is an existing check-out but it is unmodified ** 1: There is a modified check-out - there are unsaved changes | > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | ** ** This file contains code used to check-out versions of the project ** from the local repository. */ #include "config.h" #include "checkout.h" #include <assert.h> #include <zlib.h> /* ** Check to see if there is an existing check-out that has been ** modified. Return values: ** ** 0: There is an existing check-out but it is unmodified ** 1: There is a modified check-out - there are unsaved changes |
| ︙ | ︙ | |||
427 428 429 430 431 432 433 |
if( db_is_writeable("repository") ){
db_unset_mprintf(1, "ckout:%q", g.zLocalRoot);
}
unlink_local_database(1);
db_close(1);
unlink_local_database(0);
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 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 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 |
if( db_is_writeable("repository") ){
db_unset_mprintf(1, "ckout:%q", g.zLocalRoot);
}
unlink_local_database(1);
db_close(1);
unlink_local_database(0);
}
/*
** COMMAND: get
**
** Usage: %fossil get URL ?VERSION? ?OPTIONS?
**
** Download a single check-in from a remote repository named URL and
** unpack all of the files locally. The check-in is identified by VERSION.
**
** URL can be a traditional URL like one of:
**
** * https://domain.com/project
** * ssh://my-server/project.fossil
** * file:/home/user/Fossils/project.fossil
**
** Or URL can be just the name of a local repository without the "file:"
** prefix.
**
** This command works by downloading an SQL archive of the requested
** check-in and then extracting all the files from the archive.
**
** Options:
** --dest DIRECTORY Extract files into DIRECTORY. Use "--dest ."
** to extract into the local directory.
**
** -f|--force Overwrite existing files
**
** --list List all the files that would have been checked
** out but do not actually write anything to the
** filesystem.
**
** --sqlar ARCHIVE Store the check-out in an SQL-archive rather
** than unpacking them into separate files.
**
** -v|--verbose Show all files as they are extracted
*/
void get_cmd(void){
int forceFlag = find_option("force","f",0)!=0;
int bVerbose = find_option("verbose","v",0)!=0;
int bQuiet = find_option("quiet","q",0)!=0;
int bDebug = find_option("debug",0,0)!=0;
int bList = find_option("list",0,0)!=0;
const char *zSqlArchive = find_option("sqlar",0,1);
const char *z;
char *zDest = 0; /* Where to store results */
char *zSql; /* SQL used to query the results */
const char *zUrl; /* Url to get */
const char *zVers; /* Version name to get */
unsigned int mHttpFlags = HTTP_GENERIC|HTTP_NOCOMPRESS;
Blob in, out; /* I/O for the HTTP request */
Blob file; /* A file to extract */
sqlite3 *db; /* Database containing downloaded sqlar */
sqlite3_stmt *pStmt; /* Statement for querying the database */
int rc; /* Result of subroutine calls */
int nFile = 0; /* Number of files written */
int nDir = 0; /* Number of directories written */
i64 nByte = 0; /* Number of bytes written */
z = find_option("dest",0,1);
if( z ) zDest = fossil_strdup(z);
verify_all_options();
if( g.argc<3 || g.argc>4 ){
usage("URL ?VERSION? ?OPTIONS?");
}
zUrl = g.argv[2];
zVers = g.argc==4 ? g.argv[3] : db_main_branch();
/* Parse the URL of the repository */
url_parse(zUrl, 0);
/* Construct an appropriate name for the destination directory */
if( zDest==0 ){
int i;
const char *zTail;
const char *zDot;
int n;
if( g.url.isFile ){
zTail = file_tail(g.url.name);
}else{
zTail = file_tail(g.url.path);
}
zDot = strchr(zTail,'.');
if( zDot==0 ) zDot = zTail+strlen(zTail);
n = (int)(zDot - zTail);
zDest = mprintf("%.*s-%s", n, zTail, zVers);
for(i=0; zDest[i]; i++){
char c = zDest[i];
if( !fossil_isalnum(c) && c!='-' && c!='^' && c!='~' && c!='_' ){
zDest[i] = '-';
}
}
}
if( bDebug ){
fossil_print("dest = %s\n", zDest);
}
/* Error checking */
if( zDest!=file_tail(zDest) ){
fossil_fatal("--dest must be a simple directory name, not a path");
}
if( zVers!=file_tail(zVers) ){
fossil_fatal("The \"fossil get\" command does not currently work with"
" version names that contain \"/\". This will be fixed in"
" a future release.");
}
/* To relax the restrictions above, change the subpath URL formula below
** to use query parameters. Ex: /sqlar?r=%t&name=%t */
if( !forceFlag ){
if( zSqlArchive ){
if( file_isdir(zSqlArchive, ExtFILE)>0 ){
fossil_fatal("file already exists: \"%s\"", zSqlArchive);
}
}else if( file_isdir(zDest, ExtFILE)>0 ){
if( fossil_strcmp(zDest,".")==0 ){
if( file_directory_list(zDest,0,1,1,0) ){
fossil_fatal("current directory is not empty");
}
}else{
fossil_fatal("\"%s\" already exists", zDest);
}
}
}
/* Construct a subpath on the URL if necessary */
if( g.url.isFile ){
g.url.subpath = mprintf("/sqlar/%t/%t.sqlar", zVers, zDest);
}else{
g.url.subpath = mprintf("%s/sqlar/%t/%t.sqlar", g.url.path, zVers, zDest);
}
if( bDebug ){
urlparse_print(0);
}
/* Fetch the ZIP archive for the requested check-in */
blob_init(&in, 0, 0);
blob_init(&out, 0, 0);
if( bDebug ) mHttpFlags |= HTTP_VERBOSE;
if( bQuiet ) mHttpFlags |= HTTP_QUIET;
rc = http_exchange(&in, &out, mHttpFlags, 4, 0);
if( rc
|| out.nUsed<512
|| (out.nUsed%512)!=0
|| memcmp(out.aData,"SQLite format 3",16)!=0
){
fossil_fatal("Server did not return the requested check-in.");
}
if( zSqlArchive ){
blob_write_to_file(&out, zSqlArchive);
if( bVerbose ) fossil_print("%s\n", zSqlArchive);
return;
}
rc = sqlite3_open(":memory:", &db);
if( rc==SQLITE_OK ){
int sz = blob_size(&out);
rc = sqlite3_deserialize(db, 0, (unsigned char*)blob_buffer(&out), sz, sz,
SQLITE_DESERIALIZE_READONLY);
}
if( rc!=SQLITE_OK ){
fossil_fatal("Cannot create an in-memory database: %s",
sqlite3_errmsg(db));
}
zSql = mprintf("SELECT name, mode, sz, data FROM sqlar"
" WHERE name GLOB '%q*'", zDest);
rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
fossil_free(zSql);
if( rc!=0 ){
fossil_fatal("SQL error: %s\n", sqlite3_errmsg(db));
}
blob_init(&file, 0, 0);
while( sqlite3_step(pStmt)==SQLITE_ROW ){
const char *zFilename = (const char*)sqlite3_column_text(pStmt, 0);
int mode = sqlite3_column_int(pStmt, 1);
int sz = sqlite3_column_int(pStmt, 2);
if( bList ){
fossil_print("%s\n", zFilename);
}else if( mode & 0x4000 ){
/* A directory name */
nDir++;
file_mkdir(zFilename, ExtFILE, 1);
}else{
/* A file */
unsigned char *inBuf = (unsigned char*)sqlite3_column_blob(pStmt,3);
unsigned int nIn = (unsigned int)sqlite3_column_bytes(pStmt,3);
unsigned long int nOut2 = (unsigned long int)sz;
nFile++;
nByte += sz;
blob_resize(&file, sz);
if( nIn<sz ){
rc = uncompress((unsigned char*)blob_buffer(&file), &nOut2,
inBuf, nIn);
if( rc!=Z_OK ){
fossil_fatal("Failed to uncompress file %s", zFilename);
}
}else{
memcpy(blob_buffer(&file), inBuf, sz);
}
blob_write_to_file(&file, zFilename);
if( mode & 0x40 ){
file_setexe(zFilename, 1);
}
blob_zero(&file);
if( bVerbose ){
fossil_print("%s\n", zFilename);
}
}
}
sqlite3_finalize(pStmt);
sqlite3_close(db);
blob_zero(&out);
if( !bVerbose && !bQuiet && nFile>0 && zDest ){
fossil_print("%d files (%,lld bytes) written into %s",
nFile, nByte, zDest);
if( nDir>1 ){
fossil_print(" and %d subdirectories\n", nDir-1);
}else{
fossil_print("\n");
}
}
}
|
Changes to src/clone.c.
| ︙ | ︙ | |||
403 404 405 406 407 408 409 |
db_unprotect(PROTECT_ALL);
db_set("ssh-command", g.zSshCmd, 0);
db_protect_pop();
}
}
/*
| | < | | | < < < < < < < < < < < < < < < < < < < < < | > > | 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 |
db_unprotect(PROTECT_ALL);
db_set("ssh-command", g.zSshCmd, 0);
db_protect_pop();
}
}
/*
** WEBPAGE: howtoclone
**
** Provide instructions on how to clone this repository.
*/
void howtoclone_page(void){
login_check_credentials();
cgi_check_for_malice();
style_header("How To Clone This Repository");
if( !g.perm.Clone ){
@ <p>You are not authorized to clone this repository.
if( g.zLogin==0 || g.zLogin[0]==0 ){
@ Maybe you would be able to clone if you
@ %z(href("%R/login"))logged in</a>.
}else{
@ Contact the site administrator and ask them to give
@ you "Clone" privileges in order to clone.
}
}else{
const char *zNm = db_get("short-project-name","clone");
@ <p>Clone this repository by running a command like the following:
@ <blockquote><pre>
@ fossil clone %s(g.zBaseURL) %h(zNm).fossil
@ </pre></blockquote>
@ <p>Do a web search for "fossil clone" or similar to find additional
@ information about using a cloned Fossil repository.
}
style_finish_page();
}
|
Changes to src/content.c.
| ︙ | ︙ | |||
862 863 864 865 866 867 868 |
/* Loop over all candidate delta sources */
for(i=0; i<nSrc; i++){
int srcid = aSrc[i];
if( srcid==rid ) continue;
if( content_is_private(srcid) && !content_is_private(rid) ) continue;
/* Compute all ancestors of srcid and make sure rid is not one of them.
| | | 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 |
/* Loop over all candidate delta sources */
for(i=0; i<nSrc; i++){
int srcid = aSrc[i];
if( srcid==rid ) continue;
if( content_is_private(srcid) && !content_is_private(rid) ) continue;
/* Compute all ancestors of srcid and make sure rid is not one of them.
** If rid is an ancestor of srcid, then making rid a descendent of srcid
** would create a delta loop. */
s = srcid;
while( (s = delta_source_rid(s))>0 ){
if( s==rid ){
content_undelta(srcid);
break;
}
|
| ︙ | ︙ |
Changes to src/db.c.
| ︙ | ︙ | |||
1226 1227 1228 1229 1230 1231 1232 | } db_finalize(&s); } /* ** Execute a query. Return the first column of the first row ** of the result set as a string. Space to hold the string is | | | | 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 |
}
db_finalize(&s);
}
/*
** Execute a query. Return the first column of the first row
** of the result set as a string. Space to hold the string is
** obtained from fossil_strdup() and should be freed using fossil_free().
** If the result set is empty, return a copy of zDefault instead.
*/
char *db_text(const char *zDefault, const char *zSql, ...){
va_list ap;
Stmt s;
char *z;
va_start(ap, zSql);
db_vprepare(&s, 0, zSql, ap);
|
| ︙ | ︙ | |||
3597 3598 3599 3600 3601 3602 3603 |
return zOut;
}
/*
** Return true if the string zVal represents "true" (or "false").
*/
int is_truth(const char *zVal){
| | | | 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 |
return zOut;
}
/*
** Return true if the string zVal represents "true" (or "false").
*/
int is_truth(const char *zVal){
static const char *const azOn[] = { "on", "yes", "true" };
int i;
for(i=0; i<count(azOn); i++){
if( fossil_stricmp(zVal,azOn[i])==0 ) return 1;
}
return atoi(zVal);
}
int is_false(const char *zVal){
static const char *const azOff[] = { "off", "no", "false", "0" };
int i;
for(i=0; i<count(azOff); i++){
if( fossil_stricmp(zVal,azOff[i])==0 ) return 1;
}
|
| ︙ | ︙ | |||
4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 |
** --setmtime Set timestamps of all files to match their SCM-side
** times (the timestamp of the last check-in which modified
** them).
** --verbose If passed a URI then this flag is passed on to the clone
** operation, otherwise it has no effect
** --workdir DIR Use DIR as the working directory instead of ".". The DIR
** directory is created if it does not exist.
**
** See also: [[close]], [[clone]]
*/
void cmd_open(void){
int emptyFlag;
int keepFlag;
int forceMissingFlag;
int allowNested;
int setmtimeFlag; /* --setmtime. Set mtimes on files */
int bForce = 0; /* --force. Open even if non-empty dir */
static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
const char *zWorkDir; /* --workdir value */
const char *zRepo = 0; /* Name of the repository file */
const char *zRepoDir = 0; /* --repodir value */
char *zPwd; /* Initial working directory */
int isUri = 0; /* True if REPOSITORY is a URI */
int nLocal; /* Number of preexisting files in cwd */
int bVerbose = 0; /* --verbose option for clone */
url_proxy_options();
emptyFlag = find_option("empty",0,0)!=0;
keepFlag = find_option("keep","k",0)!=0;
forceMissingFlag = find_option("force-missing",0,0)!=0;
allowNested = find_option("nested",0,0)!=0;
setmtimeFlag = find_option("setmtime",0,0)!=0;
| > > > > > > > > > > > > | 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 |
** --setmtime Set timestamps of all files to match their SCM-side
** times (the timestamp of the last check-in which modified
** them).
** --verbose If passed a URI then this flag is passed on to the clone
** operation, otherwise it has no effect
** --workdir DIR Use DIR as the working directory instead of ".". The DIR
** directory is created if it does not exist.
** --reopen REPOFILE Changes the repository file used by the current checkout
** to REPOFILE. Use this after moving a checkout's
** repository. This may lose stash and bisect history.
**
** See also: [[close]], [[clone]]
*/
void cmd_open(void){
int emptyFlag;
int keepFlag;
int forceMissingFlag;
int allowNested;
int setmtimeFlag; /* --setmtime. Set mtimes on files */
int bForce = 0; /* --force. Open even if non-empty dir */
static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0, 0 };
const char *zWorkDir; /* --workdir value */
const char *zRepo = 0; /* Name of the repository file */
const char *zRepoDir = 0; /* --repodir value */
const char *zReopen = 0; /* --reopen REPOFILE */
char *zPwd; /* Initial working directory */
int isUri = 0; /* True if REPOSITORY is a URI */
int nLocal; /* Number of preexisting files in cwd */
int bVerbose = 0; /* --verbose option for clone */
zReopen = find_option("reopen",0,1);
if( 0!=zReopen ){
g.argc = 3;
g.argv[2] = (char*)zReopen;
move_repo_cmd();
return;
}
url_proxy_options();
emptyFlag = find_option("empty",0,0)!=0;
keepFlag = find_option("keep","k",0)!=0;
forceMissingFlag = find_option("force-missing",0,0)!=0;
allowNested = find_option("nested",0,0)!=0;
setmtimeFlag = find_option("setmtime",0,0)!=0;
|
| ︙ | ︙ | |||
4325 4326 4327 4328 4329 4330 4331 |
}
if( file_chdir(zWorkDir, 0) ){
fossil_fatal("unable to make %s the working directory", zWorkDir);
}
}
if( keepFlag==0
&& bForce==0
| | | 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 |
}
if( file_chdir(zWorkDir, 0) ){
fossil_fatal("unable to make %s the working directory", zWorkDir);
}
}
if( keepFlag==0
&& bForce==0
&& (nLocal = file_directory_list(".", 0, 1, 2, 0))>0
&& (nLocal>1 || isUri || !file_in_cwd(zRepo))
){
fossil_fatal("directory %s is not empty\n"
"use the -f (--force) option to override\n"
"or the -k (--keep) option to keep local files unchanged",
file_getcwd(0,0));
}
|
| ︙ | ︙ | |||
4389 4390 4391 4392 4393 4394 4395 |
db_open_repository(zRepo);
/* Figure out which revision to open. */
if( !emptyFlag ){
if( g.argc==4 ){
g.zOpenRevision = g.argv[3];
}else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
| | | 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 |
db_open_repository(zRepo);
/* Figure out which revision to open. */
if( !emptyFlag ){
if( g.argc==4 ){
g.zOpenRevision = g.argv[3];
}else if( db_exists("SELECT 1 FROM event WHERE type='ci'") ){
g.zOpenRevision = fossil_strdup(db_main_branch());
}
if( autosync_loop(SYNC_PULL, !bForce, "open") && !bForce ){
fossil_fatal("unable to auto-sync the repository");
}
}
|
| ︙ | ︙ |
Changes to src/default.css.
| ︙ | ︙ | |||
55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
tr.timelineCurrent td {
border-radius: 0;
border-width: 0;
}
span.timelineLeaf {
font-weight: bold;
}
span.timelineHistDsp {
font-weight: bold;
}
td.timelineTime {
vertical-align: top;
text-align: right;
white-space: nowrap;
| > > > | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
tr.timelineCurrent td {
border-radius: 0;
border-width: 0;
}
span.timelineLeaf {
font-weight: bold;
}
span.timelineHash {
font-weight: bold;
}
span.timelineHistDsp {
font-weight: bold;
}
td.timelineTime {
vertical-align: top;
text-align: right;
white-space: nowrap;
|
| ︙ | ︙ | |||
750 751 752 753 754 755 756 757 758 759 760 761 762 763 |
}
body.tkt div.content ol.tkt-changes > li:target > p > span {
border-bottom: 3px solid gold;
}
body.tkt div.content ol.tkt-changes > li:target > ol {
border-left: 1px solid gold;
}
body.cpage-ckout .file-change-line,
body.cpage-info .file-change-line,
body.cpage-vinfo .file-change-line,
body.cpage-ci .file-change-line,
body.cpage-vdiff .file-change-line {
margin-top: 16px;
margin-bottom: 16px;
| > > > > > > > > > > > > | 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 |
}
body.tkt div.content ol.tkt-changes > li:target > p > span {
border-bottom: 3px solid gold;
}
body.tkt div.content ol.tkt-changes > li:target > ol {
border-left: 1px solid gold;
}
body.tkt .tktCommentArea {
display: flex;
flex-direction: column;
}
body.tkt .newest-first-controls {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
}
body.tkt .tktCommentArea.reverse {
flex-direction: column-reverse;
}
body.cpage-ckout .file-change-line,
body.cpage-info .file-change-line,
body.cpage-vinfo .file-change-line,
body.cpage-ci .file-change-line,
body.cpage-vdiff .file-change-line {
margin-top: 16px;
margin-bottom: 16px;
|
| ︙ | ︙ | |||
1789 1790 1791 1792 1793 1794 1795 |
div.pikchr-wrapper.indent:not(.source),
div.pikchr-wrapper.indent.source.source-inline{
margin-left: 4em;
}
div.pikchr-wrapper.float-left:not(.source),
div.pikchr-wrapper.float-left.source.source-inline {
float: left;
| | | | 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 |
div.pikchr-wrapper.indent:not(.source),
div.pikchr-wrapper.indent.source.source-inline{
margin-left: 4em;
}
div.pikchr-wrapper.float-left:not(.source),
div.pikchr-wrapper.float-left.source.source-inline {
float: left;
padding: 1em 2em;
}
div.pikchr-wrapper.float-right:not(.source),
div.pikchr-wrapper.float-right.source.source-inline{
float: right;
padding: 1em 2em;
}
/* For pikchr-wrapper.source mode, toggle pre.pikchr-src and
svg.pikchr visibility... */
div.pikchr-wrapper.source > div.pikchr-src {
/* Source code ^^^^^^^ is visible, else it is hidden */
}
|
| ︙ | ︙ |
Changes to src/deltafunc.c.
| ︙ | ︙ | |||
249 250 251 252 253 254 255 256 257 258 259 260 261 262 |
#define DELTAPARSEVTAB_A2 2
#define DELTAPARSEVTAB_DELTA 3
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc64( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
}
return rc;
}
/*
** This method is the destructor for deltaparsevtab_vtab objects.
*/
| > | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
#define DELTAPARSEVTAB_A2 2
#define DELTAPARSEVTAB_DELTA 3
if( rc==SQLITE_OK ){
pNew = sqlite3_malloc64( sizeof(*pNew) );
*ppVtab = (sqlite3_vtab*)pNew;
if( pNew==0 ) return SQLITE_NOMEM;
memset(pNew, 0, sizeof(*pNew));
sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
}
return rc;
}
/*
** This method is the destructor for deltaparsevtab_vtab objects.
*/
|
| ︙ | ︙ | |||
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 |
*/
static int deltaparsevtabNext(sqlite3_vtab_cursor *cur){
deltaparsevtab_cursor *pCur = (deltaparsevtab_cursor*)cur;
const char *z;
int i = 0;
pCur->iCursor = pCur->iNext;
z = pCur->aDelta + pCur->iCursor;
pCur->a1 = deltaGetInt(&z, &i);
switch( z[0] ){
case '@': {
z++;
pCur->a2 = deltaGetInt(&z, &i);
pCur->eOp = DELTAPARSE_OP_COPY;
pCur->iNext = (int)(&z[1] - pCur->aDelta);
break;
}
case ':': {
z++;
| > > > > > > > > > > | 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 |
*/
static int deltaparsevtabNext(sqlite3_vtab_cursor *cur){
deltaparsevtab_cursor *pCur = (deltaparsevtab_cursor*)cur;
const char *z;
int i = 0;
pCur->iCursor = pCur->iNext;
if( pCur->iCursor >= pCur->nDelta ){
pCur->eOp = DELTAPARSE_OP_ERROR;
pCur->iNext = pCur->nDelta;
return SQLITE_OK;
}
z = pCur->aDelta + pCur->iCursor;
pCur->a1 = deltaGetInt(&z, &i);
switch( z[0] ){
case '@': {
z++;
if( pCur->iNext>=pCur->nDelta ){
pCur->eOp = DELTAPARSE_OP_ERROR;
pCur->iNext = pCur->nDelta;
break;
}
pCur->a2 = deltaGetInt(&z, &i);
pCur->eOp = DELTAPARSE_OP_COPY;
pCur->iNext = (int)(&z[1] - pCur->aDelta);
break;
}
case ':': {
z++;
|
| ︙ | ︙ | |||
352 353 354 355 356 357 358 |
sqlite3_result_int(ctx, pCur->a1);
break;
}
case DELTAPARSEVTAB_A2: {
if( pCur->eOp==DELTAPARSE_OP_COPY ){
sqlite3_result_int(ctx, pCur->a2);
}else if( pCur->eOp==DELTAPARSE_OP_INSERT ){
| > > > | | > | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 |
sqlite3_result_int(ctx, pCur->a1);
break;
}
case DELTAPARSEVTAB_A2: {
if( pCur->eOp==DELTAPARSE_OP_COPY ){
sqlite3_result_int(ctx, pCur->a2);
}else if( pCur->eOp==DELTAPARSE_OP_INSERT ){
if( pCur->a2 + pCur->a1 > pCur->nDelta ){
sqlite3_result_zeroblob(ctx, pCur->a1);
}else{
sqlite3_result_blob(ctx, pCur->aDelta+pCur->a2, pCur->a1,
SQLITE_TRANSIENT);
}
}
break;
}
case DELTAPARSEVTAB_DELTA: {
sqlite3_result_blob(ctx, pCur->aDelta, pCur->nDelta, SQLITE_TRANSIENT);
break;
}
|
| ︙ | ︙ | |||
381 382 383 384 385 386 387 |
/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int deltaparsevtabEof(sqlite3_vtab_cursor *cur){
deltaparsevtab_cursor *pCur = (deltaparsevtab_cursor*)cur;
| | | 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 |
/*
** Return TRUE if the cursor has been moved off of the last
** row of output.
*/
static int deltaparsevtabEof(sqlite3_vtab_cursor *cur){
deltaparsevtab_cursor *pCur = (deltaparsevtab_cursor*)cur;
return pCur->eOp==DELTAPARSE_OP_EOF || pCur->iCursor>=pCur->nDelta;
}
/*
** This method is called to "rewind" the deltaparsevtab_cursor object back
** to the first row of output. This method is always called at least
** once prior to any call to deltaparsevtabColumn() or deltaparsevtabRowid() or
** deltaparsevtabEof().
|
| ︙ | ︙ |
Changes to src/descendants.c.
| ︙ | ︙ | |||
435 436 437 438 439 440 441 |
int recomputeFlag = find_option("recompute",0,0)!=0;
int byBranch = find_option("bybranch",0,0)!=0;
int multipleFlag = find_option("multiple","m",0)!=0;
const char *zWidth = find_option("width","W",1);
char *zLastBr = 0;
int n, width;
char zLineNo[10];
| | | 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 |
int recomputeFlag = find_option("recompute",0,0)!=0;
int byBranch = find_option("bybranch",0,0)!=0;
int multipleFlag = find_option("multiple","m",0)!=0;
const char *zWidth = find_option("width","W",1);
char *zLastBr = 0;
int n, width;
char zLineNo[10];
const char *zMainBranch = db_main_branch();
if( multipleFlag ) byBranch = 1;
if( zWidth ){
width = atoi(zWidth);
if( (width!=0) && (width<=39) ){
fossil_fatal("-W|--width value must be >39 or 0");
}
|
| ︙ | ︙ | |||
533 534 535 536 537 538 539 |
}
z = mprintf("%s [%S] %s%s", zDate, zId, zCom,
zBranchPoint ? zBranchPoint : "");
comment_print(z, zCom, 7, width, get_comment_format());
fossil_free(z);
fossil_free(zBranchPoint);
}
| < | 533 534 535 536 537 538 539 540 541 542 543 544 545 546 |
}
z = mprintf("%s [%S] %s%s", zDate, zId, zCom,
zBranchPoint ? zBranchPoint : "");
comment_print(z, zCom, 7, width, get_comment_format());
fossil_free(z);
fossil_free(zBranchPoint);
}
fossil_free(zLastBr);
db_finalize(&q);
}
/*
** WEBPAGE: leaves
**
|
| ︙ | ︙ |
Changes to src/diff.c.
| ︙ | ︙ | |||
3247 3248 3249 3250 3251 3252 3253 | ** -i|--internal Use built-in diff, not an external tool ** --invert Invert the diff DIFF_INVERT ** --json Output formatted as JSON ** --label NAME Column label. Can be repeated once. ** -n|--linenum Show line numbers DIFF_LINENO ** -N|--new-file Alias for --verbose ** --noopt Disable optimization DIFF_NOOPT | | | 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 | ** -i|--internal Use built-in diff, not an external tool ** --invert Invert the diff DIFF_INVERT ** --json Output formatted as JSON ** --label NAME Column label. Can be repeated once. ** -n|--linenum Show line numbers DIFF_LINENO ** -N|--new-file Alias for --verbose ** --noopt Disable optimization DIFF_NOOPT ** -s|--numstat Show change counts DIFF_NUMSTAT ** --strip-trailing-cr Strip trailing CR DIFF_STRIP_EOLCR ** --tcl Tcl-formatted output used internally by --tk ** --unified Unified diff. ~DIFF_SIDEBYSIDE ** -v|--verbose Show complete text of added or deleted files ** -w|--ignore-all-space Ignore all whitespaces DIFF_IGNORE_ALLWS ** --webpage Format output as a stand-alone HTML webpage ** -W|--width N N character lines. wColumn |
| ︙ | ︙ | |||
3322 3323 3324 3325 3326 3327 3328 |
}
pCfg->azLabel[0] = find_option("label",0,1);
if( pCfg->azLabel[0] ){
pCfg->azLabel[1] = find_option("label",0,1);
}
if( find_option("linenum","n",0)!=0 ) diffFlags |= DIFF_LINENO;
if( find_option("noopt",0,0)!=0 ) diffFlags |= DIFF_NOOPT;
| | | 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 |
}
pCfg->azLabel[0] = find_option("label",0,1);
if( pCfg->azLabel[0] ){
pCfg->azLabel[1] = find_option("label",0,1);
}
if( find_option("linenum","n",0)!=0 ) diffFlags |= DIFF_LINENO;
if( find_option("noopt",0,0)!=0 ) diffFlags |= DIFF_NOOPT;
if( find_option("numstat","s",0)!=0 ) diffFlags |= DIFF_NUMSTAT;
if( find_option("versions","h",0)!=0 ) diffFlags |= DIFF_SHOW_VERS;
if( find_option("dark",0,0)!=0 ) diffFlags |= DIFF_DARKMODE;
if( find_option("invert",0,0)!=0 ) diffFlags |= DIFF_INVERT;
if( find_option("brief",0,0)!=0 ) diffFlags |= DIFF_BRIEF;
if( find_option("internal","i",0)==0
&& (diffFlags & (DIFF_HTML|DIFF_TCL|DIFF_DEBUG|DIFF_JSON))==0
){
|
| ︙ | ︙ | |||
3384 3385 3386 3387 3388 3389 3390 |
return;
}
find_option("i",0,0);
find_option("v",0,0);
diff_options(&DCfg, 0, 0);
zRe = find_option("regexp","e",1);
if( zRe ){
| | | 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 |
return;
}
find_option("i",0,0);
find_option("v",0,0);
diff_options(&DCfg, 0, 0);
zRe = find_option("regexp","e",1);
if( zRe ){
const char *zErr = fossil_re_compile(&DCfg.pRe, zRe, 0);
if( zErr ) fossil_fatal("regex error: %s", zErr);
}
verify_all_options();
if( g.argc!=4 ) usage("FILE1 FILE2");
blob_zero(&out);
diff_begin(&DCfg);
diff_print_filenames(g.argv[2], g.argv[3], &DCfg, &out);
|
| ︙ | ︙ | |||
3427 3428 3429 3430 3431 3432 3433 |
return;
}
find_option("i",0,0);
find_option("v",0,0);
diff_options(&DCfg, 0, 0);
zRe = find_option("regexp","e",1);
if( zRe ){
| | | 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 |
return;
}
find_option("i",0,0);
find_option("v",0,0);
diff_options(&DCfg, 0, 0);
zRe = find_option("regexp","e",1);
if( zRe ){
const char *zErr = fossil_re_compile(&DCfg.pRe, zRe, 0);
if( zErr ) fossil_fatal("regex error: %s", zErr);
}
db_find_and_open_repository(0, 0);
verify_all_options();
if( g.argc!=4 ) usage("HASH1 HASH2");
blob_zero(&out);
diff_begin(&DCfg);
|
| ︙ | ︙ | |||
3947 3948 3949 3950 3951 3952 3953 | ** -r|--revision VERSION The specific check-in containing the file ** -l|--log List all versions analyzed ** -n|--limit LIMIT LIMIT can be one of: ** N Up to N versions ** Xs As much as possible in X seconds ** none No limit ** -o|--origin VERSION The origin check-in. By default this is the | | > | 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 |
** -r|--revision VERSION The specific check-in containing the file
** -l|--log List all versions analyzed
** -n|--limit LIMIT LIMIT can be one of:
** N Up to N versions
** Xs As much as possible in X seconds
** none No limit
** -o|--origin VERSION The origin check-in. By default this is the
** root of the repository. Set to the name of
** the main branch (usually "trunk") or
** similar for a reverse annotation.
** -w|--ignore-all-space Ignore white space when comparing lines
** -Z|--ignore-trailing-space Ignore whitespace at line end
**
** See also: [[info]], [[finfo]], [[timeline]]
*/
void annotate_cmd(void){
|
| ︙ | ︙ |
Changes to src/diffcmd.c.
| ︙ | ︙ | |||
1354 1355 1356 1357 1358 1359 1360 | ** that directory as the baseline. ** -w|--ignore-all-space Ignore white space when comparing lines ** -i|--internal Use internal diff logic ** --invert Invert the diff ** --json Output formatted as JSON ** -n|--linenum Show line numbers ** -N|--new-file Alias for --verbose | | | 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 | ** that directory as the baseline. ** -w|--ignore-all-space Ignore white space when comparing lines ** -i|--internal Use internal diff logic ** --invert Invert the diff ** --json Output formatted as JSON ** -n|--linenum Show line numbers ** -N|--new-file Alias for --verbose ** -s|--numstat Show the number of added and deleted lines per ** file, omitting the diff. When combined with ** --brief, show only the total row. ** -y|--side-by-side Side-by-side diff ** --strip-trailing-cr Strip trailing CR ** --tcl Tcl-formatted output used internally by --tk ** --tclsh PATH Tcl/Tk shell used for --tk (default: "tclsh") ** --tk Launch a Tcl/Tk GUI for display |
| ︙ | ︙ | |||
1458 1459 1460 1461 1462 1463 1464 |
break;
}
pFileDir[i-2].nName = blob_size(&fname);
pFileDir[i-2].nUsed = 0;
blob_reset(&fname);
}
}
| | | 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 |
break;
}
pFileDir[i-2].nName = blob_size(&fname);
pFileDir[i-2].nUsed = 0;
blob_reset(&fname);
}
}
if( (DCfg.diffFlags & DIFF_NUMSTAT) && !(DCfg.diffFlags & DIFF_BRIEF) ){
fossil_print("%10s %10s\n", "INSERTED", "DELETED");
}
if( zCheckin!=0 ){
int ridTo = name_to_typed_rid(zCheckin, "ci");
zTo = zCheckin;
zFrom = db_text(0,
"SELECT uuid FROM blob, plink"
|
| ︙ | ︙ |
Changes to src/dispatch.c.
| ︙ | ︙ | |||
57 58 59 60 61 62 63 | #define CMDFLAG_ALIAS 0x2000 /* Command aliases */ #define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */ #define CMDFLAG_ABBREVSUBCMD 0x8000 /* Help text abbreviates subcommands */ /**************************************************************************/ /* Values for the 2nd parameter to dispatch_name_search() */ #define CMDFLAG_ANY 0x0038 /* Match anything */ | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | #define CMDFLAG_ALIAS 0x2000 /* Command aliases */ #define CMDFLAG_KEEPEMPTY 0x4000 /* Do not unset empty settings */ #define CMDFLAG_ABBREVSUBCMD 0x8000 /* Help text abbreviates subcommands */ /**************************************************************************/ /* Values for the 2nd parameter to dispatch_name_search() */ #define CMDFLAG_ANY 0x0038 /* Match anything */ #define CMDFLAG_PREFIX 0x0200 /* Prefix match is OK */ #endif /* INTERFACE */ /* ** The page_index.h file contains the definition for aCommand[] - an array ** of CmdOrPage objects that defines all available commands and webpages ** known to Fossil. |
| ︙ | ︙ | |||
273 274 275 276 277 278 279 |
int j;
while( i<n ){
char c = z[i];
if( c=='[' && (j = help_is_link(z+i, n-i))>0 ){
if( i ) blob_append(pOut, z, i);
z += i+2;
n -= i+2;
| | | 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
int j;
while( i<n ){
char c = z[i];
if( c=='[' && (j = help_is_link(z+i, n-i))>0 ){
if( i ) blob_append(pOut, z, i);
z += i+2;
n -= i+2;
blob_appendf(pOut, "<a href='%R/help/%.*s'>%.*s</a>",
j-3, z, j-3, z);
z += j-1;
n -= j-1;
i = 0;
}else if( c=='%' && n-i>=7 && strncmp(z+i,"%fossil",7)==0 ){
if( i ) blob_append(pOut, z, i);
z += i+7;
|
| ︙ | ︙ | |||
833 834 835 836 837 838 839 |
if( 0==fossil_strcmp(zName, z) ) return 1;
}
return 0;
}
/*
** WEBPAGE: help
| | | > | > > > > > > > > | > > > > > | 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 |
if( 0==fossil_strcmp(zName, z) ) return 1;
}
return 0;
}
/*
** WEBPAGE: help
** URL: /help/CMD or /help/www/PAGE
**
** Show the built-in help text for CMD or PAGE. CMD can be a command-line
** interface command or a setting name. PAGE is the name of a
** web interface. /help//PAGE also works if the double-/ makes it through
** the main web server.
**
** Query parameters:
**
** name=CMD Show help for CMD where CMD is a command name or
** or setting name. If CMD beings with "/" it is
** interpreted as a PAGE name.
**
** name=www/PAGE Show help for web page PAGE.
**
** name=/PAGE The initial "www/" on web-page help can be abbreviated as
** just "/"
**
** plaintext Show the help within <pre>...</pre>, as if it were
** displayed using the "fossil help" command.
**
** raw Show the raw help text without any formatting.
** (Used for debugging.)
*/
void help_page(void){
const char *zCmd = P("cmd");
if( zCmd==0 ) zCmd = P("name");
cgi_check_for_malice();
if( zCmd && *zCmd ){
int rc;
const CmdOrPage *pCmd = 0;
style_set_current_feature("tkt");
style_submenu_element("Topic-List", "%R/help");
if( search_restrict(SRCH_HELP)!=0 ){
style_submenu_element("Search","%R/search?y=h");
}
if( strncmp(zCmd,"www/",4)==0 && zCmd[4]!=0 ){
/* Use https://domain/fossil/help/www/timeline or similar with the "www"
** intermediate tag to view web-page documentation. */
zCmd += 3;
}
rc = dispatch_name_search(zCmd, CMDFLAG_ANY|CMDFLAG_PREFIX, &pCmd);
if( pCmd ){
style_header("Help: %s", pCmd->zName);
}else{
style_header("Help");
}
|
| ︙ | ︙ | |||
933 934 935 936 937 938 939 |
const char *z = aCommand[i].zName;
const char *zBoldOn = aCommand[i].eCmdFlags&CMDFLAG_1ST_TIER?"<b>" :"";
const char *zBoldOff = aCommand[i].eCmdFlags&CMDFLAG_1ST_TIER?"</b>":"";
if( '/'==*z || strncmp(z,"test",4)==0 ) continue;
if( (aCommand[i].eCmdFlags & CMDFLAG_SETTING)!=0 ) continue;
else if( (aCommand[i].eCmdFlags & CMDFLAG_HIDDEN)!=0 ) continue;
else if( (aCommand[i].eCmdFlags & CMDFLAG_ALIAS)!=0 ) continue;
| | | | | | | 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 984 985 986 987 988 989 990 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 |
const char *z = aCommand[i].zName;
const char *zBoldOn = aCommand[i].eCmdFlags&CMDFLAG_1ST_TIER?"<b>" :"";
const char *zBoldOff = aCommand[i].eCmdFlags&CMDFLAG_1ST_TIER?"</b>":"";
if( '/'==*z || strncmp(z,"test",4)==0 ) continue;
if( (aCommand[i].eCmdFlags & CMDFLAG_SETTING)!=0 ) continue;
else if( (aCommand[i].eCmdFlags & CMDFLAG_HIDDEN)!=0 ) continue;
else if( (aCommand[i].eCmdFlags & CMDFLAG_ALIAS)!=0 ) continue;
@ <li><a href="%R/help/%s(z)">%s(zBoldOn)%s(z)%s(zBoldOff)</a>
/* Output aliases */
if( occHelp[aCommand[i].iHelp] > 1 ){
int j;
int aliases[MX_HELP_DUP], nAliases=0;
for(j=0; j<occHelp[aCommand[i].iHelp]; j++){
if( bktHelp[aCommand[i].iHelp][j] != i ){
if( aCommand[bktHelp[aCommand[i].iHelp][j]].eCmdFlags
& CMDFLAG_ALIAS ){
aliases[nAliases++] = bktHelp[aCommand[i].iHelp][j];
}
}
}
if( nAliases>0 ){
int k;
@(\
for(k=0; k<nAliases; k++){
@<a href="%R/help/%s(aCommand[aliases[k]].zName)">\
@%s(aCommand[aliases[k]].zName)</a>%s((k<nAliases-1)?", ":"")\
}
@)\
}
}
@ </li>
}
@ </ul></div>
@ <a name='webpages'></a>
@ <h1>Available web UI pages:</h1>
@ <div class="columns" style="column-width: %s(zWidth);">
@ <ul>
for(i=0; i<MX_COMMAND; i++){
const char *z = aCommand[i].zName;
if( '/'!=*z ) continue;
else if( (aCommand[i].eCmdFlags & CMDFLAG_HIDDEN)!=0 ) continue;
if( aCommand[i].zHelp[0] ){
@ <li><a href="%R/help/www%s(z)">%s(z+1)</a></li>
}else{
@ <li>%s(z+1)</li>
}
}
@ </ul></div>
@ <a name='unsupported'></a>
@ <h1>Unsupported commands:</h1>
@ <div class="columns" style="column-width: %s(zWidth);">
@ <ul>
for(i=0; i<MX_COMMAND; i++){
const char *z = aCommand[i].zName;
if( strncmp(z,"test",4)!=0 ) continue;
else if( (aCommand[i].eCmdFlags & CMDFLAG_HIDDEN)!=0 ) continue;
if( aCommand[i].zHelp[0] ){
@ <li><a href="%R/help/%s(z)">%s(z)</a></li>
}else{
@ <li>%s(z)</li>
}
}
@ </ul></div>
@ <a name='settings'></a>
@ <h1>Settings:</h1>
@ <div class="columns" style="column-width: %s(zWidth);">
@ <ul>
for(i=0; i<MX_COMMAND; i++){
const char *z = aCommand[i].zName;
if( (aCommand[i].eCmdFlags & CMDFLAG_SETTING)==0 ) continue;
else if( (aCommand[i].eCmdFlags & CMDFLAG_HIDDEN)!=0 ) continue;
if( aCommand[i].zHelp[0] ){
@ <li><a href="%R/help/%s(z)">%s(z)</a></li>
}else{
@ <li>%s(z)</li>
}
}
@ </ul></div>
}
|
| ︙ | ︙ | |||
1153 1154 1155 1156 1157 1158 1159 |
if( bAbbrevSubcmd ){
zPattern = mprintf(" ([a-z]+ ?\\| ?)*%s\\b", zQSub);
}else{
zPattern = mprintf("> ?fossil [-a-z]+ .*\\b%s\\b", zQSub);
}
fossil_free(zQTop);
fossil_free(zQSub);
| | | 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 |
if( bAbbrevSubcmd ){
zPattern = mprintf(" ([a-z]+ ?\\| ?)*%s\\b", zQSub);
}else{
zPattern = mprintf("> ?fossil [-a-z]+ .*\\b%s\\b", zQSub);
}
fossil_free(zQTop);
fossil_free(zQSub);
fossil_re_compile(&pRe, zPattern, 0);
fossil_free(zPattern);
blob_init(&in, z, -1);
while( blob_line(&in, &line) ){
if( re_match(pRe, (unsigned char*)blob_buffer(&line), blob_size(&line)) ){
int atStart = 1;
blob_appendb(pOut, &line);
n++;
|
| ︙ | ︙ | |||
1250 1251 1252 1253 1254 1255 1256 |
int bAbbrevSubcmd /* z[] uses abbreviated subcommands */
){
ReCompiled *pRe = 0;
Blob in, line;
int n = 0;
if( bAbbrevSubcmd ){
| | | | 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 |
int bAbbrevSubcmd /* z[] uses abbreviated subcommands */
){
ReCompiled *pRe = 0;
Blob in, line;
int n = 0;
if( bAbbrevSubcmd ){
fossil_re_compile(&pRe, "^(Usage: | [a-z][-a-z|]+ .*)", 0);
}else{
fossil_re_compile(&pRe, "^(Usage: | *[Oo]r: +%fossi |> ?fossil )", 0);
}
blob_init(&in, z, -1);
while( blob_line(&in, &line) ){
if( re_match(pRe, (unsigned char*)blob_buffer(&line), blob_strlen(&line)) ){
simplify_usage_line(&line, pOut, bAbbrevSubcmd, zTopic);
n++;
}
|
| ︙ | ︙ | |||
1283 1284 1285 1286 1287 1288 1289 | ReCompiled *pRe = 0; Blob txt, line, subsection; int n = 0; int bSubsectionSeen = 0; blob_init(&txt, z, -1); blob_init(&subsection, 0, 0); | | | 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 |
ReCompiled *pRe = 0;
Blob txt, line, subsection;
int n = 0;
int bSubsectionSeen = 0;
blob_init(&txt, z, -1);
blob_init(&subsection, 0, 0);
fossil_re_compile(&pRe, "^ +-.* ", 0);
while( blob_line(&txt, &line) ){
int len = blob_size(&line);
unsigned char *zLine = (unsigned char *)blob_buffer(&line);
if( re_match(pRe, zLine, len) ){
if( blob_size(&subsection) ){
simplify_usage_line(&subsection, pOut, bAbbrevSubcmd, zCmd);
blob_reset(&subsection);
|
| ︙ | ︙ | |||
1388 1389 1390 1391 1392 1393 1394 | @ @ --args FILENAME Read additional arguments and options from FILENAME @ --case-sensitive BOOL Set case sensitivity for file names @ --cgitrace Active CGI tracing @ --chdir PATH Change to PATH before performing any operations @ --color WHEN Emit VT color escapes: 'never', 'always', or 'auto' @ --errorlog FILENAME Log errors to FILENAME | | | 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 | @ @ --args FILENAME Read additional arguments and options from FILENAME @ --case-sensitive BOOL Set case sensitivity for file names @ --cgitrace Active CGI tracing @ --chdir PATH Change to PATH before performing any operations @ --color WHEN Emit VT color escapes: 'never', 'always', or 'auto' @ --errorlog FILENAME Log errors to FILENAME @ -?|--help Show help on the command rather than running it @ --httptrace Trace outbound HTTP requests @ --localtime Display times using the local timezone @ --nocgi Do not act as CGI @ --no-th-hook Do not run TH1 hooks @ --quiet Reduce the amount of output @ --sqlstats Show SQL usage statistics when done @ --sqltrace Trace all SQL commands |
| ︙ | ︙ |
Changes to src/doc.c.
| ︙ | ︙ | |||
518 519 520 521 522 523 524 |
void mimetype_list_page(void){
int i;
char *zCustomList = 0; /* value of the mimetypes setting */
int nCustomEntries = 0; /* number of entries in the mimetypes
** setting */
mimetype_verify();
style_header("Mimetype List");
| | | | | 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 |
void mimetype_list_page(void){
int i;
char *zCustomList = 0; /* value of the mimetypes setting */
int nCustomEntries = 0; /* number of entries in the mimetypes
** setting */
mimetype_verify();
style_header("Mimetype List");
@ <p>The Fossil <a href="%R/help/www/doc">/doc</a> page uses filename
@ suffixes and the following tables to guess at the appropriate mimetype
@ for each document. Mimetypes may be customized and overridden using
@ <a href="%R/help/mimetypes">the mimetypes config setting</a>.</p>
zCustomList = db_get("mimetypes",0);
if( zCustomList!=0 ){
Blob list, entry, key, val;
@ <h1>Repository-specific mimetypes</h1>
@ <p>The following extension-to-mimetype mappings are defined via
@ the <a href="%R/help/mimetypes">mimetypes setting</a>.</p>
@ <table class='sortable mimetypetable' border=1 cellpadding=0 \
@ data-column-types='tt' data-init-sort='0'>
@ <thead>
@ <tr><th>Suffix<th>Mimetype
@ </thead>
@ <tbody>
blob_set(&list, zCustomList);
|
| ︙ | ︙ |
Changes to src/export.c.
| ︙ | ︙ | |||
489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 |
*/
void export_cmd(void){
Stmt q, q2, q3;
Bag blobs, vers;
unsigned int unused_mark = 1;
const char *markfile_in;
const char *markfile_out;
bag_init(&blobs);
bag_init(&vers);
find_option("git", 0, 0); /* Ignore the --git option for now */
markfile_in = find_option("import-marks", 0, 1);
markfile_out = find_option("export-marks", 0, 1);
if( !(gexport.zTrunkName = find_option("rename-trunk", 0, 1)) ){
| > | | 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 |
*/
void export_cmd(void){
Stmt q, q2, q3;
Bag blobs, vers;
unsigned int unused_mark = 1;
const char *markfile_in;
const char *markfile_out;
const char *zMainBranch = db_main_branch();
bag_init(&blobs);
bag_init(&vers);
find_option("git", 0, 0); /* Ignore the --git option for now */
markfile_in = find_option("import-marks", 0, 1);
markfile_out = find_option("export-marks", 0, 1);
if( !(gexport.zTrunkName = find_option("rename-trunk", 0, 1)) ){
gexport.zTrunkName = fossil_strdup(zMainBranch);
}
db_find_and_open_repository(0, 2);
verify_all_options();
if( g.argc!=2 && g.argc!=3 ){ usage("--git ?REPOSITORY?"); }
db_multi_exec("CREATE TEMPORARY TABLE oldblob(rid INTEGER PRIMARY KEY)");
|
| ︙ | ︙ | |||
627 628 629 630 631 632 633 |
const char *zBranch = db_column_text(&q, 4);
char *zMark;
bag_insert(&vers, ckinId);
db_bind_int(&q2, ":rid", ckinId);
db_step(&q2);
db_reset(&q2);
| | | 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 |
const char *zBranch = db_column_text(&q, 4);
char *zMark;
bag_insert(&vers, ckinId);
db_bind_int(&q2, ":rid", ckinId);
db_step(&q2);
db_reset(&q2);
if( zBranch==0 || fossil_strcmp(zBranch, zMainBranch)==0 ){
zBranch = gexport.zTrunkName;
}
zMark = mark_name_from_rid(ckinId, &unused_mark);
printf("commit refs/heads/");
print_ref(zBranch);
printf("\nmark %s\n", zMark);
free(zMark);
|
| ︙ | ︙ | |||
855 856 857 858 859 860 861 | ** 3 Extra details */ #define VERB_ERROR 1 #define VERB_NORMAL 2 #define VERB_EXTRA 3 static int gitmirror_verbosity = VERB_NORMAL; | | | | 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 |
** 3 Extra details
*/
#define VERB_ERROR 1
#define VERB_NORMAL 2
#define VERB_EXTRA 3
static int gitmirror_verbosity = VERB_NORMAL;
/* The main branch in the Git repository. The main branch of the
** Fossil repository (usually "trunk") is renamed to be this branch name.
*/
static const char *gitmirror_mainbranch = 0;
/*
** Output routine that depends on verbosity
*/
static void gitmirror_message(int iLevel, const char *zFormat, ...){
|
| ︙ | ︙ | |||
1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 |
Blob comment; /* The comment text for the check-in */
int nErr = 0; /* Number of errors */
int bPhantomOk; /* True if phantom files should be ignored */
char buf[24];
char *zEmail; /* Contact info for Git committer field */
int fManifest; /* Should the manifest files be included? */
int fPManifest = 0; /* OR of the manifest files for all parents */
pMan = manifest_get(rid, CFTYPE_MANIFEST, 0);
if( pMan==0 ){
/* Must be a phantom. Return without doing anything, and in particular
** without creating a mark for this check-in. */
gitmirror_message(VERB_NORMAL, "missing check-in: %s\n", zUuid);
return 0;
| > | 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 |
Blob comment; /* The comment text for the check-in */
int nErr = 0; /* Number of errors */
int bPhantomOk; /* True if phantom files should be ignored */
char buf[24];
char *zEmail; /* Contact info for Git committer field */
int fManifest; /* Should the manifest files be included? */
int fPManifest = 0; /* OR of the manifest files for all parents */
const char *zMainBranch;
pMan = manifest_get(rid, CFTYPE_MANIFEST, 0);
if( pMan==0 ){
/* Must be a phantom. Return without doing anything, and in particular
** without creating a mark for this check-in. */
gitmirror_message(VERB_NORMAL, "missing check-in: %s\n", zUuid);
return 0;
|
| ︙ | ︙ | |||
1147 1148 1149 1150 1151 1152 1153 |
}
/* Figure out which branch this check-in is a member of */
zBranch = db_text(0,
"SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=%d",
TAG_BRANCH, rid
);
| > | | 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 |
}
/* Figure out which branch this check-in is a member of */
zBranch = db_text(0,
"SELECT value FROM tagxref WHERE tagid=%d AND tagtype>0 AND rid=%d",
TAG_BRANCH, rid
);
zMainBranch = db_main_branch();
if( fossil_strcmp(zBranch, zMainBranch)==0 ){
assert( gitmirror_mainbranch!=0 );
fossil_free(zBranch);
zBranch = fossil_strdup(gitmirror_mainbranch);
}else if( zBranch==0 ){
zBranch = mprintf("unknown");
}else{
gitmirror_sanitize_name(zBranch);
|
| ︙ | ︙ |
Changes to src/extcgi.c.
| ︙ | ︙ | |||
169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
int fdFromChild = -1; /* File descriptor for reading from child */
FILE *toChild = 0; /* FILE for sending to child */
FILE *fromChild = 0; /* FILE for reading from child */
int pidChild = 0; /* Process id of the child */
int rc; /* Reply code from subroutine call */
int nContent = -1; /* Content length */
const char *zPathInfo; /* Original PATH_INFO value */
Blob reply; /* The reply */
char zLine[1000]; /* One line of the CGI reply */
const char *zSrvSw; /* SERVER_SOFTWARE */
zPathInfo = P("PATH_INFO");
login_check_credentials();
blob_init(&reply, 0, 0);
| > | 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
int fdFromChild = -1; /* File descriptor for reading from child */
FILE *toChild = 0; /* FILE for sending to child */
FILE *fromChild = 0; /* FILE for reading from child */
int pidChild = 0; /* Process id of the child */
int rc; /* Reply code from subroutine call */
int nContent = -1; /* Content length */
const char *zPathInfo; /* Original PATH_INFO value */
char *zRestrictTag; /* Tag to restrict specific documents */
Blob reply; /* The reply */
char zLine[1000]; /* One line of the CGI reply */
const char *zSrvSw; /* SERVER_SOFTWARE */
zPathInfo = P("PATH_INFO");
login_check_credentials();
blob_init(&reply, 0, 0);
|
| ︙ | ︙ | |||
227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
}
if( nScript==0 ){
zFailReason = "path does not match any file or script";
goto ext_not_found;
}
assert( nScript>=nRoot+1 );
style_set_current_page("ext/%s", &zScript[nRoot+1]);
zMime = P("mimetype");
if( zMime==0 ) zMime = mimetype_from_name(zScript);
if( zMime==0 ) zMime = "application/octet-stream";
if( !file_isexe(zScript, ExtFILE) ){
/* File is not executable. Must be a regular file. In that case,
** disallow extra path elements */
if( zPath[nScript]!=0 ){
| > > > | 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
}
if( nScript==0 ){
zFailReason = "path does not match any file or script";
goto ext_not_found;
}
assert( nScript>=nRoot+1 );
style_set_current_page("ext/%s", &zScript[nRoot+1]);
zRestrictTag = mprintf("ext/%s", &zScript[nRoot+1]);
if( robot_restrict(zRestrictTag) ) return;
fossil_free(zRestrictTag);
zMime = P("mimetype");
if( zMime==0 ) zMime = mimetype_from_name(zScript);
if( zMime==0 ) zMime = "application/octet-stream";
if( !file_isexe(zScript, ExtFILE) ){
/* File is not executable. Must be a regular file. In that case,
** disallow extra path elements */
if( zPath[nScript]!=0 ){
|
| ︙ | ︙ |
Changes to src/file.c.
| ︙ | ︙ | |||
2541 2542 2543 2544 2545 2546 2547 | #else while( z[0]=='/' && z[1]=='/' ) z++; #endif return z; } /* | | | > > > > > > > | | > > > > > > > > > | > | | | > > > | | > | | | > > > > > > > > > > > > > > > > > > > > > | > > > | | | | > > > > > > > | | > > > > > > > > > | > > > > > > > | 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 |
#else
while( z[0]=='/' && z[1]=='/' ) z++;
#endif
return z;
}
/*
** Find the name of all objects (files and subdirectories) in a given
** directory that match a GLOB pattern. If zGlob is NULL, then return
** all objects. The list is written into *pazList and the number of
** entries is returned. If pazList is NULL, then only the count is
** returned.
**
** If zDir is not a directory, *pazList is unchanged and -1 is returned.
**
** Memory used to old *pazList should be freed using a subsequent call
** to file_directory_list_free().
**
** This routine never counts the two "." and ".." special directory
** entries, even if the provided glob would match them.
*/
int file_directory_list(
const char *zDir, /* Directory to get a listing of */
const char *zGlob, /* Only list objects matching this pattern */
int omitDotFiles, /* 0: skip "." and "..", 1: no .-files, 2: keep all */
int nLimit, /* Find at most this many files. 0 means "all" */
char ***pazList /* OUT: Write the list here, if not NULL */
){
void *zNative;
DIR *d;
int n = -1;
int nAlloc = 0;
if( pazList ) *pazList = 0;
zNative = fossil_utf8_to_path(zDir,1);
d = opendir(zNative);
if( d ){
struct dirent *pEntry;
n = 0;
while( (pEntry=readdir(d))!=0 ){
char *zUtf8 = 0;
if( pEntry->d_name[0]==0 ) continue;
if( pEntry->d_name[0]=='.'
&& omitDotFiles<2
&& (omitDotFiles==1
/* Skip the special "." and ".." entries unless omitDotFiles>=2 */
|| pEntry->d_name[1]==0
|| (pEntry->d_name[1]=='.' && pEntry->d_name[2]==0)
)
){
continue;
}
if( zGlob ){
int rc;
zUtf8 = fossil_path_to_utf8(pEntry->d_name);
rc = sqlite3_strglob(zGlob, zUtf8);
if( rc ){
fossil_path_free(zUtf8);
continue;
}
}
if( pazList ){
if( n+1 >= nAlloc ){
nAlloc = 100 + n;
*pazList = fossil_realloc(*pazList, nAlloc*sizeof(char*));
}
if( zUtf8==0 ){
zUtf8 = fossil_path_to_utf8(pEntry->d_name);
}
(*pazList)[n] = fossil_strdup(zUtf8);
}
n++;
if( zUtf8 ) fossil_path_free(zUtf8);
if( nLimit>0 && n>=nLimit ) break;
}
closedir(d);
}
fossil_path_free(zNative);
if( pazList ) (*pazList)[n] = 0;
return n;
}
void file_directory_list_free(char **azList){
char **az;
if( azList==0 ) return;
az = azList;
while( az[0] ){
fossil_free(az[0]);
az++;
}
fossil_free(azList);
}
/*
** COMMAND: test-dir-list
**
** Usage: %fossil test-dir-list NAME [GLOB] [OPTIONS]
**
** Return the names of up to N objects in the directory NAME. If GLOB is
** provided, then only show objects that match the GLOB pattern.
**
** This command is intended for testing the file_directory_list() function.
**
** Options:
**
** --count Only count files, do not list them.
** --limit N Only show the first N files seen
** --nodots Do not show or count files that start with '.'
*/
void test_dir_list_cmd(void){
int omitDotFiles = find_option("nodots",0,0)!=0;
const char *zLimit = find_option("limit",0,1);
int countOnly = find_option("count",0,0)!=0;
const char *zGlob;
const char *zDir;
char **azList = 0;
int nList;
verify_all_options();
if( g.argc!=3 && g.argc!=4 ){
usage("NAME [GLOB] [-nodots]");
}
zDir = g.argv[2];
zGlob = g.argc==4 ? g.argv[3] : 0;
nList = file_directory_list(zDir, zGlob, omitDotFiles,
zLimit ? atoi(zLimit) : 0,
countOnly ? 0 : &azList);
if( countOnly ){
fossil_print("%d\n", nList);
}else{
int i;
for(i=0; i<nList; i++){
fossil_print(" %s\n", azList[i]);
}
}
file_directory_list_free(azList);
}
/*
** Internal helper for touch_cmd(). zAbsName must be resolvable as-is
** to an existing file - this function does not expand/normalize
** it. i.e. it "really should" be an absolute path. zTreeName is
** strictly cosmetic: it is used when dryRunFlag, verboseFlag, or
|
| ︙ | ︙ |
Changes to src/fileedit.c.
| ︙ | ︙ | |||
831 832 833 834 835 836 837 |
if(zDate){
cimi.zDate = fossil_strdup(zDate);
}
if(zRevision==0 || zRevision[0]==0){
if(g.localOpen/*check-out*/){
zRevision = db_lget("checkout-hash", 0)/*leak*/;
}else{
| | | 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 |
if(zDate){
cimi.zDate = fossil_strdup(zDate);
}
if(zRevision==0 || zRevision[0]==0){
if(g.localOpen/*check-out*/){
zRevision = db_lget("checkout-hash", 0)/*leak*/;
}else{
zRevision = db_main_branch();
}
}
name_to_uuid2(zRevision, "ci", &cimi.zParentUuid);
if(cimi.zParentUuid==0){
fossil_fatal("Cannot determine version to commit to.");
}
blob_read_from_file(&cimi.fileContent, zFilename, ExtFILE);
|
| ︙ | ︙ |
Changes to src/finfo.c.
| ︙ | ︙ | |||
174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
Blob fname;
int rid;
const char *zFilename;
const char *zLimit;
const char *zWidth;
const char *zOffset;
int iLimit, iOffset, iBrief, iWidth;
if( find_option("log","l",0) ){
/* this is the default, no-op */
}
zLimit = find_option("limit","n",1);
zWidth = find_option("width","W",1);
iLimit = zLimit ? atoi(zLimit) : -1;
| > | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
Blob fname;
int rid;
const char *zFilename;
const char *zLimit;
const char *zWidth;
const char *zOffset;
int iLimit, iOffset, iBrief, iWidth;
const char *zMainBranch;
if( find_option("log","l",0) ){
/* this is the default, no-op */
}
zLimit = find_option("limit","n",1);
zWidth = find_option("width","W",1);
iLimit = zLimit ? atoi(zLimit) : -1;
|
| ︙ | ︙ | |||
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
TAG_BRANCH, zFilename, filename_collation(),
iLimit, iOffset
);
blob_zero(&line);
if( iBrief == 0 ){
fossil_print("History for %s\n", blob_str(&fname));
}
while( db_step(&q)==SQLITE_ROW ){
const char *zFileUuid = db_column_text(&q, 0);
const char *zCiUuid = db_column_text(&q,1);
const char *zDate = db_column_text(&q, 2);
const char *zCom = db_column_text(&q, 3);
const char *zUser = db_column_text(&q, 4);
const char *zBr = db_column_text(&q, 5);
char *zOut;
| > | | 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
TAG_BRANCH, zFilename, filename_collation(),
iLimit, iOffset
);
blob_zero(&line);
if( iBrief == 0 ){
fossil_print("History for %s\n", blob_str(&fname));
}
zMainBranch = db_main_branch();
while( db_step(&q)==SQLITE_ROW ){
const char *zFileUuid = db_column_text(&q, 0);
const char *zCiUuid = db_column_text(&q,1);
const char *zDate = db_column_text(&q, 2);
const char *zCom = db_column_text(&q, 3);
const char *zUser = db_column_text(&q, 4);
const char *zBr = db_column_text(&q, 5);
char *zOut;
if( zBr==0 ) zBr = fossil_strdup(zMainBranch);
if( iBrief == 0 ){
fossil_print("%s ", zDate);
zOut = mprintf(
"[%S] %s (user: %s, artifact: [%S], branch: %s)",
zCiUuid, zCom, zUser, zFileUuid, zBr);
comment_print(zOut, zCom, 11, iWidth, get_comment_format());
fossil_free(zOut);
|
| ︙ | ︙ | |||
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
Stmt qparent;
int iTableId = timeline_tableid();
int tmFlags = 0; /* Viewing mode */
const char *zStyle; /* Viewing mode name */
const char *zMark; /* Mark this version of the file */
int selRid = 0; /* RID of the marked file version */
int mxfnid; /* Maximum filename.fnid value */
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
ridCi = zCI ? name_to_rid_www("ci") : 0;
if( fnid==0 ){
style_header("No such file");
}else if( ridCi==0 ){
style_header("All files named \"%s\"", zFilename);
}else{
style_header("History of %s of %s",zFilename, zCI);
}
login_anonymous_available();
tmFlags = timeline_ss_submenu();
if( tmFlags & TIMELINE_COLUMNAR ){
zStyle = "Columnar";
}else if( tmFlags & TIMELINE_COMPACT ){
zStyle = "Compact";
}else if( tmFlags & TIMELINE_VERBOSE ){
zStyle = "Verbose";
}else if( tmFlags & TIMELINE_CLASSIC ){
zStyle = "Classic";
}else{
zStyle = "Modern";
}
| > > > | 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 |
Stmt qparent;
int iTableId = timeline_tableid();
int tmFlags = 0; /* Viewing mode */
const char *zStyle; /* Viewing mode name */
const char *zMark; /* Mark this version of the file */
int selRid = 0; /* RID of the marked file version */
int mxfnid; /* Maximum filename.fnid value */
const char *zMainBranch;
login_check_credentials();
if( !g.perm.Read ){ login_needed(g.anon.Read); return; }
fnid = db_int(0, "SELECT fnid FROM filename WHERE name=%Q", zFilename);
ridCi = zCI ? name_to_rid_www("ci") : 0;
if( fnid==0 ){
style_header("No such file");
}else if( ridCi==0 ){
style_header("All files named \"%s\"", zFilename);
}else{
style_header("History of %s of %s",zFilename, zCI);
}
login_anonymous_available();
tmFlags = timeline_ss_submenu();
if( tmFlags & TIMELINE_COLUMNAR ){
zStyle = "Columnar";
}else if( tmFlags & TIMELINE_COMPACT ){
zStyle = "Compact";
}else if( tmFlags & TIMELINE_SIMPLE ){
zStyle = "Simple";
}else if( tmFlags & TIMELINE_VERBOSE ){
zStyle = "Verbose";
}else if( tmFlags & TIMELINE_CLASSIC ){
zStyle = "Classic";
}else{
zStyle = "Modern";
}
|
| ︙ | ︙ | |||
629 630 631 632 633 634 635 |
db_bind_int(&qparent, ":mid", fmid);
db_bind_int(&qparent, ":fnid", fnid);
while( db_step(&qparent)==SQLITE_ROW && nParent<count(aParent) ){
aParent[nParent] = db_column_int64(&qparent, 0);
nParent++;
}
db_reset(&qparent);
| > | | | 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 |
db_bind_int(&qparent, ":mid", fmid);
db_bind_int(&qparent, ":fnid", fnid);
while( db_step(&qparent)==SQLITE_ROW && nParent<count(aParent) ){
aParent[nParent] = db_column_int64(&qparent, 0);
nParent++;
}
db_reset(&qparent);
zMainBranch = db_main_branch();
if( zBr==0 ) zBr = fossil_strdup(zMainBranch);
if( uBg ){
zBgClr = user_color(zUser);
}else if( brBg || zBgClr==0 || zBgClr[0]==0 ){
zBgClr = strcmp(zBr, zMainBranch)==0 ? "" : hash_color(zBr);
}else if( zBgClr ){
zBgClr = reasonable_bg_color(zBgClr,0);
}
gidx = graph_add_row(pGraph,
frid>0 ? (GraphRowId)frid*(mxfnid+1)+fnid : fpid+1000000000,
nParent, 0, aParent, zBr, zBgClr,
zUuid, 0);
|
| ︙ | ︙ | |||
729 730 731 732 733 734 735 |
@ <td class="timelineDetailCell">
}
}
if( tmFlags & TIMELINE_COMPACT ){
cgi_printf("<span class='clutter' id='detail-%d'>",frid);
}
cgi_printf("<span class='timeline%sDetail'>", zStyle);
| | | > > > > > | | | 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 |
@ <td class="timelineDetailCell">
}
}
if( tmFlags & TIMELINE_COMPACT ){
cgi_printf("<span class='clutter' id='detail-%d'>",frid);
}
cgi_printf("<span class='timeline%sDetail'>", zStyle);
if( tmFlags & TIMELINE_INLINE ) cgi_printf("(");
if( zUuid && (tmFlags & TIMELINE_VERBOSE)==0 ){
@ file: %z(href("%R/file?name=%T&ci=%!S",zFName,zCkin))\
@ %S(zUuid)</a>
if( fShowId ){
int srcId = delta_source_rid(frid);
if( srcId>0 ){
@ id: %z(href("%R/deltachain/%d",frid))\
@ %d(frid)←%d(srcId)</a>
}else{
@ id: %z(href("%R/deltachain/%d",frid))%d(frid)</a>
}
}
}
if( tmFlags & TIMELINE_SIMPLE ){
@ <span class='timelineEllipsis' data-id='%d(frid)' \
@ id='ellipsis-%d(frid)'>...</span>
@ <span class='clutter' id='detail-%d(frid)'>
}
@ check-in: \
hyperlink_to_version(zCkin);
if( fShowId ){
@ (%d(fmid))
}
@ user: \
hyperlink_to_user(zUser, zDate, ",");
@ branch: %z(href("%R/timeline?t=%T",zBr))%h(zBr)</a>,
if( tmFlags & TIMELINE_INLINE ){
@ size: %d(szFile)
}else{
@ size: %d(szFile)
}
if( g.perm.Hyperlink && zUuid ){
const char *z = zFName;
@ <span id='links-%d(frid)'><span class='timelineExtraLinks'>
@ %z(href("%R/annotate?filename=%h&checkin=%s",z,zCkin))
|
| ︙ | ︙ | |||
791 792 793 794 795 796 797 |
}
}
zAncLink = href("%R/finfo?name=%T&from=%!S&debug=1",zFName,zCkin);
@ %z(zAncLink)[ancestry]</a>
}
tag_private_status(frid);
/* End timelineDetail */
| | | > > | > | 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 |
}
}
zAncLink = href("%R/finfo?name=%T&from=%!S&debug=1",zFName,zCkin);
@ %z(zAncLink)[ancestry]</a>
}
tag_private_status(frid);
/* End timelineDetail */
if( tmFlags & TIMELINE_INLINE ){
@ </span>)</span>
}else{
@ </span>
}
@ </td></tr>
}
db_finalize(&q);
db_finalize(&qparent);
if( pGraph ){
graph_finish(pGraph, 0, TIMELINE_DISJOINT);
if( pGraph->nErr ){
graph_free(pGraph);
pGraph = 0;
}else{
@ <tr class="timelineBottom" id="btm-%d(iTableId)">\
@ <td></td><td></td><td></td></tr>
}
}
@ </table>
{
int tmFlags = TIMELINE_GRAPH | TIMELINE_FILEDIFF;
timeline_output_graph_javascript(pGraph, tmFlags, iTableId);
}
style_finish_page();
}
/*
** WEBPAGE: mlink
** URL: /mlink?name=FILENAME
** URL: /mlink?ci=NAME
|
| ︙ | ︙ |
Changes to src/forum.c.
| ︙ | ︙ | |||
1910 1911 1912 1913 1914 1915 1916 |
if( pSetting==0 ) continue;
zQP[0] = 'a'+i;
zQP[1] = zQP[0];
zQP[2] = 0;
if( pSetting->width==0 ){
/* Boolean setting */
@ <tr><td align="right">
| | | | 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 |
if( pSetting==0 ) continue;
zQP[0] = 'a'+i;
zQP[1] = zQP[0];
zQP[2] = 0;
if( pSetting->width==0 ){
/* Boolean setting */
@ <tr><td align="right">
@ <a href='%R/help/%h(pSetting->name)'>%h(pSetting->name)</a>:
@ </td><td>
onoff_attribute("", zQP, pSetting->name/*works-like:"x"*/, 0, 0);
@ </td></tr>
}else{
/* Text value setting */
@ <tr><td align="right">
@ <a href='%R/help/%h(pSetting->name)'>%h(pSetting->name)</a>:
@ </td><td>
entry_attribute("", 25, pSetting->name, zQP/*works-like:""*/,
pSetting->def, 0);
@ </td></tr>
}
}
@ </tbody></table>
|
| ︙ | ︙ |
Changes to src/fossil.page.chat.js.
| ︙ | ︙ | |||
2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 |
hint: F.storage.isTransient()
? "Local store is unavailable. These settings are transient."
: ["Most of these settings are persistent via ",
F.storage.storageImplName(), ": ",
F.storage.storageHelpDescription()].join('')
},{
label: "Editing Options...",
children:[{
label: "Chat-only mode",
hint: "Toggle the page between normal fossil view and chat-only view.",
boolValue: 'chat-only-mode'
},{
label: "Ctrl-enter to Send",
hint: [
| > > > > | 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 |
hint: F.storage.isTransient()
? "Local store is unavailable. These settings are transient."
: ["Most of these settings are persistent via ",
F.storage.storageImplName(), ": ",
F.storage.storageHelpDescription()].join('')
},{
label: "Editing Options...",
hint: ["These options are all recommended but some misinteract",
"with specific browsers or software keyboards so they",
"are not enabled by default."
].join(' '),
children:[{
label: "Chat-only mode",
hint: "Toggle the page between normal fossil view and chat-only view.",
boolValue: 'chat-only-mode'
},{
label: "Ctrl-enter to Send",
hint: [
|
| ︙ | ︙ |
Added src/fossil.page.ticket.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
/*
* This script adds a checkbox to reverse the sorting on any body.tkt
* pages which contain a .tktCommentArea element.
*/
window.addEventListener( 'load', function() {
const tgt = document.querySelectorAll('.tktCommentArea');
if( !tgt ) return;
const F = globalThis.fossil, D = F.dom;
let i = 0;
for(const e of tgt) {
++i;
const childs = e.querySelectorAll('.tktCommentEntry');
if( !childs || 1===childs.length ) continue;
const cbReverseKey = 'tktCommentArea:reverse';
const cbReverse = D.checkbox();
const cbId = cbReverseKey+':'+i;
cbReverse.setAttribute('id',cbId);
const widget = D.append(
D.div(),
cbReverse,
D.label(cbReverse, " Show newest first? ")
);
widget.classList.add('newest-first-controls');
e.parentElement.insertBefore(widget,e);
const cbReverseIt = ()=>{
e.classList[cbReverse.checked ? 'add' : 'remove']('reverse');
F.storage.set(cbReverseKey, cbReverse.checked ? 1 : 0);
};
cbReverse.addEventListener('change', cbReverseIt, true);
cbReverse.checked = !!(+F.storage.get(cbReverseKey, 0));
};
}); // window.addEventListener( 'load' ...
|
Changes to src/graph.c.
| ︙ | ︙ | |||
511 512 513 514 515 516 517 518 519 520 521 522 523 524 |
u32 tmFlags /* TIMELINE flags */
){
GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
int i, j;
u64 mask;
int hasDup = 0; /* True if one or more isDup entries */
const char *zTrunk;
u8 *aMap; /* Copy of p->aiRailMap */
int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0;
int nTimewarp = 0;
int riserMargin = (tmFlags & TIMELINE_DISJOINT) ? 0 : RISER_MARGIN;
/* If mergeRiserFrom[X]==Y that means rail X holds a merge riser
** coming up from the bottom of the graph from off-screen check-in Y
| > | 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
u32 tmFlags /* TIMELINE flags */
){
GraphRow *pRow, *pDesc, *pDup, *pLoop, *pParent;
int i, j;
u64 mask;
int hasDup = 0; /* True if one or more isDup entries */
const char *zTrunk;
const char *zMainBranch;
u8 *aMap; /* Copy of p->aiRailMap */
int omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0;
int nTimewarp = 0;
int riserMargin = (tmFlags & TIMELINE_DISJOINT) ? 0 : RISER_MARGIN;
/* If mergeRiserFrom[X]==Y that means rail X holds a merge riser
** coming up from the bottom of the graph from off-screen check-in Y
|
| ︙ | ︙ | |||
704 705 706 707 708 709 710 |
pRow->idxTop = pChild->idxTop;
}
}
/* Identify rows where the primary parent is off screen. Assign
** each to a rail and draw descenders downward.
**
| | > | | 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 |
pRow->idxTop = pChild->idxTop;
}
}
/* Identify rows where the primary parent is off screen. Assign
** each to a rail and draw descenders downward.
**
** Strive to put the main branch (usually "trunk") on far left.
*/
zMainBranch = db_main_branch();
zTrunk = persistBranchName(p, zMainBranch);
for(i=0; i<2; i++){
for(pRow=p->pLast; pRow; pRow=pRow->pPrev){
if( i==0 && pRow->zBranch!=zTrunk ) continue;
if( pRow->iRail>=0 ) continue;
if( pRow->isDup ) continue;
if( pRow->nParent<0 ) continue;
if( pRow->nParent==0 || hashFind(p,pRow->aParent[0])==0 ){
|
| ︙ | ︙ |
Changes to src/graph.js.
| ︙ | ︙ | |||
719 720 721 722 723 724 725 |
var n = x.length;
for(var i=0; i<n; i++) {x[i].style.display = value;}
}
function changeDisplayById(id,value){
var x = document.getElementById(id);
if(x) x.style.display=value;
}
| | > > > > > > | | | 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 |
var n = x.length;
for(var i=0; i<n; i++) {x[i].style.display = value;}
}
function changeDisplayById(id,value){
var x = document.getElementById(id);
if(x) x.style.display=value;
}
function toggleDetail(evt){
/* Ignore clicks to hyperlinks and other "click-responsive" HTML elements.
** This click-handler is set for <SPAN> elements with the CSS class names
** "timelineEllipsis" and "timelineCompactComment", which are part of the
** "Compact" and "Simple" views. */
var xClickyHTML = /^(?:A|AREA|BUTTON|INPUT|LABEL|SELECT|TEXTAREA|DETAILS)$/;
if( xClickyHTML.test(evt.target.tagName) ) return;
var id = parseInt(this.getAttribute('data-id'))
var x = document.getElementById("detail-"+id);
if( x.style.display=="inline" ){
x.style.display="none";
document.getElementById("ellipsis-"+id).textContent = "...";
changeDisplayById("links-"+id,"none");
}else{
x.style.display="inline";
document.getElementById("ellipsis-"+id).textContent = "←";
changeDisplayById("links-"+id,"inline");
}
checkHeight();
}
function scrollToSelected(){
var x = document.getElementsByClassName('timelineSelected');
if(x[0]){
|
| ︙ | ︙ | |||
762 763 764 765 766 767 768 |
}else{
function checkHeight(){}
}
if( tx.scrollToSelect ){
scrollToSelected();
}
| | | | > > | > > | 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 |
}else{
function checkHeight(){}
}
if( tx.scrollToSelect ){
scrollToSelected();
}
/* Set the onclick= attributes for elements of the "Compact" and
** "Simple" views so that clicking turns the details on and off.
*/
var lx = topObj.getElementsByClassName('timelineEllipsis');
var i;
for(i=0; i<lx.length; i++){
if( lx[i].hasAttribute('data-id') ){
lx[i].addEventListener('click',toggleDetail);
}
}
lx = topObj.getElementsByClassName('timelineCompactComment');
for(i=0; i<lx.length; i++){
if( lx[i].hasAttribute('data-id') ){
lx[i].addEventListener('click',toggleDetail);
}
}
if( window.innerWidth<400 ){
/* On narrow displays, shift the date from the first column to the
** third column, to make the first column narrower */
lx = topObj.getElementsByClassName('timelineDateRow');
for(i=0; i<lx.length; i++){
var rx = lx[i];
|
| ︙ | ︙ |
Changes to src/http.c.
| ︙ | ︙ | |||
139 140 141 142 143 144 145 146 147 148 |
static void http_build_header(
Blob *pPayload, /* the payload that will be sent */
Blob *pHdr, /* construct the header here */
Blob *pLogin, /* Login card header value or NULL */
const char *zAltMimetype /* Alternative mimetype */
){
int nPayload = pPayload ? blob_size(pPayload) : 0;
blob_zero(pHdr);
blob_appendf(pHdr, "%s %s HTTP/1.0\r\n",
| > > > > > > > > | < | 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 164 |
static void http_build_header(
Blob *pPayload, /* the payload that will be sent */
Blob *pHdr, /* construct the header here */
Blob *pLogin, /* Login card header value or NULL */
const char *zAltMimetype /* Alternative mimetype */
){
int nPayload = pPayload ? blob_size(pPayload) : 0;
const char *zPath;
blob_zero(pHdr);
if( g.url.subpath ){
zPath = g.url.subpath;
}else if( g.url.path==0 || g.url.path[0]==0 ){
zPath = "/";
}else{
zPath = g.url.path;
}
blob_appendf(pHdr, "%s %s HTTP/1.0\r\n",
nPayload>0 ? "POST" : "GET", zPath);
if( g.url.proxyAuth ){
blob_appendf(pHdr, "Proxy-Authorization: %s\r\n", g.url.proxyAuth);
}
if( g.zHttpAuth && g.zHttpAuth[0] ){
const char *zCredentials = g.zHttpAuth;
char *zEncoded = encode64(zCredentials, -1);
blob_appendf(pHdr, "Authorization: Basic %s\r\n", zEncoded);
|
| ︙ | ︙ | |||
457 458 459 460 461 462 463 464 465 466 467 468 469 470 |
}
/* Activate the PATH= auxiliary argument to the ssh command if that
** is called for.
*/
if( g.url.isSsh
&& (g.url.flags & URL_SSH_RETRY)==0
&& ssh_needs_path_argument(g.url.hostname, -1)
){
g.url.flags |= URL_SSH_PATH;
}
if( transport_open(&g.url) ){
fossil_warning("%s", transport_errmsg(&g.url));
| > | 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 |
}
/* Activate the PATH= auxiliary argument to the ssh command if that
** is called for.
*/
if( g.url.isSsh
&& (g.url.flags & URL_SSH_RETRY)==0
&& g.db!=0
&& ssh_needs_path_argument(g.url.hostname, -1)
){
g.url.flags |= URL_SSH_PATH;
}
if( transport_open(&g.url) ){
fossil_warning("%s", transport_errmsg(&g.url));
|
| ︙ | ︙ | |||
676 677 678 679 680 681 682 |
*/
if( g.url.isSsh /* This is an SSH: sync */
&& (g.url.flags & URL_SSH_EXE)==0 /* Does not have ?fossil=.... */
&& (g.url.flags & URL_SSH_RETRY)==0 /* Not retried already */
){
/* Retry after flipping the SSH_PATH setting */
transport_close(&g.url);
| > | | | | | | > | | 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 |
*/
if( g.url.isSsh /* This is an SSH: sync */
&& (g.url.flags & URL_SSH_EXE)==0 /* Does not have ?fossil=.... */
&& (g.url.flags & URL_SSH_RETRY)==0 /* Not retried already */
){
/* Retry after flipping the SSH_PATH setting */
transport_close(&g.url);
if( (mHttpFlags & HTTP_QUIET)==0 ){
fossil_print(
"First attempt to run fossil on %s using SSH failed.\n"
"Retrying %s the PATH= argument.\n",
g.url.hostname,
(g.url.flags & URL_SSH_PATH)!=0 ? "without" : "with"
);
}
g.url.flags ^= URL_SSH_PATH|URL_SSH_RETRY;
rc = http_exchange(pSend,pReply,mHttpFlags,0,zAltMimetype);
if( rc==0 && g.db!=0 ){
(void)ssh_needs_path_argument(g.url.hostname,
(g.url.flags & URL_SSH_PATH)!=0);
}
return rc;
}else{
/* The problem could not be corrected by retrying. Report the
** the error. */
|
| ︙ | ︙ | |||
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 847 848 849 850 |
** a GET request where there is no PAYLOAD.
**
** Options:
** --compress Use ZLIB compression on the payload
** --mimetype TYPE Mimetype of the payload
** --no-cert-verify Disable TLS cert verification
** --out FILE Store the reply in FILE
** -v Verbose output
** --xfer PAYLOAD in a Fossil xfer protocol message
*/
void test_httpmsg_command(void){
const char *zMimetype;
const char *zInFile;
const char *zOutFile;
Blob in, out;
unsigned int mHttpFlags = HTTP_GENERIC|HTTP_NOCOMPRESS;
zMimetype = find_option("mimetype",0,1);
zOutFile = find_option("out","o",1);
if( find_option("verbose","v",0)!=0 ) mHttpFlags |= HTTP_VERBOSE;
if( find_option("compress",0,0)!=0 ) mHttpFlags &= ~HTTP_NOCOMPRESS;
if( find_option("no-cert-verify",0,0)!=0 ){
#ifdef FOSSIL_ENABLE_SSL
ssl_disable_cert_verification();
#endif
}
if( find_option("xfer",0,0)!=0 ){
mHttpFlags |= HTTP_USE_LOGIN;
mHttpFlags &= ~HTTP_GENERIC;
}
if( find_option("ipv4",0,0) ) g.fIPv4 = 1;
verify_all_options();
if( g.argc<3 || g.argc>5 ){
usage("URL ?PAYLOAD? ?OUTPUT?");
}
zInFile = g.argc>=4 ? g.argv[3] : 0;
if( g.argc==5 ){
if( zOutFile ){
fossil_fatal("output file specified twice: \"--out %s\" and \"%s\"",
zOutFile, g.argv[4]);
}
zOutFile = g.argv[4];
}
url_parse(g.argv[2], 0);
if( g.url.protocol[0]!='h' ){
| > > > > | > > > | 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 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 |
** a GET request where there is no PAYLOAD.
**
** Options:
** --compress Use ZLIB compression on the payload
** --mimetype TYPE Mimetype of the payload
** --no-cert-verify Disable TLS cert verification
** --out FILE Store the reply in FILE
** --subpath PATH HTTP request path for ssh: and file: URLs
** -v Verbose output
** --xfer PAYLOAD in a Fossil xfer protocol message
*/
void test_httpmsg_command(void){
const char *zMimetype;
const char *zInFile;
const char *zOutFile;
const char *zSubpath;
Blob in, out;
unsigned int mHttpFlags = HTTP_GENERIC|HTTP_NOCOMPRESS;
zMimetype = find_option("mimetype",0,1);
zOutFile = find_option("out","o",1);
if( find_option("verbose","v",0)!=0 ) mHttpFlags |= HTTP_VERBOSE;
if( find_option("compress",0,0)!=0 ) mHttpFlags &= ~HTTP_NOCOMPRESS;
if( find_option("no-cert-verify",0,0)!=0 ){
#ifdef FOSSIL_ENABLE_SSL
ssl_disable_cert_verification();
#endif
}
if( find_option("xfer",0,0)!=0 ){
mHttpFlags |= HTTP_USE_LOGIN;
mHttpFlags &= ~HTTP_GENERIC;
}
if( find_option("ipv4",0,0) ) g.fIPv4 = 1;
zSubpath = find_option("subpath",0,1);
verify_all_options();
if( g.argc<3 || g.argc>5 ){
usage("URL ?PAYLOAD? ?OUTPUT?");
}
zInFile = g.argc>=4 ? g.argv[3] : 0;
if( g.argc==5 ){
if( zOutFile ){
fossil_fatal("output file specified twice: \"--out %s\" and \"%s\"",
zOutFile, g.argv[4]);
}
zOutFile = g.argv[4];
}
url_parse(g.argv[2], 0);
if( g.url.protocol[0]!='h' ){
if( zSubpath==0 ){
fossil_fatal("the --subpath option is required for %s://",g.url.protocol);
}else{
g.url.subpath = fossil_strdup(zSubpath);
}
}
if( zInFile ){
blob_read_from_file(&in, zInFile, ExtFILE);
if( zMimetype==0 && (mHttpFlags & HTTP_GENERIC)!=0 ){
if( fossil_strcmp(zInFile,"-")==0 ){
zMimetype = "application/x-unknown";
}else{
|
| ︙ | ︙ |
Changes to src/import.c.
| ︙ | ︙ | |||
566 567 568 569 570 571 572 |
/* The argument to the "commit" line might match either of these
** patterns:
**
** (A) refs/heads/BRANCHNAME
** (B) refs/tags/TAGNAME
**
** If pattern A is used, then the branchname used is as shown.
| | | | 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 |
/* The argument to the "commit" line might match either of these
** patterns:
**
** (A) refs/heads/BRANCHNAME
** (B) refs/tags/TAGNAME
**
** If pattern A is used, then the branchname used is as shown.
** Except, the "master" branch which is the default branch name in Git
** is changed to the default main branch name in Fossil (usually "trunk")
** If the pattern is B, then the new commit should be on the same
** branch as its parent. And, we might need to add the TAGNAME
** tag to the new commit. However, if there are multiple instances
** of pattern B with the same TAGNAME, then only put the tag on the
** last commit that holds that tag.
**
** None of the above is explained in the git-fast-export
|
| ︙ | ︙ | |||
1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 |
/*
** Extract the branch or tag that the given path is on. Return the branch ID.
** Return 0 if not a branch, tag, or trunk, or if ignored by --ignore-tree.
*/
static int svn_parse_path(char *zPath, char **zFile, int *type){
char *zBranch = 0;
int branchId = 0;
if( gsvn.azIgnTree ){
const char **pzIgnTree;
unsigned nPath = strlen(zPath);
for( pzIgnTree = gsvn.azIgnTree; *pzIgnTree; ++pzIgnTree ){
const char *zIgn = *pzIgnTree;
unsigned nIgn = strlen(zIgn);
if( strncmp(zPath, zIgn, nIgn) == 0
&& ( nPath == nIgn || (nPath > nIgn && zPath[nIgn] == '/')) ){
return 0;
}
}
}
*type = SVN_UNKNOWN;
*zFile = 0;
if( gsvn.lenTrunk==0 ){
| > > | | | 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 |
/*
** Extract the branch or tag that the given path is on. Return the branch ID.
** Return 0 if not a branch, tag, or trunk, or if ignored by --ignore-tree.
*/
static int svn_parse_path(char *zPath, char **zFile, int *type){
char *zBranch = 0;
int branchId = 0;
const char *zMainBranch;
if( gsvn.azIgnTree ){
const char **pzIgnTree;
unsigned nPath = strlen(zPath);
for( pzIgnTree = gsvn.azIgnTree; *pzIgnTree; ++pzIgnTree ){
const char *zIgn = *pzIgnTree;
unsigned nIgn = strlen(zIgn);
if( strncmp(zPath, zIgn, nIgn) == 0
&& ( nPath == nIgn || (nPath > nIgn && zPath[nIgn] == '/')) ){
return 0;
}
}
}
*type = SVN_UNKNOWN;
*zFile = 0;
zMainBranch = db_main_branch();
if( gsvn.lenTrunk==0 ){
zBranch = fossil_strdup(zMainBranch);
*zFile = zPath;
*type = SVN_TRUNK;
}else
if( strncmp(zPath, gsvn.zTrunk, gsvn.lenTrunk-1)==0 ){
if( zPath[gsvn.lenTrunk-1]=='/' || zPath[gsvn.lenTrunk-1]==0 ){
zBranch = fossil_strdup(zMainBranch);
*zFile = zPath+gsvn.lenTrunk;
*type = SVN_TRUNK;
}else{
zBranch = 0;
*type = SVN_UNKNOWN;
}
}else{
|
| ︙ | ︙ | |||
1768 1769 1770 1771 1772 1773 1774 |
}else{
*renOpt->varPre = renOpt->zDefaultPre;
*renOpt->varSuf = renOpt->zDefaultSuf;
}
}
}
if( !(gimport.zTrunkName = find_option("rename-trunk", 0, 1)) ){
| | | 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 |
}else{
*renOpt->varPre = renOpt->zDefaultPre;
*renOpt->varSuf = renOpt->zDefaultSuf;
}
}
}
if( !(gimport.zTrunkName = find_option("rename-trunk", 0, 1)) ){
gimport.zTrunkName = fossil_strdup(db_main_branch());
}
if( svnFlag ){
/* Get --svn related options here, so verify_all_options() fails when
* svn-only options are specified with --git
*/
const char *zIgnTree;
|
| ︙ | ︙ |
Changes to src/info.c.
| ︙ | ︙ | |||
934 935 936 937 938 939 940 |
if( rid==0 ){
style_header("Check-in Information Error");
@ No such object: %h(zName)
style_finish_page();
return;
}
zRe = P("regex");
| | | 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 |
if( rid==0 ){
style_header("Check-in Information Error");
@ No such object: %h(zName)
style_finish_page();
return;
}
zRe = P("regex");
if( zRe ) fossil_re_compile(&pRe, zRe, 0);
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
zParent = db_text(0,
"SELECT uuid FROM plink, blob"
" WHERE plink.cid=%d AND blob.rid=plink.pid AND plink.isprim",
rid
);
isLeaf = !db_exists("SELECT 1 FROM plink WHERE pid=%d", rid);
|
| ︙ | ︙ | |||
991 992 993 994 995 996 997 |
@ <div class="accordion_panel">
@ <table class="label-value">
@ <tr><th>Comment:</th><td class="infoComment">\
@ %!W(zEComment?zEComment:zComment)</td></tr>
/* The Download: line */
if( g.perm.Zip ){
| < < < < < < < < < < < < < < < > > > > | | | | | | | < > | 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 |
@ <div class="accordion_panel">
@ <table class="label-value">
@ <tr><th>Comment:</th><td class="infoComment">\
@ %!W(zEComment?zEComment:zComment)</td></tr>
/* The Download: line */
if( g.perm.Zip ){
@ <tr><th>Downloads:</th><td>
if( robot_would_be_restricted("download") ){
@ See separate %z(href("%R/rchvdwnld/%!S",zUuid))download page</a>
}else{
char *zBase = archive_base_name(rid);
@ %z(href("%R/tarball/%s.tar.gz",zBase))Tarball</a>
@ | %z(href("%R/zip/%s.zip",zBase))ZIP archive</a>
if( g.zLogin!=0 ){
@ | %z(href("%R/sqlar/%s.sqlar",zBase))\
@ SQL archive</a></td></tr>
}
fossil_free(zBase);
}
}
@ <tr><th>Timelines:</th><td>
@ %z(href("%R/timeline?f=%!S&unhide",zUuid))family</a>
if( zParent ){
@ | %z(href("%R/timeline?p=%!S&unhide",zUuid))ancestors</a>
}
|
| ︙ | ︙ | |||
1150 1151 1152 1153 1154 1155 1156 1157 1158 |
}else if( zLinks[0] ){
zLinks += 3;
}
@ %s(zLinks)</td></tr>
}
if( g.perm.Hyperlink ){
@ <tr><th>Other Links:</th>
@ <td>
| > | | 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 |
}else if( zLinks[0] ){
zLinks += 3;
}
@ %s(zLinks)</td></tr>
}
if( g.perm.Hyperlink ){
const char *zMainBranch = db_main_branch();
@ <tr><th>Other Links:</th>
@ <td>
if( fossil_strcmp(zBrName, zMainBranch)!=0 ){
@ %z(href("%R/vdiff?branch=%!S", zUuid))branch diff</a> |
}
@ %z(href("%R/artifact/%!S",zUuid))manifest</a>
@ | %z(href("%R/ci_tags/%!S",zUuid))tags</a>
if( g.perm.Admin ){
@ | %z(href("%R/mlink?ci=%!S",zUuid))mlink table</a>
}
|
| ︙ | ︙ | |||
1446 1447 1448 1449 1450 1451 1452 |
if( robot_restrict("diff") ) return;
login_anonymous_available();
fossil_nice_default();
blob_init(&qp, 0, 0);
blob_init(&qpGlob, 0, 0);
diffType = preferred_diff_type();
zRe = P("regex");
| | | 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 |
if( robot_restrict("diff") ) return;
login_anonymous_available();
fossil_nice_default();
blob_init(&qp, 0, 0);
blob_init(&qpGlob, 0, 0);
diffType = preferred_diff_type();
zRe = P("regex");
if( zRe ) fossil_re_compile(&pRe, zRe, 0);
zBranch = P("branch");
if( zBranch && zBranch[0]==0 ) zBranch = 0;
if( zBranch ){
blob_appendf(&qp, "branch=%T", zBranch);
zMergeOrigin = mprintf("merge-in:%s", zBranch);
cgi_replace_parameter("from", zMergeOrigin);
cgi_replace_parameter("to", zBranch);
|
| ︙ | ︙ | |||
1948 1949 1950 1951 1952 1953 1954 |
*/
int preferred_diff_type(void){
int dflt;
int res;
int isBot;
static char zDflt[2]
/*static b/c cookie_link_parameter() does not copy it!*/;
| | | 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 1949 1950 1951 1952 |
*/
int preferred_diff_type(void){
int dflt;
int res;
int isBot;
static char zDflt[2]
/*static b/c cookie_link_parameter() does not copy it!*/;
if( robot_would_be_restricted("diff") ){
dflt = 0;
isBot = 1;
}else{
dflt = db_get_int("preferred-diff-type",-99);
if( dflt<=0 ) dflt = user_agent_is_likely_mobile() ? 1 : 2;
isBot = 0;
}
|
| ︙ | ︙ | |||
2049 2050 2051 2052 2053 2054 2055 |
"%R/annotate?origin=%s&checkin=%s&filename=%T",
zOrig, zCkin, zFN);
}
db_finalize(&q);
}
zRe = P("regex");
cgi_check_for_malice();
| | | 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051 2052 2053 |
"%R/annotate?origin=%s&checkin=%s&filename=%T",
zOrig, zCkin, zFN);
}
db_finalize(&q);
}
zRe = P("regex");
cgi_check_for_malice();
if( zRe ) fossil_re_compile(&pRe, zRe, 0);
if( verbose ) objdescFlags |= OBJDESC_DETAIL;
if( isPatch ){
Blob c1, c2, *pOut;
DiffConfig DCfg;
pOut = cgi_output_blob();
cgi_set_content_type("text/plain");
DCfg.diffFlags = DIFF_VERBOSE;
|
| ︙ | ︙ | |||
3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 |
blob_append(&comment, zNewComment, -1);
zUuid[10] = 0;
style_header("Edit Check-in [%s]", zUuid);
if( P("preview") ){
Blob suffix;
int nTag = 0;
const char *zDplyBr; /* Branch name used to determine BG color */
if( zNewBrFlag[0] && zNewBranch[0] ){
zDplyBr = zNewBranch;
}else{
zDplyBr = zBranchName;
}
@ <b>Preview:</b>
@ <blockquote>
@ <table border=0>
if( zNewColorFlag[0] && zNewColor && zNewColor[0] ){
@ <tr><td style="background-color:%h(reasonable_bg_color(zNewColor,0));">
}else if( zColor[0] ){
@ <tr><td style="background-color:%h(reasonable_bg_color(zColor,0));">
| > | | 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 |
blob_append(&comment, zNewComment, -1);
zUuid[10] = 0;
style_header("Edit Check-in [%s]", zUuid);
if( P("preview") ){
Blob suffix;
int nTag = 0;
const char *zDplyBr; /* Branch name used to determine BG color */
const char *zMainBranch = db_main_branch();
if( zNewBrFlag[0] && zNewBranch[0] ){
zDplyBr = zNewBranch;
}else{
zDplyBr = zBranchName;
}
@ <b>Preview:</b>
@ <blockquote>
@ <table border=0>
if( zNewColorFlag[0] && zNewColor && zNewColor[0] ){
@ <tr><td style="background-color:%h(reasonable_bg_color(zNewColor,0));">
}else if( zColor[0] ){
@ <tr><td style="background-color:%h(reasonable_bg_color(zColor,0));">
}else if( zDplyBr && fossil_strcmp(zDplyBr, zMainBranch)!=0 ){
@ <tr><td style="background-color:%h(hash_color(zDplyBr));">
}else{
@ <tr><td>
}
@ %!W(blob_str(&comment))
blob_zero(&suffix);
blob_appendf(&suffix, "(user: %h", zNewUser);
|
| ︙ | ︙ | |||
3864 3865 3866 3867 3868 3869 3870 |
@ Cancel tag <b>%h(&zTagName[4])</b></label>
}
}
db_finalize(&q);
@ </td></tr>
if( !zBranchName ){
| | | 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 |
@ Cancel tag <b>%h(&zTagName[4])</b></label>
}
}
db_finalize(&q);
@ </td></tr>
if( !zBranchName ){
zBranchName = fossil_strdup(db_main_branch());
}
if( !zNewBranch || !zNewBranch[0]){
zNewBranch = zBranchName;
}
@ <tr><th align="right" valign="top">Branching:</th>
@ <td valign="top">
@ <label><input id="newbr" type="checkbox" name="newbr" \
|
| ︙ | ︙ |
Changes to src/json.c.
| ︙ | ︙ | |||
76 77 78 79 80 81 82 |
/* When running in server/cgi "directory" mode, zPathInfo is
** prefixed with the repository's name, so in order to determine
** whether or not we're really running in json mode we have to try
** a bit harder. Problem reported here:
** https://fossil-scm.org/forum/forumpost/e4953666d6
*/
ReCompiled * pReg = 0;
| | | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
/* When running in server/cgi "directory" mode, zPathInfo is
** prefixed with the repository's name, so in order to determine
** whether or not we're really running in json mode we have to try
** a bit harder. Problem reported here:
** https://fossil-scm.org/forum/forumpost/e4953666d6
*/
ReCompiled * pReg = 0;
const char * zErr = fossil_re_compile(&pReg, "^/[^/]+/json(/.*)?", 0);
assert(zErr==0 && "Regex compilation failed?");
if(zErr==0 &&
re_match(pReg, (const unsigned char *)zPathInfo, -1)){
rc = 2;
}
re_free(pReg);
}
|
| ︙ | ︙ |
Changes to src/json_branch.c.
| ︙ | ︙ | |||
311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
*/
static cson_value * json_branch_create(void){
cson_value * payV = NULL;
cson_object * pay = NULL;
int rc = 0;
BranchCreateOptions opt;
char * zUuid = NULL;
int rid = 0;
if( !g.perm.Write ){
json_set_err(FSL_JSON_E_DENIED,
"Requires 'i' permissions.");
return NULL;
}
memset(&opt,0,sizeof(BranchCreateOptions));
| > | 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 |
*/
static cson_value * json_branch_create(void){
cson_value * payV = NULL;
cson_object * pay = NULL;
int rc = 0;
BranchCreateOptions opt;
char * zUuid = NULL;
const char *zMainBranch = db_main_branch();
int rid = 0;
if( !g.perm.Write ){
json_set_err(FSL_JSON_E_DENIED,
"Requires 'i' permissions.");
return NULL;
}
memset(&opt,0,sizeof(BranchCreateOptions));
|
| ︙ | ︙ | |||
338 339 340 341 342 343 344 |
opt.zColor = json_find_option_cstr("bgColor","bgcolor",NULL);
opt.zBasis = json_find_option_cstr("basis",NULL,NULL);
if(!opt.zBasis && !g.isHTTP){
opt.zBasis = json_command_arg(g.json.dispatchDepth+2);
}
if(!opt.zBasis){
| | | 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 |
opt.zColor = json_find_option_cstr("bgColor","bgcolor",NULL);
opt.zBasis = json_find_option_cstr("basis",NULL,NULL);
if(!opt.zBasis && !g.isHTTP){
opt.zBasis = json_command_arg(g.json.dispatchDepth+2);
}
if(!opt.zBasis){
opt.zBasis = fossil_strdup(zMainBranch);
}
opt.isPrivate = json_find_option_bool("private",NULL,NULL,-1);
if(-1==opt.isPrivate){
if(!g.isHTTP){
opt.isPrivate = (NULL != find_option("private","",0));
}else{
opt.isPrivate = 0;
|
| ︙ | ︙ |
Changes to src/json_login.c.
| ︙ | ︙ | |||
104 105 106 107 108 109 110 |
if( !jseed ){
jseed = json_getenv("cs") /* name used by HTML interface */;
}
}
if(jseed){
if( cson_value_is_number(jseed) ){
sqlite3_snprintf((int)SeedBufLen, seedBuffer, "%"CSON_INT_T_PFMT,
| | | 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
if( !jseed ){
jseed = json_getenv("cs") /* name used by HTML interface */;
}
}
if(jseed){
if( cson_value_is_number(jseed) ){
sqlite3_snprintf((int)SeedBufLen, seedBuffer, "%"CSON_INT_T_PFMT,
cson_value_get_integer(jseed));
anonSeed = seedBuffer;
}else if( cson_value_is_string(jseed) ){
anonSeed = cson_string_cstr(cson_value_get_string(jseed));
}
}
if(!anonSeed){
g.json.resultCode = preciseErrors
|
| ︙ | ︙ |
Changes to src/json_status.c.
| ︙ | ︙ | |||
93 94 95 96 97 98 99 |
/* Now get the list of non-pristine files... */
aFiles = cson_new_array();
cson_object_set( oPay, "files", cson_array_value( aFiles ) );
db_prepare(&q,
"SELECT pathname, deleted, chnged, rid, "
| | > | | < | | | < < < < | | | | > > > > > > > > > > | 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 151 152 153 |
/* Now get the list of non-pristine files... */
aFiles = cson_new_array();
cson_object_set( oPay, "files", cson_array_value( aFiles ) );
db_prepare(&q,
"SELECT pathname, deleted, chnged, rid, "
" coalesce(origname!=pathname,0) AS renamed,"
" origname"
" FROM vfile "
" WHERE is_selected(id)"
" AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1"
);
while( db_step(&q)==SQLITE_ROW ){
cson_array *aStatuses = NULL;
const char *zPathname = db_column_text(&q,0);
int isDeleted = db_column_int(&q, 1);
int isChnged = db_column_int(&q,2);
int isNew = db_column_int(&q,3)==0;
int isRenamed = db_column_int(&q,4);
cson_object * oFile;
char const * zStatus = "unmodified";
char * zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
if( isDeleted ){
zStatus = "deleted";
}else if( isNew ){
zStatus = "new" /* maintenance reminder: MUST come
BEFORE the isChnged checks. */;
}else if( !file_isfile_or_link(zFullName) ){
if( file_access(zFullName, F_OK)==0 ){
zStatus = "notAFile";
++nErr;
}else{
zStatus = "missing";
++nErr;
}
}else if( isChnged ){
switch( isChnged ){
/* These numbers from from checkin.c: status_report() */
case 1:
if( file_contains_merge_marker(zFullName) ){
zStatus = "conflict";
}else{
zStatus = "edited";
}
break;
case 2: zStatus = "updatedByMerge"; break;
case 3: zStatus = "addedByMerge"; break;
case 4: zStatus = "updatedByIntegrate"; break;
case 5: zStatus = "addedByIntegrate"; break;
case 6: zStatus = "+exec"; break;
case 7: zStatus = "+symlink"; break;
case 8: zStatus = "-exec"; break;
case 9: zStatus = "unlink"; break;
}
}
oFile = cson_new_object();
cson_array_append( aFiles, cson_object_value(oFile) );
if( isRenamed ){
if( *zStatus!='?' ){
aStatuses = cson_new_array();
|
| ︙ | ︙ |
Changes to src/leaf.c.
| ︙ | ︙ | |||
224 225 226 227 228 229 230 231 232 233 |
** leaves on that branch.
*/
int leaf_ambiguity_warning(int rid, int currentCkout){
char *zBr;
Stmt q;
int n = 0;
Blob msg;
if( leaf_ambiguity(rid)==0 ) return 0;
zBr = db_text(0, "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
TAG_BRANCH, rid);
| > > | | 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
** leaves on that branch.
*/
int leaf_ambiguity_warning(int rid, int currentCkout){
char *zBr;
Stmt q;
int n = 0;
Blob msg;
const char *zMainBranch;
if( leaf_ambiguity(rid)==0 ) return 0;
zMainBranch = db_main_branch();
zBr = db_text(0, "SELECT value FROM tagxref WHERE tagid=%d AND rid=%d",
TAG_BRANCH, rid);
if( zBr==0 ) zBr = fossil_strdup(zMainBranch);
blob_init(&msg, 0, 0);
blob_appendf(&msg, "WARNING: multiple open leaf check-ins on %s:", zBr);
db_prepare(&q,
"SELECT"
" (SELECT uuid FROM blob WHERE rid=leaf.rid),"
" (SELECT datetime(mtime,toLocal()) FROM event WHERE objid=leaf.rid),"
" leaf.rid"
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
** "th_tcl.c".
*/
struct TclContext {
int argc; /* Number of original (expanded) arguments. */
char **argv; /* Full copy of the original (expanded) arguments. */
void *hLibrary; /* The Tcl library module handle. */
void *xFindExecutable; /* See tcl_FindExecutableProc in th_tcl.c. */
void *xCreateInterp; /* See tcl_CreateInterpProc in th_tcl.c. */
void *xDeleteInterp; /* See tcl_DeleteInterpProc in th_tcl.c. */
void *xFinalize; /* See tcl_FinalizeProc in th_tcl.c. */
Tcl_Interp *interp; /* The on-demand created Tcl interpreter. */
int useObjProc; /* Non-zero if an objProc can be called directly. */
int useTip285; /* Non-zero if TIP #285 is available. */
char *setup; /* The optional Tcl setup script. */
| > > > | 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 |
** "th_tcl.c".
*/
struct TclContext {
int argc; /* Number of original (expanded) arguments. */
char **argv; /* Full copy of the original (expanded) arguments. */
void *hLibrary; /* The Tcl library module handle. */
void *xFindExecutable; /* See tcl_FindExecutableProc in th_tcl.c. */
#if TCL_MAJOR_VERSION>=9
void *xZipfsAppHook; /* See TclZipfsAppHookProc in th_tcl.c. */
#endif
void *xCreateInterp; /* See tcl_CreateInterpProc in th_tcl.c. */
void *xDeleteInterp; /* See tcl_DeleteInterpProc in th_tcl.c. */
void *xFinalize; /* See tcl_FinalizeProc in th_tcl.c. */
Tcl_Interp *interp; /* The on-demand created Tcl interpreter. */
int useObjProc; /* Non-zero if an objProc can be called directly. */
int useTip285; /* Non-zero if TIP #285 is available. */
char *setup; /* The optional Tcl setup script. */
|
| ︙ | ︙ | |||
898 899 900 901 902 903 904 |
if( find_option("localtime",0,0) ) g.fTimeFormat = 2;
if( zChdir && file_chdir(zChdir, 0) ){
fossil_fatal("unable to change directories to %s", zChdir);
}
#if USE_SEE
db_maybe_handle_saved_encryption_key_for_process(SEE_KEY_READ);
#endif
| | | 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 |
if( find_option("localtime",0,0) ) g.fTimeFormat = 2;
if( zChdir && file_chdir(zChdir, 0) ){
fossil_fatal("unable to change directories to %s", zChdir);
}
#if USE_SEE
db_maybe_handle_saved_encryption_key_for_process(SEE_KEY_READ);
#endif
if( find_option("help","?",0)!=0 ){
/* If --help is found anywhere on the command line, translate the command
* to "fossil help cmdname" where "cmdname" is the first argument that
* does not begin with a "-" character. If all arguments start with "-",
* translate to "fossil help argv[1] argv[2]...". */
int i, nNewArgc;
char **zNewArgv = fossil_malloc( sizeof(char*)*(g.argc+3) );
zNewArgv[0] = g.argv[0];
|
| ︙ | ︙ | |||
2487 2488 2489 2490 2491 2492 2493 | ** REPO for a check-in or ticket that matches the ** value of "name", then redirect to URL. There ** can be multiple "redirect:" lines that are ** processed in order. If the REPO is "*", then ** an unconditional redirect to URL is taken. ** When "*" is used a 301 permanent redirect is ** issued and the tail and query string from the | | | 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 | ** REPO for a check-in or ticket that matches the ** value of "name", then redirect to URL. There ** can be multiple "redirect:" lines that are ** processed in order. If the REPO is "*", then ** an unconditional redirect to URL is taken. ** When "*" is used a 301 permanent redirect is ** issued and the tail and query string from the ** original query are appended onto URL. ** ** jsmode: VALUE Specifies the delivery mode for JavaScript ** files. See the help text for the --jsmode ** flag of the http command. ** ** mainmenu: FILE Override the mainmenu config setting with the ** contents of the given file. |
| ︙ | ︙ | |||
3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 |
** using this command interactively over SSH. A better solution would be
** to use a different command for "ssh" sync, but we cannot do that without
** breaking legacy.
**
** Options:
** --csrf-safe N Set cgi_csrf_safe() to to return N
** --nobody Pretend to be user "nobody"
** --test Do not do special "sync" processing when operating
** over an SSH link
** --th-trace Trace TH1 execution (for debugging purposes)
** --usercap CAP User capability string (Default: "sxy")
*/
void cmd_test_http(void){
const char *zIpAddr; /* IP address of remote client */
const char *zUserCap;
int bTest = 0;
const char *zCsrfSafe = find_option("csrf-safe",0,1);
Th_InitTraceLog();
if( zCsrfSafe ) g.okCsrf = atoi(zCsrfSafe);
zUserCap = find_option("usercap",0,1);
if( !find_option("nobody",0,0) ){
if( zUserCap==0 ){
g.useLocalauth = 1;
zUserCap = "sxy";
| > > > > | 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 |
** using this command interactively over SSH. A better solution would be
** to use a different command for "ssh" sync, but we cannot do that without
** breaking legacy.
**
** Options:
** --csrf-safe N Set cgi_csrf_safe() to to return N
** --nobody Pretend to be user "nobody"
** --ssh-sim Pretend to be over an SSH connection
** --test Do not do special "sync" processing when operating
** over an SSH link
** --th-trace Trace TH1 execution (for debugging purposes)
** --usercap CAP User capability string (Default: "sxy")
*/
void cmd_test_http(void){
const char *zIpAddr; /* IP address of remote client */
const char *zUserCap;
int bTest = 0;
const char *zCsrfSafe = find_option("csrf-safe",0,1);
if( find_option("ssh-sim",0,0)!=0 ){
putenv("SSH_CONNECTION=127.0.0.1 12345 127.0.0.2 23456");
}
Th_InitTraceLog();
if( zCsrfSafe ) g.okCsrf = atoi(zCsrfSafe);
zUserCap = find_option("usercap",0,1);
if( !find_option("nobody",0,0) ){
if( zUserCap==0 ){
g.useLocalauth = 1;
zUserCap = "sxy";
|
| ︙ | ︙ |
Changes to src/main.mk.
| ︙ | ︙ | |||
160 161 162 163 164 165 166 167 168 169 170 171 172 173 | $(SRCDIR)/vfile.c \ $(SRCDIR)/wiki.c \ $(SRCDIR)/wikiformat.c \ $(SRCDIR)/winfile.c \ $(SRCDIR)/winhttp.c \ $(SRCDIR)/xfer.c \ $(SRCDIR)/xfersetup.c \ $(SRCDIR)/zip.c EXTRA_FILES = \ $(SRCDIR)/../extsrc/pikchr-worker.js \ $(SRCDIR)/../extsrc/pikchr.js \ $(SRCDIR)/../extsrc/pikchr.wasm \ $(SRCDIR)/../skins/ardoise/css.txt \ | > | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | $(SRCDIR)/vfile.c \ $(SRCDIR)/wiki.c \ $(SRCDIR)/wikiformat.c \ $(SRCDIR)/winfile.c \ $(SRCDIR)/winhttp.c \ $(SRCDIR)/xfer.c \ $(SRCDIR)/xfersetup.c \ $(SRCDIR)/xsystem.c \ $(SRCDIR)/zip.c EXTRA_FILES = \ $(SRCDIR)/../extsrc/pikchr-worker.js \ $(SRCDIR)/../extsrc/pikchr.js \ $(SRCDIR)/../extsrc/pikchr.wasm \ $(SRCDIR)/../skins/ardoise/css.txt \ |
| ︙ | ︙ | |||
235 236 237 238 239 240 241 242 243 244 245 246 247 248 | $(SRCDIR)/fossil.numbered-lines.js \ $(SRCDIR)/fossil.page.brlist.js \ $(SRCDIR)/fossil.page.chat.js \ $(SRCDIR)/fossil.page.fileedit.js \ $(SRCDIR)/fossil.page.forumpost.js \ $(SRCDIR)/fossil.page.pikchrshow.js \ $(SRCDIR)/fossil.page.pikchrshowasm.js \ $(SRCDIR)/fossil.page.whistory.js \ $(SRCDIR)/fossil.page.wikiedit.js \ $(SRCDIR)/fossil.pikchr.js \ $(SRCDIR)/fossil.popupwidget.js \ $(SRCDIR)/fossil.storage.js \ $(SRCDIR)/fossil.tabs.js \ $(SRCDIR)/fossil.wikiedit-wysiwyg.js \ | > | 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 | $(SRCDIR)/fossil.numbered-lines.js \ $(SRCDIR)/fossil.page.brlist.js \ $(SRCDIR)/fossil.page.chat.js \ $(SRCDIR)/fossil.page.fileedit.js \ $(SRCDIR)/fossil.page.forumpost.js \ $(SRCDIR)/fossil.page.pikchrshow.js \ $(SRCDIR)/fossil.page.pikchrshowasm.js \ $(SRCDIR)/fossil.page.ticket.js \ $(SRCDIR)/fossil.page.whistory.js \ $(SRCDIR)/fossil.page.wikiedit.js \ $(SRCDIR)/fossil.pikchr.js \ $(SRCDIR)/fossil.popupwidget.js \ $(SRCDIR)/fossil.storage.js \ $(SRCDIR)/fossil.tabs.js \ $(SRCDIR)/fossil.wikiedit-wysiwyg.js \ |
| ︙ | ︙ | |||
427 428 429 430 431 432 433 434 435 436 437 438 439 440 | $(OBJDIR)/vfile_.c \ $(OBJDIR)/wiki_.c \ $(OBJDIR)/wikiformat_.c \ $(OBJDIR)/winfile_.c \ $(OBJDIR)/winhttp_.c \ $(OBJDIR)/xfer_.c \ $(OBJDIR)/xfersetup_.c \ $(OBJDIR)/zip_.c OBJ = \ $(OBJDIR)/add.o \ $(OBJDIR)/ajax.o \ $(OBJDIR)/alerts.o \ $(OBJDIR)/allrepo.o \ | > | 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | $(OBJDIR)/vfile_.c \ $(OBJDIR)/wiki_.c \ $(OBJDIR)/wikiformat_.c \ $(OBJDIR)/winfile_.c \ $(OBJDIR)/winhttp_.c \ $(OBJDIR)/xfer_.c \ $(OBJDIR)/xfersetup_.c \ $(OBJDIR)/xsystem_.c \ $(OBJDIR)/zip_.c OBJ = \ $(OBJDIR)/add.o \ $(OBJDIR)/ajax.o \ $(OBJDIR)/alerts.o \ $(OBJDIR)/allrepo.o \ |
| ︙ | ︙ | |||
578 579 580 581 582 583 584 585 586 587 588 589 590 591 | $(OBJDIR)/vfile.o \ $(OBJDIR)/wiki.o \ $(OBJDIR)/wikiformat.o \ $(OBJDIR)/winfile.o \ $(OBJDIR)/winhttp.o \ $(OBJDIR)/xfer.o \ $(OBJDIR)/xfersetup.o \ $(OBJDIR)/zip.o all: $(APPNAME) install: all mkdir -p $(INSTALLDIR) cp $(APPNAME) $(INSTALLDIR) | > | 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 | $(OBJDIR)/vfile.o \ $(OBJDIR)/wiki.o \ $(OBJDIR)/wikiformat.o \ $(OBJDIR)/winfile.o \ $(OBJDIR)/winhttp.o \ $(OBJDIR)/xfer.o \ $(OBJDIR)/xfersetup.o \ $(OBJDIR)/xsystem.o \ $(OBJDIR)/zip.o all: $(APPNAME) install: all mkdir -p $(INSTALLDIR) cp $(APPNAME) $(INSTALLDIR) |
| ︙ | ︙ | |||
922 923 924 925 926 927 928 929 930 931 932 933 934 935 | $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h \ $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \ $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \ $(OBJDIR)/winfile_.c:$(OBJDIR)/winfile.h \ $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \ $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h \ $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h \ $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h \ $(SRCDIR_extsrc)/pikchr.c:$(OBJDIR)/pikchr.h \ $(SRCDIR_extsrc)/sqlite3.h \ $(SRCDIR)/th.h \ $(OBJDIR)/VERSION.h touch $(OBJDIR)/headers $(OBJDIR)/headers: Makefile | > | 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 | $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h \ $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \ $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \ $(OBJDIR)/winfile_.c:$(OBJDIR)/winfile.h \ $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \ $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h \ $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h \ $(OBJDIR)/xsystem_.c:$(OBJDIR)/xsystem.h \ $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h \ $(SRCDIR_extsrc)/pikchr.c:$(OBJDIR)/pikchr.h \ $(SRCDIR_extsrc)/sqlite3.h \ $(SRCDIR)/th.h \ $(OBJDIR)/VERSION.h touch $(OBJDIR)/headers $(OBJDIR)/headers: Makefile |
| ︙ | ︙ | |||
2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 | $(OBJDIR)/xfersetup_.c: $(SRCDIR)/xfersetup.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/xfersetup.c >$@ $(OBJDIR)/xfersetup.o: $(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/xfersetup.o -c $(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h: $(OBJDIR)/headers $(OBJDIR)/zip_.c: $(SRCDIR)/zip.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/zip.c >$@ $(OBJDIR)/zip.o: $(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c | > > > > > > > > | 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 | $(OBJDIR)/xfersetup_.c: $(SRCDIR)/xfersetup.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/xfersetup.c >$@ $(OBJDIR)/xfersetup.o: $(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/xfersetup.o -c $(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h: $(OBJDIR)/headers $(OBJDIR)/xsystem_.c: $(SRCDIR)/xsystem.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/xsystem.c >$@ $(OBJDIR)/xsystem.o: $(OBJDIR)/xsystem_.c $(OBJDIR)/xsystem.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/xsystem.o -c $(OBJDIR)/xsystem_.c $(OBJDIR)/xsystem.h: $(OBJDIR)/headers $(OBJDIR)/zip_.c: $(SRCDIR)/zip.c $(OBJDIR)/translate $(OBJDIR)/translate $(SRCDIR)/zip.c >$@ $(OBJDIR)/zip.o: $(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c |
| ︙ | ︙ |
Changes to src/markdown.md.
| ︙ | ︙ | |||
186 187 188 189 190 191 192 | > Both a footnote's text and a fragment to which a footnote applies > are subject to further interpretation as Markdown sources. ## Miscellaneous ## > * In-line images are made using **\!\[alt-text\]\(image-URL\)**. > * Use HTML for advanced formatting such as forms, noting that certain | | | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 | > Both a footnote's text and a fragment to which a footnote applies > are subject to further interpretation as Markdown sources. ## Miscellaneous ## > * In-line images are made using **\!\[alt-text\]\(image-URL\)**. > * Use HTML for advanced formatting such as forms, noting that certain > tags are [disallowed in some contexts](/help/safe-html). > * **\<!--** HTML-style comments **-->** are supported. > * Escape special characters (ex: **\[** **\(** **\|** **\***) > using backslash (ex: **\\\[** **\\\(** **\\\|** **\\\***). > * A line consisting of **---**, **\*\*\***, or **\_\_\_** is a horizontal > rule. Spaces and extra **-**/**\***/**_** are allowed. > * Paragraphs enclosed in **\<html\>...\</html\>** is passed through unchanged. > * See [daringfireball.net][] for additional information. |
| ︙ | ︙ |
Changes to src/match.c.
| ︙ | ︙ | |||
140 141 142 143 144 145 146 |
zOne = fossil_strndup(zPat, i);
zPat += i;
if( zPat[0] ) zPat++;
/* Check for regular expression syntax errors. */
if( style==MS_REGEXP ){
ReCompiled *regexp;
| | | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
zOne = fossil_strndup(zPat, i);
zPat += i;
if( zPat[0] ) zPat++;
/* Check for regular expression syntax errors. */
if( style==MS_REGEXP ){
ReCompiled *regexp;
const char *zFail = fossil_re_compile(®exp, zOne, 0);
if( zFail ){
re_free(regexp);
continue;
}
p->nPattern++;
p->aRe = fossil_realloc(p->aRe, sizeof(p->aRe)*p->nPattern);
p->aRe[p->nPattern-1] = regexp;
|
| ︙ | ︙ | |||
373 374 375 376 377 378 379 |
}
}
/* Check for regular expression syntax errors. */
if( matchStyle==MS_REGEXP ){
ReCompiled *regexp;
char *zTagDup = fossil_strndup(zTag, i);
| | | 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 |
}
}
/* Check for regular expression syntax errors. */
if( matchStyle==MS_REGEXP ){
ReCompiled *regexp;
char *zTagDup = fossil_strndup(zTag, i);
zFail = fossil_re_compile(®exp, zTagDup, 0);
re_free(regexp);
fossil_free(zTagDup);
}
/* Process success and error results. */
if( !zFail ){
/* Incorporate the match word into the output expression. %q is used to
|
| ︙ | ︙ |
Changes to src/path.c.
| ︙ | ︙ | |||
190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
PathNode *p;
path_reset();
path.brCost = branchCost;
path.pStart = path_new_node(iFrom, 0, 0);
if( iTo==iFrom ){
path.pEnd = path.pStart;
return path.pStart;
}
if( oneWayOnly && directOnly ){
db_prepare(&s,
"SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim"
);
}else if( oneWayOnly ){
| > | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
PathNode *p;
path_reset();
path.brCost = branchCost;
path.pStart = path_new_node(iFrom, 0, 0);
if( iTo==iFrom ){
path.pEnd = path.pStart;
path.pEnd->u.pTo = 0;
return path.pStart;
}
if( oneWayOnly && directOnly ){
db_prepare(&s,
"SELECT cid, 1 FROM plink WHERE pid=:pid AND isprim"
);
}else if( oneWayOnly ){
|
| ︙ | ︙ |
Changes to src/printf.c.
| ︙ | ︙ | |||
250 251 252 253 254 255 256 | ** complete input text, not just the display text. No other formatting ** is done. */ /* ** SETTING: timeline-hard-newlines boolean default=off ** ** If enabled, the timeline honors newline characters in check-in comments. | | | 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 | ** complete input text, not just the display text. No other formatting ** is done. */ /* ** SETTING: timeline-hard-newlines boolean default=off ** ** If enabled, the timeline honors newline characters in check-in comments. ** In other words, newlines are converted into <br> for HTML display. ** The default behavior, when this setting is off, is that newlines are ** treated like any other whitespace character. */ /* ** Return an appropriate set of flags for wiki_convert() for displaying ** comments on a timeline. These flag settings are determined by |
| ︙ | ︙ |
Changes to src/rebuild.c.
| ︙ | ︙ | |||
349 350 351 352 353 354 355 |
}
/*
** Check to see if the "sym-trunk" tag exists. If not, create it
** and attach it to the very first check-in.
*/
static void rebuild_tag_trunk(void){
| > | | | | 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 |
}
/*
** Check to see if the "sym-trunk" tag exists. If not, create it
** and attach it to the very first check-in.
*/
static void rebuild_tag_trunk(void){
const char *zMainBranch = db_main_branch();
int tagid = db_int(0, "SELECT 1 FROM tag WHERE tagname='sym-%q'",zMainBranch);
int rid;
char *zUuid;
if( tagid>0 ) return;
rid = db_int(0, "SELECT pid FROM plink AS x WHERE NOT EXISTS("
" SELECT 1 FROM plink WHERE cid=x.pid)");
if( rid==0 ) return;
/* Add the trunk tag to the root of the whole tree */
zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
if( zUuid==0 ) return;
tag_add_artifact("sym-", zMainBranch, zUuid, 0, 2, 0, 0);
tag_add_artifact("", "branch", zUuid, zMainBranch, 2, 0, 0);
}
/*
** Core function to rebuild the information in the derived tables of a
** fossil repository from the blobs. This function is shared between
** 'rebuild_database' ('rebuild') and 'reconstruct_cmd'
** ('reconstruct'), both of which have to regenerate this information
|
| ︙ | ︙ |
Changes to src/regexp.c.
| ︙ | ︙ | |||
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
** A nondeterministic finite automaton (NFA) is used for matching, so the
** performance is bounded by O(N*M) where N is the size of the regular
** expression and M is the size of the input string. The matcher never
** exhibits exponential behavior. Note that the X{p,q} operator expands
** to p copies of X following by q-p copies of X? and that the size of the
** regular expression in the O(N*M) performance bound is computed after
** this expansion.
*/
#include "config.h"
#include "regexp.h"
/* The end-of-input character */
#define RE_EOF 0 /* End of input */
/* The NFA is implemented as sequence of opcodes taken from the following
** set. Each opcode has a single integer argument.
*/
#define RE_OP_MATCH 1 /* Match the one character in the argument */
#define RE_OP_ANY 2 /* Match any one character. (Implements ".") */
#define RE_OP_ANYSTAR 3 /* Special optimized version of .* */
| > > > | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
** A nondeterministic finite automaton (NFA) is used for matching, so the
** performance is bounded by O(N*M) where N is the size of the regular
** expression and M is the size of the input string. The matcher never
** exhibits exponential behavior. Note that the X{p,q} operator expands
** to p copies of X following by q-p copies of X? and that the size of the
** regular expression in the O(N*M) performance bound is computed after
** this expansion.
**
** To help prevent DoS attacks, the maximum size of the NFA is restricted.
*/
#include "config.h"
#include "regexp.h"
/* The end-of-input character */
#define RE_EOF 0 /* End of input */
#define RE_START 0xfffffff /* Start of input - larger than an UTF-8 */
/* The NFA is implemented as sequence of opcodes taken from the following
** set. Each opcode has a single integer argument.
*/
#define RE_OP_MATCH 1 /* Match the one character in the argument */
#define RE_OP_ANY 2 /* Match any one character. (Implements ".") */
#define RE_OP_ANYSTAR 3 /* Special optimized version of .* */
|
| ︙ | ︙ | |||
78 79 80 81 82 83 84 85 86 87 88 89 90 91 | #define RE_OP_WORD 11 /* Perl word character [A-Za-z0-9_] */ #define RE_OP_NOTWORD 12 /* Not a perl word character */ #define RE_OP_DIGIT 13 /* digit: [0-9] */ #define RE_OP_NOTDIGIT 14 /* Not a digit */ #define RE_OP_SPACE 15 /* space: [ \t\n\r\v\f] */ #define RE_OP_NOTSPACE 16 /* Not a digit */ #define RE_OP_BOUNDARY 17 /* Boundary between word and non-word */ /* Each opcode is a "state" in the NFA */ typedef unsigned short ReStateNumber; /* Because this is an NFA and not a DFA, multiple states can be active at ** once. An instance of the following object records all active states in ** the NFA. The implementation is optimized for the common case where the | > | 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | #define RE_OP_WORD 11 /* Perl word character [A-Za-z0-9_] */ #define RE_OP_NOTWORD 12 /* Not a perl word character */ #define RE_OP_DIGIT 13 /* digit: [0-9] */ #define RE_OP_NOTDIGIT 14 /* Not a digit */ #define RE_OP_SPACE 15 /* space: [ \t\n\r\v\f] */ #define RE_OP_NOTSPACE 16 /* Not a digit */ #define RE_OP_BOUNDARY 17 /* Boundary between word and non-word */ #define RE_OP_ATSTART 18 /* Currently at the start of the string */ /* Each opcode is a "state" in the NFA */ typedef unsigned short ReStateNumber; /* Because this is an NFA and not a DFA, multiple states can be active at ** once. An instance of the following object records all active states in ** the NFA. The implementation is optimized for the common case where the |
| ︙ | ︙ | |||
111 112 113 114 115 116 117 |
struct ReCompiled {
ReInput sIn; /* Regular expression text */
const char *zErr; /* Error message to return */
char *aOp; /* Operators for the virtual machine */
int *aArg; /* Arguments to each operator */
unsigned (*xNextChar)(ReInput*); /* Next character function */
unsigned char zInit[12]; /* Initial text to match */
| | > | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
struct ReCompiled {
ReInput sIn; /* Regular expression text */
const char *zErr; /* Error message to return */
char *aOp; /* Operators for the virtual machine */
int *aArg; /* Arguments to each operator */
unsigned (*xNextChar)(ReInput*); /* Next character function */
unsigned char zInit[12]; /* Initial text to match */
int nInit; /* Number of bytes in zInit */
unsigned nState; /* Number of entries in aOp[] and aArg[] */
unsigned nAlloc; /* Slots allocated for aOp[] and aArg[] */
unsigned mxAlloc; /* Complexity limit */
};
#endif
/* Add a state to the given state set if it is not already there */
static void re_add_state(ReStateSet *pSet, int newState){
unsigned i;
for(i=0; i<pSet->nState; i++) if( pSet->aState[i]==newState ) return;
|
| ︙ | ︙ | |||
142 143 144 145 146 147 148 |
c = (c&0x1f)<<6 | (p->z[p->i++]&0x3f);
if( c<0x80 ) c = 0xfffd;
}else if( (c&0xf0)==0xe0 && p->i+1<p->mx && (p->z[p->i]&0xc0)==0x80
&& (p->z[p->i+1]&0xc0)==0x80 ){
c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f);
p->i += 2;
if( c<=0x7ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
| | | 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 |
c = (c&0x1f)<<6 | (p->z[p->i++]&0x3f);
if( c<0x80 ) c = 0xfffd;
}else if( (c&0xf0)==0xe0 && p->i+1<p->mx && (p->z[p->i]&0xc0)==0x80
&& (p->z[p->i+1]&0xc0)==0x80 ){
c = (c&0x0f)<<12 | ((p->z[p->i]&0x3f)<<6) | (p->z[p->i+1]&0x3f);
p->i += 2;
if( c<=0x7ff || (c>=0xd800 && c<=0xdfff) ) c = 0xfffd;
}else if( (c&0xf8)==0xf0 && p->i+2<p->mx && (p->z[p->i]&0xc0)==0x80
&& (p->z[p->i+1]&0xc0)==0x80 && (p->z[p->i+2]&0xc0)==0x80 ){
c = (c&0x07)<<18 | ((p->z[p->i]&0x3f)<<12) | ((p->z[p->i+1]&0x3f)<<6)
| (p->z[p->i+2]&0x3f);
p->i += 3;
if( c<=0xffff || c>0x10ffff ) c = 0xfffd;
}else{
c = 0xfffd;
|
| ︙ | ︙ | |||
183 184 185 186 187 188 189 |
*/
int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
ReStateSet aStateSet[2], *pThis, *pNext;
ReStateNumber aSpace[100];
ReStateNumber *pToFree;
unsigned int i = 0;
unsigned int iSwap = 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 |
*/
int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
ReStateSet aStateSet[2], *pThis, *pNext;
ReStateNumber aSpace[100];
ReStateNumber *pToFree;
unsigned int i = 0;
unsigned int iSwap = 0;
int c = RE_START;
int cPrev = 0;
int rc = 0;
ReInput in;
in.z = zIn;
in.i = 0;
in.mx = nIn>=0 ? nIn : (int)strlen((char const*)zIn);
/* Look for the initial prefix match, if there is one. */
if( pRe->nInit ){
unsigned char x = pRe->zInit[0];
while( in.i+pRe->nInit<=in.mx
&& (zIn[in.i]!=x ||
strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0)
){
in.i++;
}
if( in.i+pRe->nInit>in.mx ) return 0;
c = RE_START-1;
}
if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
pToFree = 0;
aStateSet[0].aState = aSpace;
}else{
pToFree = fossil_malloc( sizeof(ReStateNumber)*2*pRe->nState );
|
| ︙ | ︙ | |||
229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
pNext->nState = 0;
for(i=0; i<pThis->nState; i++){
int x = pThis->aState[i];
switch( pRe->aOp[x] ){
case RE_OP_MATCH: {
if( pRe->aArg[x]==c ) re_add_state(pNext, x+1);
break;
}
case RE_OP_ANY: {
if( c!=0 ) re_add_state(pNext, x+1);
break;
}
case RE_OP_WORD: {
if( re_word_char(c) ) re_add_state(pNext, x+1);
| > > > > | 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 |
pNext->nState = 0;
for(i=0; i<pThis->nState; i++){
int x = pThis->aState[i];
switch( pRe->aOp[x] ){
case RE_OP_MATCH: {
if( pRe->aArg[x]==c ) re_add_state(pNext, x+1);
break;
}
case RE_OP_ATSTART: {
if( cPrev==RE_START ) re_add_state(pThis, x+1);
break;
}
case RE_OP_ANY: {
if( c!=0 ) re_add_state(pNext, x+1);
break;
}
case RE_OP_WORD: {
if( re_word_char(c) ) re_add_state(pNext, x+1);
|
| ︙ | ︙ | |||
282 283 284 285 286 287 288 |
}
case RE_OP_ACCEPT: {
rc = 1;
goto re_match_end;
}
case RE_OP_CC_EXC: {
if( c==0 ) break;
| | | | 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
}
case RE_OP_ACCEPT: {
rc = 1;
goto re_match_end;
}
case RE_OP_CC_EXC: {
if( c==0 ) break;
/* fall-through */ goto re_op_cc_inc;
}
case RE_OP_CC_INC: re_op_cc_inc: {
int j = 1;
int n = pRe->aArg[x];
int hit = 0;
for(j=1; j>0 && j<n; j++){
if( pRe->aOp[x+j]==RE_OP_CC_VALUE ){
if( pRe->aArg[x+j]==c ){
hit = 1;
|
| ︙ | ︙ | |||
311 312 313 314 315 316 317 |
if( hit ) re_add_state(pNext, x+n);
break;
}
}
}
}
for(i=0; i<pNext->nState; i++){
| > > | > | | | 321 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 349 350 351 352 353 354 |
if( hit ) re_add_state(pNext, x+n);
break;
}
}
}
}
for(i=0; i<pNext->nState; i++){
int x = pNext->aState[i];
while( pRe->aOp[x]==RE_OP_GOTO ) x += pRe->aArg[x];
if( pRe->aOp[x]==RE_OP_ACCEPT ){ rc = 1; break; }
}
re_match_end:
fossil_free(pToFree);
return rc;
}
/* Resize the opcode and argument arrays for an RE under construction.
*/
static int re_resize(ReCompiled *p, int N){
char *aOp;
int *aArg;
if( N>p->mxAlloc ){ p->zErr = "REGEXP pattern too big"; return 1; }
aOp = fossil_realloc(p->aOp, N*sizeof(p->aOp[0]));
if( aOp==0 ){ p->zErr = "out of memory"; return 1; }
p->aOp = aOp;
aArg = fossil_realloc(p->aArg, N*sizeof(p->aArg[0]));
if( aArg==0 ){ p->zErr = "out of memory"; return 1; }
p->aArg = aArg;
p->nAlloc = N;
return 0;
}
/* Insert a new opcode and argument into an RE under construction. The
** insertion point is just prior to existing opcode iBefore.
|
| ︙ | ︙ | |||
466 467 468 469 470 471 472 |
int iStart;
unsigned c;
const char *zErr;
while( (c = p->xNextChar(&p->sIn))!=0 ){
iStart = p->nState;
switch( c ){
case '|':
| < | 479 480 481 482 483 484 485 486 487 488 489 490 491 492 |
int iStart;
unsigned c;
const char *zErr;
while( (c = p->xNextChar(&p->sIn))!=0 ){
iStart = p->nState;
switch( c ){
case '|':
case ')': {
p->sIn.i--;
return 0;
}
case '(': {
zErr = re_subcompile_re(p);
if( zErr ) return zErr;
|
| ︙ | ︙ | |||
502 503 504 505 506 507 508 509 510 |
re_append(p, RE_OP_FORK, iPrev - p->nState);
break;
}
case '?': {
if( iPrev<0 ) return "'?' without operand";
re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1);
break;
}
case '{': {
| > > > > > > > > | | | > > > > | > > > | > | > | | | 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 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 567 568 569 570 571 572 573 574 575 576 577 578 |
re_append(p, RE_OP_FORK, iPrev - p->nState);
break;
}
case '?': {
if( iPrev<0 ) return "'?' without operand";
re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1);
break;
}
case '$': {
re_append(p, RE_OP_MATCH, RE_EOF);
break;
}
case '^': {
re_append(p, RE_OP_ATSTART, 0);
break;
}
case '{': {
unsigned int m = 0, n = 0;
unsigned int sz, j;
if( iPrev<0 ) return "'{m,n}' without operand";
while( (c=rePeek(p))>='0' && c<='9' ){
m = m*10 + c - '0';
if( m*2>p->mxAlloc ) return "REGEXP pattern too big";
p->sIn.i++;
}
n = m;
if( c==',' ){
p->sIn.i++;
n = 0;
while( (c=rePeek(p))>='0' && c<='9' ){
n = n*10 + c-'0';
if( n*2>p->mxAlloc ) return "REGEXP pattern too big";
p->sIn.i++;
}
}
if( c!='}' ) return "unmatched '{'";
if( n<m ) return "n less than m in '{m,n}'";
p->sIn.i++;
sz = p->nState - iPrev;
if( m==0 ){
if( n==0 ) return "both m and n are zero in '{m,n}'";
re_insert(p, iPrev, RE_OP_FORK, sz+1);
iPrev++;
n--;
}else{
for(j=1; j<m; j++) re_copy(p, iPrev, sz);
}
for(j=m; j<n; j++){
re_append(p, RE_OP_FORK, sz+1);
re_copy(p, iPrev, sz);
}
if( n==0 && m>0 ){
re_append(p, RE_OP_FORK, -(int)sz);
}
break;
}
case '[': {
unsigned int iFirst = p->nState;
if( rePeek(p)=='^' ){
re_append(p, RE_OP_CC_EXC, 0);
p->sIn.i++;
}else{
re_append(p, RE_OP_CC_INC, 0);
}
while( (c = p->xNextChar(&p->sIn))!=0 ){
|
| ︙ | ︙ | |||
559 560 561 562 563 564 565 |
re_append(p, RE_OP_CC_RANGE, c);
}else{
re_append(p, RE_OP_CC_VALUE, c);
}
if( rePeek(p)==']' ){ p->sIn.i++; break; }
}
if( c==0 ) return "unclosed '['";
| | | 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 |
re_append(p, RE_OP_CC_RANGE, c);
}else{
re_append(p, RE_OP_CC_VALUE, c);
}
if( rePeek(p)==']' ){ p->sIn.i++; break; }
}
if( c==0 ) return "unclosed '['";
if( p->nState>iFirst ) p->aArg[iFirst] = p->nState - iFirst;
break;
}
case '\\': {
int specialOp = 0;
switch( rePeek(p) ){
case 'b': specialOp = RE_OP_BOUNDARY; break;
case 'd': specialOp = RE_OP_DIGIT; break;
|
| ︙ | ︙ | |||
610 611 612 613 614 615 616 | /* ** Compile a textual regular expression in zIn[] into a compiled regular ** expression suitable for us by re_match() and return a pointer to the ** compiled regular expression in *ppRe. Return NULL on success or an ** error message if something goes wrong. */ | | > > > > > > > | < < < < | | | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 |
/*
** Compile a textual regular expression in zIn[] into a compiled regular
** expression suitable for us by re_match() and return a pointer to the
** compiled regular expression in *ppRe. Return NULL on success or an
** error message if something goes wrong.
*/
static const char *re_compile(
ReCompiled **ppRe, /* OUT: write compiled NFA here */
const char *zIn, /* Input regular expression */
int mxRe, /* Complexity limit */
int noCase /* True for caseless comparisons */
){
ReCompiled *pRe;
const char *zErr;
int i, j;
*ppRe = 0;
pRe = fossil_malloc( sizeof(*pRe) );
if( pRe==0 ){
return "out of memory";
}
memset(pRe, 0, sizeof(*pRe));
pRe->xNextChar = noCase ? re_next_char_nocase : re_next_char;
pRe->mxAlloc = mxRe;
if( re_resize(pRe, 30) ){
zErr = pRe->zErr;
re_free(pRe);
return zErr;
}
if( zIn[0]=='^' ){
zIn++;
}else{
re_append(pRe, RE_OP_ANYSTAR, 0);
}
pRe->sIn.z = (unsigned char*)zIn;
pRe->sIn.i = 0;
pRe->sIn.mx = (int)strlen(zIn);
zErr = re_subcompile_re(pRe);
if( zErr ){
re_free(pRe);
return zErr;
}
if( pRe->sIn.i>=pRe->sIn.mx ){
re_append(pRe, RE_OP_ACCEPT, 0);
*ppRe = pRe;
}else{
re_free(pRe);
return "unrecognized character";
}
/* The following is a performance optimization. If the regex begins with
** ".*" (if the input regex lacks an initial "^") and afterwards there are
** one or more matching characters, enter those matching characters into
** zInit[]. The re_match() routine can then search ahead in the input
** string looking for the initial match without having to run the whole
** regex engine over the string. Do not worry about trying to match
** unicode characters beyond plane 0 - those are very rare and this is
** just an optimization. */
if( pRe->aOp[0]==RE_OP_ANYSTAR && !noCase ){
for(j=0, i=1; j<(int)sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
unsigned x = pRe->aArg[i];
if( x<=0x7f ){
pRe->zInit[j++] = (unsigned char)x;
}else if( x<=0x7ff ){
pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
pRe->zInit[j++] = 0x80 | (x&0x3f);
}else if( x<=0xffff ){
pRe->zInit[j++] = (unsigned char)(0xe0 | (x>>12));
pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
pRe->zInit[j++] = 0x80 | (x&0x3f);
}else{
break;
}
}
if( j>0 && pRe->zInit[j-1]==0 ) j--;
pRe->nInit = j;
}
return pRe->zErr;
}
/*
** Implementation of the regexp() SQL function. This function implements
** the build-in REGEXP operator. The first argument to the function is the
** pattern and the second argument is the string. So, the SQL statements:
**
** A REGEXP B
**
** is implemented as regexp(B,A).
*/
static void re_sql_func(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
ReCompiled *pRe; /* Compiled regular expression */
const char *zPattern; /* The regular expression */
const unsigned char *zStr;/* String being searched */
const char *zErr; /* Compile error message */
int setAux = 0; /* True to invoke sqlite3_set_auxdata() */
(void)argc; /* Unused */
pRe = sqlite3_get_auxdata(context, 0);
if( pRe==0 ){
zPattern = (const char*)sqlite3_value_text(argv[0]);
if( zPattern==0 ) return;
zErr = fossil_re_compile(&pRe, zPattern, sqlite3_user_data(context)!=0);
if( zErr ){
re_free(pRe);
/* The original SQLite function from which this code was copied raises
** an error if the REGEXP contained a syntax error. This variant
** silently fails to match, as that works better for Fossil.
** sqlite3_result_error(context, zErr, -1); */
sqlite3_result_int(context, 0);
return;
}
if( pRe==0 ){
sqlite3_result_error_nomem(context);
return;
}
setAux = 1;
}
zStr = (const unsigned char*)sqlite3_value_text(argv[1]);
if( zStr!=0 ){
sqlite3_result_int(context, re_match(pRe, zStr, -1));
}
if( setAux ){
sqlite3_set_auxdata(context, 0, pRe, (void(*)(void*))re_free);
}
}
/*
** Invoke this routine to register the regexp() function with the
** SQLite database connection.
*/
int re_add_sql_func(sqlite3 *db){
int rc;
rc = sqlite3_create_function(db, "regexp", 2,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
0, re_sql_func, 0, 0);
if( rc==SQLITE_OK ){
/* The regexpi(PATTERN,STRING) function is a case-insensitive version
** of regexp(PATTERN,STRING). */
rc = sqlite3_create_function(db, "regexpi", 2,
SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC,
(void*)db, re_sql_func, 0, 0);
}
return rc;
}
/*
** The input zIn is a string that we want to match exactly as part of
** a regular expression. Return a new string (in space obtained from
** fossil_malloc() or the equivalent) that escapes all regexp syntax
** characters in zIn.
*/
|
| ︙ | ︙ | |||
721 722 723 724 725 726 727 |
zIn++;
}
blob_materialize(&out);
return out.aData;
}
/*
| | < < < > > | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < > < > > > | < < | < | < < < | | 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 847 848 849 850 851 852 |
zIn++;
}
blob_materialize(&out);
return out.aData;
}
/*
** SETTING: regexp-limit width=8 default=1000
**
** Limit the size of the bytecode used to implement a regular expression
** to this many steps. It is important to limit this to avoid possible
** DoS attacks.
*/
/*
** Compile an RE using re_maxlen().
*/
const char *fossil_re_compile(
ReCompiled **ppRe, /* OUT: write compiled NFA here */
const char *zIn, /* Input regular expression */
int noCase /* True for caseless comparisons */
){
int mxLen = g.db ? db_get_int("regexp-limit",1000) : 1000;
return re_compile(ppRe, zIn, mxLen, noCase);
}
/*
** Run a "grep" over a single file read from disk.
*/
static void grep_file(ReCompiled *pRe, const char *zFile, FILE *in){
int ln = 0;
|
| ︙ | ︙ | |||
861 862 863 864 865 866 867 |
int ignoreCase = find_option("ignore-case","i",0)!=0;
int bRobot = find_option("robot-exception",0,0)!=0;
if( bRobot ){
const char *zRe;
db_find_and_open_repository(0,0);
verify_all_options();
zRe = db_get("robot-exception","^$");
| | | | 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 |
int ignoreCase = find_option("ignore-case","i",0)!=0;
int bRobot = find_option("robot-exception",0,0)!=0;
if( bRobot ){
const char *zRe;
db_find_and_open_repository(0,0);
verify_all_options();
zRe = db_get("robot-exception","^$");
zErr = fossil_re_compile(&pRe, zRe, ignoreCase);
iFileList = 2;
}else{
verify_all_options();
if( g.argc<3 ){
usage("REGEXP [FILE...]");
}
zErr = fossil_re_compile(&pRe, g.argv[2], ignoreCase);
}
if( zErr ) fossil_fatal("%s", zErr);
if( g.argc==iFileList ){
grep_file(pRe, "-", stdin);
}else{
int i;
for(i=iFileList; i<g.argc; i++){
|
| ︙ | ︙ | |||
950 951 952 953 954 955 956 |
flags |= GREP_QUIET|GREP_EXISTS;
}
db_find_and_open_repository(0, 0);
verify_all_options();
if( g.argc<4 ){
usage("REGEXP FILENAME ...");
}
| | | 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 |
flags |= GREP_QUIET|GREP_EXISTS;
}
db_find_and_open_repository(0, 0);
verify_all_options();
if( g.argc<4 ){
usage("REGEXP FILENAME ...");
}
zErr = fossil_re_compile(&pRe, g.argv[2], ignoreCase);
if( zErr ) fossil_fatal("%s", zErr);
add_content_sql_commands(g.db);
db_multi_exec("CREATE TEMP TABLE arglist(iname,fname,fnid);");
for(ii=3; ii<g.argc; ii++){
const char *zTarget = g.argv[ii];
if( file_tree_name(zTarget, &fullName, 0, 1) ){
|
| ︙ | ︙ |
Changes to src/robot.c.
| ︙ | ︙ | |||
37 38 39 40 41 42 43 |
*/
static struct RobotCache {
unsigned int h1, h2; /* Proof-of-work hash values */
unsigned int resultCache; /* 0: unknown. 1: human 2: might-be-robot */
} robot = { 0, 0, 0 };
/*
| | > > > > > | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
*/
static struct RobotCache {
unsigned int h1, h2; /* Proof-of-work hash values */
unsigned int resultCache; /* 0: unknown. 1: human 2: might-be-robot */
} robot = { 0, 0, 0 };
/*
** Allowed values for robot.resultCache.
**
** The names are slightly misleading. KNOWN_NOT_ROBOT might be set even
** if the client is a robot, but only if the robot is an approved robot.
** A better name might be "KNOWN_NOT_UNAUTHORIZED_ROBOT", but that is too
** long of a name.
*/
#define KNOWN_NOT_ROBOT 1 /* Approved to consume CPU and bandwidth */
#define MIGHT_BE_ROBOT 2 /* Might be an unapproved robot */
/*
** Compute two hashes, robot.h1 and robot.h2, that are used as
** part of determining whether or not the HTTP client is a robot.
** These hashes are based on current time, client IP address,
** and User-Agent. robot.h1 is for the current time slot and
** robot.h2 is the previous.
|
| ︙ | ︙ | |||
157 158 159 160 161 162 163 |
}
cgi_tag_query_parameter("proof");
}
/* Condition 4: If there is a "token=VALUE" query parameter with a
** valid VALUE argument, then assume that the request is coming from
** either an interactive human session, or an authorized robot that we
| | | 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
}
cgi_tag_query_parameter("proof");
}
/* Condition 4: If there is a "token=VALUE" query parameter with a
** valid VALUE argument, then assume that the request is coming from
** either an interactive human session, or an authorized robot that we
** want to treat as human. Allow it through and also set the robot cookie.
*/
z = P("token");
if( z!=0 ){
if( db_exists("SELECT 1 FROM config"
" WHERE name='token-%q'"
" AND json_valid(value,6)"
" AND value->>'user' IS NOT NULL", z)
|
| ︙ | ︙ | |||
202 203 204 205 206 207 208 |
style_header("Browser Verification");
@ <h1 id="x1">Checking to see if you are a robot<span id="x2"></span></h1>
@ <form method="GET" id="x6"><p>
@ <span id="x3" style="visibility:hidden;">\
@ Press <input type="submit" id="x5" value="Ok" focus> to continue</span>
@ <span id="x7" style="visibility:hidden;">You appear to be a robot.</span>\
@ </p>
| | | 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
style_header("Browser Verification");
@ <h1 id="x1">Checking to see if you are a robot<span id="x2"></span></h1>
@ <form method="GET" id="x6"><p>
@ <span id="x3" style="visibility:hidden;">\
@ Press <input type="submit" id="x5" value="Ok" focus> to continue</span>
@ <span id="x7" style="visibility:hidden;">You appear to be a robot.</span>\
@ </p>
if( g.zExtra && g.zExtra[0] ) cgi_tag_query_parameter("name");
cgi_query_parameters_to_hidden();
@ <input id="x4" type="hidden" name="proof" value="0">
@ </form>
@ <script nonce='%s(style_nonce())'>
@ function aaa(x){return document.getElementById(x);}\
@ function bbb(h,a){\
@ aaa("x4").value=h;\
|
| ︙ | ︙ | |||
252 253 254 255 256 257 258 | @ </script> style_finish_page(); } /* ** SETTING: robot-restrict width=40 block-text ** The VALUE of this setting is a list of GLOB patterns that match | | | > | | | | | > | > > > | > > > > > > > > > > > > > > > > > > | > > > | > > > | 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 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 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 349 350 351 352 |
@ </script>
style_finish_page();
}
/*
** SETTING: robot-restrict width=40 block-text
** The VALUE of this setting is a list of GLOB patterns that match
** pages for which complex HTTP requests from unauthenticated clients
** should be disallowed. "Unauthenticated" means the user is "nobody".
** The recommended value for this setting is:
**
** timelineX,diff,annotate,fileage,file,finfo,reports,tree,download,hexdump
**
** Usually the tag should exactly match the page name. The "diff" tag
** covers all diffing pages such as /vdiff, /fdiff, and /vpatch. The
** "annotate" tag also covers /blame and /praise. "zip" also covers
** /tarball and /sqlar. If a tag has an "X" character appended then it
** only applies if query parameters are such that the page is particularly
** difficult to compute. Useful "X" tags include "timelineX" and "zipX".
** The "ext" tag matches all extension, but a tag of the form "ext/PATH"
** only matches the extension at PATH.
**
** See the [[robot-zip-leaf]] and [[robot-zip-tag]] settings
** for additional controls associated with the "zipX" restriction.
**
** Change this setting "off" to disable all robot restrictions.
*/
/*
** SETTING: robot-exception width=40 block-text
**
** The value of this setting should be a regular expression.
** If it matches the REQUEST_URI without the SCRIPT_NAME prefix
** matches this regular expression, then the request is an exception
** to anti-robot defenses and should be allowed through. For
** example, to allow robots to download tarballs or ZIP archives
** for named versions and releases, you could use an expression like
** this:
**
** ^/tarball/(version-[0-9.]+|release)/
**
** This setting can hold multiple regular expressions, one
** regular expression per line. The input URL is exempted from
** anti-robot defenses if any of the multiple regular expressions
** matches.
*/
/*
** SETTING: robot-zip-leaf boolean
**
** If this setting is true, the robots are allowed to download tarballs,
** ZIP-archives, and SQL-archives even though "zipX" is found in
** the [[robot-restrict]] setting as long as the specific check-in being
** downloaded is a leaf check-in.
*/
/*
** SETTING: robot-zip-tag width=40 block-text
**
** If this setting is a list of GLOB patterns matching tags,
** then robots are allowed to download tarballs, ZIP-archives, and
** SQL-archives even though "zipX" appears in [[robot-restrict]], as long as
** the specific check-in being downloaded has a tags that matches
** the GLOB list of this setting. Recommended value:
** "release,robot-access".
*/
/*
** Return the default restriction GLOB
*/
const char *robot_restrict_default(void){
return "timelineX,diff,annotate,fileage,file,finfo,reports,"
"tree,hexdump,download";
}
/*
** Return true if zTag matches one of the tags in the robot-restrict
** setting.
**
** A zTag of "*" matches anything.
*/
static int robot_restrict_has_tag(const char *zTag){
static const char *zGlob = 0;
if( zGlob==0 ){
zGlob = db_get("robot-restrict",robot_restrict_default());
if( zGlob==0 ) zGlob = "";
}
if( zGlob[0]==0 || fossil_strcmp(zGlob, "off")==0 ){
return 0;
}
if( zTag==0 || (zTag[0]=='*' && zTag[1]==0) ){
return 1;
}
return glob_multi_match(zGlob,zTag);
}
/*
** Check the request URI to see if it matches one of the URI
** exceptions listed in the robot-exception setting. Return true
|
| ︙ | ︙ | |||
365 366 367 368 369 370 371 |
continue;
}
}else{
n = strlen(zRE);
}
z = mprintf("%.*s", (int)(zNL - zRE)+1, zRE);
zRE += n;
| | | > > | < > > | > > > > > > > > | > | < | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 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 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 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 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 |
continue;
}
}else{
n = strlen(zRE);
}
z = mprintf("%.*s", (int)(zNL - zRE)+1, zRE);
zRE += n;
zErr = fossil_re_compile(&pRe, z, 0);
if( zErr ){
fossil_warning("robot-exception error \"%s\" in expression \"%s\"\n",
zErr, z);
fossil_free(z);
continue;
}
fossil_free(z);
bMatch = re_match(pRe, (const unsigned char*)zRequest, nRequest);
re_free(pRe);
}
fossil_free(zRequest);
return bMatch;
}
/*
** Return true if one or more of the conditions below are true.
** Return false if all of the following are false:
**
** * The zTag is on the robot-restrict list
**
** * The client that submitted the HTTP request might be
** a robot
**
** * The Request URI does not match any of the exceptions
** in the robot-exception setting.
**
** In other words, return true if a call to robot_restrict() would
** return true and false if a call to robot_restrict() would return
** false.
**
** The difference between this routine an robot_restrict() is that
** this routine does not generate a proof-of-work captcha. This
** routine does not change the HTTP reply in any way. It simply
** returns true or false.
*/
int robot_would_be_restricted(const char *zTag){
if( robot.resultCache==KNOWN_NOT_ROBOT ) return 0;
if( !robot_restrict_has_tag(zTag) ) return 0;
if( !client_might_be_a_robot() ) return 0;
if( robot_exception() ){
robot.resultCache = KNOWN_NOT_ROBOT;
return 0;
}
return 1;
}
/*
** Check to see if the page named in the argument is on the
** robot-restrict list. If it is on the list and if the user
** is might be a robot, then bring up a captcha to test to make
** sure that client is not a robot.
**
** This routine returns true if a captcha was rendered and if subsequent
** page generation should be aborted. It returns false if the page
** should not be restricted and should be rendered normally.
*/
int robot_restrict(const char *zTag){
if( robot_would_be_restricted(zTag) ){
/* Generate the proof-of-work captcha */
ask_for_proof_that_client_is_not_robot();
return 1;
}else{
return 0;
}
}
/*
** Check to see if a robot is allowed to download a tarball, ZIP archive,
** or SQL Archive for a particular check-in identified by the "rid"
** argument. Return true to block the download. Return false to
** continue. Prior to returning true, a captcha is presented to the user.
** No output is generated when returning false.
**
** The rules:
**
** (1) If "zipX" is missing from the robot-restrict setting, then robots
** are allowed to download any archive. None of the remaining rules
** below are consulted unless "zipX" is on the robot-restrict setting.
**
** (2) If the robot-zip-leaf setting is true, then robots are allowed
** to download archives for any leaf check-in. This allows URL like
** /tarball/trunk/archive.tar.gz to work since branch labels like "trunk"
** always resolve to a leaf.
**
** (3) If the robot-zip-tag setting is a comma-separated tags, then any
** check-in that contains one of the tags on that list is allowed to
** be downloaded. This allows check-ins with tags like "release" or
** "robot-access" to be downloaded by robots.
*/
int robot_restrict_zip(int rid){
const char *zTag;
if( !robot_restrict_has_tag("zipX") || !client_might_be_a_robot() ){
return 0; /* Rule (1) */
}
if( db_get_boolean("robot-zip-leaf",0) && is_a_leaf(rid) ){
return 0; /* Rule (2) */
}
zTag = db_get("robot-zip-tag",0);
if( zTag && zTag[0] && fossil_strcmp(zTag,"off")!=0 ){
int ok = 0;
Stmt q;
db_prepare(&q,
"SELECT substr(tagname,5) FROM tagxref, tag"
" WHERE tagxref.rid=%d"
" AND tag.tagid=tagxref.tagid"
" AND tagxref.tagtype=1"
" AND tag.tagname GLOB 'sym-*'",
rid
);
while( !ok && db_step(&q)==SQLITE_ROW ){
if( glob_multi_match(zTag, db_column_text(&q,0)) ) ok = 1;
}
db_finalize(&q);
if( ok ) return 0; /* Rule (3) */
}
/* Generate the proof-of-work captcha */
ask_for_proof_that_client_is_not_robot();
return 1;
}
/*
** WEBPAGE: test-robotck
**
** Run the robot_restrict() function using the value of the "name="
** query parameter as an argument. Used for testing the robot_restrict()
** logic.
**
** Whenever this page is successfully rendered (when it doesn't go to
** the captcha) it deletes the proof-of-work cookie. So reloading the
** page will reset the cookie and restart the verification.
**
** If the zip=CHECKIN query parameter is provided, then also invoke
** robot_restrict_archive() on the RID of CHECKIN.
*/
void robot_restrict_test_page(void){
const char *zName = P("name");
const char *zZip = P("zip");
const char *zP1 = P("proof");
const char *zP2 = P(ROBOT_COOKIE);
const char *z;
int rid = 0;
if( zName==0 || zName[0]==0 ) zName = g.zPath;
login_check_credentials();
if( g.zLogin==0 ){ login_needed(1); return; }
g.zLogin = 0;
if( robot_restrict(zName) ) return;
if( zZip && zZip[0] ){
rid = symbolic_name_to_rid(zZip, "ci");
if( rid && robot_restrict_zip(rid) ) return;
}
style_set_current_feature("test");
style_header("robot_restrict() test");
@ <h1>Captcha passed</h1>
@
@ <p>
if( zP1 && zP1[0] ){
@ proof=%h(zP1)<br>
}
if( zP2 && zP2[0] ){
@ %h(ROBOT_COOKIE)=%h(zP2)<br>
cgi_set_cookie(ROBOT_COOKIE,"",0,-1);
}
if( zZip && zZip[0] ){
@ zip=%h(zZip)<br>
@ rid=%d(rid)<br>
}
if( g.perm.Admin ){
z = db_get("robot-restrict",robot_restrict_default());
if( z && z[0] ){
@ robot-restrict=%h(z)</br>
}
@ robot.h1=%u(robot.h1)<br>
|
| ︙ | ︙ |
Changes to src/schema.c.
| ︙ | ︙ | |||
558 559 560 561 562 563 564 | @ -- 2 Replaced by a merge command @ -- 3 Added by a merge command @ -- 4,5 Same as 2,3 except merge using --integrate @ -- @ CREATE TABLE vfile( @ id INTEGER PRIMARY KEY, -- ID of the checked-out file @ vid INTEGER REFERENCES blob, -- The check-in this file is part of. | | > > | 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 | @ -- 2 Replaced by a merge command @ -- 3 Added by a merge command @ -- 4,5 Same as 2,3 except merge using --integrate @ -- @ CREATE TABLE vfile( @ id INTEGER PRIMARY KEY, -- ID of the checked-out file @ vid INTEGER REFERENCES blob, -- The check-in this file is part of. @ chnged INT DEFAULT 0, @ -- 0:unchng 1:edit 2:m-chng 3:m-add 4:i-chng @ -- 5:i-add 6:+exec 7:+symlink 8:-exec 9:unlink @ deleted BOOLEAN DEFAULT 0, -- True if deleted @ isexe BOOLEAN, -- True if file should be executable @ islink BOOLEAN, -- True if file should be symlink @ rid INTEGER, -- Originally from this repository record @ mrid INTEGER, -- Based on this record due to a merge @ mtime INTEGER, -- Mtime of file on disk. sec since 1970 @ pathname TEXT, -- Full pathname relative to root |
| ︙ | ︙ |
Changes to src/search.c.
| ︙ | ︙ | |||
128 129 130 131 132 133 134 |
if( fSrchFlg & SRCHFLG_STATIC ){
p = &gSearch;
search_end(p);
}else{
p = fossil_malloc(sizeof(*p));
memset(p, 0, sizeof(*p));
}
| | | | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
if( fSrchFlg & SRCHFLG_STATIC ){
p = &gSearch;
search_end(p);
}else{
p = fossil_malloc(sizeof(*p));
memset(p, 0, sizeof(*p));
}
p->zPattern = z = mprintf("%s",zPattern);
p->zMarkBegin = mprintf("%s",zMarkBegin);
p->zMarkEnd = mprintf("%s",zMarkEnd);
p->zMarkGap = mprintf("%s",zMarkGap);
p->fSrchFlg = fSrchFlg;
blob_init(&p->snip, 0, 0);
while( *z && p->nTerm<SEARCH_MAX_TERM ){
while( *z && !ISALNUM(*z) ){ z++; }
if( *z==0 ) break;
p->a[p->nTerm].z = z;
for(i=1; ISALNUM(z[i]); i++){}
|
| ︙ | ︙ | |||
848 849 850 851 852 853 854 |
const char *zPattern, /* The query pattern */
unsigned int srchFlags /* What to search over */
){
search_init(zPattern, "<mark>", "</mark>", " ... ",
SRCHFLG_STATIC|SRCHFLG_HTML);
if( (srchFlags & SRCH_DOC)!=0 ){
char *zDocGlob = db_get("doc-glob","");
| > | | 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 |
const char *zPattern, /* The query pattern */
unsigned int srchFlags /* What to search over */
){
search_init(zPattern, "<mark>", "</mark>", " ... ",
SRCHFLG_STATIC|SRCHFLG_HTML);
if( (srchFlags & SRCH_DOC)!=0 ){
char *zDocGlob = db_get("doc-glob","");
const char *zMainBranch = db_main_branch();
char *zDocBr = db_get("doc-branch", zMainBranch);
if( zDocGlob && zDocGlob[0] && zDocBr && zDocBr[0] ){
Glob * pGlob = glob_create(zDocBr)
/* We're misusing a Glob as a list of comma-/space-delimited
** tokens. We're not actually doing glob matches here. */;
int i;
db_multi_exec(
"CREATE VIRTUAL TABLE IF NOT EXISTS temp.foci USING files_of_checkin;"
|
| ︙ | ︙ | |||
979 980 981 982 983 984 985 |
zPrefix = "The";
}else{
zPrefix = "Built-in help for the";
}
db_multi_exec(
"INSERT INTO x(label,url,score,id,snip)"
" SELECT format('%q \"%%s\" %%s',name,type),"
| | | 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 |
zPrefix = "The";
}else{
zPrefix = "Built-in help for the";
}
db_multi_exec(
"INSERT INTO x(label,url,score,id,snip)"
" SELECT format('%q \"%%s\" %%s',name,type),"
" '/help/'||name,"
" search_score(),"
" 'h'||rowid,"
" search_snippet()"
" FROM helptext"
" WHERE search_match(format('the \"%%s\" %%s',name,type),"
" helptext.helptext);",
zPrefix
|
| ︙ | ︙ | |||
1072 1073 1074 1075 1076 1077 1078 |
** replaces all non-alphanum ASCII characters with a space, and
** lower-cases all upper-case ASCII characters. The intent is to avoid
** causing errors in FTS5 searches with inputs which contain AND, OR,
** and symbols like #. The caller is responsible for passing the
** result to fossil_free().
*/
char *search_simplify_pattern(const char * zPattern){
| | | 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 |
** replaces all non-alphanum ASCII characters with a space, and
** lower-cases all upper-case ASCII characters. The intent is to avoid
** causing errors in FTS5 searches with inputs which contain AND, OR,
** and symbols like #. The caller is responsible for passing the
** result to fossil_free().
*/
char *search_simplify_pattern(const char * zPattern){
char *zPat = mprintf("%s",zPattern);
int i;
for(i=0; zPat[i]; i++){
if( (zPat[i]&0x80)==0 && !fossil_isalnum(zPat[i]) ) zPat[i] = ' ';
if( fossil_isupper(zPat[i]) ) zPat[i] = fossil_tolower(zPat[i]);
}
for(i--; i>=0 && zPat[i]==' '; i--){}
if( i<0 ){
|
| ︙ | ︙ | |||
1982 1983 1984 1985 1986 1987 1988 |
/*
** If the doc-glob and doc-br settings are valid for document search
** and if the latest check-in on doc-br is in the unindexed set of
** check-ins, then update all 'd' entries in FTSDOCS that have
** changed.
*/
static void search_update_doc_index(void){
| > | | 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 |
/*
** If the doc-glob and doc-br settings are valid for document search
** and if the latest check-in on doc-br is in the unindexed set of
** check-ins, then update all 'd' entries in FTSDOCS that have
** changed.
*/
static void search_update_doc_index(void){
const char *zMainBranch = db_main_branch();
const char *zDocBranches = db_get("doc-branch", zMainBranch);
int i;
Glob * pGlob = glob_create(zDocBranches)
/* We're misusing a Glob as a list of comma-/space-delimited
** tokens. We're not actually doing glob matches here. */;
if( !pGlob ) return;
db_multi_exec(
"CREATE TEMP TABLE current_docs(rid INTEGER PRIMARY KEY, name);"
|
| ︙ | ︙ |
Changes to src/security_audit.c.
| ︙ | ︙ | |||
367 368 369 370 371 372 373 |
}
zVulnReport = db_get("vuln-report","log");
if( fossil_strcmp(zVulnReport,"block")!=0
&& fossil_strcmp(zVulnReport,"fatal")!=0
){
@ <li><p><b>WARNING:</b>
| | | 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 |
}
zVulnReport = db_get("vuln-report","log");
if( fossil_strcmp(zVulnReport,"block")!=0
&& fossil_strcmp(zVulnReport,"fatal")!=0
){
@ <li><p><b>WARNING:</b>
@ The <a href="%R/help/vuln-report">vuln-report setting</a>
@ has a value of "%h(zVulnReport)". This disables defenses against
@ XSS or SQL-injection vulnerabilities caused by coding errors in
@ custom TH1 scripts. For the best security, change
@ the value of the vuln-report setting to "block" or "fatal".
}
/* Obsolete: */
|
| ︙ | ︙ | |||
675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 |
@ <li>%h(azCSP[ii])
}
@ </ol>
}
fossil_free(azCSP);
if( alert_enabled() ){
@ <li><p> Email alert configuration summary:
@ <table class="label-value">
stats_for_email();
@ </table>
}else{
@ <li><p> Email alerts are disabled
}
| > > > > > > | 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 |
@ <li>%h(azCSP[ii])
}
@ </ol>
}
fossil_free(azCSP);
if( alert_enabled() ){
char * zListId = db_get("email-listid", 0);
@ <li><p> Email alert configuration summary:
if( !zListId || !zListId[0] ){
@ <br><strong>WARNING:</strong> <code>email-listid</code> is not set,
@ so notifications will not include unsubscribe links.
}
fossil_free(zListId);
@ <table class="label-value">
stats_for_email();
@ </table>
}else{
@ <li><p> Email alerts are disabled
}
|
| ︙ | ︙ |
Changes to src/setup.c.
| ︙ | ︙ | |||
116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
setup_menu_entry("Robot-Defense", "setup_robot",
"Settings for configure defense against robots");
setup_menu_entry("Settings", "setup_settings",
"Web interface to the \"fossil settings\" command");
}
setup_menu_entry("Timeline", "setup_timeline",
"Timeline display preferences");
if( setup_user ){
setup_menu_entry("Login-Group", "setup_login_group",
"Manage single sign-on between this repository and others"
" on the same server");
setup_menu_entry("Tickets", "tktsetup",
"Configure the trouble-ticketing system for this repository");
setup_menu_entry("Wiki", "setup_wiki",
| > > | 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
setup_menu_entry("Robot-Defense", "setup_robot",
"Settings for configure defense against robots");
setup_menu_entry("Settings", "setup_settings",
"Web interface to the \"fossil settings\" command");
}
setup_menu_entry("Timeline", "setup_timeline",
"Timeline display preferences");
setup_menu_entry("Tarballs and ZIPs", "setup_download",
"Preferences for auto-generated tarballs and ZIP files");
if( setup_user ){
setup_menu_entry("Login-Group", "setup_login_group",
"Manage single sign-on between this repository and others"
" on the same server");
setup_menu_entry("Tickets", "tktsetup",
"Configure the trouble-ticketing system for this repository");
setup_menu_entry("Wiki", "setup_wiki",
|
| ︙ | ︙ | |||
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
setup_menu_entry("Search","srchsetup",
"Configure the built-in search engine");
setup_menu_entry("URL Aliases", "waliassetup",
"Configure URL aliases");
if( setup_user ){
setup_menu_entry("Notification", "setup_notification",
"Automatic notifications of changes via outbound email");
setup_menu_entry("Transfers", "xfersetup",
"Configure the transfer system for this repository");
}
setup_menu_entry("Skins", "setup_skin_admin",
"Select and/or modify the web interface \"skins\"");
setup_menu_entry("Moderation", "setup_modreq",
"Enable/Disable requiring moderator approval of Wiki and/or Ticket"
" changes and attachments.");
setup_menu_entry("Ad-Unit", "setup_adunit",
| > > | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
setup_menu_entry("Search","srchsetup",
"Configure the built-in search engine");
setup_menu_entry("URL Aliases", "waliassetup",
"Configure URL aliases");
if( setup_user ){
setup_menu_entry("Notification", "setup_notification",
"Automatic notifications of changes via outbound email");
#if 0 /* Disabled for now. Does this even work? */
setup_menu_entry("Transfers", "xfersetup",
"Configure the transfer system for this repository");
#endif
}
setup_menu_entry("Skins", "setup_skin_admin",
"Select and/or modify the web interface \"skins\"");
setup_menu_entry("Moderation", "setup_modreq",
"Enable/Disable requiring moderator approval of Wiki and/or Ticket"
" changes and attachments.");
setup_menu_entry("Ad-Unit", "setup_adunit",
|
| ︙ | ︙ | |||
468 469 470 471 472 473 474 |
style_header("Robot Defense Settings");
db_begin_transaction();
@ <p>A Fossil website can have billions of pages in its tree, even for a
@ modest project. Many of those pages (examples: diffs and tarballs)
@ might be expensive to compute. A robot that tries to walk the entire
@ website can present a crippling CPU and bandwidth load.
@
| | | | > > | > | > | | | | > > | | > > > > > > | | > > > > > > | > > | | < < < < | < | 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 |
style_header("Robot Defense Settings");
db_begin_transaction();
@ <p>A Fossil website can have billions of pages in its tree, even for a
@ modest project. Many of those pages (examples: diffs and tarballs)
@ might be expensive to compute. A robot that tries to walk the entire
@ website can present a crippling CPU and bandwidth load.
@
@ <p>The settings on this page are intended to help administrators
@ defend against abusive robots.
@
@ <form action="%R/setup_robot" method="post"><div>
login_insert_csrf_secret();
@ <input type="submit" name="submit" value="Apply Changes"></p>
@ <hr>
@ <p><b>Do not allow robots access to these pages.</b><br>
@ If the page name matches the GLOB pattern of this setting, and the
@ users is "nobody", and the client has not previously passed a captcha
@ test to show that it is not a robot, then the page is not displayed.
@ A captcha test is is rendered instead.
@ The default value for this setting is:
@ <p>
@    <tt>%h(robot_restrict_default())</tt>
@ <p>
@ Usually the tag should exactly match the page name. Exceptions:
@ <ul>
@ <li> The "diff" tag covers all diffing pages such as /vdiff,
@ /fdiff, and /vpatch.
@ <li> The "annotate" tag covers /annotate and also /blame and
@ /praise.
@ <li> The "zip" covers itself and also /tarball and /sqlar.
@ <li> If a tag has an "X" character appended (ex: "timelineX")
@ then it only applies if query parameters are such that
@ the page is expensive and/or unusual.
@ <li> The "ext" tag covers all extensions, but a tag like
@ "ext/PATH" only covers the specific extension at PATH.
@ </ul>
@ To disable robot restrictions, change this setting to "off".
@ (Property: <a href="%R/help/robot-restrict">robot-restrict</a>)
@ <br>
textarea_attribute("", 2, 80,
"robot-restrict", "rbrestrict", robot_restrict_default(), 0);
@ <p><b>Exception #1</b><br>
@ If "zipX" appears in the robot-restrict list above, then tarballs,
@ ZIP-archives, and SQL-archives may be downloaded by robots if
@ the check-in is a leaf (robot-zip-leaf):<br>
onoff_attribute("Allow tarballs for leaf check-ins",
"robot-zip-leaf", "rzleaf", 0, 0);
@ <p><b>Exception #2</b><br>
@ If "zipX" appears in the robot-restrict list above, then tarballs,
@ ZIP-archives, and SQL-archives may be downloaded by robots if
@ the check-in has one or more tags that match the following
@ list of GLOB patterns: (robot-zip-tag)<br>
textarea_attribute("", 2, 80,
"robot-zip-tag", "rztag", "", 0);
@ <p><b>Exception #3</b><br>
@ If the request URI matches any of the following
@ <a href="%R/re_rules">regular expressions</a> (one per line), then the
@ request is exempt from anti-robot defenses.
@ The regular expression is matched against the REQUEST_URI with the
@ SCRIPT_NAME prefix removed, and with QUERY_STRING appended following
@ a "?" if QUERY_STRING exists. (Property: robot-exception)<br>
textarea_attribute("", 3, 80,
"robot-exception", "rbexcept", "", 0);
@ <hr>
addAutoHyperlinkSettings();
@ <hr>
entry_attribute("Anonymous Login Validity", 11, "anon-cookie-lifespan",
"anoncookls", "840", 0);
@ <p>The number of minutes for which an anonymous login cookie is valid.
|
| ︙ | ︙ | |||
974 975 976 977 978 979 980 981 982 983 984 985 986 987 |
static const char *const azTimeFormats[] = {
"0", "HH:MM",
"1", "HH:MM:SS",
"2", "YYYY-MM-DD HH:MM",
"3", "YYMMDD HH:MM",
"4", "(off)"
};
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_set_current_feature("setup");
| > > > > > | 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 |
static const char *const azTimeFormats[] = {
"0", "HH:MM",
"1", "HH:MM:SS",
"2", "YYYY-MM-DD HH:MM",
"3", "YYMMDD HH:MM",
"4", "(off)"
};
static const char *const azLeafMark[] = {
"0", "No",
"1", "Yes",
"2", "Yes - with emphasis",
};
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_set_current_feature("setup");
|
| ︙ | ︙ | |||
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 |
"tdf", "0", count(azTimeFormats)/2, azTimeFormats);
@ <p>If the "HH:MM" or "HH:MM:SS" format is selected, then the date is shown
@ in a separate box (using CSS class "timelineDate") whenever the date
@ changes. With the "YYYY-MM-DD HH:MM" and "YYMMDD ..." formats,
@ the complete date and time is shown on every timeline entry using the
@ CSS class "timelineTime". (Property: "timeline-date-format")</p>
@ <hr>
entry_attribute("Max timeline comment length", 6,
"timeline-max-comment", "tmc", "0", 0);
@ <p>The maximum length of a comment to be displayed in a timeline.
@ "0" there is no length limit.
@ (Property: "timeline-max-comment")</p>
| > > > > > > | 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 |
"tdf", "0", count(azTimeFormats)/2, azTimeFormats);
@ <p>If the "HH:MM" or "HH:MM:SS" format is selected, then the date is shown
@ in a separate box (using CSS class "timelineDate") whenever the date
@ changes. With the "YYYY-MM-DD HH:MM" and "YYMMDD ..." formats,
@ the complete date and time is shown on every timeline entry using the
@ CSS class "timelineTime". (Property: "timeline-date-format")</p>
@ <hr>
multiple_choice_attribute("Leaf Markings", "timeline-mark-leaves",
"tml", "1", count(azLeafMark)/2, azLeafMark);
@ <p>Should timeline entries for leaf check-ins be identified in the
@ detail section. (Property: "timeline-mark-leaves")</p>
@ <hr>
entry_attribute("Max timeline comment length", 6,
"timeline-max-comment", "tmc", "0", 0);
@ <p>The maximum length of a comment to be displayed in a timeline.
@ "0" there is no length limit.
@ (Property: "timeline-max-comment")</p>
|
| ︙ | ︙ | |||
1164 1165 1166 1167 1168 1169 1170 |
(db_get_versioned(pSet->name, NULL, NULL)!=0);
if( bIfChng && setting_has_default_value(pSet, db_get(pSet->name,0)) ){
continue;
}
onoff_attribute("", pSet->name,
pSet->var!=0 ? pSet->var : pSet->name /*works-like:"x"*/,
is_truth(pSet->def), hasVersionableValue);
| | | | | 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 |
(db_get_versioned(pSet->name, NULL, NULL)!=0);
if( bIfChng && setting_has_default_value(pSet, db_get(pSet->name,0)) ){
continue;
}
onoff_attribute("", pSet->name,
pSet->var!=0 ? pSet->var : pSet->name /*works-like:"x"*/,
is_truth(pSet->def), hasVersionableValue);
@ <a href='%R/help/%s(pSet->name)'>%h(pSet->name)</a>
if( pSet->versionable ){
@ (v)<br>
} else {
@ <br>
}
}
}
@ <br><input type="submit" name="submit" value="Apply Changes">
@ </td><td style="width:50px;"></td><td valign="top">
@ <table>
for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
if( pSet->width>0 && !pSet->forceTextArea ){
int hasVersionableValue = pSet->versionable &&
(db_get_versioned(pSet->name, NULL, NULL)!=0);
if( bIfChng && setting_has_default_value(pSet, db_get(pSet->name,0)) ){
continue;
}
@ <tr><td>
@ <a href='%R/help/%s(pSet->name)'>%h(pSet->name)</a>
if( pSet->versionable ){
@ (v)
} else {
@
}
@</td><td>
entry_attribute("", /*pSet->width*/ 25, pSet->name,
pSet->var!=0 ? pSet->var : pSet->name /*works-like:"x"*/,
(char*)pSet->def, hasVersionableValue);
@</td></tr>
}
}
@</table>
@ </td><td style="width:50px;"></td><td valign="top">
for(i=0, pSet=aSetting; i<nSetting; i++, pSet++){
if( pSet->width>0 && pSet->forceTextArea ){
int hasVersionableValue = db_get_versioned(pSet->name, NULL, NULL)!=0;
if( bIfChng && setting_has_default_value(pSet, db_get(pSet->name,0)) ){
continue;
}
@ <a href='%R/help/%s(pSet->name)'>%s(pSet->name)</a>
if( pSet->versionable ){
@ (v)<br>
} else {
@ <br>
}
textarea_attribute("", /*rows*/ 2, /*cols*/ 35, pSet->name,
pSet->var!=0 ? pSet->var : pSet->name /*works-like:"x"*/,
|
| ︙ | ︙ | |||
1315 1316 1317 1318 1319 1320 1321 | @ Other repositories use this URL to clone or sync against this repository. @ This is also the basename for hyperlinks included in email alert text. @ Omit the trailing "/". @ If this repo will not be set up as a persistent server and will not @ be sending email alerts, then leave this entry blank. @ Suggested value: "%h(g.zBaseURL)" @ (Property: "email-url")</p> | < < < < < < < < < < < < < < < < < < | 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 |
@ Other repositories use this URL to clone or sync against this repository.
@ This is also the basename for hyperlinks included in email alert text.
@ Omit the trailing "/".
@ If this repo will not be set up as a persistent server and will not
@ be sending email alerts, then leave this entry blank.
@ Suggested value: "%h(g.zBaseURL)"
@ (Property: "email-url")</p>
@ <hr>
entry_attribute("Index Page", 60, "index-page", "idxpg", "/home", 0);
@ <p>Enter the pathname of the page to display when the "Home" menu
@ option is selected and when no pathname is
@ specified in the URL. For example, if you visit the url:</p>
@
@ <blockquote><p>%h(g.zBaseURL)</p></blockquote>
|
| ︙ | ︙ | |||
1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 |
@ </ol>
@
@ <p>The default value is blank, meaning no added entries.
@ (Property: sitemap-extra)
@ <p>
textarea_attribute("Custom Sitemap Entries", 8, 80,
"sitemap-extra", "smextra", "", 0);
@ <hr>
@ <p><input type="submit" name="submit" value="Apply Changes"></p>
@ </div></form>
db_end_transaction(0);
style_finish_page();
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
@ </ol>
@
@ <p>The default value is blank, meaning no added entries.
@ (Property: sitemap-extra)
@ <p>
textarea_attribute("Custom Sitemap Entries", 8, 80,
"sitemap-extra", "smextra", "", 0);
@ <hr>
@ <p><input type="submit" name="submit" value="Apply Changes"></p>
@ </div></form>
db_end_transaction(0);
style_finish_page();
}
/*
** WEBPAGE: setup_download
**
** The "Admin/Download" page. Requires Setup privilege.
*/
void setup_download(void){
login_check_credentials();
if( !g.perm.Setup ){
login_needed(0);
return;
}
style_set_current_feature("setup");
style_header("Tarball and ZIP Downloads");
db_begin_transaction();
@ <form action="%R/setup_download" method="post"><div>
login_insert_csrf_secret();
@ <input type="submit" name="submit" value="Apply Changes"></p>
@ <hr>
entry_attribute("Tarball and ZIP Name Prefix", 20, "short-project-name",
"spn", "", 0);
@ <p>This is used as a prefix for the names of generated tarballs and
@ ZIP archive. Keep this prefix brief and use only lower-case ASCII
@ characters, digits, "_", "-" in the name. If this setting is blank,
@ then the full <a href='%R/help/project-name'>project-name</a> setting
@ is used instead.
@ (Property: "short-project-name")
@ </p>
@ <hr>
@ <p><b>Configuration for the <a href="%R/download">/download</a> page.</b>
@ <p>The value is a TCL list divided into groups of four tokens:
@ <ol>
@ <li> Maximum number of matches (COUNT).
@ <li> Tag to match using glob (TAG).
@ <li> Maximum age of check-ins to match (MAX_AGE).
@ <li> Comment to apply to matches (COMMENT).
@ </ol>
@ Each 4-tuple will match zero or more check-ins. The /download page
@ displays the union of matches from all 4-tuples.
@ See the <a href="%R/help/suggested-downloads">suggested-downloads</a>
@ setting documentation for further detail.
@ <p>
@ The /download page is omitted from the <a href="%R/sitemap">/sitemap</a>
@ if the first token is "0" or "off" or "no". The default value
@ for this setting is "off".
@ (Property: <a href="%R/help/suggested-downloads">suggested-downloads</a>)
@ <p>
textarea_attribute("", 4, 80,
"suggested-downloads", "sgtrlst", "off", 0);
@ <hr>
@ <p><input type="submit" name="submit" value="Apply Changes"></p>
@ </div></form>
db_end_transaction(0);
style_finish_page();
}
|
| ︙ | ︙ | |||
2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 |
/*
** WEBPAGE: srchsetup
**
** Configure the search engine. Requires Admin privilege.
*/
void page_srchsetup(){
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_set_current_feature("setup");
style_header("Search Configuration");
| > | 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 |
/*
** WEBPAGE: srchsetup
**
** Configure the search engine. Requires Admin privilege.
*/
void page_srchsetup(){
const char *zMainBranch;
login_check_credentials();
if( !g.perm.Admin ){
login_needed(0);
return;
}
style_set_current_feature("setup");
style_header("Search Configuration");
|
| ︙ | ︙ | |||
2247 2248 2249 2250 2251 2252 2253 | @ <td>Search all Markdown files in the doc/ subfolder and all README.txt @ files.</tr> @ <tr><td>*<td><td>Search all checked-in files</tr> @ <tr><td><i>(blank)</i><td> @ <td>Search nothing. (Disables document search).</tr> @ </table> @ <hr> | > | | > | 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 |
@ <td>Search all Markdown files in the doc/ subfolder and all README.txt
@ files.</tr>
@ <tr><td>*<td><td>Search all checked-in files</tr>
@ <tr><td><i>(blank)</i><td>
@ <td>Search nothing. (Disables document search).</tr>
@ </table>
@ <hr>
zMainBranch = db_main_branch();
entry_attribute("Document Branches", 20, "doc-branch", "db", zMainBranch, 0);
@ <p>When searching documents, use the versions of the files found at the
@ type of the "Document Branches" branch. Recommended value: the name of
@ the main branch (usually "trunk").
@ Document search is disabled if blank. It may be a list of branch names
@ separated by spaces and/or commas.
@ <hr>
onoff_attribute("Search Check-in Comments", "search-ci", "sc", 0, 0);
@ <br>
onoff_attribute("Search Documents", "search-doc", "sd", 0, 0);
@ <br>
|
| ︙ | ︙ |
Changes to src/sitemap.c.
| ︙ | ︙ | |||
130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
@ <li>%z(href("%R/tree?type=flat"))Flat-view</a></li>
@ <li>%z(href("%R/fileage?name=trunk"))File ages for Trunk</a></li>
@ <li>%z(href("%R/uvlist"))Unversioned Files</a>
if( g.perm.Write && zEditGlob[0]!=0 ){
@ <li>%z(href("%R/fileedit"))On-line File Editor</li>
}
@ </ul>
}
if( g.perm.Read ){
@ <li>%z(href("%R/timeline"))Project Timeline</a>
@ <ul>
@ <li>%z(href("%R/reports"))Activity Reports</a></li>
@ <li>%z(href("%R/sitemap-timeline"))Other timelines</a></li>
@ </ul>
| > > > | 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
@ <li>%z(href("%R/tree?type=flat"))Flat-view</a></li>
@ <li>%z(href("%R/fileage?name=trunk"))File ages for Trunk</a></li>
@ <li>%z(href("%R/uvlist"))Unversioned Files</a>
if( g.perm.Write && zEditGlob[0]!=0 ){
@ <li>%z(href("%R/fileedit"))On-line File Editor</li>
}
@ </ul>
}
if( g.perm.Zip && db_get_boolean("suggested-downloads",0)!=0 ){
@ <li>%z(href("%R/download"))Tarballs and ZIPs</a>
}
if( g.perm.Read ){
@ <li>%z(href("%R/timeline"))Project Timeline</a>
@ <ul>
@ <li>%z(href("%R/reports"))Activity Reports</a></li>
@ <li>%z(href("%R/sitemap-timeline"))Other timelines</a></li>
@ </ul>
|
| ︙ | ︙ |
Changes to src/skins.c.
| ︙ | ︙ | |||
1343 1344 1345 1346 1347 1348 1349 |
builtin_request_js("skin.js");
style_finish_page();
}
/*
** WEBPAGE: skins
**
| | | 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 |
builtin_request_js("skin.js");
style_finish_page();
}
/*
** WEBPAGE: skins
**
** Show a list of all of the built-in skins, plus the repository skin,
** and provide the user with an opportunity to change to any of them.
*/
void skins_page(void){
int i;
char *zBase = fossil_strdup(g.zTop);
size_t nBase = strlen(zBase);
login_check_credentials();
|
| ︙ | ︙ | |||
1371 1372 1373 1374 1375 1376 1377 |
@ <p class="warning">Warning:
if( iDraftSkin>0 ){
@ you are using a draft skin,
}else{
@ this fossil instance was started with a hard-coded skin
@ value
}
| | | 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 |
@ <p class="warning">Warning:
if( iDraftSkin>0 ){
@ you are using a draft skin,
}else{
@ this fossil instance was started with a hard-coded skin
@ value
}
@ which supersedes any option selected below. A skin selected
@ below will be recorded in your
@ "%z(href("%R/fdscookie"))fossil_display_settings</a>" cookie
@ but will not be used so long as the site has a
@ higher-priority skin in place.
@ </p>
}
@ <p>The following skins are available for this repository:</p>
|
| ︙ | ︙ |
Changes to src/sqlcmd.c.
| ︙ | ︙ | |||
419 420 421 422 423 424 425 | fossil_close(1, noRepository); sqlite3_shutdown(); #ifndef _WIN32 linenoiseSetMultiLine(1); #endif atexit(sqlcmd_atexit); g.zConfigDbName = zConfigDb; | | | 419 420 421 422 423 424 425 426 427 428 429 430 | fossil_close(1, noRepository); sqlite3_shutdown(); #ifndef _WIN32 linenoiseSetMultiLine(1); #endif atexit(sqlcmd_atexit); g.zConfigDbName = zConfigDb; g.argv[1] = "--noinit"; sqlite3_shell(g.argc, g.argv); sqlite3_cancel_auto_extension((void(*)(void))sqlcmd_autoinit); fossil_close(0, noRepository); } |
Changes to src/stash.c.
| ︙ | ︙ | |||
548 549 550 551 552 553 554 | ** ** > fossil stash goto ?STASHID? ** ** Update to the baseline check-out for STASHID then apply the ** changes of STASHID. Keep STASHID so that it can be reused ** This command is undoable. ** | | | | | | 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 | ** ** > fossil stash goto ?STASHID? ** ** Update to the baseline check-out for STASHID then apply the ** changes of STASHID. Keep STASHID so that it can be reused ** This command is undoable. ** ** > fossil stash drop|rm ?STASHIDs...? ?-a|--all? ** ** Forget everything about the given STASHIDs. Forget the whole ** stash if the -a|--all flag is used. Individual drops are ** undoable but -a|--all is not. ** ** > fossil stash diff ?STASHID? ?DIFF-OPTIONS? ** > fossil stash gdiff ?STASHID? ?DIFF-OPTIONS? ** ** Show diffs of the current working directory and what that ** directory would be if STASHID were applied. With gdiff, ** gdiff-command is used instead of internal diff logic. |
| ︙ | ︙ |
Changes to src/stat.c.
| ︙ | ︙ | |||
92 93 94 95 96 97 98 |
}
sqlite3_close(db);
}else
if( fossil_strcmp(zDest,"dir")==0
&& (zDir = db_get("email-send-dir",0))!=0
){
@ Written to files in "%h(zDir)"
| | | 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
}
sqlite3_close(db);
}else
if( fossil_strcmp(zDest,"dir")==0
&& (zDir = db_get("email-send-dir",0))!=0
){
@ Written to files in "%h(zDir)"
@ (%,d(file_directory_list(zDir,0,1,0,0)) messages)
}else
if( fossil_strcmp(zDest,"relay")==0
&& (zRelay = db_get("email-send-relayhost",0))!=0
){
@ Relay to %h(zRelay) using SMTP
}
else{
|
| ︙ | ︙ |
Changes to src/tar.c.
| ︙ | ︙ | |||
29 30 31 32 33 34 35 36 37 38 39 40 41 42 | unsigned char *aHdr; /* Space for building headers */ char *zSpaces; /* Spaces for padding */ char *zPrevDir; /* Name of directory for previous entry */ int nPrevDirAlloc; /* size of zPrevDir */ Blob pax; /* PAX data */ } tball; /* ** field lengths of 'ustar' name and prefix fields. */ #define USTAR_NAME_LEN 100 #define USTAR_PREFIX_LEN 155 | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 |
unsigned char *aHdr; /* Space for building headers */
char *zSpaces; /* Spaces for padding */
char *zPrevDir; /* Name of directory for previous entry */
int nPrevDirAlloc; /* size of zPrevDir */
Blob pax; /* PAX data */
} tball;
/*
** Convert a string so that it contains only lower-case ASCII, digits,
** "_" and "-". Changes are made in-place.
*/
static void sanitize_name(char *zName){
int i;
char c;
if( zName==0 ) return;
for(i=0; (c = zName[i])!=0; i++){
if( fossil_isupper(c) ){
zName[i] = fossil_tolower(c);
}else if( !fossil_isalnum(c) && c!='_' && c!='-' ){
if( c<=0x7f ){
zName[i] = '_';
}else{
/* 123456789 123456789 123456 */
zName[i] = "abcdefghijklmnopqrstuvwxyz"[(unsigned)c%26];
}
}
}
}
/*
** Compute a sensible base-name for an archive file (tarball, ZIP, or SQLAR)
** based on the rid of the check-in contained in that file.
**
** PROJECTNAME-DATETIME-HASHPREFIX
**
** So that the name will be safe to use as a URL or a filename on any system,
** the name is only allowed to contain lower-case ASCII alphabetics,
** digits, '_' and '-'. Upper-case ASCII is converted to lower-case. All
** other bytes are mapped into a lower-case alphabetic.
**
** The value returned is obtained from mprintf() or fossil_strdup() and should
** be released by the caller using fossil_free().
*/
char *archive_base_name(int rid){
char *zPrefix;
char *zName;
zPrefix = db_get("short-project-name",0);
if( zPrefix==0 || zPrefix[0]==0 ){
zPrefix = db_get("project-name","unnamed");
}
zName = db_text(0,
"SELECT %Q||"
" strftime('-%%Y%%m%%d%%H%%M%%S-',event.mtime)||"
" substr(blob.uuid,1,10)"
" FROM blob, event"
" WHERE blob.rid=%d"
" AND event.objid=%d",
zPrefix, rid, rid);
fossil_free(zPrefix);
sanitize_name(zName);
return zName;
}
/*
** field lengths of 'ustar' name and prefix fields.
*/
#define USTAR_NAME_LEN 100
#define USTAR_PREFIX_LEN 155
|
| ︙ | ︙ | |||
651 652 653 654 655 656 657 |
}
zOut = g.argv[3];
if( fossil_strcmp("/dev/null",zOut)==0 || fossil_strcmp("",zOut)==0 ){
zOut = 0;
}
if( zName==0 ){
| | < < < < < < < < > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > | > > | | > > > | > | > | > > > > > > > > > > > > > > > > > > > > > | > > > | | | > > > | > | | > | > > > | > > > > | | | > > > > > > > > > > > | > > > > > > > > > > > > > | > > > > > > > | > > | > | > | > | > | > > > > > > > > > > > > > > > > | 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 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 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 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 |
}
zOut = g.argv[3];
if( fossil_strcmp("/dev/null",zOut)==0 || fossil_strcmp("",zOut)==0 ){
zOut = 0;
}
if( zName==0 ){
zName = archive_base_name(rid);
}
tarball_of_checkin(rid, zOut ? &tarball : 0,
zName, pInclude, pExclude, listFlag);
glob_free(pInclude);
glob_free(pExclude);
if( listFlag ) fflush(stdout);
if( zOut ){
blob_write_to_file(&tarball, zOut);
blob_reset(&tarball);
}
}
/*
** This is a helper routine for tar_uuid_from_name(). It handles
** the case where *pzName contains no "/" character. Check for
** format (3). Return the hash if the name matches format (3),
** or return NULL if it does not.
*/
static char *format_three_parser(const char *zName){
int iDot = 0; /* Index in zName[] of the first '.' */
int iDash1 = 0; /* Index in zName[] of the '-' before the timestamp */
int iDash2 = 0; /* Index in zName[] of the '-' between timestamp and hash */
int nHash; /* Size of the hash */
char *zHash; /* A copy of the hash value */
char *zDate; /* Copy of the timestamp */
char *zUuid; /* Final result */
int i; /* Loop query */
Stmt q; /* Query to verify that hash and timestamp agree */
for(i=0; zName[i]; i++){
char c = zName[i];
if( c=='.' ){ iDot = i; break; }
if( c=='-' ){ iDash1 = iDash2; iDash2 = i; }
if( !fossil_isalnum(c) && c!='_' && c!='-' ){ break; }
}
if( iDot==0 ) return 0;
if( iDash1==0 ) return 0;
nHash = iDot - iDash2 - 1;
if( nHash<8 ) return 0; /* HASH value too short */
if( (iDash2 - iDash1)!=15 ) return 0; /* Wrong timestamp size */
zHash = fossil_strndup(&zName[iDash2+1], nHash);
zDate = fossil_strndup(&zName[iDash1+1], 14);
db_prepare(&q,
"SELECT blob.uuid"
" FROM blob JOIN event ON event.objid=blob.rid"
" WHERE blob.uuid GLOB '%q*'"
" AND strftime('%%Y%%m%%d%%H%%M%%S',event.mtime)='%q'",
zHash, zDate
);
fossil_free(zHash);
fossil_free(zDate);
if( db_step(&q)==SQLITE_ROW ){
zUuid = fossil_strdup(db_column_text(&q,0));
}else{
zUuid = 0;
}
db_finalize(&q);
return zUuid;
}
/*
** Check to see if the input string is of one of the following
** two the forms:
**
** check-in-name/filename.ext (1)
** tag-name/check-in-name/filename.ext (2)
** project-datetime-hash.ext (3)
**
** In other words, check to see if the input string contains either
** a check-in name or a tag-name and a check-in name separated by
** a slash. There must be between 0 or 2 "/" characters. In the
** second form, tag-name must be an individual tag (not a branch-tag)
** that is found on the check-in identified by the check-in-name.
**
** If the condition is true, then:
**
** * Make *pzName point to the filename suffix only
** * return a copy of the check-in name in memory from mprintf().
**
** If the condition is false, leave *pzName unchanged and return either
** NULL or an empty string. Normally NULL is returned, however an
** empty string is returned for format (2) if check-in-name does not
** match tag-name.
**
** Format (2) is specifically designed to allow URLs like this:
**
** /tarball/release/UUID/PROJECT.tar.gz
**
** Such URLs will pass through most anti-robot filters because of the
** "/tarball/release" prefix will match the suggested "robot-exception"
** pattern and can still refer to an historic release rather than just
** the most recent release.
**
** Format (3) is designed to allow URLs like this:
**
** /tarball/fossil-20251018193920-d6c9aee97df.tar.gz
**
** In other words, filename itself contains sufficient information to
** uniquely identify the check-in, including a timestamp of the form
** YYYYMMDDHHMMSS and a prefix of the check-in hash. The timestamp
** and hash must immediately preceed the first "." in the name.
*/
char *tar_uuid_from_name(char **pzName){
char *zName = *pzName; /* Original input */
int n1 = 0; /* Bytes in first prefix (tag-name) */
int n2 = 0; /* Bytes in second prefix (check-in-name) */
int n = 0; /* max(n1,n2) */
int i; /* Loop counter */
for(i=n1=n2=0; zName[i]; i++){
if( zName[i]=='/' ){
if( n1==0 ){
n = n1 = i;
}else if( n2==0 ){
n = n2 = i;
}else{
return 0; /* More than two "/" characters seen */
}
}
}
if( n1==0 ){
/* Check for format (3) */
return format_three_parser(*pzName);
}
if( zName[n+1]==0 ){
return 0; /* No filename suffix */
}
if( n2==0 ){
/* Format (1): check-in name only. The check-in-name is not verified */
zName[n1] = 0;
*pzName = fossil_strdup(&zName[n1+1]);
return zName;
}else if( n2>n1+1 ){
/* Format (2): tag-name/check-in-name. Verify that check-in-name is real
** and that the check-in has the tag named by tag-name.
*/
char *zCkin = mprintf("%.*s", n2-n1-1, &zName[n1+1]);
char *zTag;
int rid = symbolic_name_to_rid(zCkin,"ci");
int hasTag;
if( rid<=0 ){
fossil_free(zCkin);
return fossil_strdup("");
}
zTag = mprintf("%.*s", n1, zName);
hasTag = db_exists(
"SELECT 1 FROM tagxref, tag"
" WHERE tagxref.rid=%d"
" AND tag.tagid=tagxref.tagid"
" AND tagxref.tagtype=1"
" AND tag.tagname='sym-%q'",
rid, zTag
);
fossil_free(zTag);
if( !hasTag ){
fossil_free(zCkin);
return fossil_strdup("");
}
*pzName = fossil_strdup(&zName[n2+1]);
return zCkin;
}else{
return 0;
}
}
/*
** WEBPAGE: tarball
** URL: /tarball/NAME.tar.gz
** or: /tarball/VERSION/NAME.tar.gz
** or: /tarball/TAG/VERSION/NAME.tar.gz
**
** Generate a compressed tarball for the check-in specified by VERSION.
** The tarball is called NAME.tar.gz and has a top-level directory called
** NAME. If TAG is provided, then VERSION must hold TAG or else an error
** is returned.
**
** The optional VERSION element defaults to the name of the main branch
** (usually "trunk") per the r= rules below.
** All of the following URLs are equivalent:
**
** /tarball/release/xyz.tar.gz
** /tarball?r=release&name=xyz.tar.gz
** /tarball/xyz.tar.gz?r=release
** /tarball?name=release/xyz.tar.gz
**
** Query parameters:
**
** name=[CKIN/]NAME The optional CKIN component of the name= parameter
** identifies the check-in from which the tarball is
** constructed. If CKIN is omitted and there is no
** r= query parameter, then use the name of the main
** branch (usually "trunk"). NAME is the
** name of the download file. The top-level directory
** in the generated tarball is called by NAME with the
** file extension removed.
**
** r=TAG TAG identifies the check-in that is turned into a
** compressed tarball. The default value is the name of
** the main branch (usually "trunk").
** If r= is omitted and if the name= query parameter
** contains one "/" character then the of part the
** name= value before the / becomes the TAG and the
** part of the name= value after the / is the download
** filename. If no check-in is specified by either
** name= or r=, then the name of the main branch
** (usually "trunk") is used.
**
** in=PATTERN Only include files that match the comma-separate
** list of GLOB patterns in PATTERN, as with ex=
**
** ex=PATTERN Omit any file that match PATTERN. PATTERN is a
** comma-separated list of GLOB patterns, where each
** pattern can optionally be quoted using ".." or '..'.
** Any file matching both ex= and in= is excluded.
**
** Robot Defenses:
**
** * If "zip" appears in the robot-restrict setting, then robots are
** not allowed to access this page. Suspected robots will be
** presented with a captcha.
**
** * If "zipX" appears in the robot-restrict setting, then robots are
** restricted in the same way as with "zip", but with exceptions.
** If the check-in for which an archive is requested is a leaf check-in
** and if the robot-zip-leaf setting is true, then the request is
** allowed. Or if the check-in has a tag that matches any of the
** GLOB patterns on the list in the robot-zip-tag setting, then the
** request is allowed. Otherwise, the usual robot defenses are
** activated.
*/
void tarball_page(void){
int rid;
char *zName, *zRid, *zKey;
int nName, nRid;
const char *zInclude; /* The in= query parameter */
const char *zExclude; /* The ex= query parameter */
|
| ︙ | ︙ | |||
764 765 766 767 768 769 770 |
if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
if( robot_restrict("zip") ) return;
fossil_nice_default();
zName = fossil_strdup(PD("name",""));
z = P("r");
if( z==0 ) z = P("uuid");
if( z==0 ) z = tar_uuid_from_name(&zName);
| | | 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 |
if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
if( robot_restrict("zip") ) return;
fossil_nice_default();
zName = fossil_strdup(PD("name",""));
z = P("r");
if( z==0 ) z = P("uuid");
if( z==0 ) z = tar_uuid_from_name(&zName);
if( z==0 ) z = fossil_strdup(db_main_branch());
g.zOpenRevision = zRid = fossil_strdup(z);
nRid = strlen(zRid);
zInclude = P("in");
if( zInclude ) pInclude = glob_create(zInclude);
zExclude = P("ex");
if( zExclude ) pExclude = glob_create(zExclude);
if( zInclude==0 && zExclude==0 ){
|
| ︙ | ︙ | |||
795 796 797 798 799 800 801 802 803 804 805 806 807 808 |
}
rid = symbolic_name_to_rid(nRid?zRid:zName, "ci");
if( rid==0 ){
cgi_set_status(404, "Not Found");
@ Not found
return;
}
if( nRid==0 && nName>10 ) zName[10] = 0;
/* Compute a unique key for the cache entry based on query parameters */
blob_init(&cacheKey, 0, 0);
blob_appendf(&cacheKey, "/tarball/%z", rid_to_uuid(rid));
blob_appendf(&cacheKey, "/%q", zName);
if( zInclude ) blob_appendf(&cacheKey, ",in=%Q", zInclude);
| > | 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 |
}
rid = symbolic_name_to_rid(nRid?zRid:zName, "ci");
if( rid==0 ){
cgi_set_status(404, "Not Found");
@ Not found
return;
}
if( robot_restrict_zip(rid) ) return;
if( nRid==0 && nName>10 ) zName[10] = 0;
/* Compute a unique key for the cache entry based on query parameters */
blob_init(&cacheKey, 0, 0);
blob_appendf(&cacheKey, "/tarball/%z", rid_to_uuid(rid));
blob_appendf(&cacheKey, "/%q", zName);
if( zInclude ) blob_appendf(&cacheKey, ",in=%Q", zInclude);
|
| ︙ | ︙ | |||
846 847 848 849 850 851 852 |
fossil_free(zName);
fossil_free(zRid);
g.zOpenRevision = 0;
blob_reset(&cacheKey);
cgi_set_content(&tarball);
cgi_set_content_type("application/x-compressed");
}
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 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 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 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 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 |
fossil_free(zName);
fossil_free(zRid);
g.zOpenRevision = 0;
blob_reset(&cacheKey);
cgi_set_content(&tarball);
cgi_set_content_type("application/x-compressed");
}
/*
** This routine is called for each check-in on the /download page to
** construct the "extra" information after the description.
*/
void download_extra(
Stmt *pQuery, /* Current row of the timeline query */
int tmFlags, /* Flags to www_print_timeline() */
const char *zThisUser, /* Suppress links to this user */
const char *zThisTag /* Suppress links to this tag */
){
const char *zType = db_column_text(pQuery, 7);
assert( zType!=0 );
if( zType[0]!='c' ){
timeline_extra(pQuery, tmFlags, zThisUser, zThisTag);
}else{
int rid = db_column_int(pQuery, 0);
const char *zUuid = db_column_text(pQuery, 1);
char *zBrName = branch_of_rid(rid);
char *zNm;
if( tmFlags & TIMELINE_COLUMNAR ){
@ <nobr>check-in: \
@ %z(href("%R/info/%!S",zUuid))<span class='timelineHash'>\
@ %S(zUuid)</span></a></nobr><br>
if( fossil_strcmp(zBrName,"trunk")!=0 ){
@ <nobr>branch: \
@ %z(href("%R/timeline?r=%t",zBrName))%h(zBrName)</a></nobr><br>\
}
}else{
if( (tmFlags & TIMELINE_CLASSIC)==0 ){
@ check-in: %z(href("%R/info/%!S",zUuid))\
@ <span class='timelineHash'>%S(zUuid)</span></a>
}
if( (tmFlags & TIMELINE_GRAPH)==0 && fossil_strcmp(zBrName,"trunk")!=0 ){
@ branch: \
@ %z(href("%R/timeline?r=%t",zBrName))%h(zBrName)</a>
}
}
zNm = archive_base_name(rid);
@ %z(href("%R/tarball/%s.tar.gz",zNm))\
@ <button>Tarball</button></a>
@ %z(href("%R/zip/%s.zip",zNm))\
@ <button>ZIP Archive</button></a>
fossil_free(zBrName);
fossil_free(zNm);
}
}
/*
** SETTING: suggested-downloads width=70 block-text
**
** This setting controls the suggested tarball/ZIP downloads on the
** [[/download]] page. The value is a TCL list. Each set of four items
** defines a set of check-ins to be added to the suggestion list.
** The items in each group are:
**
** | COUNT TAG MAX_AGE COMMENT
**
** COUNT is the number of check-ins to match, starting with the most
** recent and working bacwards in time. Check-ins match if they contain
** the tag TAG. If MAX_AGE is not an empty string, then it specifies
** the maximum age of any matching check-in. COMMENT is an optional
** comment for each match.
**
** The special value of "OPEN-LEAF" for TAG matches any check-in that
** is an open leaf.
**
** MAX_AGE is of the form "{AMT UNITS}" where AMT is a floating point
** value and UNITS is one of "seconds", "hours", "days", "weeks", "months",
** or "years". If MAX_AGE is an empty string then there is no age limit.
**
** If COMMENT is not an empty string, then it is an additional comment
** added to the output description of the suggested download. The idea of
** COMMENT is to explain to the reader why a check-in is a suggested
** download.
**
** Example:
**
** | 1 trunk {} {Latest Trunk Check-in}
** | 5 OPEN-LEAF {1 month} {Active Branch}
** | 999 release {1 year} {Official Release}
**
** The value causes the /download page to show the union of the most
** recent trunk check-in of any age, the five most recent
** open leaves within the past month, and essentially
** all releases within the past year. If the same check-in matches more
** than one rule, the COMMENT of the first match is used.
*/
/*
** WEBPAGE: /download
**
** Show a special no-graph timeline of recent important check-ins with
** an opportunity to pull tarballs and ZIPs.
*/
void download_page(void){
Stmt q; /* The actual timeline query */
const char *zTarlistCfg; /* Configuration string */
char **azItem; /* Decomposed elements of zTarlistCfg */
int *anItem; /* Bytes in each term of azItem[] */
int nItem; /* Number of terms in azItem[] */
int i; /* Loop counter */
int tmFlags; /* Timeline display flags */
int n; /* Number of suggested downloads */
double rNow; /* Current time. Julian day number */
int bPlainTextCom; /* Use plain-text comments */
login_check_credentials();
if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
style_set_current_feature("timeline");
style_header("Suggested Downloads");
zTarlistCfg = db_get("suggested-downloads","off");
db_multi_exec(
"CREATE TEMP TABLE tarlist(rid INTEGER PRIMARY KEY, com TEXT);"
);
rNow = db_double(0.0,"SELECT julianday()");
if( !g.interp ) Th_FossilInit(0);
Th_SplitList(g.interp, zTarlistCfg, (int)strlen(zTarlistCfg),
&azItem, &anItem, &nItem);
bPlainTextCom = db_get_boolean("timeline-plaintext",0);
for(i=0; i<nItem-3; i+=4){
int cnt; /* The number of instances of zLabel to use */
char *zLabel; /* The label to match */
double rStart; /* Starting time, julian day number */
char *zComment = 0; /* Comment to apply */
if( anItem[i]==1 && azItem[i][0]=='*' ){
cnt = -1;
}else if( anItem[i]<1 ){
cnt = 0;
}else{
cnt = atoi(azItem[i]);
}
if( cnt==0 ) continue;
zLabel = fossil_strndup(azItem[i+1],anItem[i+1]);
if( anItem[i+2]==0 ){
rStart = 0.0;
}else{
char *zMax = fossil_strndup(azItem[i+2], anItem[i+2]);
double r = atof(zMax);
if( strstr(zMax,"sec") ){
rStart = rNow - r/86400.0;
}else
if( strstr(zMax,"hou") ){
rStart = rNow - r/24.0;
}else
if( strstr(zMax,"da") ){
rStart = rNow - r;
}else
if( strstr(zMax,"wee") ){
rStart = rNow - r*7.0;
}else
if( strstr(zMax,"mon") ){
rStart = rNow - r*30.44;
}else
if( strstr(zMax,"yea") ){
rStart = rNow - r*365.24;
}else
{ /* Default to seconds */
rStart = rNow - r/86400.0;
}
}
if( anItem[i+3]==0 ){
zComment = fossil_strdup("");
}else if( bPlainTextCom ){
zComment = mprintf("** %.*s ** ", anItem[i+3], azItem[i+3]);
}else{
zComment = mprintf("<b>%.*s</b>\n<p>", anItem[i+3], azItem[i+3]);
}
if( fossil_strcmp("OPEN-LEAF",zLabel)==0 ){
db_multi_exec(
"INSERT OR IGNORE INTO tarlist(rid,com)"
" SELECT leaf.rid, %Q FROM leaf, event"
" WHERE event.objid=leaf.rid"
" AND event.mtime>=%.6f"
" AND NOT EXISTS(SELECT 1 FROM tagxref"
" WHERE tagxref.rid=leaf.rid"
" AND tagid=%d AND tagtype>0)"
" ORDER BY event.mtime DESC LIMIT %d",
zComment, rStart, TAG_CLOSED, cnt
);
}else{
db_multi_exec(
"WITH taglist(tid) AS"
" (SELECT tagid FROM tag WHERE tagname GLOB 'sym-%q')"
"INSERT OR IGNORE INTO tarlist(rid,com)"
" SELECT event.objid, %Q FROM event CROSS JOIN tagxref"
" WHERE event.type='ci'"
" AND event.mtime>=%.6f"
" AND tagxref.tagid IN taglist"
" AND tagtype>0"
" AND tagxref.rid=event.objid"
" ORDER BY event.mtime DESC LIMIT %d",
zLabel, zComment, rStart, cnt
);
}
fossil_free(zLabel);
fossil_free(zComment);
}
Th_Free(g.interp, azItem);
n = db_int(0, "SELECT count(*) FROM tarlist");
if( n==0 ){
@ <h2>No tarball/ZIP suggestions are available at this time</h2>
}else{
@ <h2>%d(n) Tarball/ZIP Download Suggestion%s(n>1?"s":""):</h2>
db_prepare(&q,
"WITH matches AS (%s AND blob.rid IN (SELECT rid FROM tarlist))\n"
"SELECT blobRid, uuid, timestamp,"
" com||comment,"
" user, leaf, bgColor, eventType, tags, tagid, brief, mtime"
" FROM matches JOIN tarlist ON tarlist.rid=blobRid"
" ORDER BY matches.mtime DESC",
timeline_query_for_www()
);
tmFlags = TIMELINE_DISJOINT | TIMELINE_NOSCROLL | TIMELINE_COLUMNAR
| TIMELINE_BRCOLOR;
www_print_timeline(&q, tmFlags, 0, 0, 0, 0, 0, download_extra);
db_finalize(&q);
}
if( g.perm.Clone ){
char *zNm = fossil_strdup(db_get("project-name","clone"));
sanitize_name(zNm);
@ <hr>
@ <h2>You Can Clone This Repository</h2>
@
@ <p>Clone this repository by running a command similar to the following:
@ <blockquote><pre>
@ fossil clone %s(g.zBaseURL) %h(zNm).fossil
@ </pre></blockquote>
@ <p>A clone gives you local access to all historical content.
@ Cloning is a bandwidth- and CPU-efficient alternative to extracting
@ multiple tarballs and ZIPs.
@ Do a web search for "fossil clone" or similar to find additional
@ information about using a cloned Fossil repository. Or ask your
@ favorite AI how to extract content from a Fossil clone.
fossil_free(zNm);
}
style_finish_page();
}
/*
** WEBPAGE: rchvdwnld
**
** Short for "archive download". This page should have a single name=
** query parameter that is a check-in hash or symbolic name. The resulting
** page offers a menu of possible download options for that check-in,
** including tarball, ZIP, or SQLAR.
**
** This is a utility page. The /dir and /tree pages sometimes have a
** "Download" option in their submenu which redirects here. Those pages
** used to have separate "Tarball" and "ZIP" submenu entries, but as
** submenu entries appear in alphabetical order, that caused the two
** submenu entries to be separated from one another, which is distracting.
**
** If the name= does not have a unique resolution, no error is generated.
** Instead, a redirect to the home page for the repository is made.
**
** Robots are excluded from this page if either of the keywords
** "zip" or "download" appear in the [[robot-restrict]] setting.
*/
void rchvdwnld_page(void){
const char *zUuid;
char *zBase;
int nUuid;
int rid;
char *zTags;
login_check_credentials();
if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
if( robot_restrict("zip") || robot_restrict("download") ) return;
zUuid = P("name");
if( zUuid==0
|| (nUuid = (int)strlen(zUuid))<6
|| !validate16(zUuid,-1)
|| (rid = db_int(0, "SELECT rid FROM blob WHERE uuid GLOB '%q*'", zUuid))==0
|| !db_exists("SELECT 1 from event WHERE type='ci' AND objid=%d",rid)
){
rid = symbolic_name_to_rid(zUuid, "ci");
if( rid<=0 ){
fossil_redirect_home();
}
}
zUuid = db_text(zUuid, "SELECT uuid FROM blob WHERE rid=%d", rid);
zTags = db_text(0,
"SELECT if(cnt,' ('||tags||')','') FROM ("
"SELECT group_concat(substr(tagname,5),', ') AS tags, count(*) AS cnt"
" FROM tag JOIN tagxref USING(tagid)"
" WHERE rid=%d"
" AND tagtype=1"
" AND tagname GLOB 'sym-*'"
")",
rid
);
style_header("Downloads For Check-in %!S", zUuid);
zBase = archive_base_name(rid);
@ <div class="section accordion">Downloads for check-in \
@ %z(href("%R/info/%!S",zUuid))%S(zUuid)</a>%h(zTags)</div>
@ <div class="accordion_panel">
@ <table class="label-value">
@ <tr>
@ <th>Tarball:</th>
@ <td>%z(href("%R/tarball/%s.tar.gz",zBase))\
@ %s(g.zBaseURL)/tarball/%s(zBase).tar.gz</a></td>
@ </tr>
@
@ <tr>
@ <th>ZIP:</th>
@ <td>%z(href("%R/zip/%s.zip",zBase))\
@ %s(g.zBaseURL)/zip/%s(zBase).zip</a></td>
@ </tr>
@
@ <tr>
@ <th>SQLAR:</th>
@ <td>%z(href("%R/sqlar/%s.sqlar",zBase))\
@ %s(g.zBaseURL)/sqlar/%s(zBase).sqlar</a></td>
@ </tr>
@ </table></div>
fossil_free(zBase);
@ <div class="section accordion">Context</div><div class="accordion_panel">
render_checkin_context(rid, 0, 0, 0);
@ </div>
builtin_request_js("accordion.js");
style_finish_page();
}
|
Changes to src/terminal.c.
| ︙ | ︙ | |||
131 132 133 134 135 136 137 |
TerminalSize ts;
if( terminal_get_size(&ts) ){
return ts.nLines;
}
return nDefault;
}
| < < < < < < < < < < < < < < | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
TerminalSize ts;
if( terminal_get_size(&ts) ){
return ts.nLines;
}
return nDefault;
}
/*
** Return true if it is reasonable is emit VT100 escape codes.
*/
int terminal_is_vt100(void){
if( g.colorOutput==COLOR_VT_NEVER) return 0;
if( g.colorOutput==COLOR_VT_ALWAYS) return 1;
/* Check the terminal if g.colorOutput is COLOR_VT_UNSET or COLOR_VT_AUTO. */
|
| ︙ | ︙ |
Changes to src/th_main.c.
| ︙ | ︙ | |||
2143 2144 2145 2146 2147 2148 2149 |
if( fossil_strcmp(argv[nArg], "-nocase")==0 ){
noCase = 1; nArg++;
}
if( fossil_strcmp(argv[nArg], "--")==0 ) nArg++;
if( nArg+2!=argc ){
return Th_WrongNumArgs(interp, REGEXP_WRONGNUMARGS);
}
| | | 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 |
if( fossil_strcmp(argv[nArg], "-nocase")==0 ){
noCase = 1; nArg++;
}
if( fossil_strcmp(argv[nArg], "--")==0 ) nArg++;
if( nArg+2!=argc ){
return Th_WrongNumArgs(interp, REGEXP_WRONGNUMARGS);
}
zErr = fossil_re_compile(&pRe, argv[nArg], noCase);
if( !zErr ){
Th_SetResultInt(interp, re_match(pRe,
(const unsigned char *)argv[nArg+1], TH1_LEN(argl[nArg+1])));
rc = TH_OK;
}else{
Th_SetResult(interp, zErr, -1);
rc = TH_ERROR;
|
| ︙ | ︙ | |||
2200 2201 2202 2203 2204 2205 2206 |
url_parse_local(argv[nArg], 0, &urlData);
if( urlData.isSsh || urlData.isFile ){
Th_ErrorMessage(interp, "url must be http:// or https://", 0, 0);
return TH_ERROR;
}
zRegexp = db_get("th1-uri-regexp", 0);
if( zRegexp && zRegexp[0] ){
| | | 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 |
url_parse_local(argv[nArg], 0, &urlData);
if( urlData.isSsh || urlData.isFile ){
Th_ErrorMessage(interp, "url must be http:// or https://", 0, 0);
return TH_ERROR;
}
zRegexp = db_get("th1-uri-regexp", 0);
if( zRegexp && zRegexp[0] ){
const char *zErr = fossil_re_compile(&pRe, zRegexp, 0);
if( zErr ){
Th_SetResult(interp, zErr, -1);
return TH_ERROR;
}
}
if( !pRe || !re_match(pRe, (const unsigned char *)urlData.canonical, -1) ){
Th_SetResult(interp, "url not allowed", -1);
|
| ︙ | ︙ |
Changes to src/th_tcl.c.
| ︙ | ︙ | |||
100 101 102 103 104 105 106 | # define _WIN32_WINNT 0x0502 /* SetDllDirectory, Windows XP SP2 */ # endif # include <windows.h> # ifndef TCL_DIRECTORY_SEP # define TCL_DIRECTORY_SEP '\\' # endif # ifndef TCL_LIBRARY_NAME | | | | | | | > > > | 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 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | # define _WIN32_WINNT 0x0502 /* SetDllDirectory, Windows XP SP2 */ # endif # include <windows.h> # ifndef TCL_DIRECTORY_SEP # define TCL_DIRECTORY_SEP '\\' # endif # ifndef TCL_LIBRARY_NAME # define TCL_LIBRARY_NAME "tcl91.dll\0" # endif # ifndef TCL_MINOR_OFFSET # define TCL_MINOR_OFFSET (4) # endif # ifndef dlopen # define dlopen(a,b) (void *)LoadLibrary((a)) # endif # ifndef dlsym # define dlsym(a,b) GetProcAddress((HANDLE)(a),(b)) # endif # ifndef dlclose # define dlclose(a) FreeLibrary((HANDLE)(a)) # endif # else # include <dlfcn.h> # ifndef TCL_DIRECTORY_SEP # define TCL_DIRECTORY_SEP '/' # endif # if defined(__CYGWIN__) && (TCL_MAJOR_VERSION > 8) # ifndef TCL_LIBRARY_NAME # define TCL_LIBRARY_NAME "cygtcl9.1.dll\0" # endif # ifndef TCL_MINOR_OFFSET # define TCL_MINOR_OFFSET (8) # endif # elif defined(__APPLE__) # ifndef TCL_LIBRARY_NAME # define TCL_LIBRARY_NAME "libtcl9.1.dylib\0" # endif # ifndef TCL_MINOR_OFFSET # define TCL_MINOR_OFFSET (8) # endif # elif defined(__FreeBSD__) # ifndef TCL_LIBRARY_NAME # define TCL_LIBRARY_NAME "libtcl91.so\0" # endif # ifndef TCL_MINOR_OFFSET # define TCL_MINOR_OFFSET (7) # endif # else # ifndef TCL_LIBRARY_NAME # define TCL_LIBRARY_NAME "libtcl9.1.so\0" # endif # ifndef TCL_MINOR_OFFSET # define TCL_MINOR_OFFSET (8) # endif # endif /* defined(__CYGWIN__) */ # endif /* defined(_WIN32) */ # ifndef TCL_FINDEXECUTABLE_NAME # define TCL_FINDEXECUTABLE_NAME "_Tcl_FindExecutable\0" # endif # ifndef TCL_ZIPFSAPPHOOK_NAME # define TCL_ZIPFSAPPHOOK_NAME "_TclZipfs_AppHook\0" # endif # ifndef TCL_CREATEINTERP_NAME # define TCL_CREATEINTERP_NAME "_Tcl_CreateInterp\0" # endif # ifndef TCL_DELETEINTERP_NAME # define TCL_DELETEINTERP_NAME "_Tcl_DeleteInterp\0" # endif # ifndef TCL_FINALIZE_NAME |
| ︙ | ︙ | |||
187 188 189 190 191 192 193 194 195 196 197 198 199 200 | ** the only Tcl API functions that MUST be called prior to being able to call ** Tcl_InitStubs (i.e. because it requires a Tcl interpreter). For complete ** cleanup if the Tcl stubs initialization fails somehow, the Tcl_DeleteInterp ** and Tcl_Finalize function types are also required. */ #if TCL_MAJOR_VERSION>=9 typedef const char *(tcl_FindExecutableProc) (const char *); #else typedef void (tcl_FindExecutableProc) (const char *); #endif typedef Tcl_Interp *(tcl_CreateInterpProc) (void); typedef void (tcl_DeleteInterpProc) (Tcl_Interp *); typedef void (tcl_FinalizeProc) (void); | > | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | ** the only Tcl API functions that MUST be called prior to being able to call ** Tcl_InitStubs (i.e. because it requires a Tcl interpreter). For complete ** cleanup if the Tcl stubs initialization fails somehow, the Tcl_DeleteInterp ** and Tcl_Finalize function types are also required. */ #if TCL_MAJOR_VERSION>=9 typedef const char *(tcl_FindExecutableProc) (const char *); typedef const char *(tcl_ZipfsAppHookProc) (int *, char ***); #else typedef void (tcl_FindExecutableProc) (const char *); #endif typedef Tcl_Interp *(tcl_CreateInterpProc) (void); typedef void (tcl_DeleteInterpProc) (Tcl_Interp *); typedef void (tcl_FinalizeProc) (void); |
| ︙ | ︙ | |||
258 259 260 261 262 263 264 |
if( !tclStubsPtr || (tclStubsPtr->magic!=TCL_STUB_MAGIC) ){
Th_ErrorMessage(interp,
"could not initialize Tcl stubs: incompatible mechanism",
(const char *)"", 0);
return TH_ERROR;
}
/* NOTE: At this point, the Tcl API functions should be available. */
| | | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
if( !tclStubsPtr || (tclStubsPtr->magic!=TCL_STUB_MAGIC) ){
Th_ErrorMessage(interp,
"could not initialize Tcl stubs: incompatible mechanism",
(const char *)"", 0);
return TH_ERROR;
}
/* NOTE: At this point, the Tcl API functions should be available. */
if( Tcl_PkgRequireEx(tclInterp, "Tcl", "8.5-", 0, (void *)&tclStubsPtr)==0 ){
Th_ErrorMessage(interp,
"could not initialize Tcl stubs: incompatible version",
(const char *)"", 0);
return TH_ERROR;
}
return TH_OK;
}
|
| ︙ | ︙ | |||
402 403 404 405 406 407 408 409 410 411 412 413 414 415 |
** copied from and should be kept in sync with the one in "main.c".
*/
struct TclContext {
int argc; /* Number of original arguments. */
char **argv; /* Full copy of the original arguments. */
void *hLibrary; /* The Tcl library module handle. */
tcl_FindExecutableProc *xFindExecutable; /* Tcl_FindExecutable() pointer. */
tcl_CreateInterpProc *xCreateInterp; /* Tcl_CreateInterp() pointer. */
tcl_DeleteInterpProc *xDeleteInterp; /* Tcl_DeleteInterp() pointer. */
tcl_FinalizeProc *xFinalize; /* Tcl_Finalize() pointer. */
Tcl_Interp *interp; /* The on-demand created Tcl interpreter. */
int useObjProc; /* Non-zero if an objProc can be called directly. */
int useTip285; /* Non-zero if TIP #285 is available. */
const char *setup; /* The optional Tcl setup script. */
| > > > | 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 |
** copied from and should be kept in sync with the one in "main.c".
*/
struct TclContext {
int argc; /* Number of original arguments. */
char **argv; /* Full copy of the original arguments. */
void *hLibrary; /* The Tcl library module handle. */
tcl_FindExecutableProc *xFindExecutable; /* Tcl_FindExecutable() pointer. */
#if TCL_MAJOR_VERSION>=9
tcl_ZipfsAppHookProc *xZipfsAppHook; /* TclZipfsAppHook() pointer. */
#endif
tcl_CreateInterpProc *xCreateInterp; /* Tcl_CreateInterp() pointer. */
tcl_DeleteInterpProc *xDeleteInterp; /* Tcl_DeleteInterp() pointer. */
tcl_FinalizeProc *xFinalize; /* Tcl_Finalize() pointer. */
Tcl_Interp *interp; /* The on-demand created Tcl interpreter. */
int useObjProc; /* Non-zero if an objProc can be called directly. */
int useTip285; /* Non-zero if TIP #285 is available. */
const char *setup; /* The optional Tcl setup script. */
|
| ︙ | ︙ | |||
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 |
char *file_dirname(const char *zPath); /* file.h */
void fossil_free(void *p); /* util.h */
static int loadTcl(
Th_Interp *interp,
void **phLibrary,
tcl_FindExecutableProc **pxFindExecutable,
tcl_CreateInterpProc **pxCreateInterp,
tcl_DeleteInterpProc **pxDeleteInterp,
tcl_FinalizeProc **pxFinalize
){
#if defined(USE_TCL_STUBS)
const char *zEnvPath = fossil_getenv(TCL_PATH_ENV_VAR_NAME);
char aFileName[] = TCL_LIBRARY_NAME;
#endif /* defined(USE_TCL_STUBS) */
if( !phLibrary || !pxFindExecutable || !pxCreateInterp ||
!pxDeleteInterp || !pxFinalize ){
Th_ErrorMessage(interp,
"invalid Tcl loader argument(s)", (const char *)"", 0);
return TH_ERROR;
}
#if defined(USE_TCL_STUBS)
do {
char *zFileName;
void *hLibrary;
if( !zEnvPath ){
zFileName = aFileName; /* NOTE: Assume present in PATH. */
}else if( file_isdir(zEnvPath, ExtFILE)==1 ){
#if TCL_USE_SET_DLL_DIRECTORY
| > > > > > > > > > > > | 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 |
char *file_dirname(const char *zPath); /* file.h */
void fossil_free(void *p); /* util.h */
static int loadTcl(
Th_Interp *interp,
void **phLibrary,
tcl_FindExecutableProc **pxFindExecutable,
#if TCL_MAJOR_VERSION>=9
tcl_ZipfsAppHookProc **pxZipfsAppHook,
#endif
tcl_CreateInterpProc **pxCreateInterp,
tcl_DeleteInterpProc **pxDeleteInterp,
tcl_FinalizeProc **pxFinalize
){
#if defined(USE_TCL_STUBS)
const char *zEnvPath = fossil_getenv(TCL_PATH_ENV_VAR_NAME);
char aFileName[] = TCL_LIBRARY_NAME;
#endif /* defined(USE_TCL_STUBS) */
if( !phLibrary || !pxFindExecutable || !pxCreateInterp ||
!pxDeleteInterp || !pxFinalize ){
Th_ErrorMessage(interp,
"invalid Tcl loader argument(s)", (const char *)"", 0);
return TH_ERROR;
}
#if defined(USE_TCL_STUBS)
#if TCL_MAJOR_VERSION<9
#if defined(_WIN32) || defined(__FreeBSD__)
aFileName[TCL_MINOR_OFFSET-1] = '0' + TCL_MAJOR_VERSION;
#else
aFileName[TCL_MINOR_OFFSET-2] = '0' + TCL_MAJOR_VERSION;
#endif
aFileName[TCL_MINOR_OFFSET] = '0' + TCL_MINOR_VERSION;
#endif
do {
char *zFileName;
void *hLibrary;
if( !zEnvPath ){
zFileName = aFileName; /* NOTE: Assume present in PATH. */
}else if( file_isdir(zEnvPath, ExtFILE)==1 ){
#if TCL_USE_SET_DLL_DIRECTORY
|
| ︙ | ︙ | |||
868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 |
hLibrary = dlopen(zFileName, RTLD_NOW | RTLD_GLOBAL);
/* NOTE: If the file name was allocated, free it now. */
if( zFileName!=aFileName ){
sqlite3_free(zFileName); zFileName = 0;
}
if( hLibrary ){
tcl_FindExecutableProc *xFindExecutable;
tcl_CreateInterpProc *xCreateInterp;
tcl_DeleteInterpProc *xDeleteInterp;
tcl_FinalizeProc *xFinalize;
const char *procName = TCL_FINDEXECUTABLE_NAME;
xFindExecutable = (tcl_FindExecutableProc *)dlsym(hLibrary, procName+1);
if( !xFindExecutable ){
xFindExecutable = (tcl_FindExecutableProc *)dlsym(hLibrary, procName);
}
if( !xFindExecutable ){
Th_ErrorMessage(interp,
"could not locate Tcl_FindExecutable", (const char *)"", 0);
dlclose(hLibrary); hLibrary = 0;
return TH_ERROR;
}
procName = TCL_CREATEINTERP_NAME;
xCreateInterp = (tcl_CreateInterpProc *)dlsym(hLibrary, procName+1);
if( !xCreateInterp ){
xCreateInterp = (tcl_CreateInterpProc *)dlsym(hLibrary, procName);
}
if( !xCreateInterp ){
Th_ErrorMessage(interp,
| > > > > > > > > > > | 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 |
hLibrary = dlopen(zFileName, RTLD_NOW | RTLD_GLOBAL);
/* NOTE: If the file name was allocated, free it now. */
if( zFileName!=aFileName ){
sqlite3_free(zFileName); zFileName = 0;
}
if( hLibrary ){
tcl_FindExecutableProc *xFindExecutable;
#if TCL_MAJOR_VERSION>=9
tcl_ZipfsAppHookProc *xZipfsAppHook;
#endif
tcl_CreateInterpProc *xCreateInterp;
tcl_DeleteInterpProc *xDeleteInterp;
tcl_FinalizeProc *xFinalize;
const char *procName = TCL_FINDEXECUTABLE_NAME;
xFindExecutable = (tcl_FindExecutableProc *)dlsym(hLibrary, procName+1);
if( !xFindExecutable ){
xFindExecutable = (tcl_FindExecutableProc *)dlsym(hLibrary, procName);
}
if( !xFindExecutable ){
Th_ErrorMessage(interp,
"could not locate Tcl_FindExecutable", (const char *)"", 0);
dlclose(hLibrary); hLibrary = 0;
return TH_ERROR;
}
#if TCL_MAJOR_VERSION>=9
procName = TCL_ZIPFSAPPHOOK_NAME;
xZipfsAppHook = (tcl_ZipfsAppHookProc *)dlsym(hLibrary, procName+1);
if( !xZipfsAppHook ){
xZipfsAppHook = (tcl_ZipfsAppHookProc *)dlsym(hLibrary, procName);
}
#endif
procName = TCL_CREATEINTERP_NAME;
xCreateInterp = (tcl_CreateInterpProc *)dlsym(hLibrary, procName+1);
if( !xCreateInterp ){
xCreateInterp = (tcl_CreateInterpProc *)dlsym(hLibrary, procName);
}
if( !xCreateInterp ){
Th_ErrorMessage(interp,
|
| ︙ | ︙ | |||
917 918 919 920 921 922 923 924 925 926 927 928 |
Th_ErrorMessage(interp,
"could not locate Tcl_Finalize", (const char *)"", 0);
dlclose(hLibrary); hLibrary = 0;
return TH_ERROR;
}
*phLibrary = hLibrary;
*pxFindExecutable = xFindExecutable;
*pxCreateInterp = xCreateInterp;
*pxDeleteInterp = xDeleteInterp;
*pxFinalize = xFinalize;
return TH_OK;
}
| > > > | | > > > | 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 |
Th_ErrorMessage(interp,
"could not locate Tcl_Finalize", (const char *)"", 0);
dlclose(hLibrary); hLibrary = 0;
return TH_ERROR;
}
*phLibrary = hLibrary;
*pxFindExecutable = xFindExecutable;
#if TCL_MAJOR_VERSION>=9
*pxZipfsAppHook = xZipfsAppHook;
#endif
*pxCreateInterp = xCreateInterp;
*pxDeleteInterp = xDeleteInterp;
*pxFinalize = xFinalize;
return TH_OK;
}
} while( --aFileName[TCL_MINOR_OFFSET]!='6' && aFileName[TCL_MINOR_OFFSET]>='0'); /* Tcl 8.6+ */
aFileName[TCL_MINOR_OFFSET] = 'x';
Th_ErrorMessage(interp,
"could not load any supported Tcl shared library \"",
aFileName, -1);
return TH_ERROR;
#else
*phLibrary = 0;
*pxFindExecutable = Tcl_FindExecutable;
#if TCL_MAJOR_VERSION>=9
*pxZipfsAppHook = (tcl_ZipfsAppHookProc *)(void *)TclZipfs_AppHook;
#endif
*pxCreateInterp = Tcl_CreateInterp;
*pxDeleteInterp = Tcl_DeleteInterp;
*pxFinalize = Tcl_Finalize;
return TH_OK;
#endif /* defined(USE_TCL_STUBS) */
}
|
| ︙ | ︙ | |||
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 |
"invalid Tcl context", (const char *)"", 0);
return TH_ERROR;
}
if( tclContext->interp ){
return TH_OK;
}
if( loadTcl(interp, &tclContext->hLibrary, &tclContext->xFindExecutable,
&tclContext->xCreateInterp, &tclContext->xDeleteInterp,
&tclContext->xFinalize)!=TH_OK ){
return TH_ERROR;
}
argc = tclContext->argc;
argv = tclContext->argv;
if( argc>0 && argv ){
argv0 = argv[0];
}
tclContext->xFindExecutable(argv0);
tclInterp = tclContext->xCreateInterp();
if( !tclInterp ){
Th_ErrorMessage(interp,
"could not create Tcl interpreter", (const char *)"", 0);
return TH_ERROR;
}
#if defined(USE_TCL_STUBS)
#if defined(FOSSIL_ENABLE_TCL_PRIVATE_STUBS)
if( initTclStubs(interp, tclInterp)!=TH_OK ){
tclContext->xDeleteInterp(tclInterp);
tclInterp = 0;
return TH_ERROR;
}
#else
| > > > > > > > > | | 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 |
"invalid Tcl context", (const char *)"", 0);
return TH_ERROR;
}
if( tclContext->interp ){
return TH_OK;
}
if( loadTcl(interp, &tclContext->hLibrary, &tclContext->xFindExecutable,
#if TCL_MAJOR_VERSION >= 9
&tclContext->xZipfsAppHook,
#endif
&tclContext->xCreateInterp, &tclContext->xDeleteInterp,
&tclContext->xFinalize)!=TH_OK ){
return TH_ERROR;
}
argc = tclContext->argc;
argv = tclContext->argv;
if( argc>0 && argv ){
argv0 = argv[0];
}
#if TCL_MAJOR_VERSION>=9
if (tclContext->xZipfsAppHook) {
tclContext->xZipfsAppHook(&tclContext->argc, &tclContext->argv);
}
#endif
tclContext->xFindExecutable(argv0);
tclInterp = tclContext->xCreateInterp();
if( !tclInterp ){
Th_ErrorMessage(interp,
"could not create Tcl interpreter", (const char *)"", 0);
return TH_ERROR;
}
#if defined(USE_TCL_STUBS)
#if defined(FOSSIL_ENABLE_TCL_PRIVATE_STUBS)
if( initTclStubs(interp, tclInterp)!=TH_OK ){
tclContext->xDeleteInterp(tclInterp);
tclInterp = 0;
return TH_ERROR;
}
#else
if( !Tcl_InitStubs(tclInterp, "8.5-", 0) ){
Th_ErrorMessage(interp,
"could not initialize Tcl stubs", (const char *)"", 0);
tclContext->xDeleteInterp(tclInterp);
tclInterp = 0;
return TH_ERROR;
}
#endif /* defined(FOSSIL_ENABLE_TCL_PRIVATE_STUBS) */
|
| ︙ | ︙ |
Changes to src/timeline.c.
| ︙ | ︙ | |||
113 114 115 116 117 118 119 | #define TIMELINE_SHOWRID 0x0000400 /* Show RID values in addition to hashes */ #define TIMELINE_BISECT 0x0000800 /* Show supplemental bisect information */ #define TIMELINE_COMPACT 0x0001000 /* Use the "compact" view style */ #define TIMELINE_VERBOSE 0x0002000 /* Use the "detailed" view style */ #define TIMELINE_MODERN 0x0004000 /* Use the "modern" view style */ #define TIMELINE_COLUMNAR 0x0008000 /* Use the "columns" view style */ #define TIMELINE_CLASSIC 0x0010000 /* Use the "classic" view style */ | > > | | 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | #define TIMELINE_SHOWRID 0x0000400 /* Show RID values in addition to hashes */ #define TIMELINE_BISECT 0x0000800 /* Show supplemental bisect information */ #define TIMELINE_COMPACT 0x0001000 /* Use the "compact" view style */ #define TIMELINE_VERBOSE 0x0002000 /* Use the "detailed" view style */ #define TIMELINE_MODERN 0x0004000 /* Use the "modern" view style */ #define TIMELINE_COLUMNAR 0x0008000 /* Use the "columns" view style */ #define TIMELINE_CLASSIC 0x0010000 /* Use the "classic" view style */ #define TIMELINE_SIMPLE 0x0020000 /* Use the "simple" view style */ #define TIMELINE_INLINE 0x0033000 /* Mask for views with in-line display */ #define TIMELINE_VIEWS 0x003f000 /* Mask for all of the view styles */ #define TIMELINE_NOSCROLL 0x0100000 /* Don't scroll to the selection */ #define TIMELINE_FILEDIFF 0x0200000 /* Show File differences, not ckin diffs */ #define TIMELINE_CHPICK 0x0400000 /* Show cherrypick merges */ #define TIMELINE_FILLGAPS 0x0800000 /* Dotted lines for missing nodes */ #define TIMELINE_XMERGE 0x1000000 /* Omit merges from off-graph nodes */ #define TIMELINE_NOTKT 0x2000000 /* Omit extra ticket classes */ #define TIMELINE_FORUMTXT 0x4000000 /* Render all forum messages */ |
| ︙ | ︙ | |||
168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
if( pPost ){
sqlite3_result_text(context, pPost->zWiki, -1, SQLITE_TRANSIENT);
manifest_destroy(pPost);
}
}
/*
** Output a timeline in the web format given a query. The query
** should return these columns:
**
** 0. rid
** 1. artifact hash
** 2. Date/Time
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 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 349 350 351 352 353 354 355 |
if( pPost ){
sqlite3_result_text(context, pPost->zWiki, -1, SQLITE_TRANSIENT);
manifest_destroy(pPost);
}
}
/*
** This routine generates the default "extra" text after the description
** in a timeline.
**
** Example: "(check-in: [abcdefg], user: drh, tags: trunk)"
**
** This routine is used if no xExtra argument is supplied to
** www_print_timeline().
*/
void timeline_extra(
Stmt *pQuery, /* Current row of the timeline query */
int tmFlags, /* Flags to www_print_timeline() */
const char *zThisUser, /* Suppress links to this user */
const char *zThisTag /* Suppress links to this tag */
){
int rid = db_column_int(pQuery, 0);
const char *zUuid = db_column_text(pQuery, 1);
const char *zDate = db_column_text(pQuery, 2);
const char *zType = db_column_text(pQuery, 7);
const char *zUser = db_column_text(pQuery, 4);
const char *zTagList = db_column_text(pQuery, 8);
int tagid = db_column_int(pQuery, 9);
const char *zDispUser = zUser && zUser[0] ? zUser : "anonymous";
if( (tmFlags & TIMELINE_INLINE)!=0 ){
cgi_printf("(");
}
if( (tmFlags & TIMELINE_CLASSIC)==0 ){
if( zType[0]=='c' ){
const char *zPrefix = 0;
static int markLeaves = -1;
if( markLeaves<0 ){
markLeaves = db_get_int("timeline-mark-leaves",1);
if( markLeaves<0 ) markLeaves = 1;
}
if( strcmp(zUuid, MANIFEST_UUID)==0 ){
/* This will only ever happen when Fossil is drawing a timeline for
** its own self-host repository. If the timeline shows the specific
** check-in corresponding to the current executable, then tag that
** check-in with "self" */
zPrefix = "self ";
}else if( markLeaves && db_column_int(pQuery,5) ){
if( markLeaves==1 ){
zPrefix = has_closed_tag(rid) ? "closed " : "leaf ";
}else{
zPrefix = has_closed_tag(rid) ?
"<span class='timelineLeaf'>Closed-Leaf</span>\n" :
"<span class='timelineLeaf'>Leaf</span>\n";
}
}
cgi_printf("%scheck-in: %z<span class='timelineHash'>"
"%S</span></a> ",
zPrefix, href("%R/info/%!S",zUuid),zUuid);
}else if( zType[0]=='e' && tagid ){
cgi_printf("technote: ");
hyperlink_to_event_tagid(tagid<0?-tagid:tagid);
}else{
cgi_printf("artifact: %z%S</a> ",
href("%R/info/%!S",zUuid),zUuid);
}
}else if( zType[0]=='g' || zType[0]=='w' || zType[0]=='t'
|| zType[0]=='n' || zType[0]=='f'){
cgi_printf("artifact: %z%S</a> ",href("%R/info/%!S",zUuid),zUuid);
}
if( (tmFlags & TIMELINE_SIMPLE)!=0 ){
@ <span class='timelineEllipsis' id='ellipsis-%d(rid)' \
@ data-id='%d(rid)'>...</span>
@ <span class='clutter' id='detail-%d(rid)'>
}
if( g.perm.Hyperlink && fossil_strcmp(zDispUser, zThisUser)!=0 ){
char *zLink;
if( zType[0]!='f' || (tmFlags & TIMELINE_FORUMTXT)==0 ){
zLink = mprintf("%R/timeline?u=%h&c=%t&y=a", zDispUser, zDate);
}else{
zLink = mprintf("%R/timeline?u=%h&c=%t&y=a&vfx", zDispUser, zDate);
}
cgi_printf("user: %z%h</a>", href("%z",zLink), zDispUser);
}else{
cgi_printf("user: %h", zDispUser);
}
/* Generate the "tags: TAGLIST" at the end of the comment, together
** with hyperlinks to the tag list.
*/
if( zTagList && zTagList[0]==0 ) zTagList = 0;
if( zTagList ){
if( g.perm.Hyperlink ){
int i;
const char *z = zTagList;
Blob links;
blob_zero(&links);
while( z && z[0] ){
for(i=0; z[i] && (z[i]!=',' || z[i+1]!=' '); i++){}
if( zThisTag==0 || memcmp(z, zThisTag, i)!=0 || zThisTag[i]!=0 ){
blob_appendf(&links,
"%z%#h</a>%.2s",
href("%R/timeline?r=%#t&c=%t",i,z,zDate), i,z, &z[i]
);
}else{
blob_appendf(&links, "%#h", i+2, z);
}
if( z[i]==0 ) break;
z += i+2;
}
cgi_printf(" tags: %s", blob_str(&links));
blob_reset(&links);
}else{
cgi_printf(" tags: %h", zTagList);
}
}
if( tmFlags & TIMELINE_SHOWRID ){
int srcId = delta_source_rid(rid);
if( srcId ){
cgi_printf(" id: %z%d←%d</a>",
href("%R/deltachain/%d",rid), rid, srcId);
}else{
cgi_printf(" id: %z%d</a>",
href("%R/deltachain/%d",rid), rid);
}
}
tag_private_status(rid);
if( (tmFlags & TIMELINE_SIMPLE)!=0 ){
cgi_printf("</span>"); /* End of the declutter span */
}
/* End timelineDetail */
if( (tmFlags & TIMELINE_INLINE)!=0 ){
cgi_printf(")");
}
}
/*
** SETTING: timeline-truncate-at-blank boolean default=off
**
** If enabled, check-in comments displayed on the timeline are truncated
** at the first blank line of the comment text. The comment text after
** the first blank line is only seen in the /info or similar pages that
** show details about the check-in.
*/
/*
** SETTING: timeline-tslink-info boolean default=off
**
** The hyperlink on the timestamp associated with each timeline entry,
** on the far left-hand side of the screen, normally targets another
** /timeline page that shows the entry in context. However, if this
** option is turned on, that hyperlink targets the /info page showing
** the details of the entry.
*/
/*
** SETTING: timeline-mark-leaves width=5 default=1
**
** Determine whether or not leaf check-ins are marked as such in the
** details section of the timeline. The value is an integer between 0
** and 2:
**
** 0 Do not show any special marking for leaf check-ins.
**
** 1 Show just "leaf" or "closed"
**
** 2 Show "Leaf" or "Closed-Leaf" with emphasis
**
** The default is currently 1. Prior to 2025-10-19, the default was 2.
** This setting has no effect on the "Classic" view, which always behaves
** as if the setting were 2.
*/
/*
** Output a timeline in the web format given a query. The query
** should return these columns:
**
** 0. rid
** 1. artifact hash
** 2. Date/Time
|
| ︙ | ︙ | |||
192 193 194 195 196 197 198 | Stmt *pQuery, /* Query to implement the timeline */ int tmFlags, /* Flags controlling display behavior */ const char *zThisUser, /* Suppress links to this user */ const char *zThisTag, /* Suppress links to this tag */ Matcher *pLeftBranch, /* Comparison function to use for zLeftBranch */ int selectedRid, /* Highlight the line with this RID value or zero */ int secondRid, /* Secondary highlight (or zero) */ | | > > > < < < < < < < < < < < < < < < < < > > < | < < < | 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 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 444 445 446 447 |
Stmt *pQuery, /* Query to implement the timeline */
int tmFlags, /* Flags controlling display behavior */
const char *zThisUser, /* Suppress links to this user */
const char *zThisTag, /* Suppress links to this tag */
Matcher *pLeftBranch, /* Comparison function to use for zLeftBranch */
int selectedRid, /* Highlight the line with this RID value or zero */
int secondRid, /* Secondary highlight (or zero) */
void (*xExtra)(Stmt*,int,const char*,const char*) /* generate "extra" text */
){
int mxWikiLen;
Blob comment;
int prevTagid = 0;
int suppressCnt = 0;
char zPrevDate[20];
GraphContext *pGraph = 0;
int prevWasDivider = 0; /* True if previous output row was <hr> */
int fchngQueryInit = 0; /* True if fchngQuery is initialized */
Stmt fchngQuery; /* Query for file changes on check-ins */
int pendingEndTr = 0; /* True if a </td></tr> is needed */
int vid = 0; /* Current check-out version */
int dateFormat = 0; /* 0: HH:MM (default) */
int bCommentGitStyle = 0; /* Only show comments through first blank line */
const char *zStyle; /* Sub-name for classes for the style */
const char *zDateFmt;
int iTableId = timeline_tableid();
int bTimestampLinksToInfo; /* True if timestamp hyperlinks go to the /info
** page rather than the /timeline page */
const char *zMainBranch = db_main_branch();
if( cgi_is_loopback(g.zIpAddr) && db_open_local(0) ){
vid = db_lget_int("checkout", 0);
}
if( xExtra==0 ) xExtra = timeline_extra;
zPrevDate[0] = 0;
mxWikiLen = db_get_int("timeline-max-comment", 0);
dateFormat = db_get_int("timeline-date-format", 0);
bCommentGitStyle = db_get_int("timeline-truncate-at-blank", 0);
bTimestampLinksToInfo = db_get_boolean("timeline-tslink-info", 0);
if( (tmFlags & TIMELINE_VIEWS)==0 ){
tmFlags |= timeline_ss_cookie();
}
if( tmFlags & TIMELINE_COLUMNAR ){
zStyle = "Columnar";
}else if( tmFlags & TIMELINE_COMPACT ){
zStyle = "Compact";
}else if( tmFlags & TIMELINE_SIMPLE ){
zStyle = "Simple";
}else if( tmFlags & TIMELINE_VERBOSE ){
zStyle = "Verbose";
}else if( tmFlags & TIMELINE_CLASSIC ){
zStyle = "Classic";
}else{
zStyle = "Modern";
}
zDateFmt = P("datefmt");
if( zDateFmt ) dateFormat = atoi(zDateFmt);
pGraph = graph_init();
if( (tmFlags & TIMELINE_CHPICK)!=0
&& !db_table_exists("repository","cherrypick")
){
tmFlags &= ~TIMELINE_CHPICK;
}
@ <table id="timelineTable%d(iTableId)" class="timelineTable"> \
@ <!-- tmFlags: 0x%x(tmFlags) -->
blob_zero(&comment);
while( db_step(pQuery)==SQLITE_ROW ){
int rid = db_column_int(pQuery, 0);
const char *zUuid = db_column_text(pQuery, 1);
int isLeaf = db_column_int(pQuery, 5);
const char *zBgClr = db_column_text(pQuery, 6);
const char *zDate = db_column_text(pQuery, 2);
const char *zType = db_column_text(pQuery, 7);
const char *zUser = db_column_text(pQuery, 4);
int tagid = db_column_int(pQuery, 9);
char *zBr = 0; /* Branch */
int commentColumn = 3; /* Column containing comment text */
int modPending; /* Pending moderation */
char *zDateLink; /* URL for the link on the timestamp */
int drawDetailEllipsis; /* True to show ellipsis in place of detail */
int gidx = 0; /* Graph row identifier */
int isSelectedOrCurrent = 0; /* True if current row is selected */
|
| ︙ | ︙ | |||
432 433 434 435 436 437 438 |
&& (pGraph || zBgClr==0 || (tmFlags & (TIMELINE_BRCOLOR|TIMELINE_DELTA))!=0)
){
zBr = branch_of_rid(rid);
if( zBgClr==0 || (tmFlags & TIMELINE_BRCOLOR)!=0 ){
/* If no background color is specified, use a color based on the
** branch name */
if( tmFlags & (TIMELINE_DELTA|TIMELINE_NOCOLOR) ){
| | > | | | | | | | | | | | | | | | | | | | | | | > | 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 |
&& (pGraph || zBgClr==0 || (tmFlags & (TIMELINE_BRCOLOR|TIMELINE_DELTA))!=0)
){
zBr = branch_of_rid(rid);
if( zBgClr==0 || (tmFlags & TIMELINE_BRCOLOR)!=0 ){
/* If no background color is specified, use a color based on the
** branch name */
if( tmFlags & (TIMELINE_DELTA|TIMELINE_NOCOLOR) ){
}else if( zBr==0 || strcmp(zBr, zMainBranch)==0 ){
zBgClr = 0;
}else{
zBgClr = hash_color(zBr);
}
}
}
if( zType[0]=='c' && pGraph ){
int nParent = 0;
int nCherrypick = 0;
GraphRowId aParent[GR_MAX_RAIL];
static Stmt qparent;
if( tmFlags & TIMELINE_GRAPH ){
db_static_prepare(&qparent,
"SELECT pid FROM plink"
" WHERE cid=:rid AND pid NOT IN phantom"
" ORDER BY isprim DESC /*sort*/"
);
db_bind_int(&qparent, ":rid", rid);
while( db_step(&qparent)==SQLITE_ROW && nParent<count(aParent) ){
aParent[nParent++] = db_column_int(&qparent, 0);
}
db_reset(&qparent);
if( (tmFlags & TIMELINE_CHPICK)!=0 && nParent>0 ){
static Stmt qcherrypick;
db_static_prepare(&qcherrypick,
"SELECT parentid FROM cherrypick"
" WHERE childid=:rid AND parentid NOT IN phantom"
);
db_bind_int(&qcherrypick, ":rid", rid);
while( db_step(&qcherrypick)==SQLITE_ROW && nParent<count(aParent) ){
aParent[nParent++] = db_column_int(&qcherrypick, 0);
nCherrypick++;
}
db_reset(&qcherrypick);
}
}
gidx = graph_add_row(pGraph, rid, nParent, nCherrypick, aParent,
zBr, zBgClr, zUuid,
isLeaf ? isLeaf + 2 * has_closed_tag(rid) : 0);
@ <div id="m%d(gidx)" class="tl-nodemark"></div>
}else if( zType[0]=='e' && pGraph && zBgClr && zBgClr[0] ){
/* For technotes, make a graph node with nParent==(-1). This will
|
| ︙ | ︙ | |||
596 597 598 599 600 601 602 |
@ %W(blob_str(&truncated))
blob_reset(&truncated);
drawDetailEllipsis = 0;
}else{
cgi_printf("%W",blob_str(&comment));
}
}
| < < < < < < < < | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < | | 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 |
@ %W(blob_str(&truncated))
blob_reset(&truncated);
drawDetailEllipsis = 0;
}else{
cgi_printf("%W",blob_str(&comment));
}
}
@ </span>
blob_reset(&comment);
/* Generate extra information and hyperlinks that follow the comment.
** Example: "(check-in: [abcdefg], user: drh, tags: trunk)"
*/
if( drawDetailEllipsis ){
@ <span class='timelineEllipsis' id='ellipsis-%d(rid)' \
@ data-id='%d(rid)'>...</span>
}
if( tmFlags & TIMELINE_COLUMNAR ){
if( !isSelectedOrCurrent ){
@ <td class="timelineDetailCell%s(zExtraClass)" id='md%d(gidx)'>
}else{
@ <td class="timelineDetailCell%s(zExtraClass)">
}
}
if( tmFlags & TIMELINE_COMPACT ){
cgi_printf("<span class='clutter' id='detail-%d'>",rid);
}
cgi_printf("<span class='timeline%sDetail'>", zStyle);
xExtra(pQuery, tmFlags, zThisUser, zThisTag);
if( tmFlags & TIMELINE_COMPACT ){
@ </span></span>
}else{
@ </span>
}
/* Generate the file-change list if requested */
if( (tmFlags & (TIMELINE_FCHANGES|TIMELINE_FRENAMES))!=0
&& zType[0]=='c' && g.perm.Hyperlink
){
int inUl = 0;
if( !fchngQueryInit ){
db_prepare(&fchngQuery,
|
| ︙ | ︙ | |||
906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 |
int iTopRow; /* Index of the top row of the graph */
int fileDiff; /* True for file diff. False for check-in diff */
int omitDescenders; /* True to omit descenders */
int scrollToSelect; /* True to scroll to the selection */
int dwellTimeout; /* Milliseconds to wait for tooltips to show */
int closeTimeout; /* Milliseconds to wait for tooltips to close */
u8 *aiMap; /* The rail map */
iRailPitch = atoi(PD("railpitch","0"));
showArrowheads = skin_detail_boolean("timeline-arrowheads");
circleNodes = skin_detail_boolean("timeline-circle-nodes");
colorGraph = skin_detail_boolean("timeline-color-graph-lines");
iTopRow = pGraph->pFirst ? pGraph->pFirst->idx : 0;
omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0;
fileDiff = (tmFlags & TIMELINE_FILEDIFF)!=0;
| > > | 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 |
int iTopRow; /* Index of the top row of the graph */
int fileDiff; /* True for file diff. False for check-in diff */
int omitDescenders; /* True to omit descenders */
int scrollToSelect; /* True to scroll to the selection */
int dwellTimeout; /* Milliseconds to wait for tooltips to show */
int closeTimeout; /* Milliseconds to wait for tooltips to close */
u8 *aiMap; /* The rail map */
u8 bNoGraph; /* True to show a minimal graph */
bNoGraph = (tmFlags & TIMELINE_GRAPH)==0;
iRailPitch = atoi(PD("railpitch","0"));
showArrowheads = skin_detail_boolean("timeline-arrowheads");
circleNodes = skin_detail_boolean("timeline-circle-nodes");
colorGraph = skin_detail_boolean("timeline-color-graph-lines");
iTopRow = pGraph->pFirst ? pGraph->pFirst->idx : 0;
omitDescenders = (tmFlags & TIMELINE_DISJOINT)!=0;
fileDiff = (tmFlags & TIMELINE_FILEDIFF)!=0;
|
| ︙ | ︙ | |||
928 929 930 931 932 933 934 |
@ "iRailPitch": %d(iRailPitch),
@ "colorGraph": %d(colorGraph),
@ "nomo": %d(PB("nomo")),
@ "iTopRow": %d(iTopRow),
@ "omitDescenders": %d(omitDescenders),
@ "fileDiff": %d(fileDiff),
@ "scrollToSelect": %d(scrollToSelect),
| | | 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 |
@ "iRailPitch": %d(iRailPitch),
@ "colorGraph": %d(colorGraph),
@ "nomo": %d(PB("nomo")),
@ "iTopRow": %d(iTopRow),
@ "omitDescenders": %d(omitDescenders),
@ "fileDiff": %d(fileDiff),
@ "scrollToSelect": %d(scrollToSelect),
@ "nrail": %d(bNoGraph?1:pGraph->mxRail+1),
@ "baseUrl": "%R",
@ "dwellTimeout": %d(dwellTimeout),
@ "closeTimeout": %d(closeTimeout),
@ "hashDigits": %d(hash_digits(1)),
@ "bottomRowId": "btm-%d(iTableId)",
if( pGraph->nRow==0 ){
@ "rowinfo": null
|
| ︙ | ︙ | |||
990 991 992 993 994 995 996 |
* br: The branch to which the artifact belongs
*/
aiMap = pGraph->aiRailMap;
for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){
int k = 0;
cgi_printf("{\"id\":%d,", pRow->idx);
cgi_printf("\"bg\":\"%s\",", pRow->zBgClr);
| > > > | > | > > | | 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 |
* br: The branch to which the artifact belongs
*/
aiMap = pGraph->aiRailMap;
for(pRow=pGraph->pFirst; pRow; pRow=pRow->pNext){
int k = 0;
cgi_printf("{\"id\":%d,", pRow->idx);
cgi_printf("\"bg\":\"%s\",", pRow->zBgClr);
if( bNoGraph ){
cgi_printf("\"r\":0,"); /* Chng to ":-1" to omit node circles */
}else{
cgi_printf("\"r\":%d,", pRow->iRail>=0 ? aiMap[pRow->iRail] : -1);
}
if( pRow->bDescender && !bNoGraph ){
cgi_printf("\"d\":%d,", pRow->bDescender);
}
if( pRow->mergeOut>=0 ){
cgi_printf("\"mo\":%d,", aiMap[pRow->mergeOut]);
if( pRow->mergeUpto==0 ) pRow->mergeUpto = pRow->idx;
cgi_printf("\"mu\":%d,", pRow->mergeUpto);
if( pRow->cherrypickUpto>0 && pRow->cherrypickUpto<=pRow->mergeUpto ){
cgi_printf("\"cu\":%d,", pRow->cherrypickUpto);
}
}
if( bNoGraph ){
cgi_printf("\"u\":-1,");
}else if( pRow->isStepParent ){
cgi_printf("\"sb\":%d,", pRow->aiRiser[pRow->iRail]);
}else{
cgi_printf("\"u\":%d,", pRow->aiRiser[pRow->iRail]);
}
k = 0;
if( pRow->isLeaf ) k |= 1;
if( pRow->isLeaf & 2) k |= 2;
|
| ︙ | ︙ | |||
1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 |
assert( i<=count(az) );
}
if( i>2 ){
style_submenu_multichoice("y", i/2, az, isDisabled);
}
}
/*
** Return the default value for the "ss" cookie or query parameter.
** The "ss" cookie determines the graph style. See the
** timeline_view_styles[] global constant for a list of choices.
*/
const char *timeline_default_ss(void){
static const char *zSs = 0;
| > > > > > > > > > > > > > > > > | 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 |
assert( i<=count(az) );
}
if( i>2 ){
style_submenu_multichoice("y", i/2, az, isDisabled);
}
}
/*
** SETTING: timeline-default-style width=5 default=m
**
** This setting determines the default "view style" for timelines.
** The setting should be a single character, one of the following:
**
** c Compact
** j Columnar
** m Modern
** s Simple
** v Verbose
** x Classic
**
** The default value is m (Modern).
*/
/*
** Return the default value for the "ss" cookie or query parameter.
** The "ss" cookie determines the graph style. See the
** timeline_view_styles[] global constant for a list of choices.
*/
const char *timeline_default_ss(void){
static const char *zSs = 0;
|
| ︙ | ︙ | |||
1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 |
const char *v = cookie_value("ss",0);
if( v==0 ) v = timeline_default_ss();
switch( v[0] ){
case 'c': tmFlags = TIMELINE_COMPACT; break;
case 'v': tmFlags = TIMELINE_VERBOSE; break;
case 'j': tmFlags = TIMELINE_COLUMNAR; break;
case 'x': tmFlags = TIMELINE_CLASSIC; break;
default: tmFlags = TIMELINE_MODERN; break;
}
return tmFlags;
}
/* Available timeline display styles, together with their y= query
** parameter names.
*/
const char *const timeline_view_styles[] = {
"m", "Modern View",
"j", "Columnar View",
"c", "Compact View",
"v", "Verbose View",
"x", "Classic View",
};
#if INTERFACE
| > > | | 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 |
const char *v = cookie_value("ss",0);
if( v==0 ) v = timeline_default_ss();
switch( v[0] ){
case 'c': tmFlags = TIMELINE_COMPACT; break;
case 'v': tmFlags = TIMELINE_VERBOSE; break;
case 'j': tmFlags = TIMELINE_COLUMNAR; break;
case 'x': tmFlags = TIMELINE_CLASSIC; break;
case 's': tmFlags = TIMELINE_SIMPLE; break;
default: tmFlags = TIMELINE_MODERN; break;
}
return tmFlags;
}
/* Available timeline display styles, together with their y= query
** parameter names.
*/
const char *const timeline_view_styles[] = {
"m", "Modern View",
"j", "Columnar View",
"c", "Compact View",
"s", "Simple View",
"v", "Verbose View",
"x", "Classic View",
};
#if INTERFACE
# define N_TIMELINE_VIEW_STYLE 6
#endif
/*
** Add the select/option box to the timeline submenu that is used to
** set the ss= parameter that determines the viewing mode.
**
** Return the TIMELINE_* value appropriate for the view-style.
|
| ︙ | ︙ | |||
1361 1362 1363 1364 1365 1366 1367 |
**
** with an optional "Z" timeline modifier at the end. Return true if
** the input is a valid date space and false if not.
*/
static int timeline_is_datespan(const char *zDay){
size_t n = strlen(zDay);
int i, d, m;
| | | 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 |
**
** with an optional "Z" timeline modifier at the end. Return true if
** the input is a valid date space and false if not.
*/
static int timeline_is_datespan(const char *zDay){
size_t n = strlen(zDay);
int i, d, m;
if( n<17 || n>18 ) return 0;
if( n==18 ){
if( zDay[17]!='Z' && zDay[17]!='z' ) return 0;
n--;
}
if( zDay[8]!='-' ) return 0;
for(i=0; i<17 && (fossil_isdigit(zDay[i]) || i==8); i++){}
|
| ︙ | ︙ | |||
1387 1388 1389 1390 1391 1392 1393 | return 1; } /* ** Find the first check-in encountered with a particular tag ** when moving either forwards are backwards in time from a ** particular starting point (iFrom). Return the rid of that | | | | 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 |
return 1;
}
/*
** Find the first check-in encountered with a particular tag
** when moving either forwards are backwards in time from a
** particular starting point (iFrom). Return the rid of that
** first check-in. If there are no check-ins in the descendent
** or ancestor set of check-in iFrom that match the tag, then
** return 0.
*/
static int timeline_endpoint(
int iFrom, /* Starting point */
const char *zEnd, /* Tag we are searching for */
int bForward /* 1: forwards in time (descendants) 0: backwards */
){
int tagId;
int endId = 0;
Stmt q;
int ans = 0;
|
| ︙ | ︙ | |||
1588 1589 1590 1591 1592 1593 1594 | ** ft=DESCENDANT ... going forward to DESCENDANT ** dp=CHECKIN Same as 'd=CHECKIN&p=CHECKIN' ** dp2=CKIN2 Same as 'd2=CKIN2&p2=CKIN2' ** df=CHECKIN Same as 'd=CHECKIN&n1=all&nd'. Mnemonic: "Derived From" ** bt=CHECKIN "Back To". Show ancenstors going back to CHECKIN ** p=CX ... from CX back to time of CHECKIN ** from=CX ... path from CX back to CHECKIN | | | | 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 1713 | ** ft=DESCENDANT ... going forward to DESCENDANT ** dp=CHECKIN Same as 'd=CHECKIN&p=CHECKIN' ** dp2=CKIN2 Same as 'd2=CKIN2&p2=CKIN2' ** df=CHECKIN Same as 'd=CHECKIN&n1=all&nd'. Mnemonic: "Derived From" ** bt=CHECKIN "Back To". Show ancenstors going back to CHECKIN ** p=CX ... from CX back to time of CHECKIN ** from=CX ... path from CX back to CHECKIN ** ft=CHECKIN "Forward To": Show descendents forward to CHECKIN ** d=CX ... from CX up to the time of CHECKIN ** from=CX ... path from CX up to CHECKIN ** t=TAG Show only check-ins with the given TAG ** r=TAG Same as 't=TAG&rel'. Mnemonic: "Related" ** tl=TAGLIST Same as 't=TAGLIST&ms=brlist'. Mnemonic: "Tag List" ** rl=TAGLIST Same as 'r=TAGLIST&ms=brlist'. Mnemonic: "Related List" ** ml=TAGLIST Same as 'tl=TAGLIST&mionly'. Mnemonic: "Merge-in List" ** sl=TAGLIST "Sort List". Draw TAGLIST branches ordered left to right. ** rel Show related check-ins as well as those matching t=TAG ** mionly Show related parents but not related children. ** nowiki Do not show wiki associated with branch or tag ** ms=MATCHSTYLE Set tag name match algorithm. One of "exact", "glob", ** "like", or "regexp". ** u=USER Only show items associated with USER ** y=TYPE 'ci', 'w', 't', 'n', 'e', 'f', or 'all'. ** ss=VIEWSTYLE c: "Compact", v: "Verbose", m: "Modern", j: "Columnar", ** x: "Classic". ** advm Use the "Advanced" or "Busy" menu design. ** ng No Graph. ** ncp Omit cherrypick merges ** nd Do not highlight the focus check-in ** nsm Omit the submenu ** nc Omit all graph colors other than highlights ** v Show details of files changed |
| ︙ | ︙ | |||
1828 1829 1830 1831 1832 1833 1834 |
}
if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum)
|| (bisectLocal && !g.perm.Setup)
){
login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
return;
}
| > | > | 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 |
}
if( (!g.perm.Read && !g.perm.RdTkt && !g.perm.RdWiki && !g.perm.RdForum)
|| (bisectLocal && !g.perm.Setup)
){
login_needed(g.anon.Read && g.anon.RdTkt && g.anon.RdWiki);
return;
}
if( zBefore || zCirca ){
if( robot_restrict("timelineX") ) return;
}
if( !bisectLocal ){
etag_check(ETAG_QUERY|ETAG_COOKIE|ETAG_DATA|ETAG_CONFIG, 0);
}
cookie_read_parameter("y","y");
zType = P("y");
if( zType==0 ){
zType = g.perm.Read ? "ci" : "all";
|
| ︙ | ︙ | |||
2042 2043 2044 2045 2046 2047 2048 |
disableY = 1;
}else{
zBisect = 0;
}
style_header("Timeline");
if( advancedMenu ){
| | | 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 |
disableY = 1;
}else{
zBisect = 0;
}
style_header("Timeline");
if( advancedMenu ){
style_submenu_element("Help", "%R/help/www/timeline");
}
login_anonymous_available();
timeline_temp_table();
blob_zero(&sql);
blob_zero(&desc);
blob_append(&sql, "INSERT OR IGNORE INTO timeline ", -1);
blob_append(&sql, timeline_query_for_www(), -1);
|
| ︙ | ︙ | |||
2283 2284 2285 2286 2287 2288 2289 |
zFwdTo = P("ft");
if( zFwdTo && bSeparateDandP ){
if( zError==0 ){
zError = "Cannot use the ft= query parameter when both p= and d= "
"are used and have distinct values.";
}
zFwdTo = 0;
| | | 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 |
zFwdTo = P("ft");
if( zFwdTo && bSeparateDandP ){
if( zError==0 ){
zError = "Cannot use the ft= query parameter when both p= and d= "
"are used and have distinct values.";
}
zFwdTo = 0;
}
if( zFwdTo ){
double rStartDate = mtime_of_rid(d_rid, 0.0);
ridFwdTo = first_checkin_with_tag_after_date(zFwdTo, rStartDate);
if( ridFwdTo==0 ){
ridFwdTo = name_to_typed_rid(zBackTo,"ci");
}
if( ridFwdTo ){
|
| ︙ | ︙ | |||
2342 2343 2344 2345 2346 2347 2348 |
zBackTo = P("bt");
if( zBackTo && bSeparateDandP ){
if( zError==0 ){
zError = "Cannot use the bt= query parameter when both p= and d= "
"are used and have distinct values.";
}
zBackTo = 0;
| | | 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 |
zBackTo = P("bt");
if( zBackTo && bSeparateDandP ){
if( zError==0 ){
zError = "Cannot use the bt= query parameter when both p= and d= "
"are used and have distinct values.";
}
zBackTo = 0;
}
if( zBackTo ){
double rDateLimit = mtime_of_rid(p_rid, 0.0);
ridBackTo = last_checkin_with_tag_before_date(zBackTo, rDateLimit);
if( ridBackTo==0 ){
ridBackTo = name_to_typed_rid(zBackTo,"ci");
}
if( ridBackTo && !haveParameterN ) nEntry = 0;
|
| ︙ | ︙ | |||
2368 2369 2370 2371 2372 2373 2374 |
removeFileGlobFromOk(zChng);
db_multi_exec("%s", blob_sql_text(&sql));
}else{
removeFileGlobFromOk(zChng);
np = db_int(0, "SELECT count(*)-1 FROM ok");
if( np>0 || nd==0 ){
if( nd>0 ) blob_appendf(&desc, " and ");
| | | 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 |
removeFileGlobFromOk(zChng);
db_multi_exec("%s", blob_sql_text(&sql));
}else{
removeFileGlobFromOk(zChng);
np = db_int(0, "SELECT count(*)-1 FROM ok");
if( np>0 || nd==0 ){
if( nd>0 ) blob_appendf(&desc, " and ");
blob_appendf(&desc, "%d ancestor%s",
np>=0 ? np : 0, (1==np)?"":"s");
db_multi_exec("%s", blob_sql_text(&sql));
}
if( useDividers && !selectedRid ) selectedRid = p_rid;
}
}
|
| ︙ | ︙ | |||
2651 2652 2653 2654 2655 2656 2657 |
fossil_free(zNext);
}
blob_append_sql(&cond,
" AND event.mtime>=julianday(%Q,%Q)"
" AND event.mtime<julianday(%Q,%Q,'+1 day')\n",
zStart, zTZMod, zEnd, zTZMod);
nEntry = -1;
| | | 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 |
fossil_free(zNext);
}
blob_append_sql(&cond,
" AND event.mtime>=julianday(%Q,%Q)"
" AND event.mtime<julianday(%Q,%Q,'+1 day')\n",
zStart, zTZMod, zEnd, zTZMod);
nEntry = -1;
if( fossil_ui_localtime() && bZulu ){
zDay = mprintf("%d days between %zZ and %zZ", nDay, zStart, zEnd);
}else{
zDay = mprintf("%d days between %z and %z", nDay, zStart, zEnd);
}
}
else if( zDay ){
|
| ︙ | ︙ | |||
3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 |
if( useDividers && zMark && zMark[0] ){
double r = symbolic_name_to_mtime(zMark, 0, 0);
if( r>0.0 && !selectedRid ) selectedRid = timeline_add_divider(r);
}
blob_zero(&sql);
if( PB("oldestfirst") ){
db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby ASC /*scan*/");
}else{
db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
}
if( fossil_islower(desc.aData[0]) ){
desc.aData[0] = fossil_toupper(desc.aData[0]);
}
if( zBrName ){
| > | 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 |
if( useDividers && zMark && zMark[0] ){
double r = symbolic_name_to_mtime(zMark, 0, 0);
if( r>0.0 && !selectedRid ) selectedRid = timeline_add_divider(r);
}
blob_zero(&sql);
if( PB("oldestfirst") ){
db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby ASC /*scan*/");
tmFlags &= ~(TIMELINE_GRAPH|TIMELINE_CHPICK);
}else{
db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
}
if( fossil_islower(desc.aData[0]) ){
desc.aData[0] = fossil_toupper(desc.aData[0]);
}
if( zBrName ){
|
| ︙ | ︙ | |||
3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 |
}
blob_reset(&desc);
/* Report any errors. */
if( zError ){
@ <p class="generalError">%h(zError)</p>
}
if( zNewerButton ){
@ %z(chref("button","%s",zNewerButton))%h(zNewerButtonLabel)\
@ ↑</a>
}
cgi_check_for_malice();
{
| > > > > > > > > > > | 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 |
}
blob_reset(&desc);
/* Report any errors. */
if( zError ){
@ <p class="generalError">%h(zError)</p>
}
/* Swap zNewer and zOlder buttons if we display oldestfirst */
if( PB("oldestfirst") ){
char *zSwap = zNewerButton;
char *zSwapLabel = zNewerButtonLabel;
zNewerButton = zOlderButton;
zNewerButtonLabel = zOlderButtonLabel;
zOlderButton = zSwap;
zOlderButtonLabel = zSwapLabel;
}
if( zNewerButton ){
@ %z(chref("button","%s",zNewerButton))%h(zNewerButtonLabel)\
@ ↑</a>
}
cgi_check_for_malice();
{
|
| ︙ | ︙ | |||
3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 |
** --full Extra verbose entry formatting
** -n|--limit N If N is positive, output the first N entries. If
** N is negative, output the first -N lines. If N is
** zero, no limit. Default is -20 meaning 20 lines.
** --offset P Skip P changes
** -p|--path PATH Output items affecting PATH only.
** PATH can be a file or a sub directory.
** -R REPO_FILE Specifies the repository db to use. Default is
** the current check-out's repository.
** --sql Show the SQL used to generate the timeline
** -t|--type TYPE Output items from the given types only, such as:
** ci = file commits only
** e = technical notes only
** f = forum posts only
** t = tickets only
** w = wiki commits only
** -v|--verbose Output the list of files changed by each commit
** and the type of each change (edited, deleted,
** etc.) after the check-in comment.
** -W|--width N Width of lines (default is to auto-detect). N must be
** either greater than 20 or it must be zero 0 to
** indicate no limit, resulting in a single line per
** entry.
*/
void timeline_cmd(void){
Stmt q;
int n, k, width;
const char *zLimit;
const char *zWidth;
const char *zOffset;
const char *zType;
char *zOrigin;
char *zDate;
Blob sql;
int objid = 0;
Blob uuid;
int mode = TIMELINE_MODE_NONE;
| > > > | > > | 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 |
** --full Extra verbose entry formatting
** -n|--limit N If N is positive, output the first N entries. If
** N is negative, output the first -N lines. If N is
** zero, no limit. Default is -20 meaning 20 lines.
** --offset P Skip P changes
** -p|--path PATH Output items affecting PATH only.
** PATH can be a file or a sub directory.
** -r|--reverse Show items in chronological order.
** -R REPO_FILE Specifies the repository db to use. Default is
** the current check-out's repository.
** --sql Show the SQL used to generate the timeline
** -t|--type TYPE Output items from the given types only, such as:
** ci = file commits only
** e = technical notes only
** f = forum posts only
** t = tickets only
** w = wiki commits only
** -u|--for-user USER Only show items associated with USER
** -v|--verbose Output the list of files changed by each commit
** and the type of each change (edited, deleted,
** etc.) after the check-in comment.
** -W|--width N Width of lines (default is to auto-detect). N must be
** either greater than 20 or it must be zero 0 to
** indicate no limit, resulting in a single line per
** entry.
*/
void timeline_cmd(void){
Stmt q;
int n, k, width;
const char *zLimit;
const char *zWidth;
const char *zOffset;
const char *zType;
const char *zUser;
char *zOrigin;
char *zDate;
Blob sql;
int objid = 0;
Blob uuid;
int mode = TIMELINE_MODE_NONE;
int verboseFlag = 0;
int reverseFlag = 0;
int iOffset;
const char *zFilePattern = 0;
const char *zFormat = 0;
const char *zBr = 0;
Blob treeName;
int showSql = 0;
verboseFlag = find_option("verbose","v", 0)!=0;
if( !verboseFlag){
verboseFlag = find_option("showfiles","f", 0)!=0; /* deprecated */
}
db_find_and_open_repository(0, 0);
zLimit = find_option("limit","n",1);
zWidth = find_option("width","W",1);
zType = find_option("type","t",1);
zUser = find_option("for-user","u",1);
zFilePattern = find_option("path","p",1);
zFormat = find_option("format","F",1);
zBr = find_option("branch","b",1);
if( find_option("current-branch","c",0)!=0 ){
if( !g.localOpen ){
fossil_fatal("not within an open check-out");
}else{
|
| ︙ | ︙ | |||
3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 |
fossil_fatal("-W|--width value must be >20 or 0");
}
}else{
width = -1;
}
zOffset = find_option("offset",0,1);
iOffset = zOffset ? atoi(zOffset) : 0;
/* We should be done with options.. */
verify_all_options();
if( g.argc>=4 ){
k = strlen(g.argv[2]);
if( strncmp(g.argv[2],"before",k)==0 ){
mode = TIMELINE_MODE_BEFORE;
}else if( strncmp(g.argv[2],"after",k)==0 && k>1 ){
mode = TIMELINE_MODE_AFTER;
}else if( strncmp(g.argv[2],"descendants",k)==0 ){
mode = TIMELINE_MODE_CHILDREN;
}else if( strncmp(g.argv[2],"children",k)==0 ){
mode = TIMELINE_MODE_CHILDREN;
}else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){
mode = TIMELINE_MODE_PARENTS;
}else if( strncmp(g.argv[2],"parents",k)==0 ){
mode = TIMELINE_MODE_PARENTS;
}else if(!zType && !zLimit){
usage("?WHEN? ?CHECKIN|DATETIME? ?-n|--limit #? ?-t|--type TYPE? "
| > | | 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 |
fossil_fatal("-W|--width value must be >20 or 0");
}
}else{
width = -1;
}
zOffset = find_option("offset",0,1);
iOffset = zOffset ? atoi(zOffset) : 0;
reverseFlag = find_option("reverse","r",0)!=0;
/* We should be done with options.. */
verify_all_options();
if( g.argc>=4 ){
k = strlen(g.argv[2]);
if( strncmp(g.argv[2],"before",k)==0 ){
mode = TIMELINE_MODE_BEFORE;
}else if( strncmp(g.argv[2],"after",k)==0 && k>1 ){
mode = TIMELINE_MODE_AFTER;
}else if( strncmp(g.argv[2],"descendants",k)==0 ){
mode = TIMELINE_MODE_CHILDREN;
}else if( strncmp(g.argv[2],"children",k)==0 ){
mode = TIMELINE_MODE_CHILDREN;
}else if( strncmp(g.argv[2],"ancestors",k)==0 && k>1 ){
mode = TIMELINE_MODE_PARENTS;
}else if( strncmp(g.argv[2],"parents",k)==0 ){
mode = TIMELINE_MODE_PARENTS;
}else if(!zType && !zLimit){
usage("?WHEN? ?CHECKIN|DATETIME? ?-n|--limit #? ?-t|--type TYPE? "
"?-W|--width WIDTH? ?-p|--path PATH? ?-r|--reverse?");
}
if( '-' != *g.argv[3] ){
zOrigin = g.argv[3];
}else{
zOrigin = "now";
}
}else if( g.argc==3 ){
|
| ︙ | ︙ | |||
3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 |
blob_append_sql(&sql, "\n AND event.mtime %s %s",
( mode==TIMELINE_MODE_BEFORE ||
mode==TIMELINE_MODE_PARENTS ) ? "<=" : ">=", zDate /*safe-for-%s*/
);
if( zType && (zType[0]!='a') ){
blob_append_sql(&sql, "\n AND event.type=%Q ", zType);
}
/* When zFilePattern is specified, compute complete ancestry;
* limit later at print_timeline() */
if( mode==TIMELINE_MODE_CHILDREN || mode==TIMELINE_MODE_PARENTS ){
db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
if( mode==TIMELINE_MODE_CHILDREN ){
compute_descendants(objid, (zFilePattern ? 0 : n));
| > > > | 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 |
blob_append_sql(&sql, "\n AND event.mtime %s %s",
( mode==TIMELINE_MODE_BEFORE ||
mode==TIMELINE_MODE_PARENTS ) ? "<=" : ">=", zDate /*safe-for-%s*/
);
if( zType && (zType[0]!='a') ){
blob_append_sql(&sql, "\n AND event.type=%Q ", zType);
}
if( zUser && (zUser[0]!='\0') ){
blob_append_sql(&sql, "\n AND user0=%Q ", zUser);
}
/* When zFilePattern is specified, compute complete ancestry;
* limit later at print_timeline() */
if( mode==TIMELINE_MODE_CHILDREN || mode==TIMELINE_MODE_PARENTS ){
db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
if( mode==TIMELINE_MODE_CHILDREN ){
compute_descendants(objid, (zFilePattern ? 0 : n));
|
| ︙ | ︙ | |||
3850 3851 3852 3853 3854 3855 3856 |
" AND e.comment LIKE '_checkin/%%'\n"
" LEFT JOIN tagxref tx ON tx.rid=b.rid AND tx.tagid=%d\n"
" WHERE tx.value='%q'\n"
")\n" /* No merge closures */
" AND (tagxref.value IS NULL OR tagxref.value='%q')",
zBr, zBr, zBr, TAG_BRANCH, zBr, zBr);
}
| | | | > | > | 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 |
" AND e.comment LIKE '_checkin/%%'\n"
" LEFT JOIN tagxref tx ON tx.rid=b.rid AND tx.tagid=%d\n"
" WHERE tx.value='%q'\n"
")\n" /* No merge closures */
" AND (tagxref.value IS NULL OR tagxref.value='%q')",
zBr, zBr, zBr, TAG_BRANCH, zBr, zBr);
}
if( mode==TIMELINE_MODE_AFTER ){
int lim = n;
if( n == 0 ){
lim = -1; /* 0 means no limit */
}else if( n < 0 ){
lim = -n;
}
/* Complete the above outer select. */
blob_append_sql(&sql,
"\nORDER BY event.mtime LIMIT %d) t ORDER BY t.mDateTime %s",
lim, reverseFlag ? "" : "DESC");
}else{
blob_append_sql(&sql,
"\nORDER BY event.mtime %s", reverseFlag ? "" : "DESC");
}
if( iOffset>0 ){
/* Don't handle LIMIT here, otherwise print_timeline()
* will not determine the end-marker correctly! */
blob_append_sql(&sql, "\n LIMIT -1 OFFSET %d", iOffset);
}
if( showSql ){
|
| ︙ | ︙ |
Changes to src/tkt.c.
| ︙ | ︙ | |||
789 790 791 792 793 794 795 796 797 798 799 800 801 802 |
safe_html_context(DOCSRC_TICKET);
Th_Render(zScript);
if( g.thTrace ) Th_Trace("END_TKTVIEW<br>\n", -1);
if( zFullName ){
attachment_list(zFullName, "<h2>Attachments:</h2>", 1);
}
style_finish_page();
}
/*
** TH1 command: append_field FIELD STRING
**
| > > > > | 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 |
safe_html_context(DOCSRC_TICKET);
Th_Render(zScript);
if( g.thTrace ) Th_Trace("END_TKTVIEW<br>\n", -1);
if( zFullName ){
attachment_list(zFullName, "<h2>Attachments:</h2>", 1);
}
builtin_fossil_js_bundle_or("dom", "storage", NULL);
builtin_request_js("fossil.page.ticket.js");
builtin_fulfill_js_requests();
style_finish_page();
}
/*
** TH1 command: append_field FIELD STRING
**
|
| ︙ | ︙ |
Changes to src/tktsetup.c.
| ︙ | ︙ | |||
492 493 494 495 496 497 498 |
@ html "(0)</td></tr>\n"
@ } else {
@ html "<td class='tktDspValue' colspan='3'>Deleted</td></tr>\n"
@ }
@ }
@
@ if {[capexpr {n}]} {
| | | | 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 |
@ html "(0)</td></tr>\n"
@ } else {
@ html "<td class='tktDspValue' colspan='3'>Deleted</td></tr>\n"
@ }
@ }
@
@ if {[capexpr {n}]} {
@ submenu link "Copy Ticket" $baseurl/tktnew/$tkt_uuid
@ }
@ if {[capexpr {nk}]} {
@ submenu link "Edit Wiki" $baseurl/wikiedit?name=ticket/$tkt_uuid
@ }
@ </th1>
@ <tr><td class="tktDspLabel">Title:</td>
@ <td class="tktDspValue" colspan="3">
@ $<title>
@ </td></tr>
@ <tr><td class="tktDspLabel">Status:</td><td class="tktDspValue">
|
| ︙ | ︙ | |||
611 612 613 614 615 616 617 |
@ FROM ticketchng
@ WHERE tkt_id=$tkt_id AND length(icomment)>0} {
@ if {$seenRow} {
@ html "<hr>\n"
@ } else {
@ html "<tr><td class='tktDspLabel' style='text-align:left'>\n"
@ html "User Comments:</td></tr>\n"
| | > | 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 |
@ FROM ticketchng
@ WHERE tkt_id=$tkt_id AND length(icomment)>0} {
@ if {$seenRow} {
@ html "<hr>\n"
@ } else {
@ html "<tr><td class='tktDspLabel' style='text-align:left'>\n"
@ html "User Comments:</td></tr>\n"
@ html "<tr><td colspan='5' class='tktDspValue'><div class='tktCommentArea'>\n"
@ set seenRow 1
@ }
@ html "<div class='tktCommentEntry'>"
@ html "<span class='tktDspCommenter'>"
@ puts $xlogin
@ if {$xlogin ne $xusername && [string length $xusername]>0} {
@ puts " (claiming to be $xusername)"
@ }
@ puts " added on $xdate:"
@ html "</span>\n"
|
| ︙ | ︙ | |||
635 636 637 638 639 640 641 642 |
@ html [lindex [markdown $xcomment] 1]
@ } elseif {$xmimetype eq "text/html"} {
@ wiki "<p><nowiki>\n[string trimright $xcomment]\n</nowiki>\n"
@ } else {
@ set r [randhex]
@ wiki "<verbatim-$r links>[string trimright $xcomment]</verbatim-$r>\n"
@ }
@ }
| > | | 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 |
@ html [lindex [markdown $xcomment] 1]
@ } elseif {$xmimetype eq "text/html"} {
@ wiki "<p><nowiki>\n[string trimright $xcomment]\n</nowiki>\n"
@ } else {
@ set r [randhex]
@ wiki "<verbatim-$r links>[string trimright $xcomment]</verbatim-$r>\n"
@ }
@ html "</div>"; # .tktCommentEntry
@ }
@ if {$seenRow} {html "</div></td></tr>\n"}
@ </th1>
@ </table>
;
/*
** Return the code used to generate the view ticket page
|
| ︙ | ︙ | |||
798 799 800 801 802 803 804 |
@ WHERE tkt_id=$tkt_id AND length(icomment)>0} {
@ if {$seenRow} {
@ html "<hr>\n"
@ } else {
@ html "<tr><td colspan='2'><hr></td></tr>\n"
@ html "<tr><td colspan='2' class='tktDspLabel' style='text-align:left'>\n"
@ html "Previous User Comments:</td></tr>\n"
| | > | 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 |
@ WHERE tkt_id=$tkt_id AND length(icomment)>0} {
@ if {$seenRow} {
@ html "<hr>\n"
@ } else {
@ html "<tr><td colspan='2'><hr></td></tr>\n"
@ html "<tr><td colspan='2' class='tktDspLabel' style='text-align:left'>\n"
@ html "Previous User Comments:</td></tr>\n"
@ html "<tr><td colspan='2' class='tktDspValue'><div class='tktCommentArea'>\n"
@ set seenRow 1
@ }
@ html "<div class='tktCommentEntry'>"
@ html "<span class='tktDspCommenter'>"
@ puts $xlogin
@ if {$xlogin ne $xusername && [string length $xusername]>0} {
@ puts " (claiming to be $xusername)"
@ }
@ puts " added on $xdate:"
@ html "</span>\n"
|
| ︙ | ︙ | |||
822 823 824 825 826 827 828 829 |
@ html [lindex [markdown $xcomment] 1]
@ } elseif {$xmimetype eq "text/html"} {
@ wiki "<p><nowiki>\n[string trimright $xcomment]\n</nowiki>\n"
@ } else {
@ set r [randhex]
@ wiki "<verbatim-$r links>[string trimright $xcomment]</verbatim-$r>\n"
@ }
@ }
| > | | 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 |
@ html [lindex [markdown $xcomment] 1]
@ } elseif {$xmimetype eq "text/html"} {
@ wiki "<p><nowiki>\n[string trimright $xcomment]\n</nowiki>\n"
@ } else {
@ set r [randhex]
@ wiki "<verbatim-$r links>[string trimright $xcomment]</verbatim-$r>\n"
@ }
@ html "</div>"; # .tktCommentEntry
@ }
@ if {$seenRow} {html "</div></td></tr>\n"}
@ </th1>
@
@ </table>
;
/*
** Return the code used to generate the edit ticket page
|
| ︙ | ︙ |
Changes to src/unicode.c.
| ︙ | ︙ | |||
42 43 44 45 46 47 48 |
*/
static const unsigned int aEntry[] = {
0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163403,
| | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | < > | | | | | | | | > | | | | | | > > | | | | | | > > | > | | > | | | | | > | > | | | | | | | | > | | 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 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
*/
static const unsigned int aEntry[] = {
0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163403,
0x00164437, 0x0017CC02, 0x00180020, 0x00192C15, 0x0019A804,
0x0019C001, 0x001B5001, 0x001B580F, 0x001B9C07, 0x001BF402,
0x001C000E, 0x001C3C01, 0x001C4401, 0x001CC01B, 0x001E980B,
0x001FAC09, 0x001FD804, 0x001FF403, 0x00205804, 0x00206C09,
0x00209403, 0x0020A405, 0x0020C00F, 0x00216403, 0x00217801,
0x00222001, 0x00224002, 0x00225C09, 0x0023283A, 0x0024E803,
0x0024F812, 0x00254407, 0x00258804, 0x0025C001, 0x00260403,
0x0026F001, 0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01,
0x00278802, 0x0027C802, 0x0027E802, 0x0027F402, 0x00280403,
0x0028F001, 0x0028F805, 0x00291C02, 0x00292C03, 0x00294401,
0x0029C002, 0x0029D402, 0x002A0403, 0x002AF001, 0x002AF808,
0x002B1C03, 0x002B2C03, 0x002B8802, 0x002BC002, 0x002BE806,
0x002C0403, 0x002CF001, 0x002CF807, 0x002D1C02, 0x002D2C03,
0x002D5403, 0x002D8802, 0x002DC001, 0x002E0801, 0x002EF805,
0x002F1803, 0x002F2804, 0x002F5C01, 0x002FCC08, 0x00300005,
0x0030F001, 0x0030F807, 0x00311803, 0x00312804, 0x00315402,
0x00318802, 0x0031DC01, 0x0031FC01, 0x00320404, 0x0032F001,
0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802,
0x0033CC01, 0x00340004, 0x0034EC02, 0x0034F807, 0x00351803,
0x00352804, 0x00353C01, 0x00355C01, 0x00358802, 0x0035E401,
0x00360403, 0x00372801, 0x00373C06, 0x00375801, 0x00376008,
0x0037C803, 0x0038C401, 0x0038D007, 0x0038FC01, 0x00391C09,
0x00396802, 0x003AC401, 0x003AD009, 0x003B2007, 0x003C041F,
0x003CD00C, 0x003DC417, 0x003E340B, 0x003E6424, 0x003EF80F,
0x003F380D, 0x0040AC14, 0x00412806, 0x00415804, 0x00417803,
0x00418803, 0x00419C07, 0x0041C404, 0x0042080C, 0x00423C01,
0x00426806, 0x0043EC01, 0x004D740C, 0x004E400A, 0x00500001,
0x0059B402, 0x005A0001, 0x005A6C02, 0x005BAC03, 0x005C4804,
0x005CC805, 0x005D4802, 0x005DC802, 0x005ED023, 0x005F6004,
0x005F7401, 0x00600010, 0x00621402, 0x0062A401, 0x0064800C,
0x0064C00C, 0x00650001, 0x00651002, 0x00677822, 0x00685C05,
0x00687802, 0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007,
0x006AA006, 0x006AC02E, 0x006B800C, 0x006C0005, 0x006CD011,
0x006D3802, 0x006D6829, 0x006E840D, 0x006F980E, 0x006FF004,
0x00709014, 0x0070EC05, 0x0071F802, 0x00730008, 0x00734019,
0x0073B401, 0x0073D001, 0x0073DC03, 0x00770040, 0x007EF401,
0x007EFC03, 0x007F3403, 0x007F7403, 0x007FB403, 0x007FF402,
0x00800065, 0x0081980A, 0x0081E805, 0x00822805, 0x00828022,
0x00834021, 0x00840002, 0x00840C04, 0x00842002, 0x00845001,
0x00845803, 0x00847806, 0x00849401, 0x00849C01, 0x0084A401,
0x0084B801, 0x0084E802, 0x00850005, 0x00852804, 0x00853C01,
0x00862802, 0x0086429A, 0x0091000B, 0x0092704E, 0x00940276,
0x009E53E0, 0x00ADD88A, 0x00B39406, 0x00B3BC03, 0x00B3E404,
0x00B3F802, 0x00B5C001, 0x00B5FC01, 0x00B7804F, 0x00B8C02E,
0x00BA001A, 0x00BA6C59, 0x00BC00D6, 0x00BFC015, 0x00C02019,
0x00C0A807, 0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001,
0x00C3EC01, 0x00C64002, 0x00C6580A, 0x00C70026, 0x00C7BC01,
0x00C8001F, 0x00C8A81E, 0x00C94001, 0x00C98020, 0x00CA2827,
0x00CB0140, 0x01370040, 0x02924037, 0x0293F802, 0x02983403,
0x0299BC10, 0x029A7802, 0x029BC008, 0x029C0017, 0x029C8002,
0x029E2402, 0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C0A,
0x02A0D804, 0x02A1D004, 0x02A20002, 0x02A2D012, 0x02A33802,
0x02A38012, 0x02A3E003, 0x02A3F001, 0x02A3FC01, 0x02A4980A,
0x02A51C0D, 0x02A57C01, 0x02A60004, 0x02A6CC1B, 0x02A77802,
0x02A79401, 0x02A8A40E, 0x02A90C01, 0x02A93002, 0x02A97004,
0x02A9DC03, 0x02A9EC03, 0x02AAC001, 0x02AAC803, 0x02AADC02,
0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07, 0x02ABD402,
0x02AD6C01, 0x02ADA802, 0x02AF8C0B, 0x03600001, 0x036DFC02,
0x036FFC02, 0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC821,
0x03F4F812, 0x03F64002, 0x03F72008, 0x03F7F01E, 0x03F88033,
0x03F95013, 0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807,
0x03FCEC06, 0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405,
0x04040003, 0x0404DC09, 0x0405E411, 0x04063003, 0x0406400D,
0x04068001, 0x0407402E, 0x040B8001, 0x040DD805, 0x040E7C01,
0x040F4001, 0x0415BC01, 0x04215C01, 0x0421DC02, 0x04247C01,
0x0424FC01, 0x04280403, 0x04281402, 0x04283004, 0x0428E003,
0x0428FC01, 0x04294009, 0x0429FC01, 0x042B2001, 0x042B9402,
0x042BC007, 0x042CE407, 0x042E6404, 0x04349004, 0x0435A406,
0x04363802, 0x043AAC03, 0x043B4009, 0x043BE806, 0x043D180B,
0x043D5405, 0x043E0808, 0x04400003, 0x0440E016, 0x0441C001,
0x0441CC02, 0x0441FC04, 0x0442C013, 0x04433401, 0x04440003,
0x04449C0E, 0x04450004, 0x04451402, 0x0445CC03, 0x04460003,
0x0446CC0E, 0x0447140B, 0x04476C01, 0x04477403, 0x0448B013,
0x04490401, 0x044AA401, 0x044B7C0C, 0x044C0004, 0x044CEC02,
0x044CF807, 0x044D1C02, 0x044D2C03, 0x044D5C01, 0x044D8802,
0x044D9807, 0x044DC005, 0x044EE009, 0x044F0801, 0x044F1401,
0x044F1C04, 0x044F3005, 0x044F4801, 0x044F5002, 0x044F5C02,
0x044F8402, 0x0450D412, 0x04512C05, 0x04516802, 0x04517402,
0x0452C014, 0x04531801, 0x0456BC07, 0x0456E020, 0x04577002,
0x0458C014, 0x0459800D, 0x045AAC0D, 0x045AE401, 0x045C740F,
0x045CF004, 0x0460B010, 0x0464C006, 0x0464DC02, 0x0464EC04,
0x04650001, 0x04650805, 0x04674407, 0x04676807, 0x04678801,
0x04679001, 0x0468040A, 0x0468CC07, 0x0468EC0D, 0x0469440B,
0x046A2813, 0x046A7805, 0x046C000A, 0x046D8008, 0x046F8401,
0x0470BC08, 0x0470E008, 0x04710405, 0x0471C002, 0x04724816,
0x0472A40E, 0x0474C406, 0x0474E801, 0x0474F002, 0x0474FC07,
0x04751C01, 0x04762805, 0x04764002, 0x04764C05, 0x047BCC06,
0x047C0002, 0x047C0C01, 0x047CD007, 0x047CF812, 0x047D6801,
0x047F541D, 0x047FFC01, 0x0491C005, 0x04BFC402, 0x04D0C011,
0x04D11C0F, 0x05847812, 0x05A9B802, 0x05ABC006, 0x05ACC010,
0x05AD1002, 0x05B5B403, 0x05BA5C04, 0x05BD3C01, 0x05BD4437,
0x05BE3C04, 0x05BF8801, 0x05BF9001, 0x05BFC002, 0x06F27008,
0x073000F0, 0x0733E803, 0x073401B4, 0x073AE817, 0x073B8011,
0x073C002E, 0x073CC017, 0x073D4074, 0x074000F6, 0x07440027,
0x0744A4C2, 0x07480046, 0x074C0057, 0x075B0401, 0x075B6C01,
0x075BEC01, 0x075C5401, 0x075CD401, 0x075D3C01, 0x075DBC01,
0x075E2401, 0x075EA401, 0x075F0C01, 0x0760028C, 0x076A6C05,
0x076A840F, 0x07800007, 0x07802011, 0x07806C07, 0x07808C02,
0x07809805, 0x07823C01, 0x0784C007, 0x07853C01, 0x078AB801,
0x078BB004, 0x078BFC01, 0x0793B004, 0x0797B802, 0x0797FC01,
0x079B8C01, 0x079B9801, 0x079BB802, 0x079BD401, 0x07A34007,
0x07A51007, 0x07A57802, 0x07B2B001, 0x07B2C001, 0x07B4B801,
0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F, 0x07C2C40F,
0x07C3040F, 0x07C34425, 0x07C434A1, 0x07C7981D, 0x07C8402C,
0x07C90009, 0x07C94002, 0x07C98006, 0x07CC03D9, 0x07DB7011,
0x07DBC00D, 0x07DC00DA, 0x07DF800C, 0x07DFC001, 0x07E0000C,
0x07E04038, 0x07E1400A, 0x07E18028, 0x07E2401E, 0x07E2C00C,
0x07E30002, 0x07E34009, 0x07E40158, 0x07E9800E, 0x07E9C00D,
0x07EA000B, 0x07EA3839, 0x07EB2001, 0x07EB3410, 0x07EB7C0C,
0x07EBBC0A, 0x07EC0093, 0x07EE505C, 0x07EFE801, 0x38000401,
0x38008060, 0x380400F0,
};
static const unsigned int aAscii[4] = {
0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
};
if( (unsigned int)c<128 ){
return ( (aAscii[c >> 5] & ((unsigned int)1 << (c & 0x001F)))==0 );
|
| ︙ | ︙ | |||
238 239 240 241 242 243 244 |
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( key>=aDia[iRes] );
if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
| | < | 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
iLo = iTest+1;
}else{
iHi = iTest-1;
}
}
assert( key>=aDia[iRes] );
if( bComplex==0 && (aChar[iRes] & 0x80) ) return c;
return (c > (aDia[iRes]>>3) + (aDia[iRes]&0x07)) ? c : ((int)aChar[iRes] & 0x7F);
}
/*
** Return true if the argument interpreted as a unicode codepoint
** is a diacritical modifier character.
*/
|
| ︙ | ︙ | |||
289 290 291 292 293 294 295 |
** http://www.unicode.org for details.
*/
static const struct TableEntry {
unsigned short iCode;
unsigned char flags;
unsigned char nRange;
} aEntry[] = {
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | > | | | | | | | | | | | | | | | | | > | | | | | | | | | > | | | | < | 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 326 327 328 329 330 331 332 333 334 335 336 337 338 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 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
** http://www.unicode.org for details.
*/
static const struct TableEntry {
unsigned short iCode;
unsigned char flags;
unsigned char nRange;
} aEntry[] = {
{65, 16, 26}, {181, 70, 1}, {192, 16, 23},
{216, 16, 7}, {256, 1, 48}, {306, 1, 6},
{313, 1, 16}, {330, 1, 46}, {376, 168, 1},
{377, 1, 6}, {383, 156, 1}, {385, 56, 1},
{386, 1, 4}, {390, 50, 1}, {391, 0, 1},
{393, 48, 2}, {395, 0, 1}, {398, 38, 1},
{399, 44, 1}, {400, 46, 1}, {401, 0, 1},
{403, 48, 1}, {404, 52, 1}, {406, 58, 1},
{407, 54, 1}, {408, 0, 1}, {412, 58, 1},
{413, 60, 1}, {415, 62, 1}, {416, 1, 6},
{422, 66, 1}, {423, 0, 1}, {425, 66, 1},
{428, 0, 1}, {430, 66, 1}, {431, 0, 1},
{433, 64, 2}, {435, 1, 4}, {439, 68, 1},
{440, 0, 1}, {444, 0, 1}, {452, 2, 1},
{453, 0, 1}, {455, 2, 1}, {456, 0, 1},
{458, 2, 1}, {459, 1, 18}, {478, 1, 18},
{497, 2, 1}, {498, 1, 4}, {502, 174, 1},
{503, 186, 1}, {504, 1, 40}, {544, 162, 1},
{546, 1, 18}, {570, 78, 1}, {571, 0, 1},
{573, 160, 1}, {574, 76, 1}, {577, 0, 1},
{579, 158, 1}, {580, 34, 1}, {581, 36, 1},
{582, 1, 10}, {837, 42, 1}, {880, 1, 4},
{886, 0, 1}, {895, 42, 1}, {902, 22, 1},
{904, 20, 3}, {908, 32, 1}, {910, 30, 2},
{913, 16, 17}, {931, 16, 9}, {962, 0, 1},
{975, 4, 1}, {976, 192, 1}, {977, 194, 1},
{981, 198, 1}, {982, 196, 1}, {984, 1, 24},
{1008, 188, 1}, {1009, 190, 1}, {1012, 182, 1},
{1013, 180, 1}, {1015, 0, 1}, {1017, 204, 1},
{1018, 0, 1}, {1021, 162, 3}, {1024, 40, 16},
{1040, 16, 32}, {1120, 1, 34}, {1162, 1, 54},
{1216, 6, 1}, {1217, 1, 14}, {1232, 1, 96},
{1329, 28, 38}, {4256, 74, 38}, {4295, 74, 1},
{4301, 74, 1}, {5112, 202, 6}, {7296, 138, 1},
{7297, 140, 1}, {7298, 142, 1}, {7299, 146, 2},
{7301, 144, 1}, {7302, 148, 1}, {7303, 150, 1},
{7304, 108, 1}, {7305, 0, 1}, {7312, 154, 43},
{7357, 154, 3}, {7680, 1, 150}, {7835, 184, 1},
{7838, 128, 1}, {7840, 1, 96}, {7944, 202, 8},
{7960, 202, 6}, {7976, 202, 8}, {7992, 202, 8},
{8008, 202, 6}, {8025, 203, 8}, {8040, 202, 8},
{8072, 202, 8}, {8088, 202, 8}, {8104, 202, 8},
{8120, 202, 2}, {8122, 178, 2}, {8124, 200, 1},
{8126, 136, 1}, {8136, 176, 4}, {8140, 200, 1},
{8147, 132, 1}, {8152, 202, 2}, {8154, 172, 2},
{8163, 134, 1}, {8168, 202, 2}, {8170, 170, 2},
{8172, 204, 1}, {8184, 164, 2}, {8186, 166, 2},
{8188, 200, 1}, {8486, 130, 1}, {8490, 124, 1},
{8491, 126, 1}, {8498, 14, 1}, {8544, 8, 16},
{8579, 0, 1}, {9398, 10, 26}, {11264, 28, 48},
{11360, 0, 1}, {11362, 120, 1}, {11363, 152, 1},
{11364, 122, 1}, {11367, 1, 6}, {11373, 116, 1},
{11374, 118, 1}, {11375, 112, 1}, {11376, 114, 1},
{11378, 0, 1}, {11381, 0, 1}, {11390, 110, 2},
{11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1},
{42560, 1, 46}, {42624, 1, 28}, {42786, 1, 14},
{42802, 1, 62}, {42873, 1, 4}, {42877, 106, 1},
{42878, 1, 10}, {42891, 0, 1}, {42893, 96, 1},
{42896, 1, 4}, {42902, 1, 20}, {42922, 88, 1},
{42923, 84, 1}, {42924, 86, 1}, {42925, 92, 1},
{42926, 88, 1}, {42928, 100, 1}, {42929, 94, 1},
{42930, 98, 1}, {42931, 72, 1}, {42932, 1, 16},
{42948, 190, 1}, {42949, 90, 1}, {42950, 104, 1},
{42951, 1, 4}, {42955, 82, 1}, {42956, 1, 16},
{42972, 80, 1}, {42997, 0, 1}, {43888, 102, 80},
{64261, 0, 1}, {65313, 16, 26},
};
static const unsigned short aiOff[] = {
1, 2, 8, 15, 16, 26, 27, 28,
32, 34, 37, 38, 39, 40, 48, 63,
64, 69, 71, 79, 80, 116, 202, 203,
205, 206, 207, 209, 210, 211, 213, 214,
217, 218, 219, 775, 928, 7264, 10792, 10795,
22975, 23193, 23217, 23221, 23228, 23229, 23231, 23254,
23256, 23275, 23278, 26672, 30152, 30204, 35267, 54721,
54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274,
57921, 58019, 58301, 58317, 58363, 59314, 59315, 59324,
59325, 59326, 59332, 59356, 61722, 62528, 65268, 65341,
65373, 65406, 65408, 65410, 65415, 65424, 65436, 65439,
65450, 65462, 65472, 65476, 65478, 65480, 65482, 65488,
65506, 65511, 65514, 65521, 65527, 65528, 65529,
};
int ret = c;
assert( sizeof(unsigned short)==2 && sizeof(unsigned char)==1 );
if( c<128 ){
|
| ︙ | ︙ | |||
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 |
}
else if( c>=66560 && c<66600 ){
ret = c + 40;
}
else if( c>=66736 && c<66772 ){
ret = c + 40;
}
else if( c>=68736 && c<68787 ){
ret = c + 64;
}
else if( c>=71840 && c<71872 ){
ret = c + 32;
}
else if( c>=93760 && c<93792 ){
ret = c + 32;
}
else if( c>=125184 && c<125218 ){
ret = c + 34;
}
return ret;
}
| > > > > > > > > > > > > > > > > > > | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 |
}
else if( c>=66560 && c<66600 ){
ret = c + 40;
}
else if( c>=66736 && c<66772 ){
ret = c + 40;
}
else if( c>=66928 && c<66939 ){
ret = c + 39;
}
else if( c>=66940 && c<66955 ){
ret = c + 39;
}
else if( c>=66956 && c<66963 ){
ret = c + 39;
}
else if( c>=66964 && c<66966 ){
ret = c + 39;
}
else if( c>=68736 && c<68787 ){
ret = c + 64;
}
else if( c>=68944 && c<68966 ){
ret = c + 32;
}
else if( c>=71840 && c<71872 ){
ret = c + 32;
}
else if( c>=93760 && c<93792 ){
ret = c + 32;
}
else if( c>=93856 && c<93881 ){
ret = c + 27;
}
else if( c>=125184 && c<125218 ){
ret = c + 34;
}
return ret;
}
|
Changes to src/update.c.
| ︙ | ︙ | |||
754 755 756 757 758 759 760 |
int vid;
Manifest *pManifest;
/* Determine the check-in manifest artifact ID. Panic on failure. */
if( zRevision ){
vid = name_to_typed_rid(zRevision, "ci");
}else if( !g.localOpen ){
| | | 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 |
int vid;
Manifest *pManifest;
/* Determine the check-in manifest artifact ID. Panic on failure. */
if( zRevision ){
vid = name_to_typed_rid(zRevision, "ci");
}else if( !g.localOpen ){
vid = name_to_typed_rid(db_main_branch(), "ci");
}else{
vid = db_lget_int("checkout", 0);
if( !is_a_version(vid) ){
if( vid==0 ) return 0;
zRevision = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", vid);
if( zRevision ){
fossil_fatal("check-out artifact is not a check-in: %s", zRevision);
|
| ︙ | ︙ |
Changes to src/url.c.
| ︙ | ︙ | |||
56 57 58 59 60 61 62 63 64 65 66 67 68 69 | int dfltPort; /* The default port for the given protocol */ char *path; /* Pathname for http: */ char *user; /* User id for http: */ char *passwd; /* Password for http: */ char *canonical; /* Canonical representation of the URL */ char *proxyAuth; /* Proxy-Authorizer: string */ char *fossil; /* The fossil query parameter on ssh: */ char *pwConfig; /* CONFIG table entry that gave us the password */ unsigned flags; /* Boolean flags controlling URL processing */ int useProxy; /* Used to remember that a proxy is in use */ int proxyOrigPort; /* Tunneled port number for https through proxy */ char *proxyUrlPath; /* Remember path when proxy is use */ char *proxyUrlCanonical; /* Remember canonical path when proxy is use */ }; | > | 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | int dfltPort; /* The default port for the given protocol */ char *path; /* Pathname for http: */ char *user; /* User id for http: */ char *passwd; /* Password for http: */ char *canonical; /* Canonical representation of the URL */ char *proxyAuth; /* Proxy-Authorizer: string */ char *fossil; /* The fossil query parameter on ssh: */ char *subpath; /* Secondary HTTP request path for ssh: and file: */ char *pwConfig; /* CONFIG table entry that gave us the password */ unsigned flags; /* Boolean flags controlling URL processing */ int useProxy; /* Used to remember that a proxy is in use */ int proxyOrigPort; /* Tunneled port number for https through proxy */ char *proxyUrlPath; /* Remember path when proxy is use */ char *proxyUrlCanonical; /* Remember canonical path when proxy is use */ }; |
| ︙ | ︙ | |||
404 405 406 407 408 409 410 411 412 413 414 415 416 417 | } fossil_free(p->canonical); fossil_free(p->name); fossil_free(p->path); fossil_free(p->user); fossil_free(p->passwd); fossil_free(p->fossil); fossil_free(p->pwConfig); memset(p, 0, sizeof(*p)); } /* ** Move a URL parse from one UrlData object to another. */ | > | 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 | } fossil_free(p->canonical); fossil_free(p->name); fossil_free(p->path); fossil_free(p->user); fossil_free(p->passwd); fossil_free(p->fossil); fossil_free(p->subpath); fossil_free(p->pwConfig); memset(p, 0, sizeof(*p)); } /* ** Move a URL parse from one UrlData object to another. */ |
| ︙ | ︙ | |||
481 482 483 484 485 486 487 488 489 490 491 492 493 494 |
fossil_print("g.url.passwd = %s\n", g.url.passwd);
}else{
fossil_print("g.url.passwd = ************\n");
}
fossil_print("g.url.pwConfig = %s\n", g.url.pwConfig);
fossil_print("g.url.canonical = %s\n", g.url.canonical);
fossil_print("g.url.fossil = %s\n", g.url.fossil);
fossil_print("g.url.flags = 0x%04x\n", g.url.flags);
fossil_print("url_full(g.url) = %z\n", url_full(&g.url));
}
/*
** COMMAND: test-urlparser
**
| > | 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 |
fossil_print("g.url.passwd = %s\n", g.url.passwd);
}else{
fossil_print("g.url.passwd = ************\n");
}
fossil_print("g.url.pwConfig = %s\n", g.url.pwConfig);
fossil_print("g.url.canonical = %s\n", g.url.canonical);
fossil_print("g.url.fossil = %s\n", g.url.fossil);
fossil_print("g.url.subpath = %s\n", g.url.subpath);
fossil_print("g.url.flags = 0x%04x\n", g.url.flags);
fossil_print("url_full(g.url) = %z\n", url_full(&g.url));
}
/*
** COMMAND: test-urlparser
**
|
| ︙ | ︙ |
Changes to src/util.c.
| ︙ | ︙ | |||
993 994 995 996 997 998 999 |
bFound = 1;
}
zPath += i;
}
return bFound;
}
| < < < < < < < < < < < < < < < < < < < < < < < < | 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 |
bFound = 1;
}
zPath += i;
}
return bFound;
}
/*
** Return the name of a command that will launch a web-browser.
*/
const char *fossil_web_browser(void){
const char *zBrowser = 0;
#if defined(_WIN32)
zBrowser = db_get("web-browser", "start \"\"");
|
| ︙ | ︙ |
Changes to src/xfer.c.
| ︙ | ︙ | |||
1331 1332 1333 1334 1335 1336 1337 |
zScript = xfer_push_code();
if( zScript ){ /* NOTE: Are TH1 transfer hooks enabled? */
pzUuidList = &zUuidList;
pnUuidList = &nUuidList;
}
if( g.syncInfo.zLoginCard ){
/* Login card received via HTTP Cookie header */
| < | 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 |
zScript = xfer_push_code();
if( zScript ){ /* NOTE: Are TH1 transfer hooks enabled? */
pzUuidList = &zUuidList;
pnUuidList = &nUuidList;
}
if( g.syncInfo.zLoginCard ){
/* Login card received via HTTP Cookie header */
blob_zero(&xfer.line);
blob_append(&xfer.line, g.syncInfo.zLoginCard, -1);
xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken,
count(xfer.aToken));
fossil_free( g.syncInfo.zLoginCard );
g.syncInfo.zLoginCard = 0;
if( xfer.nToken==4
|
| ︙ | ︙ |
Added src/xsystem.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 151 152 153 154 155 156 157 158 159 160 161 162 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 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 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 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 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 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 |
/*
** Copyright (c) 2025 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
** drh@sqlite.org
**
*******************************************************************************
**
** This file contains code used to implement "fossil system ..." command.
**
** Fossil is frequently used by people familiar with Unix but who must
** sometimes also work on Windows systems. The "fossil sys ..." command
** provides a few work-arounds for command unix command-line utilities to
** help make development on Windows more habitable for long-time unix
** users. The commands provided here are normally cheap substitutes to
** their more feature-reach unix counterparts. But they are sufficient to
** get the job done.
**
** This source code file is called "xsystem.c" with the 'x' up front because
** if it were called "system.c", then makeheaders would generate a "system.h"
** header file, and that might be confused with an actual system header
** file.
*/
#include "config.h"
#include "xsystem.h"
#include "qrf.h"
#include <time.h>
/* Date and time */
void xsystem_date(int argc, char **argv){
(void)argc;
(void)argv;
fossil_print("%z = ", cgi_iso8601_datestamp());
fossil_print("%z\n", cgi_rfc822_datestamp(time(0)));
}
/* Present working diretory */
void xsystem_pwd(int argc, char **argv){
char *zPwd = file_getcwd(0, 0);
fossil_print("%z\n", zPwd);
}
/* Implement "stty size" */
void xsystem_stty(int argc, char **argv){
TerminalSize ts;
if( argc!=2 || strcmp(argv[1],"size")!=0 ){
fossil_print("ERROR: only \"stty size\" is supported\n");
}else{
terminal_get_size(&ts);
fossil_print("%d %d\n", ts.nLines, ts.nColumns);
}
}
/* Show where an executable is located on PATH */
void xsystem_which(int argc, char **argv){
int ePrint = 1;
int i;
for(i=1; i<argc; i++){
const char *z = argv[i];
if( z[0]!='-' ){
fossil_app_on_path(z, ePrint);
}else{
if( z[1]=='-' && z[2]!=0 ) z++;
if( fossil_strcmp(z,"-a")==0 ){
ePrint = 2;
}else
{
fossil_fatal("unknown option \"%s\"", argv[i]);
}
}
}
}
/*
** Bit values for the mFlags paramater to "ls"
*/
#define LS_LONG 0x001 /* -l Long format - one object per line */
#define LS_REVERSE 0x002 /* -r Reverse the sort order */
#define LS_MTIME 0x004 /* -t Sort by mtime, newest first */
#define LS_SIZE 0x008 /* -S Sort by size, largest first */
#define LS_COMMA 0x010 /* -m Comma-separated list */
#define LS_DIRONLY 0x020 /* -d Show just directory name, not content */
#define LS_ALL 0x040 /* -a Show all entries */
#define LS_COLOR 0x080 /* Colorize the output */
#define LS_COLUMNS 0x100 /* -C Split column output */
/* xWrite() callback from QRF
*/
static int xsystem_write(void *NotUsed, const char *zText, sqlite3_int64 n){
fossil_puts(zText, 0, (int)n);
return SQLITE_OK;
}
/* Helper function for xsystem_ls(): Make entries in the LS table
** for every file or directory zName.
**
** If zName is a directory, load all files contained within that directory.
** If zName is just a file, load only that file.
*/
static void xsystem_ls_insert(
sqlite3_stmt *pStmt,
const char *zName,
int mFlags
){
char *aList[2];
char **azList;
int nList;
int i;
const char *zPrefix;
switch( file_isdir(zName, ExtFILE) ){
case 1: { /* A directory */
if( (mFlags & LS_DIRONLY)==0 ){
int omitDots = (mFlags & LS_ALL)!=0 ? 2 : 1;
azList = 0;
nList = file_directory_list(zName, 0, omitDots, 0, &azList);
zPrefix = fossil_strcmp(zName,".") ? zName : 0;
break;
}
}
case 2: { /* A file */
aList[0] = (char*)zName;
aList[1] = 0;
azList = aList;
nList = 1;
zPrefix = 0;
break;
}
default: { /* Does not exist */
return;
}
}
for(i=0; i<nList; i++){
char *zFile = zPrefix ? mprintf("%s/%s",zPrefix,azList[i]) : azList[i];
int mode = file_mode(zFile, ExtFILE);
sqlite3_int64 sz = file_size(zFile, ExtFILE);
sqlite3_int64 mtime = file_mtime(zFile, ExtFILE);
#ifdef _WIN32
if( (mFlags & LS_ALL)==0 ){
wchar_t *zMbcs = fossil_utf8_to_path(zFile, 1);
DWORD attr = GetFileAttributesW(zMbcs);
fossil_path_free(zMbcs);
if( attr & FILE_ATTRIBUTE_HIDDEN ){
if( zPrefix ) fossil_free(zFile);
continue;
}
}
#endif
sqlite3_bind_text(pStmt, 1, azList[i], -1, SQLITE_TRANSIENT);
sqlite3_bind_int64(pStmt, 2, mtime);
sqlite3_bind_int64(pStmt, 3, sz);
sqlite3_bind_int(pStmt, 4, mode);
sqlite3_bind_int64(pStmt, 5, strlen(zFile));
/* TODO: wcwidth()------^^^^^^ */
sqlite3_step(pStmt);
sqlite3_reset(pStmt);
if( zPrefix ) fossil_free(zFile);
}
if( azList!=aList ){
file_directory_list_free(azList);
}
}
/*
** Return arguments to ORDER BY that will correctly sort the entires.
*/
static const char *xsystem_ls_orderby(int mFlags){
static const char *zSortTypes[] = {
"fn COLLATE NOCASE",
"mtime DESC",
"size DESC",
"fn COLLATE NOCASE DESC",
"mtime",
"size"
};
int i = 0;
if( mFlags & LS_MTIME ) i = 1;
if( mFlags & LS_SIZE ) i = 2;
if( mFlags & LS_REVERSE ) i += 3;
return zSortTypes[i];
}
/*
** color(fn,mode)
**
** SQL function to colorize a filename based on its mode.
*/
static void colorNameFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
const char *zName = (const char*)sqlite3_value_text(argv[0]);
int iMode = sqlite3_value_int(argv[1]);
sqlite3_str *pOut;
if( zName==0 ) return;
pOut = sqlite3_str_new(0);
#ifdef _WIN32
if( sqlite3_strlike("%.exe",zName,0)==0 ) iMode |= 0111;
#endif
if( iMode & 040000 ){
/* A directory */
sqlite3_str_appendall(pOut, "\033[1;34m");
}else if( iMode & 0100 ){
/* Executable */
sqlite3_str_appendall(pOut, "\033[1;32m");
}
sqlite3_str_appendall(pOut, zName);
if( (iMode & 040100)!=0 ){
sqlite3_str_appendall(pOut, "\033[0m");
}
sqlite3_result_text(context, sqlite3_str_value(pOut), -1, SQLITE_TRANSIENT);
sqlite3_str_free(pOut);
}
/* Alternative implementation that does *not* introduce color */
static void nocolorNameFunc(
sqlite3_context *context,
int argc,
sqlite3_value **argv
){
sqlite3_result_value(context, argv[0]);
}
/*
** Show ls output information for content in the LS table
*/
static void xsystem_ls_render(
sqlite3 *db,
int mFlags
){
sqlite3_stmt *pStmt;
if( mFlags & LS_COLOR ){
sqlite3_create_function(db, "color",2,SQLITE_UTF8,0,colorNameFunc,0,0);
}else{
sqlite3_create_function(db, "color",2,SQLITE_UTF8,0,nocolorNameFunc,0,0);
}
if( (mFlags & LS_LONG)!=0 ){
/* Long mode */
char *zSql;
int szSz = 8;
sqlite3_prepare_v2(db, "SELECT length(max(size)) FROM ls", -1, &pStmt, 0);
if( sqlite3_step(pStmt)==SQLITE_ROW ){
szSz = sqlite3_column_int(pStmt, 0);
}
sqlite3_finalize(pStmt);
pStmt = 0;
zSql = mprintf(
"SELECT mode, size, datetime(mtime,'unixepoch'), color(fn,mode)"
" FROM ls ORDER BY %s",
xsystem_ls_orderby(mFlags));
sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
while( sqlite3_step(pStmt)==SQLITE_ROW ){
char zMode[12];
const char *zName = (const char*)sqlite3_column_text(pStmt, 3);
int mode = sqlite3_column_int(pStmt, 0);
#ifdef _WIN32
memcpy(zMode, "-rw-", 5);
if( mode & 040000 ){
zMode[0] = 'd';
zMode[3] = 'x';
}else if( sqlite3_strlike("%.EXE",zName,0)==0 ){
zMode[3] = 'x';
}
#else
memcpy(zMode, "----------", 11);
if( mode & 040000 ) zMode[0] = 'd';
if( mode & 0400 ) zMode[1] = 'r';
if( mode & 0200 ) zMode[2] = 'w';
if( mode & 0100 ) zMode[3] = 'x';
if( mode & 0040 ) zMode[4] = 'r';
if( mode & 0020 ) zMode[5] = 'w';
if( mode & 0010 ) zMode[6] = 'x';
if( mode & 0004 ) zMode[7] = 'r';
if( mode & 0002 ) zMode[8] = 'w';
if( mode & 0001 ) zMode[9] = 'x';
#endif
fossil_print("%s %*lld %s %s\n",
zMode,
szSz,
sqlite3_column_int64(pStmt, 1),
sqlite3_column_text(pStmt, 2),
zName);
}
sqlite3_finalize(pStmt);
}else if( (mFlags & LS_COMMA)!=0 ){
/* Comma-separate list */
int mx = terminal_get_width(80);
int sumW = 0;
char *zSql;
zSql = mprintf("SELECT color(fn,mode), dlen FROM ls ORDER BY %s",
xsystem_ls_orderby(mFlags));
sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
while( sqlite3_step(pStmt)==SQLITE_ROW ){
const char *z = (const char*)sqlite3_column_text(pStmt, 0);
int w = sqlite3_column_int(pStmt, 1);
if( sumW==0 ){
fossil_print("%s", z);
sumW = w;
}else if( sumW + w + 2 >= mx ){
fossil_print("\n%s", z);
sumW = w;
}else{
fossil_print(", %s", z);
sumW += w+2;
}
}
fossil_free(zSql);
sqlite3_finalize(pStmt);
if( sumW>0 ) fossil_print("\n");
}else{
/* Column mode with just filenames */
sqlite3_qrf_spec spec;
char *zSql;
memset(&spec, 0, sizeof(spec));
spec.iVersion = 1;
spec.xWrite = xsystem_write;
spec.eStyle = QRF_STYLE_Column;
spec.bTitles = QRF_No;
spec.eEsc = QRF_No;
if( mFlags & LS_COLUMNS ){
spec.nScreenWidth = terminal_get_width(80);
spec.bSplitColumn = QRF_Yes;
}
zSql = mprintf("SELECT color(fn,mode) FROM ls ORDER BY %s",
xsystem_ls_orderby(mFlags));
sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
fossil_free(zSql);
sqlite3_format_query_result(pStmt, &spec, 0);
sqlite3_finalize(pStmt);
}
sqlite3_exec(db, "DELETE FROM ls;", 0, 0, 0);
}
/* List files "ls"
** Options:
**
** -a Show files that begin with "."
** -C List by colums
** --color=WHEN Colorize output?
** -d Show just directory names, not content
** -l Long listing
** -m Comma-separated list
** -r Reverse sort
** -S Sort by size, largest first
** -t Sort by mtime, newest first
*/
void xsystem_ls(int argc, char **argv){
int i, rc;
sqlite3 *db;
sqlite3_stmt *pStmt = 0;
int mFlags = 0;
int nFile = 0;
int nDir = 0;
int bAutoColor = 1;
int needBlankLine = 0;
rc = sqlite3_open(":memory:", &db);
if( rc || db==0 ){
fossil_fatal("Cannot open in-memory database");
}
sqlite3_exec(db, "CREATE TABLE ls(fn,mtime,size,mode,dlen);", 0,0,0);
rc = sqlite3_prepare_v2(db, "INSERT INTO ls VALUES(?1,?2,?3,?4,?5)",
-1, &pStmt, 0);
if( rc || db==0 ){
fossil_fatal("Cannot prepare INSERT statement");
}
for(i=1; i<argc; i++){
const char *z = argv[i];
if( z[0]=='-' ){
if( z[1]=='-' ){
if( strncmp(z,"--color",7)==0 ){
if( z[7]==0 || strcmp(&z[7],"=always")==0 ){
mFlags |= LS_COLOR;
}else if( strcmp(&z[7],"=never")==0 ){
bAutoColor = 0;
}
}else{
fossil_fatal("unknown option: %s", z);
}
}else{
int k;
for(k=1; z[k]; k++){
switch( z[k] ){
case 'a': mFlags |= LS_ALL; break;
case 'd': mFlags |= LS_DIRONLY; break;
case 'l': mFlags |= LS_LONG; break;
case 'm': mFlags |= LS_COMMA; break;
case 'r': mFlags |= LS_REVERSE; break;
case 'S': mFlags |= LS_SIZE; break;
case 't': mFlags |= LS_MTIME; break;
case 'C': mFlags |= LS_COLUMNS; break;
default: {
fossil_fatal("unknown option: -%c", z[k]);
}
}
}
}
}else{
if( (mFlags & LS_DIRONLY)==0 && file_isdir(z, ExtFILE)==1 ){
nDir++;
}else{
nFile++;
xsystem_ls_insert(pStmt, z, mFlags);
}
}
}
if( fossil_isatty(1) ){
if( bAutoColor ) mFlags |= LS_COLOR;
mFlags |= LS_COLUMNS;
}
if( nFile>0 ){
xsystem_ls_render(db, mFlags);
needBlankLine = 1;
}else if( nDir==0 ){
xsystem_ls_insert(pStmt, ".", mFlags);
xsystem_ls_render(db, mFlags);
}
if( nDir>0 ){
for(i=1; i<argc; i++){
const char *z = argv[i];
if( z[0]=='-' ) continue;
if( file_isdir(z, ExtFILE)!=1 ) continue;
if( needBlankLine ){
fossil_print("\n");
needBlankLine = 0;
}
fossil_print("%s:\n", z);
xsystem_ls_insert(pStmt, z, mFlags);
xsystem_ls_render(db, mFlags);
}
}
sqlite3_finalize(pStmt);
sqlite3_close(db);
}
/*
** Available system commands.
*/
typedef struct XSysCmd XSysCmd;
static struct XSysCmd {
const char *zName;
void (*xFunc)(int,char**);
const char *zHelp;
} aXSysCmd[] = {
{ "date", xsystem_date,
"\n"
"Show the current system time and date\n"
},
{ "ls", xsystem_ls,
"[OPTIONS] [PATH] ...\n"
"Options:\n"
" -a Show files that begin with '.'\n"
" -C Split columns\n"
" -d Show just directory names, not content\n"
" -l Long listing\n"
" -m Comma-separated list\n"
" -r Reverse sort order\n"
" -S Sort by size, largest first\n"
" -t Sort by mtime, newest first\n"
" --color[=WHEN] Colorize output?\n"
},
{ "pwd", xsystem_pwd,
"\n"
"Show the Present Working Directory name\n"
},
{ "stty", xsystem_stty,
"\n"
"Show the size of the TTY\n"
},
{ "which", xsystem_which,
"EXE ...\n"
"Show the location on PATH of executables EXE\n"
"Options:\n"
" -a Show all path locations rather than just the first\n"
},
};
/*
** COMMAND: system
**
** Usage: %fossil system COMMAND ARGS...
**
** Often abbreviated as just "fossil sys", this command provides primative,
** low-level unix-like commands for use on systems that lack those commands
** natively.
**
** Type "fossil sys help" for a list of available commands.
**
** Type "fossil sys help COMMAND" for detailed help on a particular
** command.
*/
void xsystem_cmd(void){
int i;
const char *zCmd;
int bHelp = 0;
if( g.argc<=2 || (g.argc==3 && fossil_strcmp(g.argv[2],"help")==0) ){
fossil_print("Available commands:\n");
for(i=0; i<count(aXSysCmd); i++){
if( (i%4)==3 || i==count(aXSysCmd)-1 ){
fossil_print(" %s\n", aXSysCmd[i].zName);
}else{
fossil_print(" %-12s", aXSysCmd[i].zName);
}
}
return;
}
zCmd = g.argv[2];
if( fossil_strcmp(zCmd, "help")==0 ){
bHelp = 1;
zCmd = g.argv[3];
}
for(i=0; i<count(aXSysCmd); i++){
if( fossil_strcmp(zCmd,aXSysCmd[i].zName)==0 ){
if( !bHelp ){
aXSysCmd[i].xFunc(g.argc-2, g.argv+2);
}else{
fossil_print("Usage: fossil system %s %s", zCmd, aXSysCmd[i].zHelp);
}
return;
}
}
fossil_fatal("Unknown system command \"%s\"."
" Use \"%s system help\" for a list of available commands",
zCmd, g.argv[0]);
}
|
Changes to src/zip.c.
| ︙ | ︙ | |||
404 405 406 407 408 409 410 |
assert( p->db );
blob_zero(&p->tmp);
sqlite3_exec(p->db,
"PRAGMA page_size=512;"
"PRAGMA journal_mode = off;"
"PRAGMA cache_spill = off;"
"BEGIN;"
| | | | | | | | 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 |
assert( p->db );
blob_zero(&p->tmp);
sqlite3_exec(p->db,
"PRAGMA page_size=512;"
"PRAGMA journal_mode = off;"
"PRAGMA cache_spill = off;"
"BEGIN;"
"CREATE TABLE sqlar(\n"
" name TEXT PRIMARY KEY, -- name of the file\n"
" mode INT, -- access permissions\n"
" mtime INT, -- last modification time\n"
" sz INT, -- original file size\n"
" data BLOB -- compressed content\n"
");", 0, 0, 0
);
sqlite3_prepare(p->db,
"INSERT INTO sqlar VALUES(?, ?, ?, ?, ?)", -1,
&p->pInsert, 0
);
assert( p->pInsert );
|
| ︙ | ︙ | |||
862 863 864 865 866 867 868 |
}
zOut = g.argv[3];
if( fossil_strcmp(zOut,"")==0 || fossil_strcmp(zOut,"/dev/null")==0 ){
zOut = 0;
}
if( zName==0 ){
| | < < < < < < < < | 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 |
}
zOut = g.argv[3];
if( fossil_strcmp(zOut,"")==0 || fossil_strcmp(zOut,"/dev/null")==0 ){
zOut = 0;
}
if( zName==0 ){
zName = archive_base_name(rid);
}
zip_of_checkin(eType, rid, zOut ? &zip : 0,
zName, pInclude, pExclude, listFlag);
glob_free(pInclude);
glob_free(pExclude);
if( zOut ){
blob_write_to_file(&zip, zOut);
|
| ︙ | ︙ | |||
959 960 961 962 963 964 965 | ** /zip/[VERSION/]NAME.zip ** /sqlar/[VERSION/]NAME.sqlar ** ** Generate a ZIP Archive or an SQL Archive for the check-in specified by ** VERSION. The archive is called NAME.zip or NAME.sqlar and has a top-level ** directory called NAME. ** | | > | > | > | > > > > > > > > > > > > > > > > | 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 984 985 986 987 988 989 990 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 |
** /zip/[VERSION/]NAME.zip
** /sqlar/[VERSION/]NAME.sqlar
**
** Generate a ZIP Archive or an SQL Archive for the check-in specified by
** VERSION. The archive is called NAME.zip or NAME.sqlar and has a top-level
** directory called NAME.
**
** The optional VERSION element defaults to the name of the main branch
** (usually "trunk") per the r= rules below.
** All of the following URLs are equivalent:
**
** /zip/release/xyz.zip
** /zip?r=release&name=xyz.zip
** /zip/xyz.zip?r=release
** /zip?name=release/xyz.zip
**
** Query parameters:
**
** name=[CKIN/]NAME The optional CKIN component of the name= parameter
** identifies the check-in from which the archive is
** constructed. If CKIN is omitted and there is no
** r= query parameter, then use the name of the main
** branch (usually "trunk"). NAME is the
** name of the download file. The top-level directory
** in the generated archive is called by NAME with the
** file extension removed.
**
** r=TAG TAG identifies the check-in that is turned into an
** SQL or ZIP archive. The default value is the name
** of the main branch (usually "trunk").
** If r= is omitted and if the name= query parameter
** contains one "/" character then the of part the
** name= value before the / becomes the TAG and the
** part of the name= value after the / is the download
** filename. If no check-in is specified by either
** name= or r=, then the name of the main branch
** (usually "trunk") is used.
**
** in=PATTERN Only include files that match the comma-separate
** list of GLOB patterns in PATTERN, as with ex=
**
** ex=PATTERN Omit any file that match PATTERN. PATTERN is a
** comma-separated list of GLOB patterns, where each
** pattern can optionally be quoted using ".." or '..'.
** Any file matching both ex= and in= is excluded.
**
** Robot Defenses:
**
** * If "zip" appears in the robot-restrict setting, then robots are
** not allowed to access this page. Suspected robots will be
** presented with a captcha.
**
** * If "zipX" appears in the robot-restrict setting, then robots are
** restricted in the same way as with "zip", but with exceptions.
** If the check-in for which an archive is requested is a leaf check-in
** and if the robot-zip-leaf setting is true, then the request is
** allowed. Or if the check-in has a tag that matches any of the
** GLOB patterns on the list in the robot-zip-tag setting, then the
** request is allowed. Otherwise, the usual robot defenses are
** activated.
*/
void baseline_zip_page(void){
int rid;
const char *z;
char *zName, *zRid, *zKey;
int nName, nRid;
const char *zInclude; /* The in= query parameter */
|
| ︙ | ︙ | |||
1014 1015 1016 1017 1018 1019 1020 |
login_check_credentials();
if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
if( robot_restrict("zip") ) return;
if( fossil_strcmp(g.zPath, "sqlar")==0 ){
eType = ARCHIVE_SQLAR;
zType = "SQL";
| < < < | | 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 |
login_check_credentials();
if( !g.perm.Zip ){ login_needed(g.anon.Zip); return; }
if( robot_restrict("zip") ) return;
if( fossil_strcmp(g.zPath, "sqlar")==0 ){
eType = ARCHIVE_SQLAR;
zType = "SQL";
}else{
eType = ARCHIVE_ZIP;
zType = "ZIP";
}
fossil_nice_default();
zName = fossil_strdup(PD("name",""));
z = P("r");
if( z==0 ) z = P("uuid");
if( z==0 ) z = tar_uuid_from_name(&zName);
if( z==0 ) z = fossil_strdup(db_main_branch());
nName = strlen(zName);
g.zOpenRevision = zRid = fossil_strdup(z);
nRid = strlen(zRid);
zInclude = P("in");
if( zInclude ) pInclude = glob_create(zInclude);
zExclude = P("ex");
if( zExclude ) pExclude = glob_create(zExclude);
|
| ︙ | ︙ | |||
1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 |
}
rid = symbolic_name_to_rid(nRid?zRid:zName, "ci");
if( rid<=0 ){
cgi_set_status(404, "Not Found");
@ Not found
return;
}
if( nRid==0 && nName>10 ) zName[10] = 0;
/* Compute a unique key for the cache entry based on query parameters */
blob_init(&cacheKey, 0, 0);
blob_appendf(&cacheKey, "/%s/%z", g.zPath, rid_to_uuid(rid));
blob_appendf(&cacheKey, "/%q", zName);
if( zInclude ) blob_appendf(&cacheKey, ",in=%Q", zInclude);
| > | 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 |
}
rid = symbolic_name_to_rid(nRid?zRid:zName, "ci");
if( rid<=0 ){
cgi_set_status(404, "Not Found");
@ Not found
return;
}
if( robot_restrict_zip(rid) ) return;
if( nRid==0 && nName>10 ) zName[10] = 0;
/* Compute a unique key for the cache entry based on query parameters */
blob_init(&cacheKey, 0, 0);
blob_appendf(&cacheKey, "/%s/%z", g.zPath, rid_to_uuid(rid));
blob_appendf(&cacheKey, "/%q", zName);
if( zInclude ) blob_appendf(&cacheKey, ",in=%Q", zInclude);
|
| ︙ | ︙ |
Changes to test/commit-warning.test.
| ︙ | ︙ | |||
158 159 160 161 162 163 164 | 1\tutf-nobom-16be.txt\tbinary data 1\tutf-nobom-16le.txt\tbinary data 1}]]} ############################################################################### | < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | 158 159 160 161 162 163 164 165 166 | 1\tutf-nobom-16be.txt\tbinary data 1\tutf-nobom-16le.txt\tbinary data 1}]]} ############################################################################### test_cleanup |
Changes to test/json.test.
| ︙ | ︙ | |||
174 175 176 177 178 179 180 |
# specific fields and that it lacks specific fields.
proc test_json_payload {testname okfields badfields} {
test_dict_keys $testname [dict get $::JR payload] $okfields $badfields
}
#### VERSION AKA HAI
| | | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 |
# specific fields and that it lacks specific fields.
proc test_json_payload {testname okfields badfields} {
test_dict_keys $testname [dict get $::JR payload] $okfields $badfields
}
#### VERSION AKA HAI
# The JSON API generally assumes we have a repository, so let it have one.
# Set FOSSIL_USER to ensure consistent results in "json user list"
set _fossil_user ""
if [info exists env(FOSSIL_USER)] {
set _fossil_user $env(FOSSIL_USER)
}
set ::env(FOSSIL_USER) "JSON-TEST-USER"
|
| ︙ | ︙ |
Changes to test/set-manifest.test.
| ︙ | ︙ | |||
36 37 38 39 40 41 42 |
# On ActiveTcl, add it with teacup. On other platforms, YMMV.
# teacup install sha1
if {[catch {package require sha1}] != 0} {
puts "The \"sha1\" package is not available."
test_cleanup_then_return
}
| | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# On ActiveTcl, add it with teacup. On other platforms, YMMV.
# teacup install sha1
if {[catch {package require sha1}] != 0} {
puts "The \"sha1\" package is not available."
test_cleanup_then_return
}
# We need a repository, so let it have one.
test_setup
#### Verify classic behavior of the manifest setting
# Setting is off by default, and there are no extra files.
fossil settings manifest
test "set-manifest-1" {[regexp {^manifest *$} $RESULT]}
|
| ︙ | ︙ |
Name change from test/settings.test to test/settings.test.off.
| ︙ | ︙ |
Changes to test/tester.tcl.
| ︙ | ︙ | |||
26 27 28 29 30 31 32 | # scripts), append the script base names as arguments: # # tclsh ../test/tester.tcl ../bld/fossil <script-basename>... # # We use some things introduced in 8.6 such as lmap. auto.def should # have found us a suitable Tcl installation. | | | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# scripts), append the script base names as arguments:
#
# tclsh ../test/tester.tcl ../bld/fossil <script-basename>...
#
# We use some things introduced in 8.6 such as lmap. auto.def should
# have found us a suitable Tcl installation.
package require Tcl 8.6-
set testfiledir [file normalize [file dirname [info script]]]
set testrundir [pwd]
set testdir [file normalize [file dirname $argv0]]
set fossilexe [file normalize [lindex $argv 0]]
set is_windows [expr {$::tcl_platform(platform) eq "windows"}]
set is_cygwin [regexp {^CYGWIN} $::tcl_platform(os)]
|
| ︙ | ︙ |
Changes to tools/email-sender.tcl.
1 2 3 4 5 6 7 | #!/usr/bin/tcl # # Monitor the database file named by the DBFILE variable # looking for email messages sent by Fossil. Forward each # to /usr/sbin/sendmail. # set POLLING_INTERVAL 10000 ;# milliseconds | | > > > > > > > > > | | > > > > > > | | > | > > > > > > > | > | 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 |
#!/usr/bin/tcl
#
# Monitor the database file named by the DBFILE variable
# looking for email messages sent by Fossil. Forward each
# to /usr/sbin/sendmail.
#
set POLLING_INTERVAL 10000 ;# milliseconds
set DBFILE /home/www/data/emailqueue.db
set PIPE "/usr/sbin/sendmail -ti"
package require sqlite3
# puts "SQLite version [sqlite3 -version]"
sqlite3 db $DBFILE
db timeout 5000
catch {db eval {PRAGMA journal_mode=WAL}}
db eval {
CREATE TABLE IF NOT EXISTS email(
emailid INTEGER PRIMARY KEY,
msg TXT
);
CREATE TABLE IF NOT EXISTS sentlog(
mtime INT,
xto TEXT,
xfrom TEXT,
xsubject TEXT,
xsize INT
);
}
set ctr 0
while {1} {
set n 0
db transaction immediate {
set emailid 0
db eval {SELECT emailid, msg FROM email LIMIT 1} {
set pipe $PIPE
set to unk
set subject none
set size [string length $msg]
regexp {To:[^\n]*<([^>]+)>} $msg all to
regexp {\nSubject:[ ]*([^\r\n]+)} $msg all subject
set subject [string trim $subject]
if {[regexp {\nFrom:[^\n]*<([^>]+)>} $msg all from]} {
append pipe " -f $from"
}
set out [open |$pipe w]
puts -nonewline $out $msg
flush $out
close $out
incr n
incr ctr
}
if {$n>0} {
db eval {DELETE FROM email WHERE emailid=$emailid}
db eval {INSERT INTO sentlog(mtime,xto,xfrom,xsubject,xsize)
VALUES(unixepoch(),$to,$from,$subject,$size)}
}
}
if {$n==0} {
if {$ctr>100} {
db eval {DELETE FROM sentlog WHERE mtime<unixepoch('now','-30 days')}
set ctr 0
}
after $POLLING_INTERVAL
}
}
|
Changes to tools/fossil-autocomplete.zsh.
| ︙ | ︙ | |||
158 159 160 161 162 163 164 |
# Scaffolding code for common options can be generated with `__fossil_format_options -o`.
_common_options=(
"(--help --args)"--args'[FILENAME Read additional arguments and options from FILENAME]:file:_files'
"(--help --cgitrace)"--cgitrace'[Active CGI tracing]'
"(--help --comfmtflags --comment-format)"--comfmtflags'[VALUE Set comment formatting flags to VALUE]:value:'
"(--help --comment-format --comfmtflags)"--comment-format'[VALUE Alias for --comfmtflags]:value:'
"(--help --errorlog)"--errorlog'[FILENAME Log errors to FILENAME]:file:_files'
| > | | 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# Scaffolding code for common options can be generated with `__fossil_format_options -o`.
_common_options=(
"(--help --args)"--args'[FILENAME Read additional arguments and options from FILENAME]:file:_files'
"(--help --cgitrace)"--cgitrace'[Active CGI tracing]'
"(--help --comfmtflags --comment-format)"--comfmtflags'[VALUE Set comment formatting flags to VALUE]:value:'
"(--help --comment-format --comfmtflags)"--comment-format'[VALUE Alias for --comfmtflags]:value:'
"(--help --errorlog)"--errorlog'[FILENAME Log errors to FILENAME]:file:_files'
"(- -? --help)"{-?,--help}
'[Show help on the command rather than running it]'
"(--help --httptrace)"--httptrace'[Trace outbound HTTP requests]'
"(--help --localtime)"--localtime'[Display times using the local timezone]'
"(--help --no-th-hook)"--no-th-hook'[Do not run TH1 hooks]'
"(--help --quiet)"--quiet'[Reduce the amount of output]'
"(--help --sqlstats)"--sqlstats'[Show SQL usage statistics when done]'
"(--help --sqltrace)"--sqltrace'[Trace all SQL commands]'
"(--help --sshtrace)"--sshtrace'[Trace SSH activity]'
|
| ︙ | ︙ |
Changes to tools/makeheaders.c.
| ︙ | ︙ | |||
484 485 486 487 488 489 490 |
#define StringGet(S) ((S)->zText?(S)->zText:"")
/*
** Compute a hash on a string. The number returned is a non-negative
** value between 0 and 2**31 - 1
*/
static int Hash(const char *z, int n){
| | | | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 |
#define StringGet(S) ((S)->zText?(S)->zText:"")
/*
** Compute a hash on a string. The number returned is a non-negative
** value between 0 and 2**31 - 1
*/
static int Hash(const char *z, int n){
unsigned int h = 0;
if( n<=0 ){
n = strlen(z);
}
while( n-- ){
h = h ^ (h<<5) ^ *z++;
}
return (int)(h & 0x7fffffff);
}
/*
** Given an identifier name, try to find a declaration for that
** identifier in the hash table. If found, return a pointer to
** the Decl structure. If not found, return 0.
*/
|
| ︙ | ︙ |
Changes to tools/makemake.tcl.
| ︙ | ︙ | |||
193 194 195 196 197 198 199 200 201 202 203 204 205 206 | vfile wiki wikiformat winfile winhttp xfer xfersetup zip http_ssl } # Source files which live under $srcDirExt, but only those for which # we need to run makeheaders. External sources which have their own # header files must not be in this list. | > | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 | vfile wiki wikiformat winfile winhttp xfer xfersetup xsystem zip http_ssl } # Source files which live under $srcDirExt, but only those for which # we need to run makeheaders. External sources which have their own # header files must not be in this list. |
| ︙ | ︙ |
Changes to win/Makefile.dmc.
| ︙ | ︙ | |||
30 31 32 33 34 35 36 | SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_SETLK_TIMEOUT -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_SETLK_TIMEOUT -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen PIKCHR_OPTIONS = -DPIKCHR_TOKEN_LIMIT=10000 | | | | | 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 | SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_SETLK_TIMEOUT -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP SHELL_OPTIONS = -DNDEBUG=1 -DSQLITE_DQS=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_DEFAULT_WAL_SYNCHRONOUS=1 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_OMIT_DECLTYPE -DSQLITE_OMIT_DEPRECATED -DSQLITE_OMIT_PROGRESS_CALLBACK -DSQLITE_OMIT_SHARED_CACHE -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_MAX_EXPR_DEPTH=0 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_DBSTAT_VTAB -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_MATH_FUNCTIONS -DSQLITE_ENABLE_SETLK_TIMEOUT -DSQLITE_ENABLE_STMTVTAB -DSQLITE_HAVE_ZLIB -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_TRUSTED_SCHEMA=0 -DHAVE_USLEEP -Dmain=sqlite3_shell -DSQLITE_SHELL_IS_UTF8=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=sqlcmd_get_dbname -DSQLITE_SHELL_INIT_PROC=sqlcmd_init_proc -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen PIKCHR_OPTIONS = -DPIKCHR_TOKEN_LIMIT=10000 SRC = add_.c ajax_.c alerts_.c allrepo_.c attach_.c backlink_.c backoffice_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c capabilities_.c captcha_.c cgi_.c chat_.c checkin_.c checkout_.c clearsign_.c clone_.c color_.c comformat_.c configure_.c content_.c cookies_.c db_.c delta_.c deltacmd_.c deltafunc_.c descendants_.c diff_.c diffcmd_.c dispatch_.c doc_.c encode_.c etag_.c event_.c export_.c extcgi_.c file_.c fileedit_.c finfo_.c foci_.c forum_.c fshell_.c fusefs_.c fuzz_.c glob_.c graph_.c gzip_.c hname_.c hook_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c interwiki_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c match_.c md5_.c merge_.c merge3_.c moderate_.c name_.c patch_.c path_.c piechart_.c pikchrshow_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c repolist_.c report_.c robot_.c rss_.c schema_.c search_.c security_audit_.c setup_.c setupuser_.c sha1_.c sha1hard_.c sha3_.c shun_.c sitemap_.c skins_.c smtp_.c sqlcmd_.c stash_.c stat_.c statrep_.c style_.c sync_.c tag_.c tar_.c terminal_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c unversioned_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c xfer_.c xfersetup_.c xsystem_.c zip_.c OBJ = $(OBJDIR)\add$O $(OBJDIR)\ajax$O $(OBJDIR)\alerts$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\backlink$O $(OBJDIR)\backoffice$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\capabilities$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\chat$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\color$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\cookies$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\deltafunc$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\dispatch$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\etag$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\extcgi$O $(OBJDIR)\file$O $(OBJDIR)\fileedit$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\forum$O $(OBJDIR)\fshell$O $(OBJDIR)\fusefs$O $(OBJDIR)\fuzz$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\hname$O $(OBJDIR)\hook$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\interwiki$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\match$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\patch$O $(OBJDIR)\path$O $(OBJDIR)\piechart$O $(OBJDIR)\pikchrshow$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\repolist$O $(OBJDIR)\report$O $(OBJDIR)\robot$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\security_audit$O $(OBJDIR)\setup$O $(OBJDIR)\setupuser$O $(OBJDIR)\sha1$O $(OBJDIR)\sha1hard$O $(OBJDIR)\sha3$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\smtp$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\statrep$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\terminal$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\unversioned$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\xsystem$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O RC=$(DMDIR)\bin\rcc RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__ APPNAME = $(OBJDIR)\fossil$(E) all: $(APPNAME) $(APPNAME) : translate$E mkindex$E codecheck1$E headers $(OBJ) $(OBJDIR)\link cd $(OBJDIR) codecheck1$E $(SRC) $(DMDIR)\bin\link @link $(OBJDIR)\fossil.res: $B\win\fossil.rc $(RC) $(RCFLAGS) -o$@ $** $(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res +echo add ajax alerts allrepo attach backlink backoffice bag bisect blob branch browse builtin bundle cache capabilities captcha cgi chat checkin checkout clearsign clone color comformat configure content cookies db delta deltacmd deltafunc descendants diff diffcmd dispatch doc encode etag event export extcgi file fileedit finfo foci forum fshell fusefs fuzz glob graph gzip hname hook http http_socket http_ssl http_transport import info interwiki json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html match md5 merge merge3 moderate name patch path piechart pikchrshow pivot popen pqueue printf publish purge rebuild regexp repolist report robot rss schema search security_audit setup setupuser sha1 sha1hard sha3 shun sitemap skins smtp sqlcmd stash stat statrep style sync tag tar terminal th_main timeline tkt tktsetup undo unicode unversioned update url user utf8 util verify vfile wiki wikiformat winfile winhttp xfer xfersetup xsystem zip shell sqlite3 th th_lang > $@ +echo fossil >> $@ +echo fossil >> $@ +echo $(LIBS) >> $@ +echo. >> $@ +echo fossil >> $@ translate$E: $(SRCDIR_tools)\translate.c |
| ︙ | ︙ | |||
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 | +translate$E $** > $@ $(OBJDIR)\xfersetup$O : xfersetup_.c xfersetup.h $(TCC) -o$@ -c xfersetup_.c xfersetup_.c : $(SRCDIR)\xfersetup.c +translate$E $** > $@ $(OBJDIR)\zip$O : zip_.c zip.h $(TCC) -o$@ -c zip_.c zip_.c : $(SRCDIR)\zip.c +translate$E $** > $@ headers: makeheaders$E page_index.h builtin_data.h VERSION.h | > > > > > > | | 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 | +translate$E $** > $@ $(OBJDIR)\xfersetup$O : xfersetup_.c xfersetup.h $(TCC) -o$@ -c xfersetup_.c xfersetup_.c : $(SRCDIR)\xfersetup.c +translate$E $** > $@ $(OBJDIR)\xsystem$O : xsystem_.c xsystem.h $(TCC) -o$@ -c xsystem_.c xsystem_.c : $(SRCDIR)\xsystem.c +translate$E $** > $@ $(OBJDIR)\zip$O : zip_.c zip.h $(TCC) -o$@ -c zip_.c zip_.c : $(SRCDIR)\zip.c +translate$E $** > $@ headers: makeheaders$E page_index.h builtin_data.h VERSION.h +makeheaders$E add_.c:add.h ajax_.c:ajax.h alerts_.c:alerts.h allrepo_.c:allrepo.h attach_.c:attach.h backlink_.c:backlink.h backoffice_.c:backoffice.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h capabilities_.c:capabilities.h captcha_.c:captcha.h cgi_.c:cgi.h chat_.c:chat.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h color_.c:color.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h cookies_.c:cookies.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h deltafunc_.c:deltafunc.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h dispatch_.c:dispatch.h doc_.c:doc.h encode_.c:encode.h etag_.c:etag.h event_.c:event.h export_.c:export.h extcgi_.c:extcgi.h file_.c:file.h fileedit_.c:fileedit.h finfo_.c:finfo.h foci_.c:foci.h forum_.c:forum.h fshell_.c:fshell.h fusefs_.c:fusefs.h fuzz_.c:fuzz.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h hname_.c:hname.h hook_.c:hook.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h interwiki_.c:interwiki.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h match_.c:match.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h patch_.c:patch.h path_.c:path.h piechart_.c:piechart.h pikchrshow_.c:pikchrshow.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h repolist_.c:repolist.h report_.c:report.h robot_.c:robot.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h security_audit_.c:security_audit.h setup_.c:setup.h setupuser_.c:setupuser.h sha1_.c:sha1.h sha1hard_.c:sha1hard.h sha3_.c:sha3.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h smtp_.c:smtp.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h statrep_.c:statrep.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h terminal_.c:terminal.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h unversioned_.c:unversioned.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h xsystem_.c:xsystem.h zip_.c:zip.h $(SRCDIR_extsrc)\pikchr.c:pikchr.h $(SRCDIR_extsrc)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR_extsrc)\cson_amalgamation.h @copy /Y nul: headers |
Changes to win/Makefile.mingw.
| ︙ | ︙ | |||
546 547 548 549 550 551 552 553 554 555 556 557 558 559 | $(SRCDIR)/vfile.c \ $(SRCDIR)/wiki.c \ $(SRCDIR)/wikiformat.c \ $(SRCDIR)/winfile.c \ $(SRCDIR)/winhttp.c \ $(SRCDIR)/xfer.c \ $(SRCDIR)/xfersetup.c \ $(SRCDIR)/zip.c EXTRA_FILES = \ $(SRCDIR)/../extsrc/pikchr-worker.js \ $(SRCDIR)/../extsrc/pikchr.js \ $(SRCDIR)/../extsrc/pikchr.wasm \ $(SRCDIR)/../skins/ardoise/css.txt \ | > | 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 | $(SRCDIR)/vfile.c \ $(SRCDIR)/wiki.c \ $(SRCDIR)/wikiformat.c \ $(SRCDIR)/winfile.c \ $(SRCDIR)/winhttp.c \ $(SRCDIR)/xfer.c \ $(SRCDIR)/xfersetup.c \ $(SRCDIR)/xsystem.c \ $(SRCDIR)/zip.c EXTRA_FILES = \ $(SRCDIR)/../extsrc/pikchr-worker.js \ $(SRCDIR)/../extsrc/pikchr.js \ $(SRCDIR)/../extsrc/pikchr.wasm \ $(SRCDIR)/../skins/ardoise/css.txt \ |
| ︙ | ︙ | |||
621 622 623 624 625 626 627 628 629 630 631 632 633 634 | $(SRCDIR)/fossil.numbered-lines.js \ $(SRCDIR)/fossil.page.brlist.js \ $(SRCDIR)/fossil.page.chat.js \ $(SRCDIR)/fossil.page.fileedit.js \ $(SRCDIR)/fossil.page.forumpost.js \ $(SRCDIR)/fossil.page.pikchrshow.js \ $(SRCDIR)/fossil.page.pikchrshowasm.js \ $(SRCDIR)/fossil.page.whistory.js \ $(SRCDIR)/fossil.page.wikiedit.js \ $(SRCDIR)/fossil.pikchr.js \ $(SRCDIR)/fossil.popupwidget.js \ $(SRCDIR)/fossil.storage.js \ $(SRCDIR)/fossil.tabs.js \ $(SRCDIR)/fossil.wikiedit-wysiwyg.js \ | > | 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 | $(SRCDIR)/fossil.numbered-lines.js \ $(SRCDIR)/fossil.page.brlist.js \ $(SRCDIR)/fossil.page.chat.js \ $(SRCDIR)/fossil.page.fileedit.js \ $(SRCDIR)/fossil.page.forumpost.js \ $(SRCDIR)/fossil.page.pikchrshow.js \ $(SRCDIR)/fossil.page.pikchrshowasm.js \ $(SRCDIR)/fossil.page.ticket.js \ $(SRCDIR)/fossil.page.whistory.js \ $(SRCDIR)/fossil.page.wikiedit.js \ $(SRCDIR)/fossil.pikchr.js \ $(SRCDIR)/fossil.popupwidget.js \ $(SRCDIR)/fossil.storage.js \ $(SRCDIR)/fossil.tabs.js \ $(SRCDIR)/fossil.wikiedit-wysiwyg.js \ |
| ︙ | ︙ | |||
813 814 815 816 817 818 819 820 821 822 823 824 825 826 | $(OBJDIR)/vfile_.c \ $(OBJDIR)/wiki_.c \ $(OBJDIR)/wikiformat_.c \ $(OBJDIR)/winfile_.c \ $(OBJDIR)/winhttp_.c \ $(OBJDIR)/xfer_.c \ $(OBJDIR)/xfersetup_.c \ $(OBJDIR)/zip_.c OBJ = \ $(OBJDIR)/add.o \ $(OBJDIR)/ajax.o \ $(OBJDIR)/alerts.o \ $(OBJDIR)/allrepo.o \ | > | 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 | $(OBJDIR)/vfile_.c \ $(OBJDIR)/wiki_.c \ $(OBJDIR)/wikiformat_.c \ $(OBJDIR)/winfile_.c \ $(OBJDIR)/winhttp_.c \ $(OBJDIR)/xfer_.c \ $(OBJDIR)/xfersetup_.c \ $(OBJDIR)/xsystem_.c \ $(OBJDIR)/zip_.c OBJ = \ $(OBJDIR)/add.o \ $(OBJDIR)/ajax.o \ $(OBJDIR)/alerts.o \ $(OBJDIR)/allrepo.o \ |
| ︙ | ︙ | |||
964 965 966 967 968 969 970 971 972 973 974 975 976 977 | $(OBJDIR)/vfile.o \ $(OBJDIR)/wiki.o \ $(OBJDIR)/wikiformat.o \ $(OBJDIR)/winfile.o \ $(OBJDIR)/winhttp.o \ $(OBJDIR)/xfer.o \ $(OBJDIR)/xfersetup.o \ $(OBJDIR)/zip.o APPNAME = fossil.exe APPTARGETS = #### If the USE_WINDOWS variable exists, it is assumed that we are building # inside of a Windows-style shell; otherwise, it is assumed that we are | > | 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 | $(OBJDIR)/vfile.o \ $(OBJDIR)/wiki.o \ $(OBJDIR)/wikiformat.o \ $(OBJDIR)/winfile.o \ $(OBJDIR)/winhttp.o \ $(OBJDIR)/xfer.o \ $(OBJDIR)/xfersetup.o \ $(OBJDIR)/xsystem.o \ $(OBJDIR)/zip.o APPNAME = fossil.exe APPTARGETS = #### If the USE_WINDOWS variable exists, it is assumed that we are building # inside of a Windows-style shell; otherwise, it is assumed that we are |
| ︙ | ︙ | |||
1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 | $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h \ $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \ $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \ $(OBJDIR)/winfile_.c:$(OBJDIR)/winfile.h \ $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \ $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h \ $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h \ $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h \ $(SRCDIR_extsrc)/pikchr.c:$(OBJDIR)/pikchr.h \ $(SRCDIR_extsrc)/sqlite3.h \ $(SRCDIR)/th.h \ $(OBJDIR)/VERSION.h echo Done >$(OBJDIR)/headers | > | 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 | $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h \ $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h \ $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h \ $(OBJDIR)/winfile_.c:$(OBJDIR)/winfile.h \ $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h \ $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h \ $(OBJDIR)/xfersetup_.c:$(OBJDIR)/xfersetup.h \ $(OBJDIR)/xsystem_.c:$(OBJDIR)/xsystem.h \ $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h \ $(SRCDIR_extsrc)/pikchr.c:$(OBJDIR)/pikchr.h \ $(SRCDIR_extsrc)/sqlite3.h \ $(SRCDIR)/th.h \ $(OBJDIR)/VERSION.h echo Done >$(OBJDIR)/headers |
| ︙ | ︙ | |||
2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 | $(OBJDIR)/xfersetup_.c: $(SRCDIR)/xfersetup.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/xfersetup.c >$@ $(OBJDIR)/xfersetup.o: $(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/xfersetup.o -c $(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h: $(OBJDIR)/headers $(OBJDIR)/zip_.c: $(SRCDIR)/zip.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/zip.c >$@ $(OBJDIR)/zip.o: $(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c | > > > > > > > > | 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 | $(OBJDIR)/xfersetup_.c: $(SRCDIR)/xfersetup.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/xfersetup.c >$@ $(OBJDIR)/xfersetup.o: $(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/xfersetup.o -c $(OBJDIR)/xfersetup_.c $(OBJDIR)/xfersetup.h: $(OBJDIR)/headers $(OBJDIR)/xsystem_.c: $(SRCDIR)/xsystem.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/xsystem.c >$@ $(OBJDIR)/xsystem.o: $(OBJDIR)/xsystem_.c $(OBJDIR)/xsystem.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/xsystem.o -c $(OBJDIR)/xsystem_.c $(OBJDIR)/xsystem.h: $(OBJDIR)/headers $(OBJDIR)/zip_.c: $(SRCDIR)/zip.c $(TRANSLATE) $(TRANSLATE) $(SRCDIR)/zip.c >$@ $(OBJDIR)/zip.o: $(OBJDIR)/zip_.c $(OBJDIR)/zip.h $(SRCDIR)/config.h $(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c |
| ︙ | ︙ |
Changes to win/Makefile.msc.
| ︙ | ︙ | |||
508 509 510 511 512 513 514 515 516 517 518 519 520 521 |
"$(OX)\vfile_.c" \
"$(OX)\wiki_.c" \
"$(OX)\wikiformat_.c" \
"$(OX)\winfile_.c" \
"$(OX)\winhttp_.c" \
"$(OX)\xfer_.c" \
"$(OX)\xfersetup_.c" \
"$(OX)\zip_.c" \
"$(SRCDIR_extsrc)\pikchr.c"
EXTRA_FILES = "$(SRCDIR)\..\extsrc\pikchr-worker.js" \
"$(SRCDIR)\..\extsrc\pikchr.js" \
"$(SRCDIR)\..\extsrc\pikchr.wasm" \
"$(SRCDIR)\..\skins\ardoise\css.txt" \
| > | 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 |
"$(OX)\vfile_.c" \
"$(OX)\wiki_.c" \
"$(OX)\wikiformat_.c" \
"$(OX)\winfile_.c" \
"$(OX)\winhttp_.c" \
"$(OX)\xfer_.c" \
"$(OX)\xfersetup_.c" \
"$(OX)\xsystem_.c" \
"$(OX)\zip_.c" \
"$(SRCDIR_extsrc)\pikchr.c"
EXTRA_FILES = "$(SRCDIR)\..\extsrc\pikchr-worker.js" \
"$(SRCDIR)\..\extsrc\pikchr.js" \
"$(SRCDIR)\..\extsrc\pikchr.wasm" \
"$(SRCDIR)\..\skins\ardoise\css.txt" \
|
| ︙ | ︙ | |||
583 584 585 586 587 588 589 590 591 592 593 594 595 596 |
"$(SRCDIR)\fossil.numbered-lines.js" \
"$(SRCDIR)\fossil.page.brlist.js" \
"$(SRCDIR)\fossil.page.chat.js" \
"$(SRCDIR)\fossil.page.fileedit.js" \
"$(SRCDIR)\fossil.page.forumpost.js" \
"$(SRCDIR)\fossil.page.pikchrshow.js" \
"$(SRCDIR)\fossil.page.pikchrshowasm.js" \
"$(SRCDIR)\fossil.page.whistory.js" \
"$(SRCDIR)\fossil.page.wikiedit.js" \
"$(SRCDIR)\fossil.pikchr.js" \
"$(SRCDIR)\fossil.popupwidget.js" \
"$(SRCDIR)\fossil.storage.js" \
"$(SRCDIR)\fossil.tabs.js" \
"$(SRCDIR)\fossil.wikiedit-wysiwyg.js" \
| > | 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 |
"$(SRCDIR)\fossil.numbered-lines.js" \
"$(SRCDIR)\fossil.page.brlist.js" \
"$(SRCDIR)\fossil.page.chat.js" \
"$(SRCDIR)\fossil.page.fileedit.js" \
"$(SRCDIR)\fossil.page.forumpost.js" \
"$(SRCDIR)\fossil.page.pikchrshow.js" \
"$(SRCDIR)\fossil.page.pikchrshowasm.js" \
"$(SRCDIR)\fossil.page.ticket.js" \
"$(SRCDIR)\fossil.page.whistory.js" \
"$(SRCDIR)\fossil.page.wikiedit.js" \
"$(SRCDIR)\fossil.pikchr.js" \
"$(SRCDIR)\fossil.popupwidget.js" \
"$(SRCDIR)\fossil.storage.js" \
"$(SRCDIR)\fossil.tabs.js" \
"$(SRCDIR)\fossil.wikiedit-wysiwyg.js" \
|
| ︙ | ︙ | |||
781 782 783 784 785 786 787 788 789 790 791 792 793 794 |
"$(OX)\vfile$O" \
"$(OX)\wiki$O" \
"$(OX)\wikiformat$O" \
"$(OX)\winfile$O" \
"$(OX)\winhttp$O" \
"$(OX)\xfer$O" \
"$(OX)\xfersetup$O" \
"$(OX)\zip$O" \
"$(OX)\fossil.res"
!ifndef BASEAPPNAME
BASEAPPNAME = fossil
!endif
| > | 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 |
"$(OX)\vfile$O" \
"$(OX)\wiki$O" \
"$(OX)\wikiformat$O" \
"$(OX)\winfile$O" \
"$(OX)\winhttp$O" \
"$(OX)\xfer$O" \
"$(OX)\xfersetup$O" \
"$(OX)\xsystem$O" \
"$(OX)\zip$O" \
"$(OX)\fossil.res"
!ifndef BASEAPPNAME
BASEAPPNAME = fossil
!endif
|
| ︙ | ︙ | |||
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 | echo "$(OX)\vfile.obj" >> $@ echo "$(OX)\wiki.obj" >> $@ echo "$(OX)\wikiformat.obj" >> $@ echo "$(OX)\winfile.obj" >> $@ echo "$(OX)\winhttp.obj" >> $@ echo "$(OX)\xfer.obj" >> $@ echo "$(OX)\xfersetup.obj" >> $@ echo "$(OX)\zip.obj" >> $@ echo $(LIBS) >> $@ "$(OBJDIR)\translate$E": "$(SRCDIR_tools)\translate.c" $(BCC) /Fe$@ /Fo$(@D)\ /Fd$(@D)\ $** "$(OBJDIR)\makeheaders$E": "$(SRCDIR_tools)\makeheaders.c" | > | 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 | echo "$(OX)\vfile.obj" >> $@ echo "$(OX)\wiki.obj" >> $@ echo "$(OX)\wikiformat.obj" >> $@ echo "$(OX)\winfile.obj" >> $@ echo "$(OX)\winhttp.obj" >> $@ echo "$(OX)\xfer.obj" >> $@ echo "$(OX)\xfersetup.obj" >> $@ echo "$(OX)\xsystem.obj" >> $@ echo "$(OX)\zip.obj" >> $@ echo $(LIBS) >> $@ "$(OBJDIR)\translate$E": "$(SRCDIR_tools)\translate.c" $(BCC) /Fe$@ /Fo$(@D)\ /Fd$(@D)\ $** "$(OBJDIR)\makeheaders$E": "$(SRCDIR_tools)\makeheaders.c" |
| ︙ | ︙ | |||
1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 | echo "$(SRCDIR)\fossil.numbered-lines.js" >> $@ echo "$(SRCDIR)\fossil.page.brlist.js" >> $@ echo "$(SRCDIR)\fossil.page.chat.js" >> $@ echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@ echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@ echo "$(SRCDIR)\fossil.page.pikchrshow.js" >> $@ echo "$(SRCDIR)\fossil.page.pikchrshowasm.js" >> $@ echo "$(SRCDIR)\fossil.page.whistory.js" >> $@ echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@ echo "$(SRCDIR)\fossil.pikchr.js" >> $@ echo "$(SRCDIR)\fossil.popupwidget.js" >> $@ echo "$(SRCDIR)\fossil.storage.js" >> $@ echo "$(SRCDIR)\fossil.tabs.js" >> $@ echo "$(SRCDIR)\fossil.wikiedit-wysiwyg.js" >> $@ | > | 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 | echo "$(SRCDIR)\fossil.numbered-lines.js" >> $@ echo "$(SRCDIR)\fossil.page.brlist.js" >> $@ echo "$(SRCDIR)\fossil.page.chat.js" >> $@ echo "$(SRCDIR)\fossil.page.fileedit.js" >> $@ echo "$(SRCDIR)\fossil.page.forumpost.js" >> $@ echo "$(SRCDIR)\fossil.page.pikchrshow.js" >> $@ echo "$(SRCDIR)\fossil.page.pikchrshowasm.js" >> $@ echo "$(SRCDIR)\fossil.page.ticket.js" >> $@ echo "$(SRCDIR)\fossil.page.whistory.js" >> $@ echo "$(SRCDIR)\fossil.page.wikiedit.js" >> $@ echo "$(SRCDIR)\fossil.pikchr.js" >> $@ echo "$(SRCDIR)\fossil.popupwidget.js" >> $@ echo "$(SRCDIR)\fossil.storage.js" >> $@ echo "$(SRCDIR)\fossil.tabs.js" >> $@ echo "$(SRCDIR)\fossil.wikiedit-wysiwyg.js" >> $@ |
| ︙ | ︙ | |||
2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 | "$(OBJDIR)\translate$E" $** > $@ "$(OX)\xfersetup$O" : "$(OX)\xfersetup_.c" "$(OX)\xfersetup.h" $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\xfersetup_.c" "$(OX)\xfersetup_.c" : "$(SRCDIR)\xfersetup.c" "$(OBJDIR)\translate$E" $** > $@ "$(OX)\zip$O" : "$(OX)\zip_.c" "$(OX)\zip.h" $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\zip_.c" "$(OX)\zip_.c" : "$(SRCDIR)\zip.c" "$(OBJDIR)\translate$E" $** > $@ | > > > > > > | 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 | "$(OBJDIR)\translate$E" $** > $@ "$(OX)\xfersetup$O" : "$(OX)\xfersetup_.c" "$(OX)\xfersetup.h" $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\xfersetup_.c" "$(OX)\xfersetup_.c" : "$(SRCDIR)\xfersetup.c" "$(OBJDIR)\translate$E" $** > $@ "$(OX)\xsystem$O" : "$(OX)\xsystem_.c" "$(OX)\xsystem.h" $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\xsystem_.c" "$(OX)\xsystem_.c" : "$(SRCDIR)\xsystem.c" "$(OBJDIR)\translate$E" $** > $@ "$(OX)\zip$O" : "$(OX)\zip_.c" "$(OX)\zip.h" $(TCC) /Fo$@ /Fd$(@D)\ -c "$(OX)\zip_.c" "$(OX)\zip_.c" : "$(SRCDIR)\zip.c" "$(OBJDIR)\translate$E" $** > $@ |
| ︙ | ︙ | |||
2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 | "$(OX)\vfile_.c":"$(OX)\vfile.h" \ "$(OX)\wiki_.c":"$(OX)\wiki.h" \ "$(OX)\wikiformat_.c":"$(OX)\wikiformat.h" \ "$(OX)\winfile_.c":"$(OX)\winfile.h" \ "$(OX)\winhttp_.c":"$(OX)\winhttp.h" \ "$(OX)\xfer_.c":"$(OX)\xfer.h" \ "$(OX)\xfersetup_.c":"$(OX)\xfersetup.h" \ "$(OX)\zip_.c":"$(OX)\zip.h" \ "$(SRCDIR_extsrc)\pikchr.c":"$(OX)\pikchr.h" \ "$(SRCDIR_extsrc)\sqlite3.h" \ "$(SRCDIR)\th.h" \ "$(OX)\VERSION.h" \ "$(SRCDIR_extsrc)\cson_amalgamation.h" @copy /Y nul: $@ | > | 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 | "$(OX)\vfile_.c":"$(OX)\vfile.h" \ "$(OX)\wiki_.c":"$(OX)\wiki.h" \ "$(OX)\wikiformat_.c":"$(OX)\wikiformat.h" \ "$(OX)\winfile_.c":"$(OX)\winfile.h" \ "$(OX)\winhttp_.c":"$(OX)\winhttp.h" \ "$(OX)\xfer_.c":"$(OX)\xfer.h" \ "$(OX)\xfersetup_.c":"$(OX)\xfersetup.h" \ "$(OX)\xsystem_.c":"$(OX)\xsystem.h" \ "$(OX)\zip_.c":"$(OX)\zip.h" \ "$(SRCDIR_extsrc)\pikchr.c":"$(OX)\pikchr.h" \ "$(SRCDIR_extsrc)\sqlite3.h" \ "$(SRCDIR)\th.h" \ "$(OX)\VERSION.h" \ "$(SRCDIR_extsrc)\cson_amalgamation.h" @copy /Y nul: $@ |
Changes to www/aboutcgi.wiki.
| ︙ | ︙ | |||
129 130 131 132 133 134 135 | out what web page is being requested, generates that one web page, then exits. Usually, the webpage being requested is the first term of the PATH_INFO environment variable. (Exceptions to this rule are noted in the sequel.) For our example, the first term of PATH_INFO is "timeline", which means that Fossil will generate | | | | 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 | out what web page is being requested, generates that one web page, then exits. Usually, the webpage being requested is the first term of the PATH_INFO environment variable. (Exceptions to this rule are noted in the sequel.) For our example, the first term of PATH_INFO is "timeline", which means that Fossil will generate the [/help/www/timeline|/timeline] webpage. With Fossil, terms of PATH_INFO beyond the webpage name are converted into the "name" query parameter. Hence, the following two URLs mean exactly the same thing to Fossil: <ol type='A'> <li> [https://fossil-scm.org/home/info/c14ecc43] <li> [https://fossil-scm.org/home/info?name=c14ecc43] </ol> In both cases, the CGI script is called "/fossil". For case (A), the PATH_INFO variable will be "info/c14ecc43" and so the "[/help/www/info|/info]" webpage will be generated and the suffix of PATH_INFO will be converted into the "name" query parameter, which identifies the artifact about which information is requested. In case (B), the PATH_INFO is just "info", but the same "name" query parameter is set explicitly by the URL itself. <h2>Serving Multiple Fossil Repositories From One CGI Script</h2> |
| ︙ | ︙ | |||
280 281 282 283 284 285 286 | source is seen as a space of key/value pairs which are loaded into an internal property hash table. The code that runs to generate the reply can then reference various properties values. Fossil does not care where the value of each property comes from (POST content, cookies, or query parameters) only that the property exists and has a value.</p></li> <li><p> | | | 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | source is seen as a space of key/value pairs which are loaded into an internal property hash table. The code that runs to generate the reply can then reference various properties values. Fossil does not care where the value of each property comes from (POST content, cookies, or query parameters) only that the property exists and has a value.</p></li> <li><p> The "[/help/ui|fossil ui]" and "[/help/server|fossil server]" commands are implemented using a simple built-in web server that accepts incoming HTTP requests, translates each request into a CGI invocation, then creates a separate child Fossil process to handle each request. In other words, CGI is used internally to implement "fossil ui/server". <br><br> SCGI is processed using the same built-in web server, just modified to parse SCGI requests instead of HTTP requests. Each SCGI request is |
| ︙ | ︙ |
Changes to www/aboutdownload.wiki.
1 2 3 4 5 6 7 8 | <title>How The Fossil Download Page Works</title> <h2>1.0 Overview</h2> The [/uv/download.html|Download] page for the Fossil self-hosting repository is implemented using [./unvers.wiki|unversioned files]. The "download.html" screen itself, and the various build products are all stored as unversioned content. The download.html page | | | | | | | 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 | <title>How The Fossil Download Page Works</title> <h2>1.0 Overview</h2> The [/uv/download.html|Download] page for the Fossil self-hosting repository is implemented using [./unvers.wiki|unversioned files]. The "download.html" screen itself, and the various build products are all stored as unversioned content. The download.html page uses XMLHttpRequest() to retrieve the [/help/www/juvlist|/juvlist] webpage for a list of all unversioned files. Javascript in the [/uv/download.js?mimetype=text/plain|download.js] file (which is sourced by "download.html") then figures out which unversioned files are build products and paints appropriate icons on the displayed download page. Except, the "Source Tarball" download products are not stored as unversioned files. They are computed on-demand by the [/help/www/tarball|/tarball web page]. When a new version is generated, the developers use the [/help/uv|fossil uv edit] command to make minor changes to the "[/uv/download.js?mimetype=text/plain|download.js]" file so that it knows about the new version number. Then the developers run the [/help/uv|fossil uv add] command for each build product. Finally, the [/help/uv|fossil uv sync] command is run to push all the content up to servers. All [./selfhost.wiki|three self-hosting repositories] for Fossil are updated automatically. <h2>2.0 Details</h2> The current text of the "download.html" and "download.js" files can |
| ︙ | ︙ | |||
49 50 51 52 53 54 55 | Fossil knows to add its standard header and footer information to the document, making it look just like any other page. See "[./embeddeddoc.wiki|embedded documentation]" for further details on how this <div class='fossil-doc'> markup works. With each new release, the "releases" variable in the javascript on the [/uv/download.js?mimetype=text/plain|download.js] page is | | | | | | | | 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 | Fossil knows to add its standard header and footer information to the document, making it look just like any other page. See "[./embeddeddoc.wiki|embedded documentation]" for further details on how this <div class='fossil-doc'> markup works. With each new release, the "releases" variable in the javascript on the [/uv/download.js?mimetype=text/plain|download.js] page is edited (using "[/help/uv|fossil uv edit download.js]") to add details of the release. When the JavaScript in the "download.js" file runs, it requests a listing of all unversioned content using the /juvlist URL. ([/juvlist|sample /juvlist output]). The content of the download page is constructed by matching unversioned files against regular expressions in the "releases" variable. Build products need to be constructed on different machines. The precompiled binary for Linux is compiled on Linux, the precompiled binary for Windows is compiled on Windows11, and so forth. After a new release is tagged, the release manager goes around to each of the target platforms, checks out the release and compiles it, then runs [/help/uv|fossil uv add] for the build product followed by [/help/uv|fossil uv sync] to push the new build product to the [./selfhost.wiki|various servers]. This process is repeated for each build product. When older builds are retired from the download page, the [/uv/download.js?mimetype=text/plain|download.js] page is again edited to remove the corresponding entry from the "release" variable and the edit is synced using [/help/uv|fossil uv sync]. This causes the build products to disappear from the download page immediately. But those build products are still taking up space in the unversioned content table of the server repository. To purge the obsolete build products, one or more [/help/uv|fossil uv rm] commands are run, followed by another [/help/uv|fossil uv sync]. It is important to purge obsolete build products since they take up a lot of space. At [/repo-tabsize] you can see that the unversioned table takes up a substantial fraction of the repository. <h2>3.0 Security</h2> Only users with the [/setup_ulist_notes|"y" permission] are allowed |
| ︙ | ︙ |
Changes to www/alerts.md.
1 2 3 4 5 6 7 | # Email Alerts ## Overview Beginning with version 2.7, Fossil can send email messages to subscribers to alert them to changes in the repository: | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | # Email Alerts ## Overview Beginning with version 2.7, Fossil can send email messages to subscribers to alert them to changes in the repository: * New [checkins](/help/ci) * [Ticket](./tickets.wiki) changes * [Wiki](./wikitheory.wiki) page changes * New and edited [forum](./forum.wiki) posts * Users receiving [new permissions](./caps/index.md) (admins only) * Announcements Subscribers can elect to receive emails as soon as these events happen, |
| ︙ | ︙ | |||
388 389 390 391 392 393 394 | it is running inside of a restrictive [chroot jail][cj] which is unable to hand off messages to the local MTA directly. When you configure a Fossil server this way, it adds outgoing email messages to an SQLite database file. A separate daemon process can then extract those messages for further disposition. | | < | | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 | it is running inside of a restrictive [chroot jail][cj] which is unable to hand off messages to the local MTA directly. When you configure a Fossil server this way, it adds outgoing email messages to an SQLite database file. A separate daemon process can then extract those messages for further disposition. Fossil uses a short TCL script (seen at [](/file/tools/email-sender.tcl)) that continuously monitors this database for new messages and hands any that it finds off to a local MTA using the same [pipe to MTA protocol](#pipe) as above. In this way, outbound email alerts escape the chroot jail without requiring that we insert a separate MTA configuration inside that jail. We only need to arrange that the same SQLite DB file be visible both inside and outside the chroot jail, which we do by naming the database |
| ︙ | ︙ | |||
539 540 541 542 543 544 545 | This section collects the list of Fossil UI pages and CLI commands that control the email alert system, some of which have not been mentioned so far: Commands: | | | | | | | | | | | | 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 567 | This section collects the list of Fossil UI pages and CLI commands that control the email alert system, some of which have not been mentioned so far: Commands: * The [`alerts`](/help/alerts) command * The [`test-alert`](/help/test-alert) command * The [`test-add-alerts`](/help/test-add-alerts) command Web pages available to users and subscribers: * The [`/subscribe`](/help/www/subscribe) page * The [`/alerts`](/help/www/alerts) page * The [`/unsubscribe`](/help/www/unsubscribe) page * The [`/renew`](/help/www/renew) page * The [`/contact_admin`](/help/www/contact_admin) page Administrator-only web pages: * The [`/setup_notification`](/help/www/setup_notification) page * The [`/subscribers`](/help/www/subscribers) page <a id="design"></a> ## Design of Email Alerts This section describes the low-level design of the email alert system in Fossil. This expands on the high-level administration focused material |
| ︙ | ︙ |
Changes to www/antibot.wiki.
1 2 | <title>Defense Against Robots</title> | | | | > > > > > > > > > > > > > > > > > | 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 | <title>Defense Against Robots</title> A typical Fossil website can have billions and billions of pages, and many of those pages (for example diffs and annotations and tarballs) can be expensive to compute. If a robot walks a Fossil-generated website, it can present a crippling bandwidth and CPU load. A "robots.txt" file can help, but in practice, most robots these days ignore the robots.txt file, so it won't help much. A Fossil website is intended to be used interactively by humans, not walked by robots. This article describes the techniques used by Fossil to try to welcome human users while keeping out robots. <h2>Defenses Are Enabled By Default</h2> In the latest implementations of Fossil, most robot defenses are enabled by default. You can probably get by with standing up a public-facing Fossil instance in the default configuration. But you can also customize the defenses to serve your particular needs. <h2>Customizing Anti-Robot Defenses</h2> Admin users can configure robot defenses on the "Robot Defense Settings" page (/setup_robot). That page is accessible (to Admin users) from the default menu bar by click on the "Admin" menu choice, then selecting the "Robot-Defense" link from the list. <h2>The Hyperlink User Capability</h2> Every Fossil web session has a "user". For random passers-by on the internet (and for robots) that user is "nobody". The "anonymous" user is also available for humans who do not wish to identify themselves. The difference is that "anonymous" requires a login (using a password supplied via |
| ︙ | ︙ | |||
34 35 36 37 38 39 40 | A text message appears at the top of each page in this situation to invite humans to log in as anonymous in order to activate hyperlinks. But requiring a login, even an anonymous login, can be annoying. Fossil provides other techniques for blocking robots which are less cumbersome to humans. | | | 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | A text message appears at the top of each page in this situation to invite humans to log in as anonymous in order to activate hyperlinks. But requiring a login, even an anonymous login, can be annoying. Fossil provides other techniques for blocking robots which are less cumbersome to humans. <h2>Automatic Hyperlinks Based on UserAgent and Javascript</h2> Fossil has the ability to selectively enable hyperlinks for users that lack the <b>Hyperlink</b> capability based on their UserAgent string in the HTTP request header and on the browsers ability to run Javascript. The UserAgent string is a text identifier that is included in the header of most HTTP requests that identifies the specific maker and version of |
| ︙ | ︙ | |||
66 67 68 69 70 71 72 | of the requester and so a malicious robot can forge a UserAgent string that makes it look like a human. But most robots want to "play nicely" on the internet and are quite open about the fact that they are a robot. And so the UserAgent string provides a good first-guess about whether or not a request originates from a human or a robot. | | | > | | | | < | < < < < < < < < < < < < < < < | | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 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 151 152 153 154 155 156 157 158 159 160 161 162 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 |
of the requester and so a malicious robot can forge a UserAgent
string that makes it look like a human. But most robots want
to "play nicely" on the internet and are quite open
about the fact that they are a robot. And so the UserAgent string
provides a good first-guess about whether or not a request originates
from a human or a robot.
The [/help/auto-hyperlink|auto-hyperlink] setting, shown as
"<b>Enable hyperlinks based on User-Agent and/or Javascript</b>" on
the Robot Defense Settings page,
can be set to "UserAgent only" or "UserAgent and Javascript" or "off".
If the UserAgent string looks like a human and not a robot, then
Fossil will enable hyperlinks even if the <b>Hyperlink</b> capability
is omitted from the user permissions. This setting gives humans easy
access to the hyperlinks while preventing robots
from walking the billions of pages on a typical Fossil site.
If the setting is "UserAgent only" (2), then the hyperlinks are simply
enabled and that is all. But if the setting is "UserAgent and Javascript" (1),
then the hyperlinks are not enabled directly.
Instead, the HTML code that is generated contains anchor tags ("<a>")
with "href=" attributes that point to [/honeypot] rather than the correct
link. JavaScript code is added to the end of the page that goes back and
fills in the correct "href=" attributes of
the anchor tags with the true hyperlink targets, thus enabling the hyperlinks.
This extra step of using JavaScript to enable the hyperlink targets
is a security measure against robots that forge a human-looking
UserAgent string. Most robots do not bother to run JavaScript and
so to the robot the empty anchor tag will be useless. But all modern
web browsers implement JavaScript, so hyperlinks will show up
normally for human users.
If the [/help/auto-hyperlink|"auto-hyperlink"] setting is (2)
"<b>Enable hyperlinks using User-Agent and/or Javascript</b>",
then there are now two additional sub-settings that control when
hyperlinks are enabled.
The first new sub-setting is a delay (in milliseconds) before setting
the "href=" attributes on anchor tags. The default value for this
delay is 10 milliseconds. The idea here is that a robots will try to
interpret the links on the page immediately, and will not wait for delayed
scripts to be run, and thus will never enable the true links.
The second sub-setting waits to run the
JavaScript that sets the "href=" attributes on anchor tags until after
at least one "mousedown" or "mousemove" event has been detected on the
<body> element of the page. The thinking here is that robots will not be
simulating mouse motion and so no mouse events will ever occur and
hence the hyperlinks will never become enabled for robots.
See also [./loadmgmt.md|Managing Server Load] for a description
of how expensive pages can be disabled when the server is under heavy
load.
<h2>Do Not Allow Robot Access To Certain Pages</h2>
The [/help/robot-restrict|robot-restrict setting] is a comma-separated
list of GLOB patterns for pages for which robot access is prohibited.
The default value is:
<blockquote><pre>
timelineX,diff,annotate,fileage,file,finfo,reports
</pre></blockquote>
Each entry corresponds to the first path element on the URI for a
Fossil-generated page. If Fossil does not know for certain that the
HTTP request is coming from a human, then any attempt to access one of
these pages brings up a javascript-powered captcha. The user has to
click the accept button the captcha once, and that sets a cookie allowing
the user to continue surfing without interruption for 15 minutes or so
before being presented with another captcha.
Some path elements have special meanings:
* <b>timelineX →</b>
This means a subset of /timeline/ pages that are considered
"expensive". The exact definition of which timeline pages are
expensive and which are not is still the subject of active
experimentation and is likely to change by the time you read this
text. The idea is that anybody (including robots) can see a timeline
of the most recent changes, but timelines of long-ago change or that
contain lists of file changes or other harder-to-compute values are
prohibited.
* <b>zip →</b>
The special "zip" keyword also matches "/tarball/" and "/sqlar/".
* <b>zipX →</b>
This is like "zip" in that it restricts access to "/zip/", "/tarball"/
and "/sqlar/" but with exceptions:<ol type="a">
<li><p> If the [/help/robot-zip-leaf|robot-zip-leaf] setting is
true, then tarballs of leaf check-ins are allowed. This permits
URLs that attempt to download the latest check-in on trunk or
from a named branch, for example.
<li><p> If a check-in has a tag that matches the GLOB list in
[/help/robot-zip-tag|robot-zip-tag], then tarballs of that
check-in are allowed. This allow check-ins tagged with
"release" or "allow-robots" (for example) to be downloaded
without restriction.
</ol>
The "zipX" restriction is not in the default robot-restrict setting.
This is something you might want to add, depending on your needs.
* <b>diff →</b>
This matches /vdiff/ and /fdiff/ and /vpatch/ and any other page that
is primarily about showing the difference between two check-ins or two
file versioons.
* <b>annotate →</b>
This also matches /blame/ and /praise/.
Other special keywords may be added in the future.
The default [/help/robot-restrict|robot-restrict]
setting has been shown in practice to do a good job of keeping
robots from consuming all available CPU and bandwidth while will
still allowing humans access to the full power of the site without
having to be logged in.
One possible enhancement is to add "zipX" to the
[/help/robot-restrict|robot-restrict] setting,
and enable [help?cmd=robot-zip-leaf|robot-zip-leaf]
and configure [help?cmd=robot-zip-tag|robot-zip-tag].
Do this if you find that robots downloading lots of
obscure tarballs is causing load issues on your site.
<h2>Anti-robot Exception RegExps</h2>
The [/help/robot-exception|robot-exception setting] under the name
of <b>Exceptions to anti-robot restrictions</b> is a list of
[/re_rules|regular expressions], one per line, that match
URIs that will bypass the captcha and allow robots full access. The
intent of this setting is to allow automated build scripts
to download specific tarballs of project snapshots.
The recommended value for this setting allows robots to use URIs of the
following form:
<blockquote>
<b>https://</b><i>DOMAIN</i><b>/tarball/release/</b><i>HASH</i><b>/</b><i>NAME</i><b>.tar.gz</b>
</blockquote>
The <i>HASH</i> part of this URL can be any valid
[./checkin_names.wiki|check-in name]. The link works as long as that
check-in is tagged with the "release" symbolic tag. In this way,
robots are permitted to download tarballs (and ZIP archives) of official
releases, but not every intermediate check-in between releases. Humans
who are willing to click the captcha can still download whatever they
want, but robots are blocked by the captcha. This prevents aggressive
robots from downloading tarballs of every historical check-in of your
project, once per day, which many robots these days seem eager to do.
For example, on the Fossil project itself, this URL will work, even for
robots:
<blockquote>
https://fossil-scm.org/home/tarball/release/version-2.27/fossil-scm.tar.gz
</blockquote>
But the next URL will not work for robots because check-in 3bbd18a284c8bd6a
is not tagged as a "release":
<blockquote>
https://fossil-scm.org/home/tarball/release/3bbd18a284c8bd6a/fossil-scm.tar.gz
</blockquote>
The second URL will work for humans, just not robots.
<h2>The Ongoing Struggle</h2>
Fossil currently does a good job of providing easy access to humans
while keeping out troublesome robots. However, robots
continue to grow more sophisticated, requiring ever more advanced
defenses. This "arms race" is unlikely to ever end. The developers of
Fossil will continue to try improve the robot defenses of Fossil so
check back from time to time for the latest releases and updates.
Readers of this page who have suggestions on how to improve the robot
defenses in Fossil are invited to submit your ideas to the Fossil Users
forum:
[https://fossil-scm.org/forum].
|
Changes to www/backoffice.md.
| ︙ | ︙ | |||
32 33 34 35 36 37 38 | request. After each webpage is generated, Fossil checks to see if any backoffice work needs to be done. If there is work to do, and no other process is already assigned to do the work, then a new backoffice process is started to do the work. This happens for every webpage, regardless of how that webpage is launched, and regardless of the purpose of the webpage. This also happens on the | | | | | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | request. After each webpage is generated, Fossil checks to see if any backoffice work needs to be done. If there is work to do, and no other process is already assigned to do the work, then a new backoffice process is started to do the work. This happens for every webpage, regardless of how that webpage is launched, and regardless of the purpose of the webpage. This also happens on the server for "[fossil sync](/help/sync)" and [fossil clone](/help/clone)" commands which are implemented as web requests - albeit requests that the human user never sees. Web requests can arrive at the Fossil server via direct TCP/IP (for example when Fossil is started using commands like "[fossil server](/help/server)") or via [CGI](./server/any/cgi.md) or [SCGI](./server/any/scgi.md) or via SSH. A backoffice process might be started regardless of the origin of the request. The backoffice is not a daemon. Each backoffice process runs for a short while and then exits. This helps keep Fossil easy to manage, since there |
| ︙ | ︙ | |||
98 99 100 101 102 103 104 | some system - OpenBSD in particular. We still do not understand why this is. (If you have insights, please share them on the [Fossil Forum](https://fossil-scm.org/forum) so that we can perhaps fix the problem.) For now, the backoffice must be run manually on OpenBSD systems. To set up fully-manual backoffice, first disable the automatic backoffice | | | | 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 |
some system - OpenBSD in particular. We still do not understand why
this is. (If you have insights, please share them on the
[Fossil Forum](https://fossil-scm.org/forum) so that we can perhaps
fix the problem.) For now, the backoffice must be run manually
on OpenBSD systems.
To set up fully-manual backoffice, first disable the automatic backoffice
using the "[backoffice-disable](/help/backoffice-disable)" setting.
fossil setting backoffice-disable on
Then arrange to invoke the backoffice separately using a command
like this:
fossil backoffice --poll 30 _REPOSITORY-LIST_
Multiple repositories can be named. This one command will handle
launching the backoffice for all of them. There are additional useful
command-line options. See the "[fossil backoffice](/help/backoffice)"
documentation for details.
The backoffice processes run manually using the "fossil backoffice"
command do not normally use a lease. That means that if you run the
"fossil backoffice" command with --poll and you forget to disable
automatic backoffice by setting the "backoffice-disable" flag, then
you might have one backoffice running due to a command and another due
|
| ︙ | ︙ |
Changes to www/backup.md.
| ︙ | ︙ | |||
66 67 68 69 70 71 72 | #### <a id="other-cfg"></a> Others A repo’s URL aliases, [interwiki configuration](./interwiki.md), and [ticket customizations](./custom_tcket.wiki) also do not normally sync. | | | 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | #### <a id="other-cfg"></a> Others A repo’s URL aliases, [interwiki configuration](./interwiki.md), and [ticket customizations](./custom_tcket.wiki) also do not normally sync. [cfg]: /help/configuration ## <a id="private"></a> Private Branches The very nature of Fossil’s [private branch feature][pbr] ensures that remote clones don’t get a copy of those branches. Normally this is |
| ︙ | ︙ | |||
287 288 289 290 291 292 293 | pipe the decrypted SQL dump into `fossil sql`, because on startup, Fossil normally goes looking for tables created by `fossil init`, and it won’t find them in a newly-created repo DB. We get around this by passing the `--no-repository` flag, which suppresses this behavior. Doing it this way saves you from needing to go and build a matching version of `sqlite3` just to restore the backup. | | | 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | pipe the decrypted SQL dump into `fossil sql`, because on startup, Fossil normally goes looking for tables created by `fossil init`, and it won’t find them in a newly-created repo DB. We get around this by passing the `--no-repository` flag, which suppresses this behavior. Doing it this way saves you from needing to go and build a matching version of `sqlite3` just to restore the backup. [bu]: /help/backup [grcp]: https://www.grc.com/passwords.htm [hb]: https://brew.sh [hbul]: https://docs.brew.sh/FAQ#what-does-keg-only-mean [lz4]: https://lz4.github.io/lz4/ [pbr]: ./private.wiki [rint]: https://www.random.org/integers/?num=1&min=100000&max=1000000&col=5&base=10&format=html&rnd=new [Setup]: ./caps/admin-v-setup.md#apsu [shun]: ./shunning.wiki [tkt]: ./tickets.wiki [uv]: ./unvers.wiki |
Changes to www/blame.wiki.
1 2 3 4 | <title>The Annotate Algorithm</title> <h2>1.0 Introduction</h2> | | | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <title>The Annotate Algorithm</title> <h2>1.0 Introduction</h2> The [/help/annotate|fossil annotate], [/help/blame|fossil blame], and [/help/praise|fossil praise] commands, and the [/help/www/annotate|/annotate], [/help/www/blame|/blame], and [/help/www/praise|/praise] web pages are all used to show the most recent check-in that modified each line of a particular file. This article overviews the algorithm used to compute the annotation for a file in Fossil. <h2>2.0 Algorithm</h2> <ol type='1'> |
| ︙ | ︙ | |||
43 44 45 46 47 48 49 | <h2>3.0 Discussion and Notes</h2> The time-consuming part of this algorithm is step 6b - computing the diff from all historical versions of the file to the version of the file under analysis. For a large file that has many historical changes, this can take several seconds. For this reason, the default | | | 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | <h2>3.0 Discussion and Notes</h2> The time-consuming part of this algorithm is step 6b - computing the diff from all historical versions of the file to the version of the file under analysis. For a large file that has many historical changes, this can take several seconds. For this reason, the default [/help/www/annotate|/annotate] webpage only shows those lines that were changed by the 20 most recent modifications to the file. This allows the loop on step 6 to terminate after only 19 diffs instead of the hundreds or thousands of diffs that might be required for a frequently modified file. As currently implemented (as of 2015-12-12) the annotate algorithm does not follow files across name changes. File name change information is available in the database, and so the algorithm could be enhanced to follow files across name changes by modifications to step 3. Step 2 is interesting in that it is [/artifact/6cb824a0417?ln=196-201 | implemented] using a [https://www.sqlite.org/lang_with.html#recursivecte|recursive common table expression]. |
Changes to www/blockchain.md.
| ︙ | ︙ | |||
206 207 208 209 210 211 212 | This much is certain: Fossil is definitely not a cryptocurrency. Whether this makes it “not a blockchain” is a subjective matter. [arh]: ./hooks.md [bse]: https://www.researchgate.net/publication/311572122_What_is_Blockchain_a_Gentle_Introduction [caps]: ./caps/ | | | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 | This much is certain: Fossil is definitely not a cryptocurrency. Whether this makes it “not a blockchain” is a subjective matter. [arh]: ./hooks.md [bse]: https://www.researchgate.net/publication/311572122_What_is_Blockchain_a_Gentle_Introduction [caps]: ./caps/ [cs]: /help/clearsign [dboc]: https://en.wikipedia.org/wiki/Debasement [dsig]: https://en.wikipedia.org/wiki/Digital_signature [fb]: ./branching.wiki [GPG]: https://gnupg.org/ [PGP]: https://www.openpgp.org/ [PII]: https://en.wikipedia.org/wiki/Personal_data [PKI]: https://en.wikipedia.org/wiki/Public_key_infrastructure |
| ︙ | ︙ | |||
276 277 278 279 280 281 282 | [ctap]: ./cap-theorem.md#ap [ctca]: ./cap-theorem.md#ca [ctcp]: ./cap-theorem.md#cp [cap]: https://en.wikipedia.org/wiki/CAP_theorem [dlt]: https://en.wikipedia.org/wiki/Distributed_ledger [DVCS]: https://en.wikipedia.org/wiki/Distributed_version_control [fc]: https://en.wikipedia.org/wiki/Fiat_money | | | 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | [ctap]: ./cap-theorem.md#ap [ctca]: ./cap-theorem.md#ca [ctcp]: ./cap-theorem.md#cp [cap]: https://en.wikipedia.org/wiki/CAP_theorem [dlt]: https://en.wikipedia.org/wiki/Distributed_ledger [DVCS]: https://en.wikipedia.org/wiki/Distributed_version_control [fc]: https://en.wikipedia.org/wiki/Fiat_money [purge]: /help/purge [shun]: ./shunning.wiki <a id="dpc"></a> ## Distributed Partial Consensus If we can’t get DLT, can we at least get some kind of distributed |
| ︙ | ︙ | |||
333 334 335 336 337 338 339 | would mean that querying whether a given commit is part of the “blockchain” would be as simple as going down the list of servers and sending each an HTTP GET `/info` query for the artifact ID, concluding that the commit is legitimate once you get enough HTTP 200 status codes back. All of this is hypothetical, because Fossil doesn’t do this today. [AGI]: https://en.wikipedia.org/wiki/Artificial_general_intelligence | | | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 | would mean that querying whether a given commit is part of the “blockchain” would be as simple as going down the list of servers and sending each an HTTP GET `/info` query for the artifact ID, concluding that the commit is legitimate once you get enough HTTP 200 status codes back. All of this is hypothetical, because Fossil doesn’t do this today. [AGI]: https://en.wikipedia.org/wiki/Artificial_general_intelligence [rcks]: /help/repo-cksum <a id="anon"></a> ## Anonymity Many blockchain based technologies go to extraordinary lengths to |
| ︙ | ︙ | |||
445 446 447 448 449 450 451 | on their scores under these metrics. We may well prefer to use the fork of a software program that took *less* effort, being smaller, more self-contained, and with a smaller attack surface. [alert]: ./alerts.md [capi]: ./caps/ref.html#i | | | | | 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 | on their scores under these metrics. We may well prefer to use the fork of a software program that took *less* effort, being smaller, more self-contained, and with a smaller attack surface. [alert]: ./alerts.md [capi]: ./caps/ref.html#i [mrep]: /help/remote [scost]: https://en.wikipedia.org/wiki/Software_development_effort_estimation [scrub]: /help/scrub [sreg]: /help/self-register # Conclusion This author believes it is technologically indefensible to call Fossil a “blockchain” in any sense likely to be understood by a majority of those you’re communicating with. Using a term in a nonstandard way just because you can |
| ︙ | ︙ |
Changes to www/branching.wiki.
| ︙ | ︙ | |||
73 74 75 76 77 78 79 | works. This is also how Fossil works in autosync mode. But perhaps Bob is off-network when he does his commit, so he has no way of knowing that Alice has already committed her changes. Or, it could be that Bob has turned off "autosync" mode in Fossil. Or, maybe Bob just doesn't want to merge in Alice's changes before he has saved his own, so he forces the commit to occur using the "--allow-fork" option to | | | 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | works. This is also how Fossil works in autosync mode. But perhaps Bob is off-network when he does his commit, so he has no way of knowing that Alice has already committed her changes. Or, it could be that Bob has turned off "autosync" mode in Fossil. Or, maybe Bob just doesn't want to merge in Alice's changes before he has saved his own, so he forces the commit to occur using the "--allow-fork" option to the <b>[/help/commit | fossil commit]</b> command. For any of these reasons, two commits against check-in 2 have occurred, so the DAG now has two leaves. In such a condition, a person working with this repository has a dilemma: which version of the project is the "latest" in the sense of having the most features and the most bug fixes? When there is more than one leaf in the graph, you don't really know, which is why we |
| ︙ | ︙ | |||
109 110 111 112 113 114 115 | with "--allow-fork". (Prime example: trunk.) The inverse case — intentional forks on short-lived single-developer branches — is far easier to justify, since presumably the lone developer is never confused about why there are two or more leaves on that branch. Further justifications for intentional forking are [#forking | given below]. Let us return to Figure 2. To resolve such situations before they can | | | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | with "--allow-fork". (Prime example: trunk.) The inverse case — intentional forks on short-lived single-developer branches — is far easier to justify, since presumably the lone developer is never confused about why there are two or more leaves on that branch. Further justifications for intentional forking are [#forking | given below]. Let us return to Figure 2. To resolve such situations before they can become a real problem, Alice can use the <b>[/help/merge | fossil merge]</b> command to merge Bob's changes into her local copy of check-in 3. Without arguments, that command merges all leaves on the current branch. Alice can then verify that the merge is sensible and if so, commit the results as check-in 5. This results in a DAG as shown in Figure 3. <verbatim type="pikchr center toggle"> |
| ︙ | ︙ | |||
347 348 349 350 351 352 353 |
<li><p id="automation">You've automated Fossil, so you use
<b>fossil commit --allow-fork</b> commands to prevent Fossil from
refusing the check-in simply because it would create a fork.
<br><br>
If you are writing such a tool — e.g. a shell script to make
multiple manipulations on a Fossil repo — it's better to make it
smart enough to detect this condition and cope with it, such as
| | | 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 |
<li><p id="automation">You've automated Fossil, so you use
<b>fossil commit --allow-fork</b> commands to prevent Fossil from
refusing the check-in simply because it would create a fork.
<br><br>
If you are writing such a tool — e.g. a shell script to make
multiple manipulations on a Fossil repo — it's better to make it
smart enough to detect this condition and cope with it, such as
by making a call to <b>[/help/update | fossil update]</b>
and checking for a merge conflict. That said, if the alternative is
losing information, you may feel justified in creating forks that an
interactive user must later manually clean up with <b>fossil merge</b>
commands.</p></li>
</ol>
That leaves only one case where we can recommend use of "--allow-fork"
|
| ︙ | ︙ | |||
598 599 600 601 602 603 604 |
on a different branch at the time Alan made check-in 3, so Fossil
sees that as the tip at the time she switches her working directory
to that branch with a <b>fossil update $BRANCH</b> command. (There is an
implicit autosync in that command, if the option was enabled at the
time of the update.)</p></li>
<li><p>The same thing, only in a fresh checkout directory with a
| | | 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 |
on a different branch at the time Alan made check-in 3, so Fossil
sees that as the tip at the time she switches her working directory
to that branch with a <b>fossil update $BRANCH</b> command. (There is an
implicit autosync in that command, if the option was enabled at the
time of the update.)</p></li>
<li><p>The same thing, only in a fresh checkout directory with a
<b>[/help/open | fossil open $REPO $BRANCH]</b> command.</p></li>
<li><p>Alan makes his check-in 3 while Betty has check-in 1 or 2 as
the tip in her local clone, but because she's working with an
autosync'd connection to the same upstream repository as Alan, on
attempting what will become check-in 4, she gets the "would fork"
message from <b>fossil commit</b>, so she dutifully updates her clone
and tries again, moving her work to be a child of the new tip,
|
| ︙ | ︙ | |||
749 750 751 752 753 754 755 | This fact is helpful because it means you can reuse branch names, which is especially useful with utility branches. There are several of these in the SQLite and Fossil repositories: "broken-build," "declined," "mistake," etc. As you might guess from these names, such branch names are used in renaming the tip of one branch to shunt it off away from the mainline of that branch due to some human error. (See | | | 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 | This fact is helpful because it means you can reuse branch names, which is especially useful with utility branches. There are several of these in the SQLite and Fossil repositories: "broken-build," "declined," "mistake," etc. As you might guess from these names, such branch names are used in renaming the tip of one branch to shunt it off away from the mainline of that branch due to some human error. (See <b>[/help/amend | fossil amend]</b> and the Fossil UI check-in amendment features.) This is a workaround for Fossil's [./shunning.wiki|normal inability to forget history]: we usually don't want to actually <i>remove</i> history, but would like to sometimes set some of it aside under a new label. Because some VCSes can't cope with duplicate branch names, Fossil collapses such names down on export using the same time stamp based arbitration logic, so that only the branch with the newest check-in gets the branch name in the export. All of the above is true of tags in general, not just branches. |
Changes to www/build.wiki.
| ︙ | ︙ | |||
333 334 335 336 337 338 339 | This feature is primarily intended for fossil's developers and may change at any time. It is only known to work on Linux systems and has been seen to work on x86/64 and ARM. Fossil has builtin support for processing specific features using <tt>libfuzzer</tt>. The features which can be tested this way are | | | 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 |
This feature is primarily intended for fossil's developers and may
change at any time. It is only known to work on Linux systems and has
been seen to work on x86/64 and ARM.
Fossil has builtin support for processing specific features using
<tt>libfuzzer</tt>. The features which can be tested this way are
found in the help text for the [/help/test-fuzz|test-fuzz
command].
Fuzzing requires:
* The clang C compiler.
* libfuzzer. On Ubuntu-derived systems, it can be installed with
<tt>apt install libfuzzer-XYZ</tt>, where XYZ is a version number
|
| ︙ | ︙ | |||
508 509 510 511 512 513 514 | changed the format of list-type arguments at some point. The required minimum version is unknown, but any SDK version from May 2022 or later "should" (as of this writing) suffice. Any older version may or may not work.</div> After that succeeds, we need to run the normal build so that those generated files can be compiled in to the fossil binary, accessible | | | 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 | changed the format of list-type arguments at some point. The required minimum version is unknown, but any SDK version from May 2022 or later "should" (as of this writing) suffice. Any older version may or may not work.</div> After that succeeds, we need to run the normal build so that those generated files can be compiled in to the fossil binary, accessible via the [/help/www/builtin|/builtin page]: <pre><code>$ make</code></pre> Before checking in those newly-built files, they need to be tested by running the [/pikchrshow] page. If that page loads, the compilation process fundamentally worked (a load failure will be made obvious to the viewer). If it fails to load then the browser's dev tools console |
| ︙ | ︙ |
Changes to www/caps/admin-v-setup.md.
| ︙ | ︙ | |||
259 260 261 262 263 264 265 | In addition, Setup users can use every feature of the Fossil UI. If Fossil can do a thing, a Setup user on that repo can make Fossil do it. Setup users can do many things that Admin users cannot. They may not only use all of the Admin UI features, they may also: * See record IDs (RIDs) on screens that show them | | | | | 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
In addition, Setup users can use every feature of the Fossil UI. If Fossil can do a
thing, a Setup user on that repo can make Fossil do it.
Setup users can do many things that Admin users cannot. They may not
only use all of the Admin UI features, they may also:
* See record IDs (RIDs) on screens that show them
* See the MIME type of attachments on [`/ainfo` pages](/help/www/ainfo)
* See a remote repo’s HTTP [cache status](/help/www/cachestat)
and [pull cache entries](/help/www/cacheget)
* Edit a Setup user’s account!
The “Admin” feature of Fossil UI is so-named because Admin users can use
about half of its functions, but only Setup can use these pages:
* **Access**: This page falls under the [Security](#security)
category above, but like Configuration, it's generally something set
|
| ︙ | ︙ | |||
393 394 395 396 397 398 399 | Fossil makes these users grant themselves (or others) these capabilities deliberately, hopefully after careful consideration. ### <a id="y"></a>Write Unversioned Fossil currently doesn’t distinguish the sub-operations of | | | 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 | Fossil makes these users grant themselves (or others) these capabilities deliberately, hopefully after careful consideration. ### <a id="y"></a>Write Unversioned Fossil currently doesn’t distinguish the sub-operations of [`fossil uv`](/help/uv); they’re all covered by [**WrUnver**][capy] (“y”) capability. Since some of these operations are unconditionally destructive due to the nature of unversioned content, and since this goes against Fossil’s philosophy of immutable history, nobody gets cap “y” on a Fossil repo by default, not even the Setup or Admin users. A Setup or Admin user must grant cap “y” to someone — not necessarily themselves! — before modifications to remote unversioned content are possible. |
| ︙ | ︙ | |||
444 445 446 447 448 449 450 | [capa]: ./ref.html#a [caps]: ./ref.html#s [capx]: ./ref.html#x [capy]: ./ref.html#y | | | | 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 | [capa]: ./ref.html#a [caps]: ./ref.html#s [capx]: ./ref.html#x [capy]: ./ref.html#y [fcp]: https://fossil-scm.org/home/help/configuration [fdp]: ../fossil-v-git.wiki#devorg [forum]: https://fossil-scm.org/forum/ [fui]: /help/ui [lg]: ./login-groups.md [rs]: https://fossil-scm.org/home/doc/trunk/www/settings.wiki [sia]: https://fossil-scm.org/home/artifact?ln=1259-1260&name=0fda31b6683c206a [snoy]: https://fossil-scm.org/forum/forumpost/00e1c4ecff [th1]: ../th1.md [tt]: https://en.wikipedia.org/wiki/Tiger_team#Security [webo]: ./#webonly |
Changes to www/caps/login-groups.md.
| ︙ | ︙ | |||
115 116 117 118 119 120 121 | That creates login group G joining repo A to B, then joins C to B. Although we didn’t explicitly tie C to A, a successful login on C gets you into both A and B, within the restrictions set out above. Changes are transitive in the same way, provided you check that “apply to all” box on the user edit screen. | | | 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | That creates login group G joining repo A to B, then joins C to B. Although we didn’t explicitly tie C to A, a successful login on C gets you into both A and B, within the restrictions set out above. Changes are transitive in the same way, provided you check that “apply to all” box on the user edit screen. [lg]: /help/login-group [sh]: ../server/any/http-over-ssh.md [wo]: ./index.md#webonly ----- *[Back to Administering User Capabilities](./)* |
Changes to www/caps/ref.html.
| ︙ | ︙ | |||
313 314 315 316 317 318 319 |
</tr>
<tr id="z">
<th>z</th>
<th>Zip</th>
<td>
Pull archives of particular repository versions via <a
| | | | | 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
</tr>
<tr id="z">
<th>z</th>
<th>Zip</th>
<td>
Pull archives of particular repository versions via <a
href="/help/www/zip"><tt>/zip</tt></a>, <a
href="/help/www/tarball"><tt>/tarball</tt></a>, and <a
href="/help/www/sqlar"><tt>/sqlar</tt></a> URLs. This is an
expensive capability to grant, because creating such archives can
put a large load on <a href="../server/">a Fossil server</a> which
you may then need to <a href="../loadmgmt.md">manage</a>.
Mnemonic: <b>z</b>ip file download.
</td>
</tr>
|
| ︙ | ︙ |
Changes to www/cgi.wiki.
| ︙ | ︙ | |||
70 71 72 73 74 75 76 | This is a Boolean property. If it is present, and if the [#directory:|<b>directory:</b>] option is used, and if the PATH_INFO string is empty, then Fossil will show a list of available Fossil repositories. The "skin" of the reply is determined by the first repository in the list that has a non-zero | | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | This is a Boolean property. If it is present, and if the [#directory:|<b>directory:</b>] option is used, and if the PATH_INFO string is empty, then Fossil will show a list of available Fossil repositories. The "skin" of the reply is determined by the first repository in the list that has a non-zero [/help/repolist-skin|repolist-skin] setting. If no repository has such a non-zero repolist-skin setting, then the repository list is generic HTML without any decoration, with the page title taken from the <tt>FOSSIL_REPOLIST_TITLE</tt> environment variable. The variable can be defined in the CGI control file using the [#setenv|<tt>setenv:</tt>] statement. |
| ︙ | ︙ | |||
191 192 193 194 195 196 197 | ticket that matches the value of "name", then redirect to URL. There can be multiple "redirect:" lines that are processed in order. If the repo name is "*", then an unconditional redirect to URL is taken. <h2 id="jsmode">jsmode: <i>VALUE</i></h2> | | | 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | ticket that matches the value of "name", then redirect to URL. There can be multiple "redirect:" lines that are processed in order. If the repo name is "*", then an unconditional redirect to URL is taken. <h2 id="jsmode">jsmode: <i>VALUE</i></h2> Specifies the delivery mode for JavaScript files. See "[/help/http | http --jsmode]" for the allowed values and their meanings. <h2 id="mainmenu">mainmenu: <i>FILE</i></h2> This parameter causes the contents of the given file to override the site's <tt>mainmenu</tt> configuration setting, in much the same way that the <tt>skin</tt> setting overrides the skin. This can be used to apply a common main menu to a number of sites, and centrally maintain it, without having to copy its contents into each site. Note, however, that the contents of this setting are not stored in the repository and will not be cloned along with the repository. |
Changes to www/changes.wiki.
1 2 | <title>Change Log</title> | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > | < < | | | | | | > > | | | | | | | | | | | | | 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 151 152 153 154 155 156 157 158 |
<title>Change Log</title>
<h2 id='v2_28'>Changes for version 2.28 (pending)</h2><ol>
<li> Improvements to [./antibot.wiki|anti-robot defenses]:<ol type="a">
<li> The default configuration now allows robots to download any tarball
or similar, to better support of automated build systems.
<li> New special tag "zipX" for the [/help/robot-restrict|robot-restrict]
setting blocks robot access to tarballs, but with exceptions to support
automated build systems.
<li> Tags of the form "ext/PATH" in the robot-restrict setting block access
by robots to specific [./serverext.wiki|CGI extension] at PATH.
<li> Enhancements to the default value for the
[/help/robot-restrict|robot-restrict setting].
</ol>
<li> A drop-down menu of recent branches is now possible for the submenu, and
is used in the [/dir?ci=trunk|code browser].
<li> Easier access to generated tarballs and ZIPs:<ol type="a">
<li> When in the [/dir?ci=trunk|code browser] at the top-level,
a new "Download" submenu option is available to take the
user to a page where he can download a tarball or ZIP archive.
<li> New [/help/www/download|/download page] is available. When
configured using the new
[/help/suggested-downloads|suggested-downloads setting], a
link to [/download] named "Tarballs and ZIPs" appears in the
[/sitemap] and thus on the hamburger menu.
<li> The filenames for tarballs and ZIPs are now standardized to
include a timestamp and a hash prefix.
</ol>
<li> Timeline enhancements:<ol type="a">
<li> A new "Simple" view is available. This is compromise between "Verbose"
and "Compact" that shows only the check-in hash rather than the full
detail section. There is an ellipsis that one can click on to see the
full detail text.
<li> The artifact hash in the detail section of each timeline entry is now
emphasized (controlled by CSS) to make it easier to locate amid all
the other text and links.
<li> When clicking on the ellipsis in "Compact" or "Simple" views, the
ellipsis is replaced by a left arrow ("←") which can be clicked to
hide the extra detail again.
<li> New setting [/help/timeline-mark-leaves|timeline-mark-leaves] controls
whether or not leaf check-ins are marked in the timeline.
<li> "No-graph" timelines (using the "ng" query parameter) now show
branch colors and bare check-in circles on the left. The check-in
circles appear, but no lines connecting them.
([/timeline?ng|example]).
</ol>
<li> The [/help/timeline|timeline command] is enhanced with the new
"<tt>-u|--for-user</tt>" option.
<li> The [/help/open|open command]'s new "<tt>--reopen REPOFILE</tt>" flag
can be used to fix a checkout after moving its repository file.
<li> Update internal Unicode character tables, used in regular expression
handling, from version 13 to 17.
</ol>
<h2 id='v2_27'>Changes for version 2.27 (2025-09-30)</h2><ol>
<li> Close a potential Denial-of-Service attack against any public-facing Fossil
server involving exponential behavior in Fossil's regexp implementation.
<li> Fix a SQL injection on the [/help/www/file|/file page]. Thanks to
additional defenses built into Fossil, as well as good luck, this injection
is not exploitable for either data exfiltration or privilege escalation. The
only possible result of invoking the injection is a harmless SQL syntax error.
<li> Strengthen robot defenses to help prevent public-facing servers from being
overwhelmed by the latest generation of AI spiders.
<ol type="a">
<li> New javascript captcha used to restrict access by user "nobody" to pages
listed in the [/help/robot-restrict|robot-restrict setting].
<li> The [/help/robot-exception|robot-exception setting] is available to allow
access to pages that match a regular expression. Use this, for example, to
allow curl scripts and similar to download release tarballs.
<li> Require at least an anonymous login to access the /blame page and similar.
</ol>
<li> [/help/www/timeline|Timeline] enhancements:
<ol type="a">
<li> The chng= query parameter on the [/help/www/timeline|timeline page]
so that it works with other query parameters like p=, d=, from=, and to=.
<li> Always include nodes identify by sel1= and sel2= in the /timeline display.
<li> Improved title when p= and d= are different.
</ol>
<li> Enable the --editor option on the [/help/amend|fossil amend] command.
<li> When walking the filesystem looking for Fossil repositories, avoid descending
into directories named "/proc".
<li> Reduce memory requirements for sending authenticated sync protocol
messages.
<li> Show numstat-style change statistics in the /info and /ckout pages.
<li> Add the [/help/stash | stash rename] subcommand.
<li> Add the "-h" option to the "[/help/ls|ls]" command to display
file hashes for a specific check-in when in verbose mode.
</ol>
<h2 id='v2_26'>Changes for version 2.26 (2025-04-30)</h2><ol>
<li>Enhancements to [/help/diff|fossil diff] and similar:
<ol type="a">
<li> The argument to the --from option can be a directory name, causing
Fossil to use files under that directory as the baseline for the diff.
<li> For "gdiff", if no [/help/gdiff-command|gdiff-command setting]
is defined, Fossil tries to do a --tk diff if "tclsh" and "wish"
are available, or a --by diff if not.
<li> The "Reload" button is added to --tk diffs, to bring the displayed
diff up to date with the latest changes on disk.
<li> Add the "Hide diffs/Show diffs" toggle to web-UI diff pages that show
diffs of multiple files.
</ol>
<li>Added the [/help/www/ckout|/ckout web page] to provide information
about pending changes in a working check-out
<li>Enhancements to the [/help/ui|fossil ui] command:
<ol type="a">
<li> Defaults to using the new [/help/www/ckout|/ckout page] as its
start page. Or, if the new "--from PATH" option is present, the
default start page becomes "/ckout?exbase=PATH".
<li> The new "--extpage FILENAME" option opens the named file as if it
where in a [./serverext.wiki|CGI extension]. Example usage: the
person editing this change log has
"fossil ui --extpage www/changes.wiki" running and hence can
press "Reload" on the web browser to view edits.
<li> Accept both IPv4 and IPv6 connections on all platforms, including
Windows and OpenBSD. This also applies to the "fossil server"
command.
</ol>
<li>Enhancements to [/help/merge|fossil merge]:
<ol type="a">
<li> Added the [/help/merge-info|fossil merge-info] command and
especially the --tk option to that command, to provide analysis
of the most recent merge or update operation.
<li> When a merge conflict occurs, a new section is added to the conflict
text that shows Fossil's suggested resolution to the conflict.
</ol>
<li>Enhancements to [/help/commit|fossil commit]:
<ol type="a">
<li> If Fossil sees potential formatting mistakes (ex: bad hyperlinks)
in the check-in comment, it will alert the developer and give
him or her the opportunity to edit the comment before continuing.
This feature is controllable by the
[/help/verify-comments|verify-comments setting].
<li> The new "--if-changes" option causes the commit to become
a quiet no-op if there are no pending changes.
<li> Added the ability to sign check-ins with SSH keys. Artifacts signed
this way are ignored by all previous fossil versions, as if they
were plain-text file content instead of Fossil artifacts.
<li> Issue a warning if a user tries to commit on a check-in where the
branch has been changed.
<li> The interactive checkin comment prompt shows the formatting rules
set for that repository.
<li> Add the "--editor" option.
</ol>
<li>Deprecate the --comfmtflags and --comment-format global options and
no longer list them in the built-in help, but keep them working for
backwards compatibility.
Alternative TTY comment formatting can still be specified using the
[/help/comment-format|comment-format setting], if desired. The
default comment format is now called "canonical", not "legacy".
<li>Enhancements to the [/help/www/timeline|/timeline page]:
<ol type="a">
<li> Added the "ml=" ("Merge-in List") query parameter that works
like "rl=" ("Related List") but adds "mionly" style related
check-ins instead of the full "rel" style.
<li> For "tl=", "rl=", and "ml=", the order of the branches in the
graph now tries to match the order of the branches named in
the list.
|
| ︙ | ︙ | |||
123 124 125 126 127 128 129 |
end-points.
<li> The p= and d= parameters can now reference different check-ins,
in which case the timeline shows those check-ins that are both
ancestors of p= and descendants of d=.
<li> The saturation and intensity of user-specified checkin and branch
background colors are automatically adjusted to keep the colors
compatible with the current skin, unless the
| | | | | | | | | | | | | | | | | | | | | | | | | 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 |
end-points.
<li> The p= and d= parameters can now reference different check-ins,
in which case the timeline shows those check-ins that are both
ancestors of p= and descendants of d=.
<li> The saturation and intensity of user-specified checkin and branch
background colors are automatically adjusted to keep the colors
compatible with the current skin, unless the
[/help/raw-bgcolor|raw-bgcolor setting] is turned on.
</ol>
<li>The [/help/www/docfile|/docfile webpage] was added. It works like
/doc but keeps the title of markdown documents with the document rather
that moving it up to the page title.
<li>Added the [/help/www/clusterlist|/clusterlist page] for analysis
and debugging
<li>Added the "artifact_to_json(NAME)" SQL function that returns a JSON
decoding of the artifact described by NAME.
<li>Improvements to the [/help/patch|fossil patch] command:
<ol type="a">
<li> Fix a bug in "fossil patch create" that causes
[/help/revert|fossil revert] operations that happened
on individualfiles after a [/help/merge|fossil merge]
to be omitted from the patch.
<li> Added the [/help/patch|patch alias] command for managing
aliases for remote checkout names.
</ol>
<li>Enhancements to on-line help and the [/help/help|fossil help] command:
<ol type="a">
<li> Add the ability to search the help text, either in the UI
(on the [/help/www/search|/search page]) or from the command-line
(using the "[/help/search|fossil search -h PATTERN]" command.)
<li> Accepts an optional SUBCOMMAND argument following the
COMMAND argument and only shows results for the specified
subcommand, not the entire command.
<li> The -u (--usage) option shows only the command-line syntax
<li> The -o (--options) option shows only the command-line options
</ol>
<li>Enhancements to the [./tickets.wiki|ticket system]:
<ol type="a">
<li> Added the ability to attach wiki pages to a ticket for extended
descriptions.
<li> Added submenu to the 'View Ticket' page, to use it as
template for a new ticket.
<li> Added button 'Submit and New' to create multiple tickets
in a row.
<li> Link the version field in ticket view to a matching checkin or tag.
<li> Show creation time in report and ticket view.
<li> Show previous comments in edit ticket as reference.
</ol>
<li>Added the "hash" query parameter to the
[/help/www/whatis|/whatis webpage].
<li>Add a "user permissions changes" [/doc/trunk/www/alerts.md|subscription]
which alerts subscribers when an admin creates a new user or
when a user's permissions change.
<li>If the FOSSIL_REPOLIST_SHOW environment variable exists and contains
the substring "description", then the project description for each repository
is shown on the repository list page. The login-group for each project is
now only shown if the FOSSIL_REPOLIST_SHOW environment variable exists and
contains the substring "login-group". ([./cgi.wiki#repolist|More information])
<li>The [/doc/trunk/www/th1.md|TH1 script language] is enhanced for improved
security:
<ol type="a">
<li> TH1 now makes a distinction between
[/doc/trunk/www/th1.md#taint|tainted and untainted string values].
This makes it more difficult to write custom TH1 scripts that
contain XSS or SQL-injection bugs. The
[/help/vuln-report|vuln-report] setting was added to control
what Fossil does when it encounters a potential TH1
security problem.
<li> The "--th" option was removed from the [/help/pikchr|fossil pikchr]
command.
<li> The "enable_htmlify" TH1 command was removed.
</ol>
<li>Make [/help/www/chat|/chat] better-behaved during server outages, reducing
the frequency of reconnection attempts over time and providing feedback
to the user when the connection is down.
<li>The [/help/www/sqlar|/sqlar] page does not work for users who are not logged
in, nor are links to that page displayed to users who are not logged in. Being
logged in as "anonymous" is sufficient to overcome this restriction, assuming
that "anonymous" can download tarballs and ZIP archives.
<li>Many other minor fixes and additions.
</ol>
<h2 id='v2_25'>Changes for version 2.25 (2024-11-06)</h2>
* The "[/help/ui|fossil ui /]" command now works even for repositories
that have non-ASCII filenames
* Add the [/help/tree|fossil tree] command.
* On case-insensitive filesystems, store files using the filesystem's
preferred case rather than the case typed in by the user.
* Change the name "fossil cherry-pick" command to "fossil cherrypick",
which is more familiar to Git users. Retain the legacy name for
compatibility.
* Add new query parameters to the [/help/www/timeline|/timeline page]:
d2=, p2=, and dp2=.
* Add options to the [/help/tag|fossil tag] command that will list tag values.
* Add the -b|--brief option to the [/help/status|fossil status] command.
* Add ability to upload unversioned files via the [/help/www/uvlist|/uvlist page].
* Add history search to the [/help/www/chat|/chat page].
* Add Unix socket support to the [/help/server|server command].
* On Windows, use the root certificates managed by the operating system
(requires OpenSSL 3.2.0 or greater).
* Take into account zero-width and double-width unicode characters when
formatting the command-line timeline.
* Update the built-in SQLite to version 3.47.0. Precompiled binaries are
linked against OpenSSL 3.4.0.
* Numerous minor fixes and additions.
|
| ︙ | ︙ | |||
255 256 257 258 259 260 261 |
select one of the built-in skins as a default, or to specify a
custom skin.
</ul>
* If an "ssh:" sync fails in a way that suggests that the fossil executable
could not be found on the remote host, then retry after adding a PATH=
prefix to the command. This helps "ssh:" to "just work" when the server
is a Mac.
| | | | | | | | | | | | | | | 309 310 311 312 313 314 315 316 317 318 319 320 321 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 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 |
select one of the built-in skins as a default, or to specify a
custom skin.
</ul>
* If an "ssh:" sync fails in a way that suggests that the fossil executable
could not be found on the remote host, then retry after adding a PATH=
prefix to the command. This helps "ssh:" to "just work" when the server
is a Mac.
* Enhancements to the [/help/www/timeline|/timeline page]:
<ul>
<li> Add the x= query paramater
<li> Add the shortcut tl= and rl= query parameters
<li> Add support for from=,ft= and from=,bt= query parameter combinations
<li> Automatically highlight the endpoints for from=,to= queries.
<li> Add the to2=Z query parameter to augment from=X,to=Y so that the
path from X to Z is shown if Y cannot be found.
</ul>
* Moved the /museum/repo.fossil file referenced from the Dockerfile from
the ENTRYPOINT to the CMD part to allow use of --repolist mode.
* The [/uvlist] page now shows the hash algorithm used so that
viewers don't have to guess. The hash is shown in a fixed-width
font for a more visually pleasing display.
* If the [/help/autosync|autosync setting] contains keyword "all",
the automatic sync occurs against all defined remote repositories, not
just the default.
* Markdown formatter: improved handling of indented fenced code blocks
that contain blank lines.
* When doing a "[/help/add|fossil add]" on a system with case-insensitive
but case-preserving filenames (Mac and Windows) try to use the filename
case as it is known to the filesystem, not the case entered by the
user on the command-line. See
[forum:/forumpost/30d9c0d131610f53|forum thread 30d9c0d131610f53].
* Fix problems with one-click unsubscribe on email notifications.
* Import the latest [/doc/trunk/www/pikchr.md|Pikchr] containing support
for "diamond" objects.
* Add ability to render committed Pikchr files to SVG via
<samp>/doc/…/foo.pikchr?popup</samp> URLs.
* Update Fossil's internal robot detection logic so that it correctly
identifies the new GoogleOther crawler as a robot.
<h2 id='v2_23'>Changes for version 2.23 (2023-11-01)</h2>
* Add ability to "close" forum threads, such that unprivileged users
may no longer respond to them. Only administrators can close
threads or respond to them by default, and the
[/help/forum-close-policy|forum-close-policy setting] can be
used to add that capability to moderators.
* Add the [/help/all|fossil all whatis] command.
* The [/help/status|fossil status] command and relevant UI pages now
correctly report files which were both renamed <b>and</b> edited as such.
* Show default value of settings that have a default in
[/help/help|fossil help SETTING] output.
* On timeline graphs, show closed check-ins using an X in the middle of the
node circle or box.
* New options for email notification: Get email only for the first
post in each new thread, and/or posts that are in reply to my posts.
* Fix a regression bug introduced in version 2.22 that caused FTS5 searches
to fail for terms containing non-ASCII characters.
* Improved defense-in-depth against malicious attack:
<ul>
<li> When an attempted SQL injection attack is detected, return
HTTP result code 418, which can signal the web server to sanction
the attacking IP address.
<li> Better defense against cross-site request forgery (CSRF)
attacks.
<li> Improvements to static analysis of source code (the codecheck1.c
file in the source tree).
</ul>
* Enhance the [/help/www/dir|treeview file listings]
([/dir?type=tree&ci=trunk|example]) by displaying file sizes
and adding the option to sort by file size.
* The [/help/fts-config|fossil fts-config] command now shows how much
repository space is used by the full-text index.
* Changing a setting to an empty string is now the same as deleting the
setting, in most cases. There are a few exceptions, indicated by the
keep-empty flag on the setting definition.
* The [/help/branch|fossil branch list] command can now filter branches
that have/have not been merged into the current branch.
* Improvements to interactions with remote repositories over SSH:
<ul>
<li> Print the text of the SSH command that is run to do remote interaction,
for full disclosure to the operator.
<li> Add a PATH= argument to the [/help/ui|fossil ui remote:/] and
[/help/patch|fossil patch push/pull remote:...] commands so that
they work when the "remote" machine is a Mac and the "fossil"
executable is in the $HOME/bin directory.
</ul>
* Update built-in libraries SQLite, ZLib, Pikchr to their latest versions.
* Documentation enhancements and typo fixes.
<h2 id='v2_22'>Changes for version 2.22 (2023-05-31)</h2>
* Enhancements to the [/help/www/timeline|/timeline webpage]: <ol type="a">
<li> Add the ft=TAG query parameter which in combination with d=Y
shows all descendants of Y up to TAG
<li> Enhance the s=PATTERN (search) query parameter so that forum post
text is also searched when the "vfx" query parameter is used
<li> Fix the u= (user) query parameter so that it works with a= and b=
<li> Add the oldestfirst query parameter to show the events in reverse order.
Useful in combination with y=f and vfs and perhaps also u= to show all
|
| ︙ | ︙ | |||
367 368 369 370 371 372 373 |
inside the jail for Fossil's use.
* Add support for the trigram tokenizer for FTS5 search to enable
searching in Chinese.
* Comment lines (starting with a '#') are now supported inside
[./settings.wiki#versionable|versioned settings].
* Default permissions for anonymous users in new repositories are
changed to "hz".
| | | | | | | | | | | | | | | 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 |
inside the jail for Fossil's use.
* Add support for the trigram tokenizer for FTS5 search to enable
searching in Chinese.
* Comment lines (starting with a '#') are now supported inside
[./settings.wiki#versionable|versioned settings].
* Default permissions for anonymous users in new repositories are
changed to "hz".
* The [/help/status|fossil status] command now detects when a
file used to be a symlink and has been replaced by a regular file.
(It previously checked for the inverse case only.)
* The [/help/empty-dirs|empty-dirs setting] now reuses the same
parser as the *-glob settings instead of its prior idiosyncratic
parser, allowing quoted whitespace in patterns.
* Enhancements to the [/help/www/reports|/reports webpage]:
<ol type="a">
<li> The by-week, by-month, and by-year options now show an estimated
size of the current week, month, or year as a dashed box.
<li> New sub-categories "Merge Check-ins" and "Non-Merge Check-ins".
</ol>
<h2 id='v2_21'>Changes for version 2.21 (2023-02-25)</h2>
* Users can request a password reset. This feature is disabled by default.
Use the new [/help/self-pw-reset|self-pw-reset property] to enable it.
New web pages [/help/www/resetpw|/resetpw] and
[/help/www/reqpwreset|/reqpwreset] added.
* Add the [/help/repack|fossil repack] command (together with
[/help/all|fossil all repack]) as a convenient way to optimize the
size of one or all of the repositories on a system.
* Add the ability to put text descriptions on ticket report formats.
* Upgrade the test-find-pivot command to the [/help/merge-base|merge-base command].
* The [/help/www/chat|/chat page] can now embed fossil-rendered
views of wiki/markdown/pikchr file attachments with the caveat that such
embedding happens in an iframe and thus does not inherit styles and such
from the containing browser window.
* The [/help/all|fossil all remote] subcommand added to "fossil all".
* Passwords for remembered remote repositories are now stored as irreversible
hashes rather than obscured clear-text, for improved security.
* Add the "nossl" and "nocompress" options to CGI.
* Update search infrastructure from FTS4 to FTS5.
* Add the [/help/www/deltachain|/deltachain] page for debugging purposes.
* Writes to the database are disabled by default if the HTTP request
does not come from the same origin. This enhancement is a defense in depth
measure only; it does not address any known vulnerabilities.
* Improvements to automatic detection and mitigation of attacks from
malicious robots.
<h2 id='v2_20'>Changes for version 2.20 (2022-11-16)</h2>
* Added the [/help/chat-timeline-user|chat-timeline-user setting]. If
it is not an empty string, then any changes that would appear on the timeline
are announced in [./chat.md|the chat room].
* The /unsubscribe page now requests confirmation. [./alerts.md|Email notifications]
now contain only an "Unsubscribe" link, and not a link to subscription management.
* Added the "[/help/branch|fossil branch lsh]" subcommand to list the
most recently modified branches.
* More elements of the /info page are now inside of an accordion.
* Replace the <tt>--dryrun</tt> flag with <tt>--dry-run</tt> in all
commands which still used the former name, for consistency.
* Rebuilt [/file/Dockerfile | the stock Dockerfile] to create a "from scratch"
Busybox based container image via an Alpine Linux intermediary
* Added [/doc/trunk/www/containers.md | a new document] describing how to
|
| ︙ | ︙ | |||
446 447 448 449 450 451 452 |
* Performance enhancement for the
[./checkin_names.wiki#root|"root:BRANCHNAME" style of tag],
accomplished using a Common Table Expression in the underlying SQL.
* Sort tag listings (command line and webpage) by taking numbers into
consideration so as to cater for tags that follow semantic versioning.
* On the wiki listings, omit by default wiki pages that are associated with
check-ins and branches.
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 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 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 |
* Performance enhancement for the
[./checkin_names.wiki#root|"root:BRANCHNAME" style of tag],
accomplished using a Common Table Expression in the underlying SQL.
* Sort tag listings (command line and webpage) by taking numbers into
consideration so as to cater for tags that follow semantic versioning.
* On the wiki listings, omit by default wiki pages that are associated with
check-ins and branches.
* Add the new "[/help/describe|fossil describe]" command.
* Markdown subsystem extended with [../src/markdown.md#ftnts|footnotes support].
See corresponding [../test/markdown-test3.md|test cases],
[/wiki?name=branch/markdown-footnotes#il|known limitations] and
[forum:/forumthread/ee1f1597e46ec07a|discussion].
* Add the new special name "start:BRANCH" to refer to the first check-in of
the branch.
* Support [/wiki?name=branch/generated-tkt-mimetype&p|generated "mimetype"]
columns in the <var>TICKET</var> and <var>TICKETCHNG</var> tables.
* Fix [/timeline?r=fix_remote_url_overwrite_with_proxy|remote-url-overwrite]
bug where remote-url is overwritten by the proxy setting during sync
operation. Also require explicit "system" proxy setting to use
"http_proxy" environment variable.
* Reimplemented the [/pikchrshow] app to use a WebAssembly build of
pikchr so that it can render pikchrs on the client instead of requiring
a server round-trip.
* Add the [/help/email-listid|email-listid setting]. If set, it is
used as the List-ID header for all outbound notification emails.
* Add the "--branch" option to the "[/help/timeline|timeline]" command
to restrict the displayed items to a specific branch.
* Add the "--versions" option to "[/help/diff|fossil diff]"
to display details about the compared versions into the patch header.
* Numerous other minor enhancements.
<h2 id='v2_18'>Changes for version 2.18 (2022-02-23)</h2>
* Added support for [./ssl-server.md|SSL/TLS server mode] for commands
like "[/help/server|fossil server]" and "[/help/http|fossil http]"
* The new [/help/cherry-pick|cherry-pick command] is an alias for
[/help/merge|merge --cherrypick].
* Add new setting "[/help/large-file-size|large-file-size]". If the size
of any file in a commit exceeds this size, a warning is issued.
* Query parameter "year=YYYY" is now accepted by [/help/www/timeline|/timeline].
* The [/help/tar|tar] and [/help/zip|zip commands] no longer
sterilize the manifest file.
* Further improvement to diff alignment in cases that involve both
edits and indentation changes.
* [/doc/trunk/www/chat.md|Chat] improvements:<ul>
<li> [/help/www/chat|The /chat page] input options have been reworked
again for better cross-browser portability.
<li> When sending a [/help/www/chat|/chat] message fails, it is no longer
immediately lost and sending may optionally be retried.
<li> [/help/www/chat|/chat] can now optionally embed attachments of certain
types directly into message bodies via an iframe.
<li> Add the "--as FILENAME" option to the "[/help/chat|fossil chat send]"
command.
<li> Added the "[/help/chat|fossil chat pull]" command, available to
administrators only, for backing up the chat conversation.
</ul>
* Promote the test-detach command into the [/help/detach|detach command].
* For "[/help/pull|fossil pull]" with the --from-parent-project option,
if no URL is specified then use the last URL from the most recent prior
"fossil pull --from-parent-project".
* Add options --project-name and --project-desc to the
"[/help/init|fossil init]" command.
* The [/help/www/ext|/ext page] generates the SERVER_SOFTWARE environment
variable for clients.
* Fix the REQUEST_URI [/doc/trunk/www/aboutcgi.wiki#cgivar|CGI variable] such
that it includes the query string. This is how most other systems understand
REQUEST_URI.
* Added the --transport-command option to [/help/sync|fossil sync]
and similar.
<h2 id='v2_17'>Changes for version 2.17 (2021-10-09)</h2>
* Major improvements to the "diff" subsystem, including: <ul>
<li> Added new [/help/diff|formatting options]: --by, -b, --webpage, --json, --tcl.
<li> Partial-line matching for unified diffs
<li> Better partial-line matching for side-by-side diffs
<li> Buttons on web-based diffs to show more context
<li> Performance improvements
</ul>
* The --branchcolor option on [/help/commit|fossil commit] and
[/help/amend|fossil amend] can now take the value "auto" to
force Fossil to use its built-in automatic color choosing algorithm.
* Fossil now [./concepts.wiki#workflow|autosyncs] prior to running
[/help/open|fossil open].
* Add the [/help/ticket-default-report|ticket-default-report setting],
which if set to the title of a ticket report causes that ticket report
to be displayed below the search box in the /ticket page.
* The "nc" query parameter to the [/help/www/timeline|/timeline] page
causes all graph coloring to be omitted.
* Improvements and bug fixes to the new "[/help/ui|fossil ui REMOTE]"
feature so that it works better on a wider variety of platforms.
* In [/help/www/wikiedit|/wikiedit], show the list of attachments for
the current page and list URLs suitable for pasting them into the page.
* Add the --no-http-compression option to [/help/sync|fossil sync]
and similar.
* Print total payload bytes on a [/help/sync|fossil sync] when using
the --verbose option.
* Add the <tt>close</tt>, <tt>reopen</tt>, <tt>hide</tt>, and
</tt>unhide</tt> subcommands to [/help/branch|the branch command].
* The "-p" option to [/help/branch|fossil branch list] shows only
private branches.
* The [/md_rules|Markdown formatter] now interprets the content of
block HTML markup (such as <table>) in most cases. Only content
of <pre> and <script> is passed through verbatim.
* The [/help/wiki|wiki list command] no longer lists "deleted"
pages by default. Use the new <tt>--all</tt> option to include deleted
pages in the output.
* The [/help/all|fossil all git status] command only shows reports for
the subset of repositories that have a configured Git export.
* The [/help/www/chat|/chat] configuration was reimplemented and
provides new options, including the ability for a repository
administrator to
[./chat.md#notifications|extend the selection of notification sounds]
using unversioned files.
* Chat now uses fossil's full complement of markdown features,
instead of the prior small subset of markup it previously supported.
This retroactively applies to all chat messages, as they are
markdown-processed when they are sent instead of when they
are saved.
* Added a chat message preview mode so messages can be previewed
before being sent. Similarly, added a per-message ability to view
the raw un-parsed message text.
* The hotkey to activate preview mode in [/help/www/wikiedit|/wikiedit],
[/help/www/fileedit|/fileedit], and [/help/www/pikchrshow|/pikchrshow]
was changed from ctrl-enter to shift-enter in order to align with
[/help/www/chat|/chat]'s new preview feature and related future
changes.
<h2 id='v2_16'>Changes for Version 2.16 (2021-07-02)</h2>
* <b>Security:</b> Fix the client-side TLS so that it verifies that the
server hostname matches its certificate.
* The default "ssh" command on Windows is changed to "ssh" instead of the
legacy "plink", as ssh is now generally available on Windows systems.
Installations that still need to use the legacy "plink" can make that
happen by running: '<tt>fossil set ssh-command "plink -ssh" --global</tt>'.
* Added the [./patchcmd.md|fossil patch] command.
* The [/help/ui|fossil ui] command is enhanced in multiple ways:<ol>
<li> The REPOSITORY argument can be the name of a check-out directory.
<li> If the REPOSITORY argument is prefixed by "HOST:" or "USER@HOST:"
then the ui is run on the remote machine and tunnelled back to the local
machine using ssh. (The latest version of fossil must be installed on
both the local and the remote for this to work correctly.)
<li> The new --nobrowser and --fossilcmd options is provided.
</ol>
* The [/brlist|/brlist web page] allows the user to
select multiple branches to be displayed together in a single
timeline.
* The [./forum.wiki|Forum] provides a hyperlink on the author of each
post that goes to a timeline of recent posts by that same author.
* Added the "[/help/bisect|fossil bisect run]" command for improved
automation of bisects.
* The [/help/merge|fossil merge] command now does a better job merging
branches where files have been renamed between the current branch and the
branch being merged.
* The [/help/open|fossil open] command allows the repository file
to be inside the working directory without requiring the --force flag.
* The [/help/www/wikiedit|/wikiedit] and [/help/www/wikinew|/wikinew]
pages now default to markdown format.
* The [/help/www/login|/login] page now links to a user's forum post
timeline if the repository has forum posts.
* Tags may now be propagated for forum posts, wiki pages, and technotes.
The [/help/tag|tag command] can now manipulate and list such tags.
* [./caps/login-groups.md|Login-Groups] are now shown on the repository
list of the "[/help/all|fossil all ui]" command.
* Administrators can configure [./alerts.md|email alerts] to expire
a specific number of days (ex: 365) after the last user contact with
the Fossil server. This prevents alert emails being sent to
abandoned email accounts forever.
* SQL that defines [/tktsetup_tab|database objects for tickets] now
[/timeline?c=c717f1ef9a1a4c91|can DROP] a VIEW or an INDEX provided
that its name starts with '<code>ticket</code>' or '<code>fx_</code>'.
* Update the built-in SQLite to version 3.36.0.
* Numerous other minor enhancements.
<h2 id='v2_15'>Changes for Version 2.15 (2021-03-26) and Patch 2.15.1 on (2021-04-07)
and 2.15.2 on (2021-06-15)</h2>
* <b>Patch 2.15.2:</b> Fix the client-side TLS so that it verifies that the
server hostname matches its certificate. <b>Upgrading to
the patch is recommended.</b>
* <b>Patch 2.15.1:</b> Fix a data exfiltration bug in the server. <b>Upgrading to
the patch is recommended.</b>
* The [./defcsp.md|default CSP] has been relaxed slightly to allow
images to be loaded from any URL. All other resources are still
locked down by default.
* The built-in skins all use the "[/help/mainmenu|mainmenu]"
setting to determine the content of the main menu.
The ability to edit the
"mainmenu" setting is added on the /Admin/Configuration page.
* The hamburger menu is now available on most of the built-in skins.
* Any built-in skin named "X" can be used instead of the standard
repository skin by adding the URL parameter <tt>skin=X</tt> to the
request. The selection is persisted using the display
preferences cookie unless the "once" query parameter is also
included. The [/skins] page may be used to select a skin.
* The [/cookies] page now gives the user an opportunity to delete
individual cookies. And the /cookies page is linked from the
/sitemap, so that it appears in hamburger menus.
* The [/sitemap] extensions are now specified by a single new
"[/help/sitemap-extra|sitemap-extra setting]",
rather than a cluster of various
"sitemap-*" settings. The older settings are no longer used.
<b>This change might require minor server configuration
adjustments on servers that use /sitemap extensions.</b>
The /Admin/Configuration page provides the ability to edit
the new "sitemap-extra" setting.
* Added the "--ckout-alias NAME" option to
[/help/ui|fossil ui], [/help/server|fossil server], and
[/help/http|fossil http]. This option causes Fossil to
understand URIs of the form "/doc/NAME/..." as if they were
"[/help/www/doc|/doc/ckout/...]", to facilitate testing of
[./embeddeddoc.wiki|embedded documentation] changes prior to
check-in.
* For diff web pages, if the diff type (unified versus side-by-side)
is not specified by a query parameter, and if the
"[/help/preferred-diff-type|preferred-diff-type]"
setting is omitted or less than 1, then select the diff type based
on a guess of whether or not the request is coming from a mobile
device. Mobile gets unified and desktop gets side-by-side.
* The various pages which show diffs now have toggles to show/hide
individual diffs.
* Add the "[/help/preferred-diff-type|preferred-diff-type]"
setting to allow an admin to force a default diff type.
* The "pikchr-background" setting is now available in
"detail.txt" skin files, for better control of Pikchr
colors in inverted color schemes.
* Add the <tt>--list</tt> option to the
[/help/tarball|tarball],
[/help/zip|zip], and [/help/sqlar|sqlar]
commands.
* The javascript used to implement the hamburger menu on the
default built-in skin has been made generic so that it is usable
by a variety of skins, and promoted to an ordinary built-in
javascript file.
* New TH1 commands:
"[/doc/trunk/www/th1.md#bireqjs|builtin_request_js]",
"[/doc/trunk/www/th1.md#capexpr|capexpr]",
"foreach", "lappend", and "string match"
* The [/help/leaves|leaves command] now shows the branch point
of each leaf.
* The [/help/add|fossil add] command refuses to add files whose
names are reserved by Windows (ex: "aux") unless the --allow-reserved
option is included. This helps prevent Unix users from accidentally
creating check-ins that are unreadable by Windows users.
* Add the "re=" query parameter to the [/help/www/dir|/dir] webpage,
for symmetry with the [/help/www/tree|/tree] page.
* Update the built-in SQLite to version 3.35.0.
* The ./configure script now has the --print-minimum-sqlite-version option
that prints the minimum SQLite version required by the current version
of Fossil. This might be used by integrators who insist on building
Fossil to link against the system SQLite library rather than the
built-in copy of SQLite, to verify that their system SQLite library
is recent enough.
* Webpage that shows [/help/www/whistory|history of a wiki page]
gained client-side UI to help with comparison between two arbitrary
versions of a wiki (by the means of anchoring a "baseline" version)
and the ability to squeeze several sequential edits made by the same
user into a single "recycled" row (the latest edit in that sequence).
<h2 id='v2_14'>Changes for Version 2.14 (2021-01-20) and Patch 2.14.1 on (2021-04-07)
and 2.14.2 on (2021-06-15)</h2>
|
| ︙ | ︙ | |||
714 715 716 717 718 719 720 |
add content to a repository using Fossil 2.14 or later. No
action is needed on your part. However, if you upgrade to
version 2.14 and then later downgrade or otherwise use an earlier
version of Fossil, the email notification mechanism may fail
to send out notifications for some events, due to the missing
trigger. If you want to
permanently downgrade an installation, then you should run
| | | | | | | | | | | | 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 |
add content to a repository using Fossil 2.14 or later. No
action is needed on your part. However, if you upgrade to
version 2.14 and then later downgrade or otherwise use an earlier
version of Fossil, the email notification mechanism may fail
to send out notifications for some events, due to the missing
trigger. If you want to
permanently downgrade an installation, then you should run
"[/help/rebuild|fossil rebuild]" after the downgrade
to get email notifications working again. If you are not using
email notification, then the schema change will not affect you in
any way.
* <b>Schema Update Notice #2:</b>
This release changes how the descriptions of wiki edits are stored
in the EVENT table, for improved display on timelines. You must
run "[/help/rebuild|fossil rebuild]" to take advantage of
this enhancement. Everything will still work without
"fossil rebuild", except you will get goofy descriptions of
wiki updates in the timeline.
* Add support for [./chat.md|Fossil chat].
* The "[/help/clone|fossil clone]" command is enhanced so that
if the repository filename is omitted, an appropriate name is derived
from the remote URL and the newly cloned repo is opened. This makes
the clone command work more like Git, thus making it easier for
people transitioning from Git.
* Added the --mainbranch option to the [/help/git|fossil git export]
command.
* Added the --format option to the
"[/help/timeline|fossil timeline]" command.
* Enhance the --numstat option on the
"[/help/diff|fossil diff]" command so that it shows a total
number of lines added and deleted and total number of files
modified.
* Add the "contact" sub-command to [/help/user|fossil user].
* Added commands "[/help/all|fossil all git export]" and
"[/help/all|fossil all git status]".
* Added the "df=CHECKIN" query parameter to the
[/help/www/timeline|/timeline page].
* Improvements to the "[/sitemap]" page. Add subpages
[/sitemap-timeline] and [/sitemap-test].
* Better text position in cylinder objects of Pikchr diagrams.
* New "details.txt" settings available to custom skins to better control
the rendering of Pikchr diagrams:
<ul>
<li> pikchr-foreground
|
| ︙ | ︙ | |||
769 770 771 772 773 774 775 |
<h2 id='v2_13'>Changes for Version 2.13 (2020-11-01)</h2>
* Added support for [./interwiki.md|interwiki links].
* Enable <del> and <ins> markup in wiki.
* Improvements to the Forum threading display.
* Added support for embedding [./pikchr.md|pikchr]
markup in markdown and fossil-wiki content.
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 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 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 |
<h2 id='v2_13'>Changes for Version 2.13 (2020-11-01)</h2>
* Added support for [./interwiki.md|interwiki links].
* Enable <del> and <ins> markup in wiki.
* Improvements to the Forum threading display.
* Added support for embedding [./pikchr.md|pikchr]
markup in markdown and fossil-wiki content.
* The new "[/help/pikchr|pikchr]" command can render
pikchr scripts, optionally pre-processed with
[/doc/trunk/www/th1.md|TH1] blocks and variables exactly like
site skins are.
* The new [/help/www/pikchrshow|pikchrshow] page provides an
editor and previewer for pikchr markup.
* In [/help/www/wikiedit|/wikiedit] and
[/help/www/fileedit|/fileedit], Ctrl-Enter can now be used
initiate a preview and to toggle between the editor and preview
tabs.
* The <tt>/artifact</tt> and <tt>/file</tt> views, when in
line-number mode, now support interactive selection of a range
of lines to hyperlink to.
* Enhance the [/help/www/finfo|/finfo] webpage so that when query
parameters identify both a filename and a checkin, the resulting
graph tracks the identified file across renames.
* The built-in SQLite is updated to an alpha of version 3.34.0, and
the minimum SQLite version is increased to 3.34.0 because the
/finfo change in the previous bullet depends on enhancements to
recursive common table expressions that are only available in
SQLite 3.34.0 and later.
* Countless other minor refinements and documentation improvements.
<h2 id='v2_12'>Changes for Version 2.12.1 (2020-08-20)</h2>
* (2.12.1): Fix client-side vulnerabilities discovered by Max Justicz.
* Security fix in the "[/help/git|fossil git export]" command.
The same fix is also backported to version 2.10.1 and 2.11.1.
New "safety-net" features were added to prevent similar problems
in the future.
* Enhancements to the graph display for cases when there are
many cherry-pick merges into a single check-in.
[/timeline?f=2d75e87b760c0a9|Example]
* Enhance the [/help/open|fossil open] command with the new
--workdir option and the ability to accept a URL as the repository
name, causing the remote repository to be cloned automatically.
Do not allow "fossil open" to open in a non-empty working directory
unless the --keep option or the new --force option is used.
* Enhance the markdown formatter to more closely follow the
[https://spec.commonmark.org/0.29/#emphasis-and-strong-emphasis|CommonMark specification]
with regard to text highlighting.
Underscores in the middle of identifiers (ex: fossil_printf())
no longer need to be escaped.
* The markdown-to-html translator can prevent unsafe HTML
(for example: <script>) on user-contributed pages like forum and
tickets and wiki. The admin can adjust this behavior using
the [/help/safe-html|safe-html setting] on the Admin/Wiki page.
The default is to disallow unsafe HTML everywhere.
[https://fossil-scm.org/forum/forumpost/3714e6568f|Example].
* Added the "collapse" and "expand" capability for long forum posts.
[https://fossil-scm.org/forum/forumpost/9297029862|Example]
* The "[/help/remote-url|fossil remote]" command now has options for
specifying multiple persistent remotes with symbolic names. Currently
only one remote can be used at a time, but that might change in the
future.
* Add the "Remember me?" checkbox on the login page. Use a session
cookie for the login if it is not checked.
* Added the experimental "[/help/hook|fossil hook]" command for
managing "hook scripts" that run before checkin or after a push.
* Enhance the [/help/revert|fossil revert] command so that it
is able to revert all files beneath a directory.
* Add the [/help/bisect|fossil bisect skip] command.
* Add the [/help/backup|fossil backup] command.
* Enhance [/help/bisect|fossil bisect ui] so that it shows all unchecked
check-ins in between the innermost "good" and "bad" check-ins.
* Added the <tt>--reset</tt> flag to the "[/help/add|fossil add]",
"[/help/rm|fossil rm]", and
"[/help/addremove|fossil addremove]" commands.
* Added the "<tt>--min</tt> <i>N</i>" and "<tt>--logfile</tt> <i>FILENAME</i>"
flags to the [/help/backoffice|backoffice] command, as well as other
enhancements to make the backoffice command a viable replacement for
automatic backoffice. Other incremental backoffice improvements.
* Added the [/help/www/fileedit|/fileedit page], which allows
editing of text files online. Requires explicit activation by
a setup user.
* Translate built-in help text into HTML for display on web pages.
[/help/help|Example].
* On the [/help/www/timeline|/timeline] webpage, the combination
of query parameters "p=CHECKIN" and "bt=ANCESTOR" draws all
ancestors of CHECKIN going back to ANCESTOR. For example,
[/timeline?p=202006271506&bt=version-2.11] shows all ancestors
of the checkin that occurred on 2020-06-27 15:06 going back to
the 2.11 release.
* Update the built-in SQLite so that the
"[/help/sql|fossil sql]" command supports new output
modes ".mode box" and ".mode json".
* Add the "<tt>obscure()</tt>" SQL function to the
"[/help/sql|fossil sql]" command.
* Added virtual tables "<tt>helptext</tt>" and "<tt>builtin</tt>" to
the "[/help/sql|fossil sql]" command, providing access to the
dispatch table including all help text, and the builtin data files,
respectively.
* [./delta_format.wiki|Delta compression] is now applied to forum edits.
* The [/help/www/wikiedit|wiki editor] has been modernized and is
now Ajax-based. The WYSIWYG editing option for Fossil-format wiki
pages was removed. (Please let us know, via the site's Forum menu,
if that removal unduly impacts you.) This also changes the semantics
of the wiki "Sandbox": that pseudo-page may be freely edited but
no longer saved via the UI (the [/help/wiki|wiki CLI command]
can, though).
* The [/help/allow-symlinks|allow-symlinks setting] no longer
syncs. It must be activated individually on any clones which require
symlinks.
* Countless documentation enhancements.
<h2 id='v2_11'>Changes for Version 2.11 (2020-05-25)</h2>
* (2.11.2): Backport security fixes from 2.12.1
* (2.11.1): Backport security fix for the "fossil git export" command.
* Support [/md_rules|Markdown] in the default ticket configuration.
* Timestamp strings in [./checkin_names.wiki|object names]
can now omit punctation. So, for example, "202004181942" and
"2020-04-18 19:42" mean the same thing.
* Enhance backlink processing so that it works with Markdown-formatted
tickets and so that it works for wiki pages.
Ticket [a3572c6a5b47cd5a].
<ul><li> "[/help/rebuild|fossil rebuild]" is needed to
take full advantage of this fix. Fossil will continue
to work without the rebuild, but the new backlinks will be missing.</ul>
* The algorithm for finding the
[./tech_overview.wiki#configloc|location of the configuration database]
is enhanced to be XDG-compliant.
* Add a hide/show feature to
[./wikitheory.wiki#assocwiki|associated wiki] display on
check-in and branch information pages.
* Enhance the "[/help/info|fossil info]" command so that it
works with no arguments even if not within an open check-out.
* Many improvements to the forum and especially email notification
of forum posts, in response to community feedback after switching
SQLite support from a mailing list over to the forum.
* Minimum length of a self-registered user ID increased from 3 to 6
characters.
* When the "vfx" query parameter is used on the
"[/help/www/timeline|/timeline]" page, it causes the complete
text of forum posts to be displayed.
* Rework the "[/help/grep|fossil grep]" command to be more useful.
* Expose the [/help/redirect-to-https|redirect-to-https]
setting to the [/help/settings|settings] command.
* Improve support for CGI on IIS web servers.
* The [./serverext.wiki|/ext page] can now render index files,
in the same way as the embedded docs.
* Most commands now support the Unix-conventional "<tt>--</tt>"
flag to treat all following arguments as filenames
instead of flags.
* Added the [/help/mimetypes|mimetypes config setting]
(versionable) to enable mimetype overrides and custom definitions.
* Add an option on the /Admin/Timeline setup page to set a default
timeline style other than "Modern".
* In [./embeddeddoc.wiki|embedded documentation], hyperlink URLs
of the form "/doc/$CURRENT/..." the "$CURRENT" text is translated
into the check-in hash for the document currently being viewed.
* Added the [/help/www/phantoms|/phantoms] webpage that shows all
phantom artifacts.
* Enhancements to phantom processing to try to reduce
bandwidth-using chatter about phantoms on the sync protocol.
* Security: Fossil now assumes that the schema of every
database it opens has been tampered with by an adversary and takes
extra precautions to ensure that such tampering is harmless.
* Security: Fossil now puts the Content-Security-Policy in the
HTTP reply header, in addition to also leaving it in the
HTML <head> section, so that it is always available, even
if a custom skin overrides the HTML <head> and omits
the CSP in the process.
* Output of the [/help/diff|fossil diff -y] command automatically
adjusts according to the terminal width.
* The Content-Security-Policy is now set using the
[/help/default-csp|default-csp setting].
* Merge conflicts caused via the [/help/merge|merge] and
[/help/update|update] commands no longer leave temporary
files behind unless the new <tt>--keep-merge-files</tt> flag
is used.
* The [/help/www/artifact_stats|/artifact_stats page] is now accessible
to all users if the new "artifact_stats_enable" setting is turned
on. There is a new checkbox under the /Admin/Access menu to turn
that capability on and off.
* Add the [/help/tls-config|fossil tls-config] command for viewing
the TLS configuration and the list of SSL Cert exceptions.
* Captchas all include a button to read the captcha using an audio
file, so that they can be completed by the visually impaired.
* Stop using the IP address as part of the login cookie.
* Bug fix: fix the SSL cert validation logic so that if an exception
is allowed for particular site, the exception expires as soon as the
cert changes values.
|
| ︙ | ︙ | |||
969 970 971 972 973 974 975 | * Many minor enhancements to existing features. <h2 id='v2_10'>Changes for Version 2.10 (2019-10-04)</h2> * (2.10.2): backport security fixes from 2.12.1 * (2.10.1): backport security fix for the "fossil git export" command. * Added support for [./serverext.wiki|CGI-based Server Extensions]. | | | | | | | | | | | | | | | | | | 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 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 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 |
* Many minor enhancements to existing features.
<h2 id='v2_10'>Changes for Version 2.10 (2019-10-04)</h2>
* (2.10.2): backport security fixes from 2.12.1
* (2.10.1): backport security fix for the "fossil git export" command.
* Added support for [./serverext.wiki|CGI-based Server Extensions].
* Added the [/help/repolist-skin|repolist-skin] setting used to
add style to repository list pages.
* Enhance the hierarchical display of Forum threads to do less
indentation and to provide links back to the previous message
in the thread. Provide sequential numbers for all messages in
a forum thread.
* Add support for fenced code blocks and improved hyperlink
processing to the [/md_rules|markdown formatter].
* Add support for hyperlinks to wiki pages in the
[/md_rules|markdown formatter].
* Enhance the [/help/www/stat|/stat] page so that it gives the
option to show a breakdown of forum posts.
* The special check-in name "merge-in:BRANCH" means the source of
the most recent merge-in from the parent branch of BRANCH.
* Add hyperlinks to branch-diffs on the /info page and from
timelines of a branch.
* Add graphical context on the [/help/www/vdiff|/vdiff] page.
* Uppercase query parameters, POST parameters, and cookie names are
converted to all lowercase and entered into the parameter set,
instead of being discarded.
* Change the default [./hashpolicy.wiki|hash policy] to SHA3.
* Timeout [./server/any/cgi.md|CGI requests] after 300 seconds, or
some other value set by the
[./cgi.wiki#timeout|"timeout:" property] in the CGI script.
* The check-in lock interval is reduced from 24 hours to 60 seconds,
though the interval is now configurable using a setting.
An additional check for conflicts is added after interactive
check-in comment entry, to compensate for the reduced lock interval.
* Performance optimizations.
* Many documentation improvements.
<h2 id='v2_9'>Changes for Version 2.9 (2019-07-13)</h2>
* Added the [/help/git|fossil git export] command and instructions
for [./mirrortogithub.md|creating a GitHub mirror of a Fossil project].
* Improved handling of relative hyperlinks on the
[/help/www/artifact|/artifact] pages for wiki. For example,
hyperlinks and the lizard <img> now work correctly
for both [/artifact/2ff24ab0887cf522] and
[/doc/0d7ac90d575004c2415/www/index.wiki].
* Enhancements to the timeline graph layout, to show more information
with less clutter.
* Added tool-tips to the /timeline graph. On by default but can be
disabled by setting the "Tooltip dwell time" to 0 in the timeline
configuration.
* Copy buttons added to various check-in hash and branch name links.
* Double-clicking on a /timeline graph node now jumps to the /info page
for the check-in. So, repurpose the timestamp hyperlink to show all
activity around that check-in in time.
* Added the [/help/touch|fossil touch] command, and the --setmtime
option on the [/help/open|fossil open] and
[/help/update|fossil update] commands.
* Many documentation enhancements.
* For the "[/help/update|fossil update]" and
"[/help/checkout|fossil checkout]" commands, if a
managed file is removed because it is no longer part of the target
check-in and the directory containing the file is empty after the
file is removed and the directory is not the current working
directory and is not on the [/help/empty-dirs|empty-dirs]
list, then also remove the directory.
* Update internal Unicode character tables, used in regular expression
handling, from version 11.0 to 12.1.
* In "[/help/regexp|fossil regexp]", "[/help/grep|fossil grep]"
and the TH1 "regexp" command, the -nocase option now removes multiple
diacritics from the same character (derived from SQLite's
remove_diacritics=2)
* Added the [/help/www/secureraw|/secureraw] page that requires the
complete SHA1 or SHA3 hash, not just a prefix, before it will deliver
content.
* Accept purely numeric ISO8601 date/time strings as long as they
do not conflict with a hash. Example: "20190510134217" instead of
"2019-05-10 13:42:17". This helps keep URLs shorter and less
complicated
* Support both "1)" and "1." for numbered lists in markdown, as
commonmark does.
* The sync and clone HTTP requests omit the extra /xfer path element
from the end of the request URI. All servers since 2010 know that
the HTTP request is for a sync or clone from the mimetype so the
extra path element is not needed.
* If an automatic sync gets a permanent redirect request, then update
the saved remote URL to the new address.
* Temporary filenames (for example used for external "diff" commands)
try to preserve the suffix of the original file.
* Added the [/help/www/thisdayinhistory|/thisdayinhistory] web page.
* Enhanced parsing of [/help/www/timeline|/timeline] query parameters
"ymd=", "ym=", and "yw=". All arguments are option (in which case they
default to the current time) and all accept ISO8601 date/times without
punctuation.
* Automatically disapprove pending moderation requests for a user when
that user is deleted. This helps in dealing with spam-bots.
* Improvements to the "Capability Summary" section in the
[/help/www/secaudit0|Security Audit] web-page.
* Use new "ci-lock" and "ci-lock-failed" pragmas in the
[./sync.wiki|sync protocol] to try to prevent accident forks
caused by concurrent commits when operating in auto-sync mode.
* Fix a bug ([https://fossil-scm.org/forum/forumpost/c51b9a1169|details])
that can cause repository databases to be overwritten with debugging
output, thus corrupting the repository. This is only a factor when
CGI debugging is enabled, and even then is a rare occurrence, but it is
|
| ︙ | ︙ | |||
1165 1166 1167 1168 1169 1170 1171 |
* There is an optional "js" file for each skin that can be used to
hold javascript. This file can be loaded by reference or can be
included in the header or footer.
* Add the [./backoffice.md|backoffice].
* Update internal Unicode character tables, used in regular expression
handling, from version 10.0 to 11.0.
* Improvements to the "Security Audit" administration page
| | | 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 |
* There is an optional "js" file for each skin that can be used to
hold javascript. This file can be loaded by reference or can be
included in the header or footer.
* Add the [./backoffice.md|backoffice].
* Update internal Unicode character tables, used in regular expression
handling, from version 10.0 to 11.0.
* Improvements to the "Security Audit" administration page
* Add the [/help/branch|fossil branch current] command.
* Add the [./grep.md|grep] command.
* Update the built-in SQLite to version 3.25.1.
* Some code and interfaces are in place to support sending and
receiving email directly via SMTP, but this feature is not yet
complete or ready for production use.
* The `mv-rm-files` setting is now compiled into Fossil in the
default Fossil configuration; no longer must you say
|
| ︙ | ︙ | |||
1188 1189 1190 1191 1192 1193 1194 |
repository. This fix is the main reason for the current release.
* Added the new "Classic" timeline viewing mode. "Classic" is the
same as "Verbose" in the previous release. The "Verbose" mode is
now like "Compact" except the extra check-in details are shown by
default.
* Add support for ETags:, Last-Modified:, and If-Modified-Since:
cache control mechanisms.
| | | | | | | 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 |
repository. This fix is the main reason for the current release.
* Added the new "Classic" timeline viewing mode. "Classic" is the
same as "Verbose" in the previous release. The "Verbose" mode is
now like "Compact" except the extra check-in details are shown by
default.
* Add support for ETags:, Last-Modified:, and If-Modified-Since:
cache control mechanisms.
* Enhance the [/help/www/tarball|/tarball],
[/help/www/zip|/zip], and
[/help/www/sqlar|/sqlar] pages so that the checkin
name to be downloaded can be expressed as part of the URI,
and without the need for query parameters.
* On the [/help/www/timeline|/timeline] webpage, add the days=N
query parameter and enhance the ymd=DATE and yw=DATE query parameters
to accept 'now' as an argument to show the latest day or week.
* In the web page that comes up in response to the
[/help/all|fossil all ui] command, show the last modification
time for each repository, and allow click-to-sort on the modification
time column.
* In the tarball cache replacement algorithm, give extra weight to
tarballs that have been accessed more than once.
* Additional defenses against web-based attacks. There have not been
any known vulnerabilities. We are just being paranoid.
* Update the built-in SQLite to an alpha version of 3.24.0.
|
| ︙ | ︙ | |||
1248 1249 1250 1251 1252 1253 1254 |
* New feature: URL Aliases. URL Aliases allow an administrator
to define their own URLs on the web interface that are rewritten to
built-in URLs with specific parameters. Create and configure URL Aliases
using the /Setup/URL_Aliases menu option in the web interface.
* Add tech-note search capability.
* Add the -r|--revision and -o|--origin options to the
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 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 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 |
* New feature: URL Aliases. URL Aliases allow an administrator
to define their own URLs on the web interface that are rewritten to
built-in URLs with specific parameters. Create and configure URL Aliases
using the /Setup/URL_Aliases menu option in the web interface.
* Add tech-note search capability.
* Add the -r|--revision and -o|--origin options to the
[/help/annotate|annotate] command.
* Add the origin= query parameter to the [/help/www/annotate|/annotate]
webpage.
* The [/help/annotate|fossil annotate] command and the
[/help/www/annotate|/annotate] web page go backwards in time as far
as can be computed in 30 milliseconds by default, rather than stopping
after 20 steps. The new limit= query parameter or the --limit command-line
option can be used to alter this timeout.
* Provide separate [/help#settings|on-line help screens for each setting].
* Back out support for the --no-dir-symlinks option
* Remove support from the legacy configuration sync protocol. The only
way now to do a configuration push or pull is to use the new protocol that
was added in 2011.
* Add the from= and to= query parameters to [/help/www/fdiff|/fdiff]
in order to get a diff of two files in the same check-in.
* Fix the "ssh://" protocol to prevent an attack whereby the attacker convinces
a victim to run a "clone" with a dodgy URL and thereby gains access to their
system.
* Provide a checkbox that will temporarily disable all ad-units.
* Improvements to the [/help/www/stat|/stat] page
* Various new hyperlinks to the [/help/www/bloblist|/bloblist]
and [/help/www/bigbloblist|/bigbloblist] pages.
* Correct the [/help/www/doc|/doc] page to support read-only repositories.
* Correct [/help/www/zip|/zip], [/help/www/tarball|/tarball],
[/help/zip|zip], and [/help/tarball|tarball] pages and commands to
honor the versioned manifest setting when outside of an open checkout
directory.
* The admin-log and access-log settings are now on by default for
new repositories.
* Update the built-in SQLite to version 3.21.0.
<h2 id='v2_3'>Changes for Version 2.3 (2017-07-21)</h2>
* Update the built-in SQLite to version 3.20.0 (beta).
* Update internal Unicode character tables, used in regular expression
handling, from version 9.0 to 10.0.
* Show the last-sync-URL on the [/help/www/urllist|/urllist] page.
* Added the "Event Summary" activity report.
[/reports?type=ci&view=lastchng|example]
* Added the "Security Audit" page, available to administrators only
* Added the Last Login time to the user list page, for administrators only
* Added the --numstat option to the [/help/diff|fossil diff] command
* Limit the size of the heap and stack on unix systems, as a proactive
defense against the
[https://www.qualys.com/2017/06/19/stack-clash/stack-clash.txt|Stack Clash]
attack.
* Fix "database locked" warnings caused by "PRAGMA optimize".
* Fix a potential XSS vulnerability on the
[/help/www/help|/help] webpage.
* Documentation updates
<h2 id='v2_2'>Changes for Version 2.2 (2017-04-11)</h2>
* GIT comment tags are now handled by Fossil during import/export.
* Show the content of README files on directory listings.
([/file/skins|example])
* Support for Basic Authentication if enabled (default off).
* Show the hash algorithms used on the
[/help/www/rcvfromlist|/rcvfromlist] page.
* The [/help/www/tarball|/tarball] and [/help/www/zip|/zip] pages
now use the the r= query parameter
to select which check-in to deliver. The uuid= query parameter
is still accepted for backwards compatibility.
* Update the built-in SQLite to version 3.18.0.
* Run "[https://www.sqlite.org/pragma.html#pragma_optimize|PRAGMA optimize]"
on the database connection as it is closing.
<h2 id='v2_1'>Changes for Version 2.1 (2017-03-10)</h2>
* Add support for [./hashpolicy.wiki|hash policies] that control which
of the Hardened-SHA1 or SHA3-256 algorithms is used to name new
artifacts.
* Add the "gshow" and "gcat" subcommands to [/help/stash|fossil stash].
* Add the [/help/www/juvlist|/juvlist] web page and use it to construct
the [/uv/download.html|Download Page] of the Fossil self-hosting website
using Ajax.
<h2 id='v2_0'>Changes for Version 2.0 (2017-03-03)</h2>
* Use the
[https://github.com/cr-marcstevens/sha1collisiondetection|hardened SHA1]
implementation by Marc Stevens and Dan Shumow.
* Add the ability to read and understand
[./fileformat.wiki#names|artifact names] that are based on SHA3-256
rather than SHA1, but do not actually generate any such names.
* Added the [/help/sha3sum|sha3sum] command.
* Update the built-in SQLite to version 3.17.0.
<h2 id='v1_37'>Changes for Version 1.37 (2017-01-16)</h2>
* Add checkbox widgets to various web pages. See [/technote/8d18bf27e9|
this technote] for more information. To get the checkboxes to look as
intended, you must update the CSS in your repository and all clones.
* Add the [/help/all|fossil all ui] command
* Add the [/help/www/file|/file] webpage
* Enhance the [/help/www/brlist|/brlist] webpage to make use of branch colors.
* Add support for the ms=EXACT|LIKE|GLOB|REGEXP query parameter on the
[/help/www/timeline|/timeline] webpage, with associated form widgets.
* Enhance the [/help/changes|changes] and [/help/status|status] commands
with many new filter options so that specific kinds of changes can be
found without having to pipe through grep or sed.
* Enhanced the [/help/sqlite3|fossil sql] command so that it opens the
[./tech_overview.wiki#localdb|checkout database] and the
[./tech_overview.wiki#configdb|configuration database] in addition to the
repository database.
* TH1 enhancements:
<ul><li>Add <nowiki>[unversioned content]</nowiki> command.</li>
<li>Add <nowiki>[unversioned list]</nowiki> command.</li>
<li>Add project_description variable.</li>
</ul>
* Rename crnl-glob [/help/settings|setting] to crlf-glob, but keep
crnl-glob as a compatibility alias.
* Added the --command option to the [/help/diff|diff] command.
* Fix a C99-ism that prevents the 1.36 release from building with MSVC.
* Fix [/help/ticket|ticket set] when using the "+" prefix with fields
from the "ticketchng" table.
* Remove the "fusefs" command from builds that do not have the underlying
support enabled.
* Fixes for incremental git import/export.
* Minor security enhancements to
[./encryptedrepos.wiki|encrypted repositories].
* Update the built-in SQLite to version 3.16.2.
* Update the built-in Zlib to version 1.2.11.
<h2 id='v1_36'>Changes for Version 1.36 (2016-10-24)</h2>
* Add support for [./unvers.wiki|unversioned content],
the [/help/unversioned|fossil unversioned] command and the
[/help/www/uv|/uv] and [/uvlist] web pages.
* The [/uv/download.html|download page] is moved into
[./unvers.wiki|unversioned content] so that the self-hosting Fossil
websites no longer uses any external content.
* Added the "Search" button to the graphical diff generated by
the --tk option on the [/help/diff|diff] command.
* Added the "--checkin VERSION" option to the
[/help/diff|diff] command.
* Various performance enhancements to the [/help/diff|diff] command.
* Update internal Unicode character tables, used in regular expression
handling, from version 8.0 to 9.0.
* Update the built-in SQLite to version 3.15. Fossil now requires
the SQLITE_DBCONFIG_MAINDBNAME interface of SQLite which is only available
in SQLite version 3.15 and later and so Fossil will not work with
earlier SQLite versions.
* Fix [https://www.mail-archive.com/fossil-users@lists.fossil-scm.org/msg23618.html|multi-line timeline bug]
* Enhance the [/help/purge|fossil purge] command.
* New command [/help/shell|fossil shell].
* SQL parameters whose names are all lower-case in Ticket Report SQL
queries are filled in using HTTP query parameter values.
* Added support for [./childprojects.wiki|child projects] that are
able to pull from their parent but not push.
* Added the -nocomplain option to the TH1 "query" command.
* Added support for the chng=GLOBLIST query parameter on the
[/help/www/timeline|/timeline] webpage.
<h2 id='v1_35'>Changes for Version 1.35 (2016-06-14)</h2>
* Enable symlinks by default on all non-Windows platforms.
* Enhance the [/md_rules|Markdown formatting] so that hyperlinks that begin
with "/" are relative to the root of the Fossil repository.
* Rework the [/help/www/setup_ulist|/setup_list page] (the User List page)
to display all users in a click-to-sort table.
* Fix backslash-octal escape on filenames while importing from git
* When markdown documents begin with <h1> HTML elements, use that
header at the document title.
* Added the [/help/www/bigbloblist|/bigbloblist page].
* Enhance the [/help/www/finfo|/finfo page] so that when it is showing
the ancestors of a particular file version, it only shows direct
ancestors and omits changes on branches, thus making it show the same set
of ancestors that are used for [/help/www/blame|/blame].
* Added the --page option to the [/help/ui|fossil ui] command
* Added the [/help/bisect|fossil bisect ui] command
* Enhanced the [/help/diff|fossil diff] command so that it accepts
directory names as arguments and computes diffs on all files contained
within those directories.
* Fix the [/help/add|fossil add] command so that it shows "SKIP" for
files added that were already under management.
* TH1 enhancements:
<ul><li>Add <nowiki>[array exists]</nowiki> command.</li>
<li>Add minimal <nowiki>[array names]</nowiki> command.</li>
<li>Add tcl_platform(engine) and tcl_platform(platform) array
elements.</li>
</ul>
* Get autosetup working with MinGW.
* Fix autosetup detection of zlib in the source tree.
* Added autosetup detection of OpenSSL when it may be present under the
"compat" subdirectory of the source tree.
* Added the [/help/reparent|fossil reparent] command
* Added --include and --exclude options to [/help/tarball|fossil tarball]
and [/help/zip|fossil zip] and the in= and ex= query parameters to the
[/help/www/tarball|/tarball] and [/help/www/zip|/zip] web pages.
* Add support for [./encryptedrepos.wiki|encrypted Fossil repositories].
* If the FOSSIL_PWREADER environment variable is set, then use the program it
names in place of getpass() to read passwords and passphrases
* Option --baseurl now works on Windows.
* Numerous documentation improvements.
* Update the built-in SQLite to version 3.13.0.
<h2 id='v1_34'>Changes for Version 1.34 (2015-11-02)</h2>
* Make the [/help/clean|fossil clean] command undoable for files less
than 10MiB.
* Update internal Unicode character tables, used in regular expression
handling, from version 7.0 to 8.0.
* Add the new [/help/amend|amend] command which is used to modify
tags of a "check-in".
* Fix bug in [/help/import|import] command, handling version 3 of
the svndump format for subversion.
* Add the [/help/all|all cache] command.
* TH1 enhancements:
<ul><li>Add minimal <nowiki>[lsearch]</nowiki> command. Only exact
case-sensitive matching is supported.</li>
<li>Add the <nowiki>[glob_match]</nowiki>, <nowiki>[markdown]</nowiki>,
<nowiki>[dir]</nowiki>, and <nowiki>[encode64]</nowiki> commands.</li>
<li>Add the <nowiki>[tclIsSafe] and [tclMakeSafe]</nowiki> commands to
the Tcl integration subsystem.</li>
<li>Add 'double', 'integer', and 'list' classes to the
<nowiki>[string is]</nowiki> command.</li>
</ul>
* Add the --undo option to the [/help/diff|diff] command.
* Build-in Antirez's "linenoise" command-line editing library for use with
the [/help/sqlite3|fossil sql] command on Unix platforms.
* Add [/help/stash|stash cat] as an alias for the
[/help/stash|stash show] command.
* Automatically pull before [/help/merge|fossil merge] when auto-sync
is enabled.
* Fix --hard option to [/help/mv|fossil mv] and [/help/rm|fossil rm]
to enable them to work properly with certain relative paths.
* Change the mimetype for ".n" and ".man" files to text/plain.
* Display improvements in the [/help/bisect|fossil bisect chart] command.
* Updated the built-in SQLite to version 3.9.1 and activated JSON1 and FTS5
support (both currently unused within Fossil).
<h2 id='v1_33'>Changes for Version 1.33 (2015-05-23)</h2>
* Improved fork detection on [/help/update|fossil update],
[/help/status|fossil status] and related commands.
* Change the default skin to what used to be called "San Francisco Modern".
* Add the [/repo-tabsize] web page
* Add [/help/import|fossil import --svn], for importing a subversion
repository into fossil which was exported using "svnadmin dump".
* Add the "--compress-only" option to [/help/rebuild|fossil rebuild].
* Use a pie chart on the [/reports?view=byuser] page.
* Enhanced [/help/clean|fossil clean --verily] so that it ignores
keep-glob and ignore-glob settings. Added the -x alias for --verily.
* Add the --soft and --hard options to [/help/rm|fossil rm] and
[/help/mv|fossil mv]. The default is still --soft, but that is
now configurable at compile-time or by the mv-rm-files setting.
* Improved ability to [./customgraph.md|customize the timeline graph].
* Improvements to the [/sitemap] page.
* Automatically adjust the [/help/timeline|CLI timeline] to the terminal
width on Linux.
* Added <nowiki>[info commands] and [info vars]</nowiki> commands to TH1.
These commands perform the same function as their Tcl counterparts,
except they do not accept a pattern argument.
* Fix some obscure issues with TH1 expression processing.
* Fix titles in search results for documents that are not wiki, markdown,
or HTML.
* Formally translate TH1 to Tcl return codes and vice-versa, where
necessary, in the Tcl integration subsystem.
* Add [/help/leaves|fossil leaves -multiple], for finding multiple
leaves on the same branch.
* Added the "Blitz" skin option.
* Removed the ".fossil-settings/keep-glob" file. It should not have been
checked into the repository.
* Update the built-in SQLite to version 3.8.10.2.
* Make [/help/open|fossil open] honor ".fossil-settings/allow-symlinks".
* Allow [/help/add|fossil add] to be used on symlinks to nonexistent or
unreadable files in the same way as [/help/addremove|fossil addremove].
* Added fork warning to be issued if sync produced a fork
* Update the [/help/www/info|info] page to report when a file becomes a
symlink. Additionally show the UUID for files whose types have changed
without changing contents or symlink target.
* Have [/help/changes|fossil changes] and
[/help/status|fossil status] report when executable or symlink status
changes on otherwise unmodified files.
* Permit filtering weekday and file [/help/www/reports|reports] by user.
Also ensure the user parameter is preserved when changing types. Add a
field for direct entry of the user name to each applicable report.
* Create parent directories of [/help/settings|empty-dirs] if they don't
already exist.
* Inhibit timeline links to wiki pages that have been deleted.
<h2 id='v1_33'>Changes for Version 1.32 (2015-03-14)</h2>
* When creating a new repository using [/help/init|fossil init], ensure
that the new repository is fully compatible with historical versions of
Fossil by having a valid manifest as RID 1.
* Anti-aliased rendering of arrowheads on timeline graphs.
* Added vi/less-style key bindings to the --tk diff GUI.
* Documentation updates to fix spellings and changes all "checkins" to
"check-ins".
* Add the --repolist option to server commands such as
[/help/server|fossil server] or [/help/http|fossil http].
* Added the "Xekri" skin.
* Enhance the "ln=" query parameter on artifact displays to accept multiple
ranges, separate by spaces (or "+" when URL-encoded).
* Added [/help/forget|fossil forget] as an alias for
[/help/rm|fossil rm].
<h2 id='v1_31'>Changes For Version 1.31 (2015-02-23)</h2>
* Change the auxiliary schema by adding columns MLINK.ISAUX and MLINK.PMID
columns to the schema, to support better drawing of file change graphs.
A [/help/rebuild|fossil rebuild] is recommended but is not required.
so that the new graph drawing logic can work effectively.
* Added [/search|search] over Check-in comments, Documents, Tickets and
Wiki. Disabled by default. The search can be either a full-scan or it
can use an index that is kept up-to-date automatically. The new
/srchsetup web-page and the [/help/fts-config|fts-config] command
were added to help configure the search capability. Expect further
enhancements to the search capabilities in subsequent releases.
* Added form elements to some submenus (in particular the /timeline)
for easier operation.
* Added the --ifneeded option to [/help/rebuild|fossil rebuild].
* Added "override skins" using the "skin:" line of the CGI script or
using the --skin LABEL option on the [/help/server|server],
[/help/ui|ui], or [/help/http|http] commands.
* Embedded html documents that begin with
<doc class="fossil-doc"> are displayed with standard
headers and footers added.
* Allow <div style='...'> markup in [/wiki_rules|wiki].
* Renamed "Events" to "Technical Notes", while updating the technote
display and control pages. Add support for technotes as plain text
or as Markdown.
* Added the [/md_rules] pages containing summary instructions on the
Markdown format.
* Added the --repolist and --nojail options to the various server commands
(ex: [/help/server|fossil server]).
* Added the [/help/all|fossil all add] subcommand to "fossil all".
* Improvements to the /login page. Some hyperlinks to pages that require
"anonymous" privileges are displayed even if the current user is "nobody"
but automatically redirect to /login.
* The [/help/www/doc|/doc] web-page will now try to deliver the file
"404.md" from the top-level directory (if such a file exists) in
place of its built-in 404 text.
* Download of Tarballs and ZIP Archives by user "nobody" is now enabled
by default in new repositories.
* Enhancements to the table sorting controls. More display tables
are now sortable.
* Add IPv6 support to [/help/sync|fossil sync] and
[/help/clone|fossil clone]
* Add more skins such as "San Francisco Modern" and "Eagle".
* During shutdown, check to see if the check-out database (".fslckout")
contains a lot of free space, and if it does, VACUUM it.
* Added the [/mimetype_list] page.
* Added the [/hash-collisions] page.
* Allow the user of Common Table Expressions in the SQL that defaults
ticket reports.
* Break out the components (css, footer, and header) for the
various built-in skins into separate files in the source tree.
<h2 id='v1_30'>Changes For Version 1.30 (2015-01-19)</h2>
* Added the [/help/bundle|fossil bundle] command.
* Added the [/help/purge|fossil purge] command.
* Added the [/help/publish|fossil publish] command.
* Added the [/help/unpublished|fossil unpublished] command.
* Enhance the [/tree] webpage to show the age of each file with the option
to sort by age.
* Enhance the [/brlist] webpage to show additional information about each branch
and to be sortable by clicking on column headers.
* Add support for Docker. Just install docker and type
"sudo docker run -d -p 8080:8080 nijtmans/fossil" to get it running.
* Add the [/help/fusefs|fossil fusefs DIRECTORY] command that mounts a
Fuse Filesystem at the given DIRECTORY and populates it with read-only
copies of all historical check-ins. This only works on systems that
support FuseFS.
* Add the administrative log that records all configuration.
* Added the [/sitemap] webpage.
* Added the [/bloblist] web page.
* Let [/help/new|fossil new] no longer create an initial empty commit
by default. The first commit after checking out an empty repository will
become the initial commit.
* Added the [/help/all|fossil all dbstat] and
[/help/all|fossil all info] commands.
* Update SQLite to version 3.8.8.
* Added the --verily option to the [/help/clean|fossil clean] command.
* Add the "autosync-tries" setting to control the number of autosync attempts
before returning an error.
* Added a compile-time option (--with-miniz) to build using miniz instead
of zlib. Disabled by default.
* Support customization of commands and webpages, including the ability to
add new ones, via the "TH1 hooks" feature. Disabled by default. Enabled
via a compile-time option.
* Add the <nowiki>[checkout], [render], [styleHeader], [styleFooter],
[trace], [getParameter], [setParameter], [artifact], and
[globalState]</nowiki> commands to TH1, primarily for use by TH1 hooks.
* Automatically adjust the width of command-line timeline output according to the
detected width of the terminal.
* Prompt the user to optionally fix invalid UTF-8 at check-in.
* Added a line-number toggle option to the [/help/www/info|/info]
and [/help/www/artifact|/artifact] pages.
* Most commands now issue errors rather than silently ignoring unrecognized
command-line options.
* Use full 40-character SHA1 hashes (instead of abbreviations) in most
internal URLs.
* The "ssh:" sync method on Windows now uses "plink.exe" instead of "ssh" as
the secure-shell client program.
* Prevent a partial clone when the connection is lost.
* Make the distinction between 301 and 302 redirects.
* Allow commits against a closed check-in as long as the commit goes onto
a different branch.
* Improved cache control in the web interface reduces unnecessary requests
for common resources like the page logo and CSS.
* Fix a rare and long-standing sync protocol bug
that would silently prevent the sync from running to completion. Before
this bug-fix it was sometimes necessary to do "fossil sync --verily" to
get two repositories in sync.
* Add the [/finfo?name=src/foci.c|files_of_checkin] virtual table - useful
for ad hoc queries in the [/help/sqlite3|fossil sql] interface,
and also used internally.
* Added the "$secureurl" TH1 variable for use in headers and footers.
* (Internal:) Add the ability to include resources as separate files in the
source tree that are converted into constant byte arrays in the compiled
binary. Use this feature to store the Tk script that implements the --tk
diff option in a separate file for easier editing.
* (Internal:) Implement a system of compile-time checks to help ensure
|
| ︙ | ︙ | |||
1678 1679 1680 1681 1682 1683 1684 |
to the graphical diff display that results
from using the --tk option with the [/help/diff | fossil diff] command.
* The [/reports] page now requires Read ("o") permissions. The "byweek"
report now properly propagates the selected year through the event type
filter links.
* The [/help/info | info command] now shows leaf status of the checkout.
* Add support for tunneling https through a http proxy (Ticket [e854101c4f]).
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 1732 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 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 |
to the graphical diff display that results
from using the --tk option with the [/help/diff | fossil diff] command.
* The [/reports] page now requires Read ("o") permissions. The "byweek"
report now properly propagates the selected year through the event type
filter links.
* The [/help/info | info command] now shows leaf status of the checkout.
* Add support for tunneling https through a http proxy (Ticket [e854101c4f]).
* Add option --empty to the "[/help/open | fossil open]" command.
* Enhanced [/help/www/fileage|the fileage page] to support a glob parameter.
* Add -w|--ignore-all-space and -Z|--ignore-trailing-space options to
[/help/annotate|fossil annotate], [/help/blame|fossil blame],
[/help/diff|fossil (g)diff], [/help/stash|fossil stash diff].
* Add --strip-trailing-cr option to [/help/diff|fossil (g)diff] and
[/help/stash|fossil stash diff].
* Add button "Ignore Whitespace" to /annotate, /blame, /ci, /fdiff
and /vdiff UI pages.
* Enhance [/reports?view=byweekday|/reports] with a "byweekday" view.
* Enhance the [/help/cat|fossil cat] command so that it works outside
of a checkout when using the -R command-line option.
* Use full-length SHA1 hashes, not abbreviations, in most hyperlinks.
* Correctly render the <title> markup on wiki pages in the
[/help/www/artifact|/artifact] webpage.
* Enhance the [/help/whatis|fossil whatis] command to report on attachments
and cluster artifacts. Added the [/help/test-whatis-all] command for
testing purposes.
* Add support for HTTP Basic Authentication on [/help/clone|clone] and
[/help/sync|sync].
* Fix the [/help/stash|stash] so that it remembers added files and re-adds
them when the stash is applied.
* Fix the server so that it avoids writing to the database (and thus avoids
database locking issues) on a
[/help/pull|pull] or [/help/clone|clone].
* Add support for [./server.wiki#loadmgmt|server load management] using both
a cache of expensive pages (the [/help/cache|fossil cache] command)
and by rejecting expensive page requests when the server load average is too
high.
* Add the [/help/praise|fossil praise] command as an alias for
[/help/blame|fossil blame] for subversion compatibility.
* Enhance the [/help/test-diff|fossil test-diff] command with -y or --tk
options so that it shows both filenames above their respective columns in
the side-by-side diff output.
* Issue a warning if a [/help/add|fossil add] command tries to add a file
that matches the ignore-glob.
* Add option -W|--width to "[/help/stash|fossil stash ls]"
and "[/help/leaves|fossil leaves]" commands.
* Enhance support for running as the root user. Now works on Haiku.
* Added the <tt>-empty</tt> option to [/help/new|fossil new], which
causes it to not create an initial empty commit. The first commit after
checking out a repo created this way will become the initial commit.
* Enhance sync operations by committing each round-trip to minimize number
of retransmits when autosync fails. Include option for
[/help/update| fossil update] and [/help/merge| fossil merge] to
continue even if missing content.
* Minor portability fixes for platforms where the char type is unsigned
by default.
<h2>Changes For Version 1.28 (2014-01-27)</h2>
* Enhance [/help/www/reports | /reports] to support event type filtering.
* When cloning a repository, the user name passed via the URL (if any)
is now used as the default local admin user's name.
* Enhance the SSH transport mechanism so that it runs a single instance of
the "fossil" executable on the remote side, obviating the need for a shell
on the remote side. Some users may need to add the "?fossil=/path/to/fossil"
query parameter to "ssh:" URIs if their fossil binary is not in a standard
place.
* Add the "[/help/blame | fossil blame]" command that works just like
"fossil annotate" but uses a different output format that includes the
user who made each change and omits line numbers.
* Add the "Tarball and ZIP-archive Prefix" configuration parameter under
Admin/Configuration.
* Fix CGI processing so that it works on web servers that do not
supply REQUEST_URI.
* Add options --dirsonly, --emptydirs, and --allckouts to the
"[/help/clean | fossil clean]" command.
* Ten-fold performance improvement in large "fossil blame" or
"fossil annotate" commands.
* Add option -W|--width and --offset to "[/help/timeline | fossil timeline]"
and "[/help/finfo | fossil finfo]" commands.
* Option -n|--limit of "[/help/timeline | fossil timeline]" now
specifies the number of entries, just like all other commands which
have the -n|--limit option. The various timeline-related functions
now output "--- ?? limit (??) reached ---" at the end whenever
appropriate. Use "-n 0" if no limit is desired.
* Fix handling of password embedded in Fossil URL.
* New <tt>--once</tt> option to [/help/clone | fossil clone] command
which does not store the URL or password when cloning.
* Modify [/help/ui | fossil ui] to respect "default user" in an open
repository.
* Fossil now hides check-ins that have the "hidden" tag in timeline webpages.
* Enhance <tt>/ci_edit</tt> page to add the "hidden" tag to check-ins.
* Advanced possibilities for commit and ticket change notifications over
http using TH1 scripting.
* Add --sha1sum and --integrate options
to the "[/help/commit | fossil commit]" command.
* Add the "clean" and "extra" subcommands to the
"[/help/all | fossil all]" command
* Add the --whatif option to "[/help/clean|fossil clean]" that works the
same as "--dry-run",
so that the name does not collide with the --dry-run option of "fossil all".
* Provide a configuration option to show dates on the web timeline
as "YYMMMDD HH:MM"
* Add an option to the "stats" webpage that allows an administrator to see
the current repository schema.
* Enhancements to the "[/help/www/vdiff|/vdiff]" webpage for more difference
display options.
* Added the "[/tree?ci=trunk&expand | /tree]" webpage as an alternative
to "/dir" and make it the default way of showing file lists.
* Send gzipped HTTP responses to clients that support it.
<h2>Changes For Version 1.27 (2013-09-11)</h2>
* Enhance the [/help/changes | fossil changes],
[/help/clean | fossil clean], [/help/extras | fossil extras],
[/help/ls | fossil ls] and [/help/status | fossil status] commands
to restrict operation to files and directories named on the command-line.
* New --integrate option to [/help/merge | fossil merge], which
automatically closes the merged branch when committing.
* Renamed <tt>/stats_report</tt> page to [/reports]. Graph width is now
relative, not absolute.
* Added <tt>yw=YYYY-WW</tt> (year-week) filter to timeline to limit the results
to a specific year and calendar week number, e.g. [/timeline?yw=2013-01].
* Updates to SQLite to prevent opening a repository file using file descriptors
1 or 2 on Unix. This fixes a bug under which an assertion failure could
overwrite part of a repository database file, corrupting it.
* Added support for unlimited line lengths in side-by-side diffs.
* New --close option to [/help/commit | fossil commit], which
immediately closes the branch being committed.
* Added <tt>chart</tt> option to [/help/bisect | fossil bisect].
* Improvements to the "human or bot?" determination.
* Reports errors about missing CGI-standard environment variables for HTTP
servers which do not support them.
* Minor improvements to sync support on Windows.
* Added <tt>--scgi</tt> option to [/help/server | fossil server].
* Internal improvements to the sync process.
* The internals of the JSON API are now MIT-licensed, so downstream
users/packagers are no longer affected by the "do no evil" license
clause.
<h2>Changes For Version 1.26 (2013-06-18)</h2>
* The argument to the --port option for the [/help/ui | fossil ui] and
[/help/server | fossil server] commands can take an IP address in addition
to the port number, causing Fossil to bind to just that one IP address.
* After prompting for a password, also ask if that password should be
remembered.
* Performance improvements to the diff engine.
* Fix the side-by-side diff engine to work better with multi-byte Unicode text.
* Color-coding in the web-based annotation (blame) display. Fix the annotation
engine so that it is no longer confused by time-warps.
* The markdown formatter is now available by default and can be used for
tickets, wiki, and embedded documentation.
* Add subcommands "fossil bisect log" and "fossil bisect status" to the
[/help/bisect | fossil bisect] command, as well as other bisect enhancements.
* Enhanced defenses that prevent spiders from using excessive CPU and bandwidth.
* Consistent use of the -n or --dry-run command line options.
* Win32: Fossil now understands Cygwin paths containing one or more of
the characters <nowiki>"*:<>?|</nowiki>. Those are normally forbidden in
win32. This means that the win32 fossil.exe is better usable in a Cygwin
environment. See
[http://cygwin.com/cygwin-ug-net/using-specialnames.html#pathnames-specialchars].
|
| ︙ | ︙ |
Changes to www/chat.md.
| ︙ | ︙ | |||
53 54 55 56 57 58 59 | cases those settings can be ignored. The settings control things like the amount of time that chat messages are retained before being purged from the repository database. ## <a id="usage"></a>Usage For users with appropriate permissions, simply browse to the | | | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | cases those settings can be ignored. The settings control things like the amount of time that chat messages are retained before being purged from the repository database. ## <a id="usage"></a>Usage For users with appropriate permissions, simply browse to the [/chat](/help/www/chat) to start up a chat session. The default skin includes a "Chat" entry on the menu bar on wide screens for people with chat privilege. There is also a "Chat" option on the [Sitemap page](/sitemap), which means that chat will appear as an option under the hamburger menu for many [skins](./customskin.md). Chat messages are subject to [Fossil's full range of Markdown processing](/md_rules). Because chat messages are |
| ︙ | ︙ | |||
120 121 122 123 124 125 126 | show up in that list, nor does the chat infrastructure have a way to track and present those. That list can be used to filter messages on a specific user by tapping on that user's name, tapping a second time to remove the filter. ### <a id="cli"></a> The `fossil chat` Command | | | | | 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | show up in that list, nor does the chat infrastructure have a way to track and present those. That list can be used to filter messages on a specific user by tapping on that user's name, tapping a second time to remove the filter. ### <a id="cli"></a> The `fossil chat` Command Type [fossil chat](/help/chat) from within any open check-out to bring up a chatroom for the project that is in that checkout. The new chat window will attempt to connect to the default sync target for that check-out (the server whose URL is shown by the [fossil remote](/help/remote) command). ### <a id="robots"></a> Chat Messages From Robots The [fossil chat send](/help/chat) can be used by project-specific robots to send notifications to the chatroom. For example, on the [SQLite project](https://sqlite.org/) (for which the Fossil chatroom feature, and indeed all of Fossil, was invented) there are long-running fuzz servers that sometimes run across obscure problems. Whenever this happens, a message is sent to the SQLite developers chatroom alerting them to the problem. |
| ︙ | ︙ | |||
153 154 155 156 157 158 159 | ~~~~ Substitute the appropriate project URL, robot account name and password, message text and file attachment, of course. ### <a id="chat-robot"></a> Chat Messages For Timeline Events | | | 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | ~~~~ Substitute the appropriate project URL, robot account name and password, message text and file attachment, of course. ### <a id="chat-robot"></a> Chat Messages For Timeline Events If the [chat-timeline-user setting](/help/chat-timeline-user) is not an empty string, then any change to the repository that would normally result in a new timeline entry is announced in the chatroom. The announcement appears to come from a user whose name is given by the chat-timeline-user setting. This mechanism is similar to [email notification](./alerts.md) except that the notification is sent via chat instead of via email. |
| ︙ | ︙ | |||
187 188 189 190 191 192 193 | ## Implementation Details *You do not need to understand how Fossil chat works in order to use it. But many developers prefer to know how their tools work. This section is provided for the benefit of those curious developers.* | | | 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 |
## Implementation Details
*You do not need to understand how Fossil chat works in order to use it.
But many developers prefer to know how their tools work.
This section is provided for the benefit of those curious developers.*
The [/chat](/help/www/chat) webpage downloads a small amount of HTML
and a small amount of javascript to run the chat session. The
javascript uses XMLHttpRequest (XHR) to download chat content, post
new content, or delete historical messages. The following web
interfaces are used by the XHR:
* [/chat-poll](/help?name=/chat-poll) →
Downloads chat content as JSON.
|
| ︙ | ︙ | |||
244 245 246 247 248 249 250 | file BLOB -- Text of the uploaded file, or NULL ); ~~~ The CHAT table is not cross-linked with any other tables in the repository schema. An administrator can "DROP TABLE chat;" at any time, without harm (apart from deleting all chat history, of course). The CHAT table | | | | 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | file BLOB -- Text of the uploaded file, or NULL ); ~~~ The CHAT table is not cross-linked with any other tables in the repository schema. An administrator can "DROP TABLE chat;" at any time, without harm (apart from deleting all chat history, of course). The CHAT table is dropped when running [fossil scrub --verily](/help/scrub). On the server-side, message text is stored exactly as entered by the users. The /chat-poll page queries the CHAT table and constructs a JSON reply described in the [/chat-poll documentation](/help/www/chat-poll). The message text is translated into HTML before being converted to JSON so that the text can be safely added to the display using assignment to `innerHTML`. Though `innerHTML` assignment is generally considered unsafe, it is only so with untrusted content from untrusted sources. The chat content goes through sanitization steps which eliminate any potential security vulnerabilities of assigning that content to `innerHTML`. |
Changes to www/childprojects.wiki.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 | The repository is now a separate project, independent from its parent. Clone the new project to the developers as needed. The child project and the parent project will not normally be able to sync with one another, since they are now separate projects with distinct project codes. However, if the "--from-parent-project" command-line option is provided to the | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 | The repository is now a separate project, independent from its parent. Clone the new project to the developers as needed. The child project and the parent project will not normally be able to sync with one another, since they are now separate projects with distinct project codes. However, if the "--from-parent-project" command-line option is provided to the "[/help/pull|fossil pull]" command in the child, and the URL of parent repository is also provided on the command-line, then updates to the parent project that occurred after the child was created will be added to the child repository. Thus, by periodically doing a pull --from-parent-project, the child project is able to stay up to date with all the latest changes in the parent. |
Changes to www/chroot.md.
| ︙ | ︙ | |||
28 29 30 31 32 33 34 |
* any shared libraries your `fossil` binary is linked to, unless you
[configured Fossil with `--static`][bld] to avoid it
Fossil does all of this as one of many layers of defense against
hacks and exploits. You can prevent Fossil from entering the chroot
jail using the <tt>--nojail</tt> option to the
| | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
* any shared libraries your `fossil` binary is linked to, unless you
[configured Fossil with `--static`][bld] to avoid it
Fossil does all of this as one of many layers of defense against
hacks and exploits. You can prevent Fossil from entering the chroot
jail using the <tt>--nojail</tt> option to the
[fossil server command](/help/server)
but you cannot make Fossil hold onto root privileges. Fossil always drops
root privilege before accepting inputs, for security.
[bld]: https://fossil-scm.org/home/doc/trunk/www/build.wiki
[cj]: https://en.wikipedia.org/wiki/Chroot
[fls]: ./loadmgmt.md
|
| ︙ | ︙ |
Changes to www/ckout-workflows.md.
| ︙ | ︙ | |||
133 134 135 136 137 138 139 |
fossil clone https://dev.example.com/repo/my-project
The `/repo` addition is the key: whatever comes after is used as the
repository name. [See the docs][clone] for more details.
[caod]: https://fossil-scm.org/forum/forumpost/3f143cec74
| | | 133 134 135 136 137 138 139 140 141 142 |
fossil clone https://dev.example.com/repo/my-project
The `/repo` addition is the key: whatever comes after is used as the
repository name. [See the docs][clone] for more details.
[caod]: https://fossil-scm.org/forum/forumpost/3f143cec74
[clone]: /help/clone
<div style="height:50em" id="this-space-intentionally-left-blank"></div>
|
Changes to www/co-vs-up.md.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 |
provide a good reason to develop a habit of using `fossil checkout`
instead.
In summary, these are two separate commands; neither is an alias for the
other. They overlap enough that they can be used interchangeably for
some use cases, but `update` is more powerful and more broadly useful.
| | | | 22 23 24 25 26 27 28 29 30 31 |
provide a good reason to develop a habit of using `fossil checkout`
instead.
In summary, these are two separate commands; neither is an alias for the
other. They overlap enough that they can be used interchangeably for
some use cases, but `update` is more powerful and more broadly useful.
[co]: /help/checkout
[cvsmu]: http://web.mit.edu/gnu/doc/html/cvs_7.html#SEC37
[up]: /help/update
|
Changes to www/concepts.wiki.
| ︙ | ︙ | |||
433 434 435 436 437 438 439 | With other configuration management software, setting up a server is a lot of work and normally takes time, patience, and a lot of system knowledge. Fossil is designed to avoid this frustration. Setting up a server with Fossil is ridiculously easy. You have four options: # <b>Stand-alone server.</b> | | | | | | 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
With other configuration management software, setting up a server is
a lot of work and normally takes time, patience, and a lot of system
knowledge. Fossil is designed to avoid this frustration. Setting up
a server with Fossil is ridiculously easy. You have four options:
# <b>Stand-alone server.</b>
Simply run the [/help/server|fossil server] or
[/help/ui|fossil ui] command from the command-line.
<br><br>
# <b>CGI.</b>
Install a 2-line CGI script on a CGI-enabled web-server like Apache.
<br><br>
# <b>SCGI.</b>
Start an SCGI server using the
[/help/server| fossil server --scgi] command for handling
SCGI requests from web-servers like Nginx.
<br><br>
# <b>Inetd or Stunnel.</b>
Configure programs like inetd, xinetd, or stunnel to hand off HTTP requests
directly to the [/help/http|fossil http] command.
See the [./server/ | How To Configure A Fossil Server] document
for details.
<h2>6.0 Review Of Key Concepts</h2>
<ul>
|
| ︙ | ︙ |
Changes to www/containers.md.
| ︙ | ︙ | |||
539 540 541 542 543 544 545 |
[Install]
WantedBy=default.target
I was then able to enable email alert forwarding for select repositories
after configuring them per [the docs](./alerts.md) by saying:
$ systemctl --user daemon-reload
| | < | 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 |
[Install]
WantedBy=default.target
I was then able to enable email alert forwarding for select repositories
after configuring them per [the docs](./alerts.md) by saying:
$ systemctl --user daemon-reload
$ systemctl --user enable --now alert-sender@myproject
Because this is a parameterized script and we’ve set our repository
paths predictably, you can do this for as many repositories as you need
to by passing their names after the “`@`” sign in the commands above.
## 6. <a id="light"></a>Lightweight Alternatives to Docker
|
| ︙ | ︙ |
Changes to www/contribute.wiki.
| ︙ | ︙ | |||
38 39 40 41 42 43 44 | [https://fossil-scm.org/forum | the forum] or email them to <a href="mailto:drh@sqlite.org">drh@sqlite.org</a>. Be sure to describe in detail what the patch does and which version of Fossil it is written against. It's best to make patches against tip-of-trunk rather than against past releases. If your change is more complicated than a patch can properly encode, you | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | [https://fossil-scm.org/forum | the forum] or email them to <a href="mailto:drh@sqlite.org">drh@sqlite.org</a>. Be sure to describe in detail what the patch does and which version of Fossil it is written against. It's best to make patches against tip-of-trunk rather than against past releases. If your change is more complicated than a patch can properly encode, you may submit [/help/bundle | a Fossil bundle] instead. Unlike patches, bundles can contain multiple commits, check-in comments, file renames, file deletions, branching decisions, and more which <tt>patch(1)</tt> files cannot. It's best to make a bundle of a new branch so the change can be integrated, tested, enhanced, and merged down to trunk in a controlled fashion. A contributor agreement is not strictly necessary to submit a patch or bundle, |
| ︙ | ︙ |
Changes to www/customskin.md.
| ︙ | ︙ | |||
21 22 23 24 25 26 27 | * css.txt * details.txt * footer.txt * header.txt * js.txt Try out the built-in skins by using the --skin option on the | | | | 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | * css.txt * details.txt * footer.txt * header.txt * js.txt Try out the built-in skins by using the --skin option on the [fossil ui](/help/ui) or [fossil server](/help/server) commands. ## <a id="sharing"></a>Sharing Skins The skin of a repository is not part of the versioned state and does not "push" or "pull" like checked-in files. The skin is local to the repository. However, skins can be shared between repositories using the [fossil config](/help/configuration) command. The "fossil config push skin" command will send the local skin to a remote repository and the "fossil config pull skin" command will import a skin from a remote repository. The "fossil config export skin FILENAME" will export the skin for a repository into a file FILENAME. This file can then be imported into a different repository using the "fossil config import FILENAME" command. Unlike "push" and "pull", the "export" and "import" commands are able to move skins between |
| ︙ | ︙ | |||
302 303 304 305 306 307 308 | working as desired, the draft skin is "published" and becomes the new live skin that most users see. ### Skin Development Using A Local Text Editor An alternative approach is to copy the five control files for your baseline skin into a temporary working directory (here called | | | 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 | working as desired, the draft skin is "published" and becomes the new live skin that most users see. ### Skin Development Using A Local Text Editor An alternative approach is to copy the five control files for your baseline skin into a temporary working directory (here called "./newskin") and then launch the [fossil ui](/help/ui) command with the "--skin ./newskin" option. If the argument to the --skin option contains a "/" character, then the five control files are read out of the directory named. You can then edit the control files in the ./newskin folder using you favorite text editor, and press "Reload" on your browser to see the effects. |
| ︙ | ︙ | |||
513 514 515 516 517 518 519 |
be copied directly out of one of the subdirectories under skins. If
sources are not easily at hand, then a copy/paste out of the
CSS, footer, and header editing screens under the Admin menu will
work just as well. The important point is that the three files
be named exactly "css.txt", "footer.txt", and "header.txt" and that
they all be in the same directory.
| | | 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 |
be copied directly out of one of the subdirectories under skins. If
sources are not easily at hand, then a copy/paste out of the
CSS, footer, and header editing screens under the Admin menu will
work just as well. The important point is that the three files
be named exactly "css.txt", "footer.txt", and "header.txt" and that
they all be in the same directory.
2. Run the [fossil ui](/help/ui) command with an extra
option "--skin SKINDIR" where SKINDIR is the name of the directory
in which the three txt files were stored in step 1. This will bring
up the Fossil website using the tree files in SKINDIR.
3. Edit the *.txt files in SKINDIR. After making each small change,
press Reload on the web browser to see the effect of that change.
Iterate until the desired look is achieved.
|
| ︙ | ︙ |
Changes to www/defcsp.md.
| ︙ | ︙ | |||
29 30 31 32 33 34 35 | script-src 'self' 'nonce-$nonce'; style-src 'self' 'unsafe-inline'; img-src * data:; </pre> The default is recommended for most installations. However, the site administrators can overwrite this default CSP using the | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
script-src 'self' 'nonce-$nonce';
style-src 'self' 'unsafe-inline';
img-src * data:;
</pre>
The default is recommended for most installations. However,
the site administrators can overwrite this default CSP using the
[default-csp setting](/help/default-csp). For example,
CSP restrictions can be completely disabled by setting the default-csp to:
default-src *;
The following sections detail the maining of the default CSP setting.
### <a id="base"></a> default-src 'self' data:
|
| ︙ | ︙ | |||
284 285 286 287 288 289 290 |
external resources in the backup copies, so that when the main repo
site disappears, so do those files.
Unversioned content is in the middle of the first list above — between
fully-external content and fully in-repo content — because it isn’t
included in a clone unless you give the `--unversioned` flag. If you
then want updates to the unversioned content to be included in syncs,
| | | | | | | 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 326 327 328 329 330 |
external resources in the backup copies, so that when the main repo
site disappears, so do those files.
Unversioned content is in the middle of the first list above — between
fully-external content and fully in-repo content — because it isn’t
included in a clone unless you give the `--unversioned` flag. If you
then want updates to the unversioned content to be included in syncs,
you have to give the same flag to [a `sync` command](/help/sync).
There is no equivalent with other commands such as `up` and `pull`, so
you must then remember to give `fossil uv` commands when necessary to
pull new unversioned content down.
Thus our recommendation that you refer to in-repo resources exclusively.
[du]: /help/www/doc
[fp]: ./forum.wiki
[ru]: /help/www/raw
[spof]: https://en.wikipedia.org/wiki/Single_point_of_failure
[tkt]: ./tickets.wiki
[tn]: ./event.wiki
[tls]: ./server/debian/nginx.md
[uu]: /help/www/uv
[uv]: ./unvers.wiki
[wiki]: ./wikitheory.wiki
## <a id="override"></a>Overriding the Default CSP
If you wish to relax the default CSP’s restrictions or to tighten them
further, there are multiple ways to accomplish that.
The following methods are listed in top-down order to give the simplest
and most straightforward method first. Further methods dig down deeper
into the stack, which is helpful to understand even if you end up using
a higher-level method.
### <a id="cspsetting"></a>The `default-csp` Setting
If the [`default-csp` setting](/help/default-csp) is defined and is
not an empty string, its value is injected into the page using
[TH1](./th1.md) via one or more of the methods below, depending on the
skin you’re using and local configuration.
Changing this setting is the easiest way to set a nonstandard CSP on
your site.
|
| ︙ | ︙ |
Changes to www/delta_format.wiki.
| ︙ | ︙ | |||
24 25 26 27 28 29 30 | contained in the [../src/deltacmd.c|deltacmd.c] source file. SQL functions to create, apply, and analyze deltas are implemented by code in the [../src/deltafunc.c|deltafunc.c] source file. The following command-line tools are available to create and apply deltas and to test the delta logic: | | | | | | | 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 |
contained in the [../src/deltacmd.c|deltacmd.c] source file. SQL functions
to create, apply, and analyze deltas are implemented by code in the
[../src/deltafunc.c|deltafunc.c] source file.
The following command-line tools are available to create and apply
deltas and to test the delta logic:
* [/help/test-delta|fossil test-delta] → Run self-tests of
the delta logic
* [/help/test-delta-create|fossil test-delta-create X Y] → compute
a delta that converts file X into file Y. Output that delta.
* [/help/test-delta-apply|fossil test-delta-apply X D] → apply
delta D to input file X and output the result.
* [/help/test-delta-analyze|fossil test-delta-analyze X Y] → compute
and delta that converts file X into file Y but instead of writing the
delta to output, write performance information about the delta.
When running the [/help/sqlite3|fossil sql] command to get an
interactive SQL session connected to the repository, the following
additional SQL functions are provided:
* <b>delta_create(</b><i>X</i><b>,</b><i>Y</i><b>)</b> →
Compute a data that carries blob X into blob Y and return that delta
as a blob.
|
| ︙ | ︙ |
Changes to www/embeddeddoc.wiki.
| ︙ | ︙ | |||
34 35 36 37 38 39 40 | <pre> <i><baseurl></i><big><b>/doc/</b></big><i><version></i><big><b>/</b></big><i><filename></i> </pre> The <i><baseurl></i> is the main URL used to access the fossil web server. For example, the <i><baseurl></i> for the fossil project itself is [https://fossil-scm.org/home]. | | | | 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 | <pre> <i><baseurl></i><big><b>/doc/</b></big><i><version></i><big><b>/</b></big><i><filename></i> </pre> The <i><baseurl></i> is the main URL used to access the fossil web server. For example, the <i><baseurl></i> for the fossil project itself is [https://fossil-scm.org/home]. If you launch the web server using the "[/help/ui|fossil ui]" command line, then the <i><baseurl></i> is usually <b>http://localhost:8080/</b>. The <i><version></i> is the [./checkin_names.wiki|name of a check-in] that contains the embedded document. This might be a hash prefix for the check-in, or it might be the name of a branch or tag, or it might be a timestamp. See the prior link for more possibilities and examples. The <i id="ckout"><version></i> can also be the special identifier "<b>ckout</b>". The "<b>ckout</b>" keywords means to pull the documentation file from the local source tree on disk, not from the any check-in. The "<b>ckout</b>" keyword only works when you start your server using the "[/help/server|fossil server]" or "[/help?cmd=ui|fossil ui]" commands. The "/doc/ckout" URL is intended to show a preview of the documentation you are currently editing but have not yet checked in. The original designed purpose of the "ckout" feature is to allow the user to preview local changes to documentation before committing the change. This is an important facility, since unlike other document languages like HTML, there is still a lot of variation among rendering |
| ︙ | ︙ |
Changes to www/env-opts.md.
| ︙ | ︙ | |||
270 271 272 273 274 275 276 | `REQUEST_URI`: If defined, included in error log messages. `SCRIPT_NAME`: If defined, included in error log messages. `SSH_CONNECTION`: Informs CGI processing if the remote client is SSH. `SSL_CERT_FILE`, `SSL_CERT_DIR`: Override the [`ssl-ca-location`] | | | 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | `REQUEST_URI`: If defined, included in error log messages. `SCRIPT_NAME`: If defined, included in error log messages. `SSH_CONNECTION`: Informs CGI processing if the remote client is SSH. `SSL_CERT_FILE`, `SSL_CERT_DIR`: Override the [`ssl-ca-location`] (/help/ssl-ca-location) setting. `SQLITE_FORCE_PROXY_LOCKING`: From `sqlite3.c`, 1 means force always use proxy, 0 means never use proxy, and undefined means use proxy for non-local files only. `SQLITE_TMPDIR`: Names the temporary file location for SQLite. When set, this will be used instead of `TMPDIR`. |
| ︙ | ︙ |
Changes to www/event.wiki.
| ︙ | ︙ | |||
105 106 107 108 109 110 111 | Release Notes 2021-07-02 This note describes changes in the Fossil snapshot for ... </verbatim> The <b>-t|--technote</b> option to the <b>export</b> subcommand takes one of three identifiers: <b>DATETIME</b>; <b>TECHNOTE-ID</b>; and <b>TAG</b>. | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | Release Notes 2021-07-02 This note describes changes in the Fossil snapshot for ... </verbatim> The <b>-t|--technote</b> option to the <b>export</b> subcommand takes one of three identifiers: <b>DATETIME</b>; <b>TECHNOTE-ID</b>; and <b>TAG</b>. See the [/help/wiki | wiki help] for specifics. Users must have check-in privileges (permission "i") in order to create or edit technotes. In addition, users must have create-wiki privilege (permission "f") to create new technotes and edit-wiki privilege (permission "k") in order to edit existing technotes. Technote content may be formatted as [/wiki_rules | Fossil wiki], |
| ︙ | ︙ |
Changes to www/fileedit-page.md.
| ︙ | ︙ | |||
11 12 13 14 15 16 17 | browser halfway around the world comes with several obligatory caveats and disclaimers... ## <a id="cap"></a> `/fileedit` Does *Nothing* by Default. In order to "activate" it, a user with [the "setup" permission](./caps/index.md) must set the | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | browser halfway around the world comes with several obligatory caveats and disclaimers... ## <a id="cap"></a> `/fileedit` Does *Nothing* by Default. In order to "activate" it, a user with [the "setup" permission](./caps/index.md) must set the [fileedit-glob](/help/fileedit-glob) repository setting to a comma- or newline-delimited list of globs representing a whitelist of files which may be edited online. Any user with commit access may then edit files matching one of those globs. Certain pages within the UI get an "edit" link added to them when the current user's permissions and the whitelist both permit editing of that file. ## <a id="csrf"></a> CSRF & HTTP Referrer Headers |
| ︙ | ︙ |
Changes to www/forum.wiki.
| ︙ | ︙ | |||
370 371 372 373 374 375 376 | </ol> <h2 id="close-post">Closing Forum Posts</h2> As of version 2.23, the forum interface supports the notion of "closing" posts. By default, only users with the [./caps/index.md|'s' and 'a' capabilities] may close or re-open posts, or reply to closed | | | 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 | </ol> <h2 id="close-post">Closing Forum Posts</h2> As of version 2.23, the forum interface supports the notion of "closing" posts. By default, only users with the [./caps/index.md|'s' and 'a' capabilities] may close or re-open posts, or reply to closed posts. If the [/help/forum-close-policy|forum-close-policy configuration option] is enabled then users with [./caps/index.md|forum-moderator permissions] may also perform those actions. Closing a post has the following implications: * Only authorized users may edit or respond to such posts, recursively |
| ︙ | ︙ |
Changes to www/fossil-v-git.wiki.
| ︙ | ︙ | |||
103 104 105 106 107 108 109 | Git provides file versioning services only, whereas Fossil adds an integrated [./wikitheory.wiki | wiki], [./bugtheory.wiki | ticketing & bug tracking], [./embeddeddoc.wiki | embedded documentation], [./event.wiki | technical notes], a [./forum.wiki | web forum], and a [./chat.md | chat service], all within a single nicely-designed [./customskin.md|skinnable] web | | | 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | Git provides file versioning services only, whereas Fossil adds an integrated [./wikitheory.wiki | wiki], [./bugtheory.wiki | ticketing & bug tracking], [./embeddeddoc.wiki | embedded documentation], [./event.wiki | technical notes], a [./forum.wiki | web forum], and a [./chat.md | chat service], all within a single nicely-designed [./customskin.md|skinnable] web [/help/ui|UI], protected by [./caps/ | a fine-grained role-based access control system]. These additional capabilities are available for Git as 3rd-party add-ons, but with Fossil they are integrated into the design, to the point that it approximates "[https://github.com/ | GitHub]-in-a-box." |
| ︙ | ︙ | |||
128 129 130 131 132 133 134 | You get the same capability with several other Fossil sub-commands as well, such as "<tt>fossil all changes</tt>" to get a list of files that you forgot to commit prior to the end of your working day, across all repos. Whenever Fossil is told to modify the local checkout in some destructive | | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | You get the same capability with several other Fossil sub-commands as well, such as "<tt>fossil all changes</tt>" to get a list of files that you forgot to commit prior to the end of your working day, across all repos. Whenever Fossil is told to modify the local checkout in some destructive way ([/help/rm|fossil rm], [/help/update|fossil update], [/help/revert|fossil revert], etc.) Fossil remembers the prior state and is able to return the check-out directory to that state with a <tt>fossil undo</tt> command. While you cannot undo a commit in Fossil — [#history | on purpose!] — as long as the change remains confined to the local check-out directory only, Fossil makes undo [https://git-scm.com/book/en/v2/Git-Basics-Undoing-Things|easier than in Git]. |
| ︙ | ︙ | |||
441 442 443 444 445 446 447 |
organizations].
* <b>No easy drive-by contributions:</b> Git
[https://www.git-scm.com/docs/git-request-pull|pull requests] offer
a low-friction path to accepting
[https://www.jonobacon.com/2012/07/25/building-strong-community-structural-integrity/|drive-by
contributions]. Fossil's closest equivalents are its unique
| | | | 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 |
organizations].
* <b>No easy drive-by contributions:</b> Git
[https://www.git-scm.com/docs/git-request-pull|pull requests] offer
a low-friction path to accepting
[https://www.jonobacon.com/2012/07/25/building-strong-community-structural-integrity/|drive-by
contributions]. Fossil's closest equivalents are its unique
[/help/bundle|bundle] and [/help/patch|patch] features, which require higher engagement
than firing off a PR.⁷ This difference comes directly from the
initial designed purpose for each tool: the SQLite project doesn't
accept outside contributions from previously-unknown developers, but
the Linux kernel does.
* <b>No rebasing:</b> When your local repo clone syncs changes
up to its parent, those changes are sent exactly as they were
committed locally. [#history|There is no rebasing mechanism in
Fossil, on purpose.]
* <b>Sync over push:</b> Explicit pushes are uncommon in
Fossil-based projects: the default is to rely on
[/help/autosync|autosync mode] instead, in which each commit
syncs immediately to its parent repository. This is a mode so you
can turn it off temporarily when needed, such as when working
offline. Fossil is still a truly distributed version control system;
it's just that its starting default is to assume you're rarely out
of communication with the parent repo.
<br><br>
This is not merely a reflection of modern always-connected computing
|
| ︙ | ︙ | |||
596 597 598 599 600 601 602 | Because Git commingles the repository data with the initial checkout of that repository, the default mode of operation in Git is to stick to that single work/repo tree, even when that's a shortsighted way of working. Fossil doesn't work that way. A Fossil repository is an SQLite database file which is normally stored outside the working checkout directory. You can | | | 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 | Because Git commingles the repository data with the initial checkout of that repository, the default mode of operation in Git is to stick to that single work/repo tree, even when that's a shortsighted way of working. Fossil doesn't work that way. A Fossil repository is an SQLite database file which is normally stored outside the working checkout directory. You can [/help/open | open] a Fossil repository any number of times into any number of working directories. A common usage pattern is to have one working directory per active working branch, so that switching branches is done with a <tt>cd</tt> command rather than by checking out the branches successively in a single working directory. Fossil does allow you to switch branches within a working checkout directory, and this is also often done. It is simply that there is no |
| ︙ | ︙ | |||
680 681 682 683 684 685 686 | including all of the messy errors, dead-ends, experimental branches, and so forth. One might argue that this makes the history of a Fossil project "messy," but another point of view is that this makes the history "accurate." In actual practice, the superior reporting tools available in Fossil mean that this incidental mess is not a factor. | | | 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 | including all of the messy errors, dead-ends, experimental branches, and so forth. One might argue that this makes the history of a Fossil project "messy," but another point of view is that this makes the history "accurate." In actual practice, the superior reporting tools available in Fossil mean that this incidental mess is not a factor. Like Git, Fossil has an [/help/amend|amend command] for modifying prior commits, but unlike in Git, this works not by replacing data in the repository, but by adding a correction record to the repository that affects how later Fossil operations present the corrected data. The old information is still there in the repository, it is just overridden from the amendment point forward. Fossil lacks almost every other history rewriting mechanism listed on |
| ︙ | ︙ | |||
710 711 712 713 714 715 716 | shun certain committed artifacts, but a person cannot force their local shun requests into another repo without having admin-level control over the receiving repo as well. Fossil's shun feature isn't for fixing up everyday bad commits, it's for dealing with extreme situations: public commits of secret material, ticket/wiki/forum spam, law enforcement takedown demands, etc. | | | 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 | shun certain committed artifacts, but a person cannot force their local shun requests into another repo without having admin-level control over the receiving repo as well. Fossil's shun feature isn't for fixing up everyday bad commits, it's for dealing with extreme situations: public commits of secret material, ticket/wiki/forum spam, law enforcement takedown demands, etc. There is also the experimental [/help/purge | <tt>purge</tt> command], which differs from shunning in ways that aren't especially important in the context of this document. At a 30000 foot level, you can think of purging as useful only when you've turned off Fossil's autosync feature and want to pluck artifacts out of its hash tree before they get pushed. In that sense, it's approximately the same as <tt>git rebase -i, drop</tt>. However, given that Fossil defaults to having autosync enabled [#devorg | for good reason], the purge command |
| ︙ | ︙ | |||
819 820 821 822 823 824 825 | much work gets applied — just one check-in or a whole branch — and the merge direction. This is the sort of thing we mean when we point out that Fossil's command interface is simpler than Git's: there are fewer concepts to keep track of in your mental model of Fossil's internal operation. Fossil's implementation of the feature is also simpler to describe. The | | | 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 | much work gets applied — just one check-in or a whole branch — and the merge direction. This is the sort of thing we mean when we point out that Fossil's command interface is simpler than Git's: there are fewer concepts to keep track of in your mental model of Fossil's internal operation. Fossil's implementation of the feature is also simpler to describe. The brief online help for <tt>[/help/merge | fossil merge]</tt> is currently 41 lines long, to which you want to add the 600 lines of [./branching.wiki | the branching document]. The equivalent documentation in Git is the aggregation of the man pages for the above three commands, which is over 1000 lines, much of it mutually redundant. (e.g. Git's <tt>--edit</tt> and <tt>--no-commit</tt> options get described three times, each time differently.) Fossil's documentation is not only more concise, it gives a nice split of brief |
| ︙ | ︙ |
Changes to www/fossil_prompt.sh.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < | < < < < < < < < | | > | | > > | > | < < < | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function set_prompt() {
case `fossil status -b` in
clean)
PS1="\[\e[1;32m\]\u@\h\[\e[0m\]:\[\e[1;36m\]\w\$\[\e[0m\] "
;;
dirty)
PS1="\[\e[1;32m\]\u@\h\[\e[0m\]:\[\e[38;5;202m\]\w\$\[\e[0m\] "
;;
*)
PS1="\[\e[1;32m\]\u@\h\[\e[0m\]:\w\$ "
;;
esac
}
PROMPT_COMMAND=set_prompt
|
Changes to www/gitusers.md.
| ︙ | ︙ | |||
35 36 37 38 39 40 41 | Forum][ffor]. While we do try to explain Fossil-specific terminology inline here as-needed, you may find it helpful to skim [the Fossil glossary][gloss]. It will give you another take on our definitions here, and it may help you to understand some of the other Fossil docs better. | | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | Forum][ffor]. While we do try to explain Fossil-specific terminology inline here as-needed, you may find it helpful to skim [the Fossil glossary][gloss]. It will give you another take on our definitions here, and it may help you to understand some of the other Fossil docs better. [fbis]: /help/bisect [gbis]: https://git-scm.com/docs/git-bisect [ffor]: https://fossil-scm.org/forum [fvg]: ./fossil-v-git.wiki <a id="mwd"></a> ## Repositories and Checkouts Are Distinct |
| ︙ | ︙ | |||
88 89 90 91 92 93 94 | than `fossil checkout`. That said, one of those differences does match up with Git users’ expectations: `fossil checkout` doesn’t pull changes from the remote repository into the local clone as `fossil update` does. We think this is less broadly useful, but that’s the subject of the next section. [ckwf]: ./ckout-workflows.md | | | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | than `fossil checkout`. That said, one of those differences does match up with Git users’ expectations: `fossil checkout` doesn’t pull changes from the remote repository into the local clone as `fossil update` does. We think this is less broadly useful, but that’s the subject of the next section. [ckwf]: ./ckout-workflows.md [co]: /help/checkout #### <a id="pullup"></a> Update vs Pull The closest equivalent to [`git pull`][gpull] is not [`fossil pull`][fpull], but in fact [`fossil up`][up]. |
| ︙ | ︙ | |||
129 130 131 132 133 134 135 | In fact, these are the same operation, so they’re the same command in Fossil. The first form simply allows the `VERSION` to be implicit: the tip of the current branch. We think this is a more sensible command design than `git pull` vs `git checkout`. ([…vs `git checkout` vs `git checkout`!][gcokoan]) | | | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | In fact, these are the same operation, so they’re the same command in Fossil. The first form simply allows the `VERSION` to be implicit: the tip of the current branch. We think this is a more sensible command design than `git pull` vs `git checkout`. ([…vs `git checkout` vs `git checkout`!][gcokoan]) [fpull]: /help/pull [gpull]: https://git-scm.com/docs/git-pull [gcokoan]: https://stevelosh.com/blog/2013/04/git-koans/#s2-one-thing-well #### <a id="close" name="dotfile"></a> Closing a Check-Out The [`fossil close`][close] command dissociates a check-out directory from the |
| ︙ | ︙ | |||
167 168 169 170 171 172 173 | Closing a check-out directory is a rare operation. One use case is that you’re about to delete the directory, so you want Fossil to forget about it for the purposes of commands like [`fossil all`][all]. Even that isn’t necessary, because Fossil will detect that this has happened and forget the working directory for you. | | | 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | Closing a check-out directory is a rare operation. One use case is that you’re about to delete the directory, so you want Fossil to forget about it for the purposes of commands like [`fossil all`][all]. Even that isn’t necessary, because Fossil will detect that this has happened and forget the working directory for you. [all]: /help/all #### <a id="worktree"></a> Git Worktrees There are at least three different ways to get [Fossil-style multiple check-out directories][mcw] with Git. |
| ︙ | ︙ | |||
269 270 271 272 273 274 275 | Git, not to commend this `.fsl`-at-project-root trick to you. A better choice would be `~/museum/home/long-established-project.fossil`, if you’re following [the directory scheme exemplified in the glossary](./glossary.md#repository). That said, it does emphasize an earlier point: Fossil doesn’t care where you put the repo DB file or what you name it. | | | | | | | | | 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 | Git, not to commend this `.fsl`-at-project-root trick to you. A better choice would be `~/museum/home/long-established-project.fossil`, if you’re following [the directory scheme exemplified in the glossary](./glossary.md#repository). That said, it does emphasize an earlier point: Fossil doesn’t care where you put the repo DB file or what you name it. [clone]: /help/clone [close]: /help/close [gloss]: ./glossary.md [open]: /help/open [set]: /help/setting [server]: /help/server [stash]: /help/stash [undo]: /help/undo ## <a id="log"></a> Fossil’s Timeline Is the “Log” Git users often need to use the `git log` command to dig linearly through commit histories due to its [weak data model][wdm], giving [O(n) performance][ocomp]. |
| ︙ | ︙ | |||
414 415 416 417 418 419 420 | Granted, that’s rather obscure, but you you can also choose something intermediate like “`f time desc curr`”, which is reasonably clear. [35pct]: https://www.sqlite.org/fasterthanfs.html [btree]: https://sqlite.org/btreemodule.html [gcn]: https://git-scm.com/docs/gitrevisions | | | | | | | 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 | Granted, that’s rather obscure, but you you can also choose something intermediate like “`f time desc curr`”, which is reasonably clear. [35pct]: https://www.sqlite.org/fasterthanfs.html [btree]: https://sqlite.org/btreemodule.html [gcn]: https://git-scm.com/docs/gitrevisions [infoc]: /help/info [infow]: /help/www/info [ocomp]: https://www.bigocheatsheet.com/ [tlc]: /help/timeline [tlw]: /help/www/timeline [up]: /help/update [wdm]: ./fossil-v-git.wiki#durable ## <a id="dhead"></a> Detached HEAD State The SQL indexes in Fossil which we brought up above have a useful side benefit: you cannot have a [detached HEAD state][gdh] in Fossil, |
| ︙ | ︙ | |||
629 630 631 632 633 634 635 | Fossil doesn’t need to be told what to push or where to push it: it just keeps using the same remote server URL you gave it last until you [tell it to do something different][rem]. It pushes all branches, not just one named local branch. [capt]: ./cap-theorem.md | | | 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 | Fossil doesn’t need to be told what to push or where to push it: it just keeps using the same remote server URL you gave it last until you [tell it to do something different][rem]. It pushes all branches, not just one named local branch. [capt]: ./cap-theorem.md [rem]: /help/remote <a id="autosync"></a> ## Autosync Fossil’s [autosync][wflow] feature, normally enabled, has no equivalent in Git. If you want Fossil to behave like Git, you can turn |
| ︙ | ︙ | |||
939 940 941 942 943 944 945 | diff implementation, bypassing [your local `diff-command` setting][dcset] since the `--numstat` option has no effect when you have an external diff command set. If you leave off the `-v` flag in the second example, the `diffstat` output won’t include info about any newly-added files. | | | 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 | diff implementation, bypassing [your local `diff-command` setting][dcset] since the `--numstat` option has no effect when you have an external diff command set. If you leave off the `-v` flag in the second example, the `diffstat` output won’t include info about any newly-added files. [dcset]: https://fossil-scm.org/home/help/diff-command [dst]: https://invisible-island.net/diffstat/diffstat.html <a id="btnames"></a> ## Branch and Tag Names Fossil has no special restrictions on the names of tags and branches, |
| ︙ | ︙ | |||
962 963 964 965 966 967 968 | release in a project that uses this tagging convention. [The `fossil git export` command][fge] squashes repeated tags down to a single instance to avoid confusing Git, exporting only the newest tag, emulating Fossil’s own ambiguity resolution rule as best it can within Git’s limitations. | | | | 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 | release in a project that uses this tagging convention. [The `fossil git export` command][fge] squashes repeated tags down to a single instance to avoid confusing Git, exporting only the newest tag, emulating Fossil’s own ambiguity resolution rule as best it can within Git’s limitations. [fge]: /help/git [gcrf]: https://git-scm.com/docs/git-check-ref-format <a id="cpickrev"></a> ## Cherry-Picking and Reverting Commits Git’s separate "`git cherry-pick`" and “`git revert`” commands are options to the [`fossil merge` command][merge]: `--cherrypick` and `--backout`, respectively. We view this as sensible, since these are both merge operations, and the two actions differ only in direction. Unlike in Git, the Fossil file format remembers cherrypicks and backouts and can later show them as dashed lines on the graphical timeline. [merge]: /help/merge <a id="mvrm"></a> ## File Moves and Renames Are Soft by Default The "[`fossil mv`][mv]" and "[`fossil rm`][rm]" commands work like they |
| ︙ | ︙ | |||
1003 1004 1005 1006 1007 1008 1009 |
this setting hasn’t been overridden locally.
If you want to keep Fossil’s soft `mv/rm` behavior most of the time, you
can cast it away on a per-command basis:
fossil mv --hard old-name new-name
| | | | 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 |
this setting hasn’t been overridden locally.
If you want to keep Fossil’s soft `mv/rm` behavior most of the time, you
can cast it away on a per-command basis:
fossil mv --hard old-name new-name
[mv]: /help/mv
[rm]: /help/rm
----
## <a id="cvdate" name="cs1"></a> Case Study 1: Checking Out a Version by Date
|
| ︙ | ︙ |
Changes to www/globs.md.
| ︙ | ︙ | |||
240 241 242 243 244 245 246 | than archiving the entire checkin. The commands [`http`][], [`cgi`][], [`server`][], and [`ui`][] that implement or support with web servers provide a mechanism to name some files to serve with static content where a list of glob patterns specifies what content may be served. | | | | | | | | | | | | | | | | | | | | | | 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 | than archiving the entire checkin. The commands [`http`][], [`cgi`][], [`server`][], and [`ui`][] that implement or support with web servers provide a mechanism to name some files to serve with static content where a list of glob patterns specifies what content may be served. [`add`]: /help/add [`addremove`]: /help/addremove [`changes`]: /help/changes [`clean`]: /help/clean [`commit`]: /help/commit [`extras`]: /help/extras [`merge`]: /help/merge [`settings`]: /help/settings [`status`]: /help/status [`touch`]: /help/touch [`unset`]: /help/unset [`tarball`]: /help/tarball [`zip`]: /help/zip [`http`]: /help/http [`cgi`]: /help/cgi [`server`]: /help/server [`ui`]: /help/ui ### Web Pages that Refer to Globs The [`/timeline`][] page supports the query parameter `chng=GLOBLIST` that names a list of glob patterns defining which files to focus the timeline on. It also has the query parameters `t=TAG` and `r=TAG` that names a tag to focus on, which can be configured with `ms=STYLE` to use a glob pattern to match tag names instead of the default exact match or a couple of other comparison styles. The pages [`/tarball`][] and [`/zip`][] generate compressed archives of a specific checkin. They may be further restricted by query parameters that specify glob patterns that name files to include or exclude rather than taking the entire checkin. [`/timeline`]: /help/www/timeline [`/tarball`]: /help/www/tarball [`/zip`]: /help/www/zip ## Platform Quirks Fossil glob patterns are based on the glob pattern feature of POSIX shells. Fossil glob patterns also have a quoting mechanism, discussed [above](#syntax). Because other parts of your operating system may interpret glob |
| ︙ | ︙ | |||
510 511 512 513 514 515 516 |
$ fossil test-echo setting crlf-glob "*"
C:\> echo * | fossil test-echo setting crlf-glob --args -
The [`test-glob`][] command is also handy to test if a string
matches a glob pattern.
| | | | 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 |
$ fossil test-echo setting crlf-glob "*"
C:\> echo * | fossil test-echo setting crlf-glob --args -
The [`test-glob`][] command is also handy to test if a string
matches a glob pattern.
[`test-echo`]: /help/test-echo
[`test-glob`]: /help/test-glob
## Converting `.gitignore` to `ignore-glob`
Many other version control systems handle the specific case of
ignoring certain files differently from Fossil: they have you create
individual "ignore" files in each folder, which specify things ignored
|
| ︙ | ︙ |
Changes to www/glossary.md.
| ︙ | ︙ | |||
88 89 90 91 92 93 94 |
backup utility.
As a counterexample, a project tracking your [Vim] configuration
history is a much better use of Fossil, because it’s all held within
`~/.vim`, and your user has full rights to that subdirectory.
[AIF]: https://docs.asciidoctor.org/asciidoc/latest/directives/include/
| | | | | | | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
backup utility.
As a counterexample, a project tracking your [Vim] configuration
history is a much better use of Fossil, because it’s all held within
`~/.vim`, and your user has full rights to that subdirectory.
[AIF]: https://docs.asciidoctor.org/asciidoc/latest/directives/include/
[IGS]: /help/ignore-glob
[IFRS]: ./image-format-vs-repo-size.md
[tarball]: /help/tarball
[tw]: /help/www/tarball
[Vim]: https://www.vim.org/
[zip]: /help/zip
[zw]: /help/www/zip
## Repository <a id="repository" name="repo"></a>
A single file that contains all historical versions of all files in a
project, which can be [cloned] to other machines and
[synchronized][sync] with them. Jargon: repo.
|
| ︙ | ︙ | |||
193 194 195 196 197 198 199 | box "other/" fit move right 0.1 line dotted right until even with previous line.end move right 0.05 box invis "clones of Fossil itself, SQLite, etc." ljust ``` | | | | | | | | 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 | box "other/" fit move right 0.1 line dotted right until even with previous line.end move right 0.05 box invis "clones of Fossil itself, SQLite, etc." ljust ``` [asdis]: /help/autosync [backup]: ./backup.md [CAP]: ./cap-theorem.md [cloned]: /help/clone [pull]: /help/pull [push]: /help/push [svrcmd]: /help/server [sync]: /help/sync [repository]: #repo [repositories]: #repo ## Version / Revision / Hash / UUID <a id="version" name="hash"></a> |
| ︙ | ︙ | |||
308 309 310 311 312 313 314 | that Fossil will capture only changes to files you’ve [added][add] to the [repository], not to everything in [the check-out directory](#co) at the time of the snapshot. (Thus [the `extras` command][extras].) Contrast a snapshot taken by a virtual machine system or a [snapshotting file system][snfs], which captures changes to everything on the managed storage volume. | | | | | | 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 | that Fossil will capture only changes to files you’ve [added][add] to the [repository], not to everything in [the check-out directory](#co) at the time of the snapshot. (Thus [the `extras` command][extras].) Contrast a snapshot taken by a virtual machine system or a [snapshotting file system][snfs], which captures changes to everything on the managed storage volume. [add]: /help/add [ciname]: ./checkin_names.wiki [extras]: /help/extras [stash]: /help/stash [undo]: /help/undo ## Check-out <a id="check-out" name="co"></a> A set of files extracted from a [repository] that represent a particular [check-in](#ci) of the [project](#project). |
| ︙ | ︙ | |||
363 364 365 366 367 368 369 |
Fossil plugin for Visual Studio Code][fpvsc] defaults to storing the
repo clone within the project directory as a file called `.fsl`, but
this is because VSCode’s version control features assume it’s being
used with Git, where the repository is the `.git` subdirectory
contents. With Fossil, [different check-out workflows][cwork] are
preferred.
| | | | | 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 |
Fossil plugin for Visual Studio Code][fpvsc] defaults to storing the
repo clone within the project directory as a file called `.fsl`, but
this is because VSCode’s version control features assume it’s being
used with Git, where the repository is the `.git` subdirectory
contents. With Fossil, [different check-out workflows][cwork] are
preferred.
[commit]: /help/commit
[cwork]: ./ckout-workflows.md
[h2cflp]: https://www.sqlite.org/howtocorrupt.html#_file_locking_problems
[fpvsc]: https://marketplace.visualstudio.com/items?itemName=koog1000.fossil
[open]: /help/open
[mwd]: ./ckout-workflows.md#mcw
[update]: /help/update
## <a id="docs"></a>Embedded Documentation
Serving as an alternative to Fossil’s built-in [wiki], the [embedded
documentation feature][edoc] stores the same type of marked-up text
files, but under Fossil’s powerful version control features.
|
| ︙ | ︙ |
Changes to www/grep.md.
| ︙ | ︙ | |||
97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
| `\S` | Non-whitespace character: `[^ \t\r\n\v\f]`
There are several restrictions in Fossil `grep` relative to a fully
POSIX compatible regular expression engine. Among them are:
* There is currently no support for POSIX character classes such as
`[:lower:]`.
* Fossil `grep` does not currently attempt to take your operating
system's locale settings into account when doing this match. Since
Fossil has no way to mark a given file as having a particular
encoding, Fossil `grep` assumes the input files are in UTF-8 format.
This means Fossil `grep` will not work correctly if the files in
| > > > > > | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
| `\S` | Non-whitespace character: `[^ \t\r\n\v\f]`
There are several restrictions in Fossil `grep` relative to a fully
POSIX compatible regular expression engine. Among them are:
* There is currently no support for POSIX character classes such as
`[:lower:]`.
* The values of `p` and `q` in the "`{p,q}`" syntax can be no greater
than 999. This is because the NFA that is used for regular expression
matching is proportional in size to the largest p or q value, and hence
allowing arbitrarily large values could result in a DoS attack.
* Fossil `grep` does not currently attempt to take your operating
system's locale settings into account when doing this match. Since
Fossil has no way to mark a given file as having a particular
encoding, Fossil `grep` assumes the input files are in UTF-8 format.
This means Fossil `grep` will not work correctly if the files in
|
| ︙ | ︙ |
Changes to www/hashes.md.
| ︙ | ︙ | |||
143 144 145 146 147 148 149 | [cin]: ./checkin_names.wiki [ctkt]: ./custom_ticket.wiki [hpol]: ./hashpolicy.wiki [japi]: ./json-api/ [jart]: ./json-api/api-artifact.md [jtim]: ./json-api/api-timeline.md | | | | 143 144 145 146 147 148 149 150 151 152 153 154 | [cin]: ./checkin_names.wiki [ctkt]: ./custom_ticket.wiki [hpol]: ./hashpolicy.wiki [japi]: ./json-api/ [jart]: ./json-api/api-artifact.md [jtim]: ./json-api/api-timeline.md [mset]: /help/manifest [th1]: ./th1.md [trss]: /help/www/timeline.rss [tvb]: ./branching.wiki [uuid]: https://en.wikipedia.org/wiki/Universally_unique_identifier |
Changes to www/hashpolicy.wiki.
| ︙ | ︙ | |||
156 157 158 159 160 161 162 | automatically switched to "sha3" mode and thereafter generated only SHA3 hashes. When a new repository is created by cloning, the hash policy is copied from the parent. For new repositories created using the | | | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | automatically switched to "sha3" mode and thereafter generated only SHA3 hashes. When a new repository is created by cloning, the hash policy is copied from the parent. For new repositories created using the [/help/new|fossil new] command the default hash policy is "sha3". That means new repositories will normally hold nothing except SHA3 hashes. The hash policy for new repositories can be overridden using the "--sha1" option to the "fossil new" command. If you are still on Fossil 2.1 through 2.9 but you want Fossil to go ahead and start using SHA3 hashes, change the hash policy to |
| ︙ | ︙ |
Changes to www/hints.wiki.
1 2 3 4 5 6 7 |
<title>Fossil Tips And Usage Hints</title>
A collection of useful hints and tricks in no particular order:
1. Click on two nodes of any timeline graph in succession
to see a diff between the two versions.
| | | | | | | 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 |
<title>Fossil Tips And Usage Hints</title>
A collection of useful hints and tricks in no particular order:
1. Click on two nodes of any timeline graph in succession
to see a diff between the two versions.
2. Add the "--tk" option to "[/help/diff | fossil diff]" commands
to get a pop-up
window containing a complete side-by-side diff. (NB: The pop-up
window is run as a separate Tcl/Tk process, so you will need to
have Tcl/Tk installed on your machine for this to work. Visit
[http://www.activestate.com/activetcl] for a quick download of
Tcl/Tk if you do not already have it on your system.)
3. The "[/help/clean | fossil clean -x]" command is a great
alternative to "make clean". You can use "[/help/clean | fossil clean -f]"
as a slightly safer alternative if the "ignore-glob" setting is
not set. WARNING: make sure you did a "fossil add" for all source-files
you plan to commit, otherwise those files will be deleted without warning.
4. Use "[/help/all | fossil all changes]" to look for any uncommitted
edits in any of your Fossil projects. Use
"[/help/all | fossil all pull]" on your laptop
prior to going off network (for example, on a long plane ride)
to make sure you have all the latest content locally. Then run
"[/help/all|fossil all push]" when you get back online to upload
your changes.
5. To see an entire timeline, type "all" into the "Max:" entry box.
6. You can manually add a "c=CHECKIN" query parameter to the timeline
URL to get a snapshot of what was going on about the time of some
check-in. The "CHECKIN" can be
[./checkin_names.wiki | any valid check-in or version name], including
tags, branch names, and dates. For example, to see what was going
on in the Fossil repository on 2008-01-01, visit
[/timeline?c=2008-01-01].
7. Further to the previous two hints, there are lots of query parameters
that you can add to timeline pages. The available query parameters
are tersely documented [/help/www/timeline | here].
8. You can run "[/help/xdiff | fossil xdiff --tk $file1 $file2]"
to get a Tk pop-up window with side-by-side diffs of two files, even if
neither of the two files is part of any Fossil repository. Note that
this command is "xdiff", not "diff". Change <nobr>--tk</nobr> to
<nobr>--by</nobr> to see the diff in your web browser.
9. On web pages showing the content of a file (for example
[/artifact/c7dd1de9f]) you can manually
|
| ︙ | ︙ | |||
59 60 61 62 63 64 65 |
a mimetype of text/plain, of course.
10. When editing documentation to be checked in as managed files, you can
preview what the documentation will look like by using the special
"ckout" branch name in the "doc" URL while running "fossil ui".
See the [./embeddeddoc.wiki | embedded documentation] for details.
| | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
a mimetype of text/plain, of course.
10. When editing documentation to be checked in as managed files, you can
preview what the documentation will look like by using the special
"ckout" branch name in the "doc" URL while running "fossil ui".
See the [./embeddeddoc.wiki | embedded documentation] for details.
11. Use the "[/help/ui|fossil ui /]" command to bring up a menu of
all of your local Fossil repositories in your web browser.
12. If you have a bunch of Fossil repositories living on a remote machine
that you are able to access using ssh using a command like
"ssh login@remote", then you can bring up a user interface for all
those remote repositories using the command:
"[/help/ui|fossil ui login@remote:/]". This works by tunneling
all HTTP traffic through SSH to the remote machine.
|
Changes to www/index.wiki.
| ︙ | ︙ | |||
82 83 84 85 86 87 88 |
atomic even if interrupted by a power loss or system crash.
Automatic [./selfcheck.wiki | self-checks] verify that all aspects of
the repository are consistent prior to each commit.
8. <b>Free and Open-Source</b> — [../COPYRIGHT-BSD2.txt|2-clause BSD license].
<hr>
| | | | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
atomic even if interrupted by a power loss or system crash.
Automatic [./selfcheck.wiki | self-checks] verify that all aspects of
the repository are consistent prior to each commit.
8. <b>Free and Open-Source</b> — [../COPYRIGHT-BSD2.txt|2-clause BSD license].
<hr>
<h3>Latest Release: 2.27 ([/timeline?c=version-2.27|2025-09-30])</h3>
* [/uv/download.html|Download]
* [./changes.wiki#v2_27|Change Summary]
* [/timeline?p=version-2.27&d=version-2.26&y=ci|Check-ins in version 2.27]
* [/timeline?df=version-2.27&y=ci|Check-ins derived from the 2.27 release]
* [/timeline?t=release|Timeline of all past releases]
<hr>
<h3>Quick Start</h3>
1. [/uv/download.html|Download] or install using a package manager or
[./build.wiki|compile from sources].
|
| ︙ | ︙ |
Changes to www/inout.wiki.
| ︙ | ︙ | |||
25 26 27 28 29 30 31 | interchange formats, and so for compatibility, use of the --git option is recommended. <a id="fx_git"></a> Note that in new imports, Fossil defaults to using the email component of the Git <em>committer</em> (or <em>author</em> if <code>--use-author</code> is passed) to attribute check-ins in the imported repository. Alternatively, the | | | 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | interchange formats, and so for compatibility, use of the --git option is recommended. <a id="fx_git"></a> Note that in new imports, Fossil defaults to using the email component of the Git <em>committer</em> (or <em>author</em> if <code>--use-author</code> is passed) to attribute check-ins in the imported repository. Alternatively, the [/help/import | <code>--attribute</code>] option can be passed to have all commits by a given committer attributed to a desired username. This will create and populate the new <code>fx_git</code> table in the repository database to maintain a record of correspondent usernames and email addresses that can be used in subsequent exports or incremental imports. <h3>Converting Repositories on Windows</h3> |
| ︙ | ︙ |
Changes to www/interwiki.md.
| ︙ | ︙ | |||
62 63 64 65 66 67 68 | <a id="intermap"></a> ## Intermap The intermap defines a mapping from interwiki Tags to full URLs. The Intermap can be viewed and managed using the [fossil interwiki][iwiki] command or the [/intermap][imap] webpage. | | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | <a id="intermap"></a> ## Intermap The intermap defines a mapping from interwiki Tags to full URLs. The Intermap can be viewed and managed using the [fossil interwiki][iwiki] command or the [/intermap][imap] webpage. [iwiki]: /help/interwiki [imap]: /intermap The current intermap for a server is seen on the [/intermap][imap] page (which is read-only for non-Setup users) and at the bottom of the built-in [Fossil Wiki rules](/wiki_rules) and [Markdown rules](/md_rules) documentation pages. |
| ︙ | ︙ | |||
98 99 100 101 102 103 104 |
shows up in the "References" section of the target check-in.
([example](31af805348690958). In other words, Fossil tracks not just
"_source→target_", but it also tracks "_target→source_".
But backtracking does not work for interwiki links, since the Fossil
running on the target has no way of scanning the source text and
hence has no way of knowing that it is a target of a link from the source.
| | | 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
shows up in the "References" section of the target check-in.
([example](31af805348690958). In other words, Fossil tracks not just
"_source→target_", but it also tracks "_target→source_".
But backtracking does not work for interwiki links, since the Fossil
running on the target has no way of scanning the source text and
hence has no way of knowing that it is a target of a link from the source.
[fcfg]: /help/config
## Intermap Storage Details
The intermap is stored in the CONFIG table of the repository database,
in entries with names of the form "<tt>interwiki:</tt><i>Tag</i>". The
value for each such entry is a JSON string that defines the base URL
and extensions for Hash and Wiki links.
## See Also
1. [](https://www.mediawiki.org/wiki/Manual:Interwiki)
2. [](https://duckduckgo.com/?q=interwiki+links&ia=web)
|
Changes to www/javascript.md.
| ︙ | ︙ | |||
261 262 263 264 265 266 267 | [2cbsd]: https://fossil-scm.org/home/doc/trunk/COPYRIGHT-BSD2.txt [ciu]: https://caniuse.com/ [cskin]: ./customskin.md [dcsp]: ./defcsp.md [es2015]: https://ecma-international.org/ecma-262/6.0/ [es6dep]: https://caniuse.com/#feat=es6 | | | | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | [2cbsd]: https://fossil-scm.org/home/doc/trunk/COPYRIGHT-BSD2.txt [ciu]: https://caniuse.com/ [cskin]: ./customskin.md [dcsp]: ./defcsp.md [es2015]: https://ecma-international.org/ecma-262/6.0/ [es6dep]: https://caniuse.com/#feat=es6 [fcgi]: /help/cgi [ffor]: https://fossil-scm.org/forum/ [flic]: /doc/trunk/COPYRIGHT-BSD2.txt [fshome]: /doc/trunk/www/server/ [fslpl]: /doc/trunk/www/fossil-v-git.wiki#portable [fsrc]: https://fossil-scm.org/home/file/src [fsrv]: /help/server [hljs]: https://fossil-scm.org/forum/forumpost/9150bc22ca [ie11x]: https://techcommunity.microsoft.com/t5/microsoft-365-blog/microsoft-365-apps-say-farewell-to-internet-explorer-11-and/ba-p/1591666 [ns]: https://noscript.net/ [pjs]: https://fossil-scm.org/forum/forumpost/1198651c6d [s1]: https://blockmetry.com/blog/javascript-disabled [s2]: https://gds.blog.gov.uk/2013/10/21/how-many-people-are-missing-out-on-javascript-enhancement/ [s3]: https://w3techs.com/technologies/overview/client_side_language/all |
| ︙ | ︙ | |||
388 389 390 391 392 393 394 | ...write, write, write yet more... :w !fossil wiki commit - # vi buffer updates article ``` Extending this concept to other text editors is an exercise left to the reader. | | | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 | ...write, write, write yet more... :w !fossil wiki commit - # vi buffer updates article ``` Extending this concept to other text editors is an exercise left to the reader. [fwc]: /help/wiki [fwt]: ./wikitheory.wiki ### <a id="fedit"></a>The File Editor Fossil’s [optional file editor feature][fedit] works much like [the new wiki editor](#wedit), only on files committed to the |
| ︙ | ︙ | |||
428 429 430 431 432 433 434 | ### <a id="ln"></a>Line Numbering When viewing source files, Fossil offers to show line numbers in some cases. ([Example][mainc].) Toggling them on and off is currently handled in JavaScript, rather than forcing a page-reload via a button click. _Workaround:_ Manually edit the URL to give the “`ln`” query parameter | | | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 | ### <a id="ln"></a>Line Numbering When viewing source files, Fossil offers to show line numbers in some cases. ([Example][mainc].) Toggling them on and off is currently handled in JavaScript, rather than forcing a page-reload via a button click. _Workaround:_ Manually edit the URL to give the “`ln`” query parameter per [the `/file` docs](/help/www/file). _Potential Better Workaround:_ Someone sufficiently interested could [provide a patch][cg] to add a `<noscript>` wrapped HTML button that would reload the page with this parameter included/excluded to implement the toggle via a server round-trip. A related feature is Fossil’s JavaScript-based interactive method |
| ︙ | ︙ |
Changes to www/json-api/intro.md.
| ︙ | ︙ | |||
144 145 146 147 148 149 150 |
- **Binary data:** JSON is a text serialization method, and it takes
up the “payload” area of each HTTP request, so there is no
reasonable way to include binary data in the JSON message without
some sort of codec like Base64, for which there is no provision in
the current JSON API. You will therefore find no JSON API for
committing changes to a file in the repository, for example. Other
| | | 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
- **Binary data:** JSON is a text serialization method, and it takes
up the “payload” area of each HTTP request, so there is no
reasonable way to include binary data in the JSON message without
some sort of codec like Base64, for which there is no provision in
the current JSON API. You will therefore find no JSON API for
committing changes to a file in the repository, for example. Other
Fossil APIs such as [`/raw`](/help/www/raw) or
[`/fileedit`](../fileedit-page.md) may serve you better.
- **64-bit integers:** The JSON standard does not specify integer precision,
because it targets many different platforms, and not all of
them can support more than 32 bits. JavaScript (from which JSON
derives) supports 53 bits of integer precision, which may affect how
a given client-side JSON implementation sends large integers to Fossil’s JSON
API. Our JSON parser can cope with integers larger than 32 bits on input, and it
|
| ︙ | ︙ |
Changes to www/loadmgmt.md.
| ︙ | ︙ | |||
86 87 88 89 90 91 92 | unable to find the load average. This can either be because it is in a `chroot(2)` jail without `/proc` access, or because it is running on a system that does not support `getloadavg()` and so the load-average limiter will not function. [503]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4 | | | 86 87 88 89 90 91 92 93 94 95 96 | unable to find the load average. This can either be because it is in a `chroot(2)` jail without `/proc` access, or because it is running on a system that does not support `getloadavg()` and so the load-average limiter will not function. [503]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.5.4 [hte]: /help/www/test-env [gla]: https://linux.die.net/man/3/getloadavg [lin]: http://www.linode.com [sh]: ./selfhost.wiki |
Changes to www/makefile.wiki.
| ︙ | ︙ | |||
39 40 41 42 43 44 45 | 6. shell.c All three SQLite source files are byte-for-byte copies of files by the same name in the standard [http://www.sqlite.org/amalgamation.html | amalgamation]. The sqlite3.c file implements the database engine. The shell.c file implements the command-line shell, which is accessed in fossil using | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 6. shell.c All three SQLite source files are byte-for-byte copies of files by the same name in the standard [http://www.sqlite.org/amalgamation.html | amalgamation]. The sqlite3.c file implements the database engine. The shell.c file implements the command-line shell, which is accessed in fossil using the [/help/sqlite3 | fossil sql] command. The shell.c command-line shell uses the [https://github.com/antirez/linenoise | linenoise] library to implement line editing. linenoise comprises two source files which were copied from the upstream repository with only very minor portability edits: 7. linenoise.c |
| ︙ | ︙ | |||
70 71 72 73 74 75 76 | byte-array constants that contain various resources such as scripts and images. The builtin_data.h header file is generated from the original resource files using a small program called: 12 [/file/tools/mkbuiltin.c | mkbuiltin.c] Examples of built-in resources include the [/file/src/diff.tcl | diff.tcl] | | | 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | byte-array constants that contain various resources such as scripts and images. The builtin_data.h header file is generated from the original resource files using a small program called: 12 [/file/tools/mkbuiltin.c | mkbuiltin.c] Examples of built-in resources include the [/file/src/diff.tcl | diff.tcl] script used to implement the --tk option to [/help/diff| fossil diff], the [/file/src/markdown.md | markdown documentation], and the various CSS scripts, headers, and footers used to implement built-in skins. New resources files are added to the "extra_files" variable in [/file/tools/makemake.tcl | makemake.tcl]. The src/ subdirectory also contains documentation about the makeheaders preprocessor program: |
| ︙ | ︙ | |||
263 264 265 266 267 268 269 | * -DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 * -DSQLITE_THREADSAFE=0 * -DSQLITE_DEFAULT_FILE_FORMAT=4 * -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1 The first three symbol definitions above are required; the others are merely recommended. Extension loading is omitted as a security measure. The dbstat | | | | 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 | * -DSQLITE_LIKE_DOESNT_MATCH_BLOBS=1 * -DSQLITE_THREADSAFE=0 * -DSQLITE_DEFAULT_FILE_FORMAT=4 * -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1 The first three symbol definitions above are required; the others are merely recommended. Extension loading is omitted as a security measure. The dbstat virtual table is needed for the [/help/www/repo-tabsize|/repo-tabsize] page. FTS4 is needed for the search feature. Fossil is single-threaded so mutexing is disabled in SQLite as a performance enhancement. The SQLITE_ENABLE_EXPLAIN_COMMENTS option makes the output of "EXPLAIN" queries in the "[/help/sqlite3|fossil sql]" command much more readable. When compiling the shell.c source file, these macros are required: * -Dmain=sqlite3_main * -DSQLITE_OMIT_LOAD_EXTENSION=1 The "main()" routine in the shell must be changed into sqlite3_main() |
| ︙ | ︙ |
Changes to www/mdtest/test1.md.
| ︙ | ︙ | |||
29 30 31 32 33 34 35 | The $ROOT prefix on markdown links is superfluous. The same link works without the $ROOT prefix. (Though: the $ROOT prefix is required for HTML documents.) * Timeline: [](/timeline) | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | The $ROOT prefix on markdown links is superfluous. The same link works without the $ROOT prefix. (Though: the $ROOT prefix is required for HTML documents.) * Timeline: [](/timeline) * Help: [](/help/help) * Site-map: [](/sitemap) ## The Magic $CURRENT Document Version Translation In URI text of the form `.../doc/$CURRENT/...` the $CURRENT value is converted to the version number of the document |
| ︙ | ︙ |
Changes to www/mirrorlimitations.md.
1 2 | # Limitations On Git Mirrors | | | 1 2 3 4 5 6 7 8 9 10 | # Limitations On Git Mirrors The "<tt>[fossil git export](/help/git)</tt>" command can be used to mirror a Fossil repository to Git. ([Setup instructions](./mirrortogithub.md) and an [example](https://github.com/drhsqlite/fossil-mirror).) But the export to Git is not perfect. Some information is lost during export due to limitations in Git. This page describes what content of Fossil is not included in an export to Git. |
| ︙ | ︙ |
Changes to www/mirrortogithub.md.
| ︙ | ︙ | |||
128 129 130 131 132 133 134 |
Fossil [UI][ui] browser window or with the [`user contact`][usercmd]
subcommand on the command line. Alternatively, if this repository was
previously imported from Git using the [`--attribute`][attr] option, the
[`fx_git`][fxgit] table will be queried for correspondent email addresses.
Only if neither of these methods produce a user specified email will the
abovementioned generic address be used.
| | | | | 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
Fossil [UI][ui] browser window or with the [`user contact`][usercmd]
subcommand on the command line. Alternatively, if this repository was
previously imported from Git using the [`--attribute`][attr] option, the
[`fx_git`][fxgit] table will be queried for correspondent email addresses.
Only if neither of these methods produce a user specified email will the
abovementioned generic address be used.
[attr]: /help/import
[fxgit]: ./inout.wiki#fx_git
[ui]: /help/ui
[usercmd]: /help/user
## <a id='ex1'></a>Example GitHub Mirrors
As of this writing (2019-03-16) Fossil’s own repository is mirrored
on GitHub at:
|
| ︙ | ︙ |
Changes to www/password.wiki.
| ︙ | ︙ | |||
62 63 64 65 66 67 68 | "developer", "reader", or "nobody" and the authentication protocol for "anonymous" uses one-time captchas not persistent passwords. <h2>Web Interface Authentication</h2> When a user logs into Fossil using the web interface, the login name and password are sent in the clear to the server. For most modern fossil | | | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | "developer", "reader", or "nobody" and the authentication protocol for "anonymous" uses one-time captchas not persistent passwords. <h2>Web Interface Authentication</h2> When a user logs into Fossil using the web interface, the login name and password are sent in the clear to the server. For most modern fossil server setups with [/help/redirect-to-https|redirect-to-https] enabled, this will be protected by the SSL connection over HTTPS so it cannot be easily viewed. The server then hashes the password and compares it against the value stored in USER.PW. If they match, the server sets a cookie on the client to record the login. This cookie contains a large amount of high-quality randomness and is thus intractable to guess. The value of the cookie and the IP address of the client is stored in the USER.COOKIE and USER.IPADDR fields |
| ︙ | ︙ |
Changes to www/patchcmd.md.
1 2 | # The "fossil patch" command | | | 1 2 3 4 5 6 7 8 9 10 | # The "fossil patch" command The "[fossil patch](/help/patch)" command is designed to transfer uncommitted changes from one check-out to another, including transfering those changes to other machines. For example, if you are working on a Windows desktop and you want to test your changes on a Linux server before you commit, you can use the "fossil patch push" command to make a copy of all your changes on the remote Linux server: |
| ︙ | ︙ |
Changes to www/private.wiki.
| ︙ | ︙ | |||
45 46 47 48 49 50 51 | <div class="sidebar"> To avoid generating a missing artifact reference on peer repositories without the private branch, the merge parent is not recorded when merging the private branch into a public branch. As a consequence, the web UI timeline does not draw a merge line from the private merge parent to the public merge child. Moreover, repeat private-to-public | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | <div class="sidebar"> To avoid generating a missing artifact reference on peer repositories without the private branch, the merge parent is not recorded when merging the private branch into a public branch. As a consequence, the web UI timeline does not draw a merge line from the private merge parent to the public merge child. Moreover, repeat private-to-public merge operations (without the [/help/merge | --force option]) with files added on the private branch may only work once, but later abort with "WARNING: no common ancestor for FILE", as the parent-child relationship is not recorded. (See the [/doc/trunk/www/branching.wiki | Branching, Forking, Merging, and Tagging] document for more information.) </div> The <code>--integrate</code> option of <code>fossil merge</code> (to close |
| ︙ | ︙ |
Changes to www/quickstart.wiki.
| ︙ | ︙ | |||
252 253 254 255 256 257 258 | the repository, being what you get when you "fossil open" a repository without specifying a version, populating the working directory. To see the most recent changes made to the repository by other users, use "fossil timeline" to find out the most recent commit, and then "fossil diff" between that commit and the current tree: | | | | | 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 |
the repository, being what you get when you "fossil open" a repository
without specifying a version, populating the working directory.
To see the most recent changes made to the repository by other users, use "fossil timeline" to
find out the most recent commit, and then "fossil diff" between that commit and the
current tree:
<pre><b><verbatim>fossil timeline
=== 2021-03-28 ===
03:18:54 [ad75dfa4a0] *CURRENT* Added details to frobnicate command (user: user-one tags: trunk)
=== 2021-03-27 ===
23:58:05 [ab975c6632] Update README.md. (user: user-two tags: trunk)
⋮
fossil diff --from current --to ab975c6632
Index: frobnicate.c
============================================================
--- frobnicate.c
+++ frobnicate.c
@@ -1,10 +1,11 @@
+/* made a change to the source file */
# Original text
</verbatim></b></pre>
"current" is an alias for the checkout version, so the command
"fossil diff --from ad75dfa4a0 --to ab975c6632" gives identical results.
To commit your changes to a local-only repository:
<pre><b>fossil commit</b> <i>(... Fossil will start your editor, if defined)</i><b>
|
| ︙ | ︙ | |||
294 295 296 297 298 299 300 | specified Fossil uses line-editing in the terminal. To commit your changes to a repository that was cloned from a remote repository, you give the same command, but the results are different. Fossil defaults to [./concepts.wiki#workflow|autosync] mode, a single-stage commit that sends all changes committed to the local repository immediately on to the remote parent repository. This only | | | 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | specified Fossil uses line-editing in the terminal. To commit your changes to a repository that was cloned from a remote repository, you give the same command, but the results are different. Fossil defaults to [./concepts.wiki#workflow|autosync] mode, a single-stage commit that sends all changes committed to the local repository immediately on to the remote parent repository. This only works if you have write permission to the remote repository. <h2 id="naming">Naming of Files, Checkins, and Branches</h2> Fossil deals with information artifacts. This Quickstart document only deals with files and collections of files, but be aware there are also tickets, wiki pages and more. Every artifact in Fossil has a universally-unique hash id, and may also have a human-readable name. |
| ︙ | ︙ | |||
361 362 363 364 365 366 367 | (Contrast the [#server | many <i>other</i> ways] of setting Fossil up as an HTTP server, where the repo DB is on the other side of the HTTP server wall, inaccessible by all means other than Fossil's own mediation. For this reason, the "localhost bypasses access control" policy does <i>not</i> apply to these other interfaces. That is a very good thing, since without this difference in policy, it would be unsafe | | | 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 | (Contrast the [#server | many <i>other</i> ways] of setting Fossil up as an HTTP server, where the repo DB is on the other side of the HTTP server wall, inaccessible by all means other than Fossil's own mediation. For this reason, the "localhost bypasses access control" policy does <i>not</i> apply to these other interfaces. That is a very good thing, since without this difference in policy, it would be unsafe to bind a [/help/server | <b>fossil server</b>] instance to localhost on a high-numbered port and then reverse-proxy it out to the world via HTTPS, a practice this author does engage in, with confidence.) Once you are finished configuring Fossil, you may safely Control-C out of the <b>fossil ui</b> command to shut down this privileged built-in web server. Moreover, you may by grace of SQLite do this <i>at any time</i>: all changes are either committed durably to the repo DB or |
| ︙ | ︙ |
Changes to www/rebaseharm.md.
| ︙ | ︙ | |||
371 372 373 374 375 376 377 | developers to make intuitive leaps that the original developer was unable to make. In other words, you are asking your future maintenance developers to be smarter than the original developers! That's a beautiful wish, but there's a sharp limit to how far you can carry it. Eventually you hit the limits of human brilliance. When the operation of some bit of code is not obvious, both Fossil and | | | 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 | developers to make intuitive leaps that the original developer was unable to make. In other words, you are asking your future maintenance developers to be smarter than the original developers! That's a beautiful wish, but there's a sharp limit to how far you can carry it. Eventually you hit the limits of human brilliance. When the operation of some bit of code is not obvious, both Fossil and Git let you run a [`blame`](/help/blame) on the code file to get information about each line of code, and from that which check-in last touched a given line of code. If you squash the check-ins on a branch down to a single check-in, you throw away the information leading up to that finished form. Fossil not only preserves the check-ins surrounding the one that included the line of code you're trying to understand, its [superior data model][sdm] lets you see the surrounding check-ins in both directions; not only what lead up to it, but what came next. Git |
| ︙ | ︙ |
Changes to www/selfhost.wiki.
| ︙ | ︙ | |||
70 71 72 73 74 75 76 | /usr/local/bin/fossil all sync -u </pre> Server (2) is a <a href="http://www.linode.com/">Linode</a> located in Newark, NJ and set up just like the canonical server (1) with the addition of a cron job for synchronization. The same cron job also runs the | | | 70 71 72 73 74 75 76 77 78 | /usr/local/bin/fossil all sync -u </pre> Server (2) is a <a href="http://www.linode.com/">Linode</a> located in Newark, NJ and set up just like the canonical server (1) with the addition of a cron job for synchronization. The same cron job also runs the [/help/git|fossil git export] command after each sync in order to [./mirrortogithub.md#ex1|mirror all changes to GitHub]. |
Changes to www/server/index.html.
| ︙ | ︙ | |||
36 37 38 39 40 41 42 | Fossil server, with links to more detailed instructions specific to particular systems, should you want extra help.</p> <h2 id="prep">Repository Prep</h2> <p>Prior to serving a Fossil repository to others, consider running <a | | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | Fossil server, with links to more detailed instructions specific to particular systems, should you want extra help.</p> <h2 id="prep">Repository Prep</h2> <p>Prior to serving a Fossil repository to others, consider running <a href="$ROOT/help/ui"><tt>fossil ui</tt></a> locally and taking these minimum recommended preparation steps:</p> <ol> <li><p>Fossil creates only one user in a <a href="$ROOT/help/new">new repository</a> and gives it the <a href="../caps/admin-v-setup.md#apsu">all-powerful Setup capability</a>. The 10-digit random password generated for that user is fairly strong against remote attack, even without explicit password guess rate limiting, but because that user has so much power, you may want to give it a much stronger password under Admin → Users.</a></li> <li><p>Run the Admin → Security-Audit tool to verify that other |
| ︙ | ︙ | |||
93 94 95 96 97 98 99 | <h3 id="cgi">CGI</h3> <p>Most ordinary web servers can <a href="any/cgi.md">run Fossil as a CGI script</a>. This method is known to work with Apache, <tt>lighttpd</tt>, and <a href="any/althttpd.md"><tt>althttpd</tt></a>. The Fossil server | | | | | | 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 | <h3 id="cgi">CGI</h3> <p>Most ordinary web servers can <a href="any/cgi.md">run Fossil as a CGI script</a>. This method is known to work with Apache, <tt>lighttpd</tt>, and <a href="any/althttpd.md"><tt>althttpd</tt></a>. The Fossil server administrator places a <a href="$ROOT/help/cgi">short CGI script</a> in the web server's document hierarchy and when a client requests the URL that corresponds to that script, Fossil runs and generates the response.</p> <p>CGI is a good choice for merging Fossil into an existing web site, particularly on hosts that have CGI set up and working. The Fossil <a href="../selfhost.wiki">self-hosting repositories</a> are implemented with CGI underneath <tt>althttpd</tt>.</p> <h3 id="slist">Socket Listener</h3> <p>Socket listener daemons such as <a id="inetd" href="any/inetd.md"><tt>inetd</tt></a>, <a id="xinetd" href="any/xinetd.md"><tt>xinetd</tt></a>, <a id="stunnel" href="any/stunnel.md"><tt>stunnel</tt></a>, <a href="macos/service.md"><tt>launchd</tt></a>, and <a href="debian/service.md"><tt>systemd</tt></a> can be configured to invoke the the <a href="$ROOT/help/http"><tt>fossil http</tt></a> command to handle each incoming HTTP request. The "<tt>fossil http</tt>" command reads the HTTP request off of standard input, computes an appropriate reply, and writes the reply on standard output. There is a separate invocation of the "<tt>fossil http</tt>" command for each HTTP request. The socket listener daemon takes care of relaying content to and from the client, and (in the case of <a href="any/stunnel.md">stunnel</a>) handling TLS decryption and encryption. <h3 id="standalone">Stand-alone HTTP Server</h3> <p>This is the <a href="any/none.md">easiest method</a>. A stand-alone server uses the <a href="$ROOT/help/server"><tt>fossil server</tt></a> command to run a process that listens for incoming HTTP requests on a socket and then dispatches a copy of itself to deal with each incoming request. You can expose Fossil directly to the clients in this way or you can interpose a <a href="https://en.wikipedia.org/wiki/Reverse_proxy">reverse proxy</a> layer between the clients and Fossil.</p> <h3 id="scgi">SCGI</h3> <p>The Fossil standalone server can also handle <a href="any/scgi.md">SCGI</a>. When the <a href="$ROOT/help/server"><tt>fossil server</tt></a> command is run with the extra <tt>--scgi</tt> option, it listens for incoming SCGI requests rather than HTTP requests. This allows Fossil to respond to requests from web servers <a href="debian/nginx.md">such as nginx</a> that don't support CGI. SCGI is a simpler protocol to proxy than HTTP, since the HTTP doesn't have to be re-interpreted in terms of the proxy's existing HTTP implementation, but it's more complex to set up because you also have to set up an SCGI-to-HTTP proxy for it. It is |
| ︙ | ︙ | |||
285 286 287 288 289 290 291 | <li><p>If the repository includes <a href="../embeddeddoc.wiki">embedded documentation</a>, consider activating the search feature (Admin → Search) so that visitors can do full-text search on your documentation.</p></li> <li><p>Now that others can be making changes to the repository, consider monitoring them via <a href="../alerts.md">email alerts</a> | | | 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 | <li><p>If the repository includes <a href="../embeddeddoc.wiki">embedded documentation</a>, consider activating the search feature (Admin → Search) so that visitors can do full-text search on your documentation.</p></li> <li><p>Now that others can be making changes to the repository, consider monitoring them via <a href="../alerts.md">email alerts</a> or the <a href="$ROOT/help/www/timeline.rss">timeline RSS feed</a>.</p></li> <li><p>Turn on the various logging features.</p></li> </ol> <p>Reload the Admin → Security-Audit page occasionally during this process to double check that you have not mistakenly configured the |
| ︙ | ︙ |
Changes to www/server/windows/service.md.
| ︙ | ︙ | |||
60 61 62 63 64 65 66 | your system by accessing the `/test-env` webpage. Excluding this subdirectory will avoid certain rare failures where the fossil.exe process is unable to use the directory normally during a scan. ### <a id='PowerShell'></a>Advanced service installation using PowerShell As great as `fossil winsrv` is, it does not have one to one reflection of all of | | | | 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 | your system by accessing the `/test-env` webpage. Excluding this subdirectory will avoid certain rare failures where the fossil.exe process is unable to use the directory normally during a scan. ### <a id='PowerShell'></a>Advanced service installation using PowerShell As great as `fossil winsrv` is, it does not have one to one reflection of all of the `fossil server` [options](/help/server). When you need to use some of the more advanced options, such as `--https`, `--skin`, or `--extroot`, you will need to use PowerShell to configure and install the Windows service. PowerShell provides the [New-Service](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/new-service?view=powershell-5.1) command, which we can use to install and configure Fossil as a service. The below should all be entered as a single line in an Administrative PowerShell console. ```PowerShell New-Service -Name fossil -DisplayName fossil -BinaryPathName '"C:\Program Files\FossilSCM\fossil.exe" server --port 8080 --repolist "D:/Path/to/Repos"' -StartupType Automatic ``` Please note the use of forward slashes in the repolist path passed to Fossil. Windows will accept either back slashes or forward slashes in path names, but Fossil has a preference for forward slashes. The use of `--repolist` will make this a multiple repository server. If you want to serve only a single repository, then leave off the `--repolist` parameter and provide the full path to the proper repository file. Other options are listed in the [fossil server](/help/server) documentation. The service will be installed by default to use the Local Service account. Since Fossil only needs access to local files, this is fine and causes no issues. The service will not be running once installed. You will need to start it to proceed (the `-StartupType Automatic` parameter to `New-Service` will result in the service auto-starting on boot). This can be done by entering |
| ︙ | ︙ |
Changes to www/serverext.wiki.
| ︙ | ︙ | |||
47 48 49 50 51 52 53 |
Files in the DOCUMENT_ROOT are accessed via URLs like this:
<pre>
https://example-project.org/ext/<i>FILENAME</i>
</pre>
In other words, access files in DOCUMENT_ROOT by appending the filename
| | | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
Files in the DOCUMENT_ROOT are accessed via URLs like this:
<pre>
https://example-project.org/ext/<i>FILENAME</i>
</pre>
In other words, access files in DOCUMENT_ROOT by appending the filename
relative to DOCUMENT_ROOT to the [/help/www/ext|/ext]
page of the Fossil server.
* Files that are readable but not executable are returned as static
content.
* Files that are executable are run as CGI.
|
| ︙ | ︙ | |||
122 123 124 125 126 127 128 | the user upload a file using a form, and then displays that file in the reply. There is a link on the page that causes the fileup1 script to return a copy of its own source-code, so you can see how it works. <h3>2.3 Example #3</h3> For Fossil versions dated 2025-03-23 and later, the "--extpage FILENAME" | | | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | the user upload a file using a form, and then displays that file in the reply. There is a link on the page that causes the fileup1 script to return a copy of its own source-code, so you can see how it works. <h3>2.3 Example #3</h3> For Fossil versions dated 2025-03-23 and later, the "--extpage FILENAME" option to the [/help/ui|fossil ui] command is a short cut that treats FILENAME as a CGI extension. When the ui command starts up a new web browser pages, it points that page to the FILENAME extension. So if FILENAME is a static content file (such as an HTML file or [/md_rules|Markdown] or [/wiki_rules|Wiki] document), then the rendered content of the file is displayed. Meanwhile, the user can be editing the source text for that document in a separate window, and periodically pressing "Reload" on the web browser to instantly view the |
| ︙ | ︙ | |||
336 337 338 339 340 341 342 343 344 345 346 347 348 349 | in the same way as a traditional web-server. CGI programs that want to restrict access can examine the FOSSIL_CAPABILITIES and/or FOSSIL_USER environment variables. In other words, access control is the responsibility of the individual extension programs. <h2>7.0 Trouble-Shooting Hints</h2> Remember that the /ext will return any file in the extroot directory hierarchy as static content if the file is readable but not executable. When initially setting up the /ext mechanism, it is sometimes helpful to verify that you are able to receive static content prior to starting | > > > > > > > | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 | in the same way as a traditional web-server. CGI programs that want to restrict access can examine the FOSSIL_CAPABILITIES and/or FOSSIL_USER environment variables. In other words, access control is the responsibility of the individual extension programs. <h3>6.1 Restricting Robot Access To Extensions</h3> If the "ext" tag is found in the [/help/robot-restrict|robot-restrict setting] then clients are tested to see if they are robots before granting access to any extension. If the "ext" tag is omitted but a tag of the form "ext/PATH" is found on the robot-restrict setting, then robots are restricted from the particular extension at PATH. <h2>7.0 Trouble-Shooting Hints</h2> Remember that the /ext will return any file in the extroot directory hierarchy as static content if the file is readable but not executable. When initially setting up the /ext mechanism, it is sometimes helpful to verify that you are able to receive static content prior to starting |
| ︙ | ︙ |
Changes to www/ssl-server.md.
1 2 3 4 5 | # SSL/TLS Server Mode ## History Fossil has supported [client-side SSL/TLS][0] since [2010][1]. This means | | | | | | | 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 | # SSL/TLS Server Mode ## History Fossil has supported [client-side SSL/TLS][0] since [2010][1]. This means that commands like "[fossil sync](/help/sync)" could use SSL/TLS when contacting a server. But on the server side, commands like "[fossil server](/help/server)" operated in clear-text only. To implement an encrypted server, you had to put Fossil behind a web server or reverse proxy that handled the SSL/TLS decryption/encryption and passed cleartext down to Fossil. [0]: ./ssl.wiki [1]: /timeline?c=b05cb4a0e15d0712&y=ci&n=13 Beginning in [late December 2021](/timeline?c=f6263bb64195b07f&y=a&n=13), Fossil servers are now able to converse directly over TLS. Commands like * "[fossil server](/help/server)" * "[fossil ui](/help/ui)", and * "[fossil http](/help/http)" may now handle the encryption natively when suitably configured, without requiring a third-party proxy layer. ## <a id="usage"></a>Usage To put any of the Fossil server commands into SSL/TLS mode, simply |
| ︙ | ︙ | |||
133 134 135 136 137 138 139 | that if you have a PEM-formatted private key and a separate PEM-formatted certificate, you can concatenate the two into a single file, and the individual components will still be easily accessible. ### <a id="cat"></a>Separate or Concatenated? Given a single concatenated file that holds both your private key and your | | | 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
that if you have a PEM-formatted private key and a separate PEM-formatted
certificate, you can concatenate the two into a single file, and the
individual components will still be easily accessible.
### <a id="cat"></a>Separate or Concatenated?
Given a single concatenated file that holds both your private key and your
cert, you can hand it off to the "[fossil server](/help/server)"
command using the `--cert` option, like this:
fossil server --port 443 --cert mycert.pem /home/www/myproject.fossil
The command above is sufficient to run a fully-encrypted web site for
the "myproject.fossil" Fossil repository. This command must be run as
root, since it wants to listen on TCP port 443, and only root processes are
|
| ︙ | ︙ | |||
255 256 257 258 259 260 261 |
6. It then deletes the secret one-time-use token it used to prove
domain control. ACME’s design precludes replay attacks.
In order for all of this to happen, certbot needs to be able to create
a subdirectory named ".well-known", within a directory you specify,
then populate that subdirectory with a token file of some kind. To support
| | | | 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 |
6. It then deletes the secret one-time-use token it used to prove
domain control. ACME’s design precludes replay attacks.
In order for all of this to happen, certbot needs to be able to create
a subdirectory named ".well-known", within a directory you specify,
then populate that subdirectory with a token file of some kind. To support
this, the "[fossil server](/help/server)" and
"[fossil http](/help/http)" commands have the --acme option.
When specified, Fossil sees a URL where the path
begins with ".well-known", then instead of doing its normal processing, it
looks for a file with that pathname and returns it to the client. If
the "server" or "http" command is referencing a single Fossil repository,
then the ".well-known" sub-directory should be in the same directory as
the repository file. If the "server" or "http" command are run against
|
| ︙ | ︙ |
Changes to www/sync.wiki.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 | employed that usually reduce the number of hashes that need to be shared to a few dozen. Each repository also has local state. The local state determines the web-page formatting preferences, authorized users, ticket formats, and similar information that varies from one repository to another. The local state is not usually transferred during a sync. Except, | | | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | employed that usually reduce the number of hashes that need to be shared to a few dozen. Each repository also has local state. The local state determines the web-page formatting preferences, authorized users, ticket formats, and similar information that varies from one repository to another. The local state is not usually transferred during a sync. Except, some local state is transferred during a [/help/clone|clone] in order to initialize the local state of the new repository. Also, an administrator can sync local state using the [/help/configuration|config push] and [/help/configuration|config pull] commands. <h3 id="crdt">1.1 Conflict-Free Replicated Datatypes</h3> The "bag of artifacts" data model used by Fossil is apparently an implementation of a particular [https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type|Conflict-Free |
| ︙ | ︙ | |||
54 55 56 57 58 59 60 | All communication between client and server is via HTTP requests. The server is listening for incoming HTTP requests. The client issues one or more HTTP requests and receives replies for each request. The server might be running as an independent server | | | | | | 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 | All communication between client and server is via HTTP requests. The server is listening for incoming HTTP requests. The client issues one or more HTTP requests and receives replies for each request. The server might be running as an independent server using the [/help/server|"fossil server" command], or it might be launched from inetd or xinetd using the [/help/http|"fossil http" command]. Or the server might be [./server/any/cgi.md|launched from CGI] or from [./server/any/scgi.md|SCGI]. (See "[./server/|How To Configure A Fossil Server]" for details.) The specifics of how the server listens for incoming HTTP requests is immaterial to this protocol. The important point is that the server is listening for requests and the client is the issuer of the requests. A single [/help/push|push], [/help/pull|pull], or [/help?cmd=sync|sync] might involve multiple HTTP requests. The client maintains state between all requests. But on the server side, each request is independent. The server does not preserve any information about the client from one request to the next. Note: Throughout this article, we use the terms "server" and "client" to represent the listener and initiator of the interaction, respectively. |
| ︙ | ︙ |
Changes to www/tech_overview.wiki.
| ︙ | ︙ | |||
160 161 162 163 164 165 166 | The second case is the one that usually determines the name. Note that the FOSSIL_HOME environment variable can always be set to determine the location of the configuration database. Note also that the configuration database file itself is called ".fossil" or "fossil.db" on unix but "_fossil" on windows. | | | 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | The second case is the one that usually determines the name. Note that the FOSSIL_HOME environment variable can always be set to determine the location of the configuration database. Note also that the configuration database file itself is called ".fossil" or "fossil.db" on unix but "_fossil" on windows. The [/help/info|fossil info] command will show the location of the configuration database on a line that starts with "config-db:". <h3>2.2 Repository Databases</h3> The repository database is the file that is commonly referred to as "the repository". This is because the repository database contains, among other things, the complete revision, ticket, and wiki history for |
| ︙ | ︙ |
Changes to www/th1.md.
| ︙ | ︙ | |||
129 130 131 132 133 134 135 | Beginning with Fossil version 2.26 (circa 2025), TH1 distinguishes between "tainted" and "untainted" strings. Tainted strings are strings that are derived from user inputs that might contain text that is designed to subvert the script. Untainted strings are known to come from secure sources and are assumed to contain no malicious content. Beginning with Fossil version 2.26, and depending on the value of the | | | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | Beginning with Fossil version 2.26 (circa 2025), TH1 distinguishes between "tainted" and "untainted" strings. Tainted strings are strings that are derived from user inputs that might contain text that is designed to subvert the script. Untainted strings are known to come from secure sources and are assumed to contain no malicious content. Beginning with Fossil version 2.26, and depending on the value of the [vuln-report setting](/help/vuln-report), TH1 will prevent tainted strings from being used in ways that might lead to XSS or SQL-injection attacks. This feature helps to ensure that XSS and SQL-injection vulnerabilities are not *accidentally* added to Fossil when custom TH1 scripts for headers or footers or tickets are added to a repository. Note that the tainted/untainted distinction in strings does not make it impossible to introduce XSS and SQL-injections vulnerabilities using poorly-written TH1 scripts; it just makes it more difficult and |
| ︙ | ︙ |
Changes to www/unvers.wiki.
| ︙ | ︙ | |||
22 23 24 25 26 27 28 | Unversioned files are intended to be accessible as web pages using URLs of the form: "<tt>https://example.com/cgi-script/<b>uv</b>/<i>FILENAME</i></tt>". In other words, the URI method "<b>uv</b>" (short for "unversioned") followed by the name of the unversioned file will retrieve the content of the file. The MIME type is inferred from the filename suffix. The content of unversioned files can also be retrieved using the | | | | | | | | 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 | Unversioned files are intended to be accessible as web pages using URLs of the form: "<tt>https://example.com/cgi-script/<b>uv</b>/<i>FILENAME</i></tt>". In other words, the URI method "<b>uv</b>" (short for "unversioned") followed by the name of the unversioned file will retrieve the content of the file. The MIME type is inferred from the filename suffix. The content of unversioned files can also be retrieved using the [/help/unversioned|fossil unvers cat <i>FILENAME...</i>] or [/help/unversioned|fossil unvers export <i>FILENAME</i>] commands. A list of all unversioned files on a server can be seen using the [/help/www/uvlist|/uvlist] URL. ([/uvlist|example].) <h2>Syncing Unversioned Files</h2> Unversioned content does not sync between repositories by default. One must request it via commands such as: <pre> fossil sync <b>-u</b> fossil clone <b>-u</b> <i>URL local-repo-name</i> fossil unversioned sync </pre> The [/help/sync|fossil sync] and [/help/clone|fossil clone] commands will synchronize unversioned content if and only if they're given the "-u" (or "--unversioned") command-line option. The [/help/unversioned|fossil unversioned sync] command synchronizes the unversioned content without synchronizing anything else. Notice that the "-u" option does not work on [/help/push|fossil push] or [/help?cmd=pull|fossil pull]. The "-u" option is only available on "sync" and "clone". A rough equivalent of an unversioned pull would be the [/help?cmd=unversioned|fossil unversioned revert] command. The "unversioned revert" command causes the unversioned content on the local repository to be overwritten by the unversioned content found on the remote repository. |
| ︙ | ︙ |