Fossil SCM
Pass command line arguments to hooks via a TH1 list variable. Enhance test suite infrastructure and add tests. Update hook TH_ERROR return code handling comments to reflect reality.
Commit
b34dbc78b571a53d48638abc4ce21dd849ef693e
Parent
f90f723010b6bd1…
6 files changed
+6
-2
+28
+69
+4
+83
-11
+6
-2
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -698,11 +698,13 @@ | ||
| 698 | 698 | /* |
| 699 | 699 | ** The TH1 return codes from the hook will be handled as follows: |
| 700 | 700 | ** |
| 701 | 701 | ** TH_OK: The xFunc() and the TH1 notification will both be executed. |
| 702 | 702 | ** |
| 703 | - ** TH_ERROR: The xFunc() and the TH1 notification will both be skipped. | |
| 703 | + ** TH_ERROR: The xFunc() will be executed, the TH1 notification will be | |
| 704 | + ** skipped. If the xFunc() is being hooked, the error message | |
| 705 | + ** will be emitted. | |
| 704 | 706 | ** |
| 705 | 707 | ** TH_BREAK: The xFunc() and the TH1 notification will both be skipped. |
| 706 | 708 | ** |
| 707 | 709 | ** TH_RETURN: The xFunc() will be executed, the TH1 notification will be |
| 708 | 710 | ** skipped. |
| @@ -1589,11 +1591,13 @@ | ||
| 1589 | 1591 | /* |
| 1590 | 1592 | ** The TH1 return codes from the hook will be handled as follows: |
| 1591 | 1593 | ** |
| 1592 | 1594 | ** TH_OK: The xFunc() and the TH1 notification will both be executed. |
| 1593 | 1595 | ** |
| 1594 | - ** TH_ERROR: The xFunc() and the TH1 notification will both be skipped. | |
| 1596 | + ** TH_ERROR: The xFunc() will be executed, the TH1 notification will be | |
| 1597 | + ** skipped. If the xFunc() is being hooked, the error message | |
| 1598 | + ** will be emitted. | |
| 1595 | 1599 | ** |
| 1596 | 1600 | ** TH_BREAK: The xFunc() and the TH1 notification will both be skipped. |
| 1597 | 1601 | ** |
| 1598 | 1602 | ** TH_RETURN: The xFunc() will be executed, the TH1 notification will be |
| 1599 | 1603 | ** skipped. |
| 1600 | 1604 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -698,11 +698,13 @@ | |
| 698 | /* |
| 699 | ** The TH1 return codes from the hook will be handled as follows: |
| 700 | ** |
| 701 | ** TH_OK: The xFunc() and the TH1 notification will both be executed. |
| 702 | ** |
| 703 | ** TH_ERROR: The xFunc() and the TH1 notification will both be skipped. |
| 704 | ** |
| 705 | ** TH_BREAK: The xFunc() and the TH1 notification will both be skipped. |
| 706 | ** |
| 707 | ** TH_RETURN: The xFunc() will be executed, the TH1 notification will be |
| 708 | ** skipped. |
| @@ -1589,11 +1591,13 @@ | |
| 1589 | /* |
| 1590 | ** The TH1 return codes from the hook will be handled as follows: |
| 1591 | ** |
| 1592 | ** TH_OK: The xFunc() and the TH1 notification will both be executed. |
| 1593 | ** |
| 1594 | ** TH_ERROR: The xFunc() and the TH1 notification will both be skipped. |
| 1595 | ** |
| 1596 | ** TH_BREAK: The xFunc() and the TH1 notification will both be skipped. |
| 1597 | ** |
| 1598 | ** TH_RETURN: The xFunc() will be executed, the TH1 notification will be |
| 1599 | ** skipped. |
| 1600 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -698,11 +698,13 @@ | |
| 698 | /* |
| 699 | ** The TH1 return codes from the hook will be handled as follows: |
| 700 | ** |
| 701 | ** TH_OK: The xFunc() and the TH1 notification will both be executed. |
| 702 | ** |
| 703 | ** TH_ERROR: The xFunc() will be executed, the TH1 notification will be |
| 704 | ** skipped. If the xFunc() is being hooked, the error message |
| 705 | ** will be emitted. |
| 706 | ** |
| 707 | ** TH_BREAK: The xFunc() and the TH1 notification will both be skipped. |
| 708 | ** |
| 709 | ** TH_RETURN: The xFunc() will be executed, the TH1 notification will be |
| 710 | ** skipped. |
| @@ -1589,11 +1591,13 @@ | |
| 1591 | /* |
| 1592 | ** The TH1 return codes from the hook will be handled as follows: |
| 1593 | ** |
| 1594 | ** TH_OK: The xFunc() and the TH1 notification will both be executed. |
| 1595 | ** |
| 1596 | ** TH_ERROR: The xFunc() will be executed, the TH1 notification will be |
| 1597 | ** skipped. If the xFunc() is being hooked, the error message |
| 1598 | ** will be emitted. |
| 1599 | ** |
| 1600 | ** TH_BREAK: The xFunc() and the TH1 notification will both be skipped. |
| 1601 | ** |
| 1602 | ** TH_RETURN: The xFunc() will be executed, the TH1 notification will be |
| 1603 | ** skipped. |
| 1604 |
+28
| --- src/th_main.c | ||
| +++ src/th_main.c | ||
| @@ -1101,10 +1101,34 @@ | ||
| 1101 | 1101 | Th_Trace("set %h {%h}<br />\n", zName, zValue); |
| 1102 | 1102 | } |
| 1103 | 1103 | Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue)); |
| 1104 | 1104 | } |
| 1105 | 1105 | } |
| 1106 | + | |
| 1107 | +/* | |
| 1108 | +** Store a list value in a variable in the interpreter. | |
| 1109 | +*/ | |
| 1110 | +void Th_StoreList( | |
| 1111 | + const char *zName, | |
| 1112 | + char **pzList, | |
| 1113 | + int nList | |
| 1114 | +){ | |
| 1115 | + Th_FossilInit(TH_INIT_DEFAULT); | |
| 1116 | + if( pzList ){ | |
| 1117 | + char *zValue = 0; | |
| 1118 | + int nValue = 0; | |
| 1119 | + int i; | |
| 1120 | + for(i=0; i<nList; i++){ | |
| 1121 | + Th_ListAppend(g.interp, &zValue, &nValue, pzList[i], -1); | |
| 1122 | + } | |
| 1123 | + if( g.thTrace ){ | |
| 1124 | + Th_Trace("set %h {%h}<br />\n", zName, zValue); | |
| 1125 | + } | |
| 1126 | + Th_SetVar(g.interp, zName, -1, zValue, nValue); | |
| 1127 | + Th_Free(g.interp, zValue); | |
| 1128 | + } | |
| 1129 | +} | |
| 1106 | 1130 | |
| 1107 | 1131 | /* |
| 1108 | 1132 | ** Store an integer value in a variable in the interpreter. |
| 1109 | 1133 | */ |
| 1110 | 1134 | void Th_StoreInt(const char *zName, int iValue){ |
| @@ -1213,10 +1237,11 @@ | ||
| 1213 | 1237 | char cmdFlags |
| 1214 | 1238 | ){ |
| 1215 | 1239 | int rc = TH_OK; |
| 1216 | 1240 | Th_FossilInit(TH_INIT_HOOK); |
| 1217 | 1241 | Th_Store("cmd_name", zName); |
| 1242 | + Th_StoreList("cmd_args", g.argv, g.argc); | |
| 1218 | 1243 | Th_StoreInt("cmd_flags", cmdFlags); |
| 1219 | 1244 | rc = Th_Eval(g.interp, 0, "command_hook", -1); |
| 1220 | 1245 | if( rc==TH_ERROR ){ |
| 1221 | 1246 | int nResult = 0; |
| 1222 | 1247 | char *zResult = (char*)Th_GetResult(g.interp, &nResult); |
| @@ -1254,10 +1279,11 @@ | ||
| 1254 | 1279 | char cmdFlags |
| 1255 | 1280 | ){ |
| 1256 | 1281 | int rc; |
| 1257 | 1282 | Th_FossilInit(TH_INIT_HOOK); |
| 1258 | 1283 | Th_Store("cmd_name", zName); |
| 1284 | + Th_StoreList("cmd_args", g.argv, g.argc); | |
| 1259 | 1285 | Th_StoreInt("cmd_flags", cmdFlags); |
| 1260 | 1286 | rc = Th_Eval(g.interp, 0, "command_notify", -1); |
| 1261 | 1287 | if( g.thTrace ){ |
| 1262 | 1288 | Th_Trace("[command_notify {%h}] => %h<br />\n", zName, |
| 1263 | 1289 | Th_ReturnCodeName(rc, 0)); |
| @@ -1276,10 +1302,11 @@ | ||
| 1276 | 1302 | char cmdFlags |
| 1277 | 1303 | ){ |
| 1278 | 1304 | int rc = TH_OK; |
| 1279 | 1305 | Th_FossilInit(TH_INIT_HOOK); |
| 1280 | 1306 | Th_Store("web_name", zName); |
| 1307 | + Th_StoreList("web_args", g.argv, g.argc); | |
| 1281 | 1308 | Th_StoreInt("web_flags", cmdFlags); |
| 1282 | 1309 | rc = Th_Eval(g.interp, 0, "webpage_hook", -1); |
| 1283 | 1310 | if( rc==TH_ERROR ){ |
| 1284 | 1311 | int nResult = 0; |
| 1285 | 1312 | char *zResult = (char*)Th_GetResult(g.interp, &nResult); |
| @@ -1317,10 +1344,11 @@ | ||
| 1317 | 1344 | char cmdFlags |
| 1318 | 1345 | ){ |
| 1319 | 1346 | int rc; |
| 1320 | 1347 | Th_FossilInit(TH_INIT_HOOK); |
| 1321 | 1348 | Th_Store("web_name", zName); |
| 1349 | + Th_StoreList("web_args", g.argv, g.argc); | |
| 1322 | 1350 | Th_StoreInt("web_flags", cmdFlags); |
| 1323 | 1351 | rc = Th_Eval(g.interp, 0, "webpage_notify", -1); |
| 1324 | 1352 | if( g.thTrace ){ |
| 1325 | 1353 | Th_Trace("[webpage_notify {%h}] => %h<br />\n", zName, |
| 1326 | 1354 | Th_ReturnCodeName(rc, 0)); |
| 1327 | 1355 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -1101,10 +1101,34 @@ | |
| 1101 | Th_Trace("set %h {%h}<br />\n", zName, zValue); |
| 1102 | } |
| 1103 | Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue)); |
| 1104 | } |
| 1105 | } |
| 1106 | |
| 1107 | /* |
| 1108 | ** Store an integer value in a variable in the interpreter. |
| 1109 | */ |
| 1110 | void Th_StoreInt(const char *zName, int iValue){ |
| @@ -1213,10 +1237,11 @@ | |
| 1213 | char cmdFlags |
| 1214 | ){ |
| 1215 | int rc = TH_OK; |
| 1216 | Th_FossilInit(TH_INIT_HOOK); |
| 1217 | Th_Store("cmd_name", zName); |
| 1218 | Th_StoreInt("cmd_flags", cmdFlags); |
| 1219 | rc = Th_Eval(g.interp, 0, "command_hook", -1); |
| 1220 | if( rc==TH_ERROR ){ |
| 1221 | int nResult = 0; |
| 1222 | char *zResult = (char*)Th_GetResult(g.interp, &nResult); |
| @@ -1254,10 +1279,11 @@ | |
| 1254 | char cmdFlags |
| 1255 | ){ |
| 1256 | int rc; |
| 1257 | Th_FossilInit(TH_INIT_HOOK); |
| 1258 | Th_Store("cmd_name", zName); |
| 1259 | Th_StoreInt("cmd_flags", cmdFlags); |
| 1260 | rc = Th_Eval(g.interp, 0, "command_notify", -1); |
| 1261 | if( g.thTrace ){ |
| 1262 | Th_Trace("[command_notify {%h}] => %h<br />\n", zName, |
| 1263 | Th_ReturnCodeName(rc, 0)); |
| @@ -1276,10 +1302,11 @@ | |
| 1276 | char cmdFlags |
| 1277 | ){ |
| 1278 | int rc = TH_OK; |
| 1279 | Th_FossilInit(TH_INIT_HOOK); |
| 1280 | Th_Store("web_name", zName); |
| 1281 | Th_StoreInt("web_flags", cmdFlags); |
| 1282 | rc = Th_Eval(g.interp, 0, "webpage_hook", -1); |
| 1283 | if( rc==TH_ERROR ){ |
| 1284 | int nResult = 0; |
| 1285 | char *zResult = (char*)Th_GetResult(g.interp, &nResult); |
| @@ -1317,10 +1344,11 @@ | |
| 1317 | char cmdFlags |
| 1318 | ){ |
| 1319 | int rc; |
| 1320 | Th_FossilInit(TH_INIT_HOOK); |
| 1321 | Th_Store("web_name", zName); |
| 1322 | Th_StoreInt("web_flags", cmdFlags); |
| 1323 | rc = Th_Eval(g.interp, 0, "webpage_notify", -1); |
| 1324 | if( g.thTrace ){ |
| 1325 | Th_Trace("[webpage_notify {%h}] => %h<br />\n", zName, |
| 1326 | Th_ReturnCodeName(rc, 0)); |
| 1327 |
| --- src/th_main.c | |
| +++ src/th_main.c | |
| @@ -1101,10 +1101,34 @@ | |
| 1101 | Th_Trace("set %h {%h}<br />\n", zName, zValue); |
| 1102 | } |
| 1103 | Th_SetVar(g.interp, zName, -1, zValue, strlen(zValue)); |
| 1104 | } |
| 1105 | } |
| 1106 | |
| 1107 | /* |
| 1108 | ** Store a list value in a variable in the interpreter. |
| 1109 | */ |
| 1110 | void Th_StoreList( |
| 1111 | const char *zName, |
| 1112 | char **pzList, |
| 1113 | int nList |
| 1114 | ){ |
| 1115 | Th_FossilInit(TH_INIT_DEFAULT); |
| 1116 | if( pzList ){ |
| 1117 | char *zValue = 0; |
| 1118 | int nValue = 0; |
| 1119 | int i; |
| 1120 | for(i=0; i<nList; i++){ |
| 1121 | Th_ListAppend(g.interp, &zValue, &nValue, pzList[i], -1); |
| 1122 | } |
| 1123 | if( g.thTrace ){ |
| 1124 | Th_Trace("set %h {%h}<br />\n", zName, zValue); |
| 1125 | } |
| 1126 | Th_SetVar(g.interp, zName, -1, zValue, nValue); |
| 1127 | Th_Free(g.interp, zValue); |
| 1128 | } |
| 1129 | } |
| 1130 | |
| 1131 | /* |
| 1132 | ** Store an integer value in a variable in the interpreter. |
| 1133 | */ |
| 1134 | void Th_StoreInt(const char *zName, int iValue){ |
| @@ -1213,10 +1237,11 @@ | |
| 1237 | char cmdFlags |
| 1238 | ){ |
| 1239 | int rc = TH_OK; |
| 1240 | Th_FossilInit(TH_INIT_HOOK); |
| 1241 | Th_Store("cmd_name", zName); |
| 1242 | Th_StoreList("cmd_args", g.argv, g.argc); |
| 1243 | Th_StoreInt("cmd_flags", cmdFlags); |
| 1244 | rc = Th_Eval(g.interp, 0, "command_hook", -1); |
| 1245 | if( rc==TH_ERROR ){ |
| 1246 | int nResult = 0; |
| 1247 | char *zResult = (char*)Th_GetResult(g.interp, &nResult); |
| @@ -1254,10 +1279,11 @@ | |
| 1279 | char cmdFlags |
| 1280 | ){ |
| 1281 | int rc; |
| 1282 | Th_FossilInit(TH_INIT_HOOK); |
| 1283 | Th_Store("cmd_name", zName); |
| 1284 | Th_StoreList("cmd_args", g.argv, g.argc); |
| 1285 | Th_StoreInt("cmd_flags", cmdFlags); |
| 1286 | rc = Th_Eval(g.interp, 0, "command_notify", -1); |
| 1287 | if( g.thTrace ){ |
| 1288 | Th_Trace("[command_notify {%h}] => %h<br />\n", zName, |
| 1289 | Th_ReturnCodeName(rc, 0)); |
| @@ -1276,10 +1302,11 @@ | |
| 1302 | char cmdFlags |
| 1303 | ){ |
| 1304 | int rc = TH_OK; |
| 1305 | Th_FossilInit(TH_INIT_HOOK); |
| 1306 | Th_Store("web_name", zName); |
| 1307 | Th_StoreList("web_args", g.argv, g.argc); |
| 1308 | Th_StoreInt("web_flags", cmdFlags); |
| 1309 | rc = Th_Eval(g.interp, 0, "webpage_hook", -1); |
| 1310 | if( rc==TH_ERROR ){ |
| 1311 | int nResult = 0; |
| 1312 | char *zResult = (char*)Th_GetResult(g.interp, &nResult); |
| @@ -1317,10 +1344,11 @@ | |
| 1344 | char cmdFlags |
| 1345 | ){ |
| 1346 | int rc; |
| 1347 | Th_FossilInit(TH_INIT_HOOK); |
| 1348 | Th_Store("web_name", zName); |
| 1349 | Th_StoreList("web_args", g.argv, g.argc); |
| 1350 | Th_StoreInt("web_flags", cmdFlags); |
| 1351 | rc = Th_Eval(g.interp, 0, "webpage_notify", -1); |
| 1352 | if( g.thTrace ){ |
| 1353 | Th_Trace("[webpage_notify {%h}] => %h<br />\n", zName, |
| 1354 | Th_ReturnCodeName(rc, 0)); |
| 1355 |
+69
| --- test/tester.tcl | ||
| +++ test/tester.tcl | ||
| @@ -47,10 +47,17 @@ | ||
| 47 | 47 | foreach f [lsort [glob $testdir/*.test]] { |
| 48 | 48 | set base [file root [file tail $f]] |
| 49 | 49 | lappend argv $base |
| 50 | 50 | } |
| 51 | 51 | } |
| 52 | + | |
| 53 | +set tempPath [expr {[info exists env(TEMP)] ? \ | |
| 54 | + $env(TEMP) : [file dirname [info script]]}] | |
| 55 | + | |
| 56 | +if {$tcl_platform(platform) eq "windows"} then { | |
| 57 | + set tempPath [string map [list \\ /] $tempPath] | |
| 58 | +} | |
| 52 | 59 | |
| 53 | 60 | # start protocol |
| 54 | 61 | # |
| 55 | 62 | proc protInit {cmd} { |
| 56 | 63 | if {$::PROT} { |
| @@ -168,10 +175,72 @@ | ||
| 168 | 175 | protOut " Expected:\n [join $expected "\n "]" |
| 169 | 176 | protOut " Got:\n [join $result "\n "]" |
| 170 | 177 | test $name 0 |
| 171 | 178 | } |
| 172 | 179 | } |
| 180 | + | |
| 181 | +# Append all arguments into a single value and then returns it. | |
| 182 | +# | |
| 183 | +proc appendArgs {args} { | |
| 184 | + eval append result $args | |
| 185 | +} | |
| 186 | + | |
| 187 | +# Return the name of the versioned settings file containing the TH1 | |
| 188 | +# setup script. | |
| 189 | +# | |
| 190 | +proc getTh1SetupFileName {} { | |
| 191 | + # | |
| 192 | + # NOTE: This uses the "testdir" global variable provided by the | |
| 193 | + # test suite; alternatively, the root of the source tree | |
| 194 | + # could be obtained directly from Fossil. | |
| 195 | + # | |
| 196 | + return [file normalize [file join [file dirname $::testdir] \ | |
| 197 | + .fossil-settings th1-setup]] | |
| 198 | +} | |
| 199 | + | |
| 200 | +# Return the saved name of the versioned settings file containing | |
| 201 | +# the TH1 setup script. | |
| 202 | +# | |
| 203 | +proc getSavedTh1SetupFileName {} { | |
| 204 | + return [appendArgs [getTh1SetupFileName] . [pid]] | |
| 205 | +} | |
| 206 | + | |
| 207 | +# Sets the TH1 setup script to the one provided. Prior to calling | |
| 208 | +# this, the [saveTh1SetupFile] procedure should be called in order to | |
| 209 | +# preserve the existing TH1 setup script. Prior to completing the test, | |
| 210 | +# the [restoreTh1SetupFile] procedure should be called to restore the | |
| 211 | +# original TH1 setup script. | |
| 212 | +# | |
| 213 | +proc writeTh1SetupFile { data } { | |
| 214 | + return [write_file [getTh1SetupFileName] $data] | |
| 215 | +} | |
| 216 | + | |
| 217 | +# Saves the TH1 setup script file by renaming it, based on the current | |
| 218 | +# process ID. | |
| 219 | +# | |
| 220 | +proc saveTh1SetupFile {} { | |
| 221 | + set oldFileName [getTh1SetupFileName] | |
| 222 | + if {[file exists $oldFileName]} then { | |
| 223 | + set newFileName [getSavedTh1SetupFileName] | |
| 224 | + catch {file delete $newFileName} | |
| 225 | + file rename $oldFileName $newFileName | |
| 226 | + file delete $oldFileName | |
| 227 | + } | |
| 228 | +} | |
| 229 | + | |
| 230 | +# Restores the original TH1 setup script file by renaming it back, based | |
| 231 | +# on the current process ID. | |
| 232 | +# | |
| 233 | +proc restoreTh1SetupFile {} { | |
| 234 | + set oldFileName [getSavedTh1SetupFileName] | |
| 235 | + if {[file exists $oldFileName]} then { | |
| 236 | + set newFileName [getTh1SetupFileName] | |
| 237 | + catch {file delete $newFileName} | |
| 238 | + file rename $oldFileName $newFileName | |
| 239 | + file delete $oldFileName | |
| 240 | + } | |
| 241 | +} | |
| 173 | 242 | |
| 174 | 243 | # Perform a test |
| 175 | 244 | # |
| 176 | 245 | set test_count 0 |
| 177 | 246 | proc test {name expr} { |
| 178 | 247 | |
| 179 | 248 | ADDED test/th1-hooks-input.txt |
| 180 | 249 | ADDED test/th1-hooks.test |
| --- test/tester.tcl | |
| +++ test/tester.tcl | |
| @@ -47,10 +47,17 @@ | |
| 47 | foreach f [lsort [glob $testdir/*.test]] { |
| 48 | set base [file root [file tail $f]] |
| 49 | lappend argv $base |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | # start protocol |
| 54 | # |
| 55 | proc protInit {cmd} { |
| 56 | if {$::PROT} { |
| @@ -168,10 +175,72 @@ | |
| 168 | protOut " Expected:\n [join $expected "\n "]" |
| 169 | protOut " Got:\n [join $result "\n "]" |
| 170 | test $name 0 |
| 171 | } |
| 172 | } |
| 173 | |
| 174 | # Perform a test |
| 175 | # |
| 176 | set test_count 0 |
| 177 | proc test {name expr} { |
| 178 | |
| 179 | DDED test/th1-hooks-input.txt |
| 180 | DDED test/th1-hooks.test |
| --- test/tester.tcl | |
| +++ test/tester.tcl | |
| @@ -47,10 +47,17 @@ | |
| 47 | foreach f [lsort [glob $testdir/*.test]] { |
| 48 | set base [file root [file tail $f]] |
| 49 | lappend argv $base |
| 50 | } |
| 51 | } |
| 52 | |
| 53 | set tempPath [expr {[info exists env(TEMP)] ? \ |
| 54 | $env(TEMP) : [file dirname [info script]]}] |
| 55 | |
| 56 | if {$tcl_platform(platform) eq "windows"} then { |
| 57 | set tempPath [string map [list \\ /] $tempPath] |
| 58 | } |
| 59 | |
| 60 | # start protocol |
| 61 | # |
| 62 | proc protInit {cmd} { |
| 63 | if {$::PROT} { |
| @@ -168,10 +175,72 @@ | |
| 175 | protOut " Expected:\n [join $expected "\n "]" |
| 176 | protOut " Got:\n [join $result "\n "]" |
| 177 | test $name 0 |
| 178 | } |
| 179 | } |
| 180 | |
| 181 | # Append all arguments into a single value and then returns it. |
| 182 | # |
| 183 | proc appendArgs {args} { |
| 184 | eval append result $args |
| 185 | } |
| 186 | |
| 187 | # Return the name of the versioned settings file containing the TH1 |
| 188 | # setup script. |
| 189 | # |
| 190 | proc getTh1SetupFileName {} { |
| 191 | # |
| 192 | # NOTE: This uses the "testdir" global variable provided by the |
| 193 | # test suite; alternatively, the root of the source tree |
| 194 | # could be obtained directly from Fossil. |
| 195 | # |
| 196 | return [file normalize [file join [file dirname $::testdir] \ |
| 197 | .fossil-settings th1-setup]] |
| 198 | } |
| 199 | |
| 200 | # Return the saved name of the versioned settings file containing |
| 201 | # the TH1 setup script. |
| 202 | # |
| 203 | proc getSavedTh1SetupFileName {} { |
| 204 | return [appendArgs [getTh1SetupFileName] . [pid]] |
| 205 | } |
| 206 | |
| 207 | # Sets the TH1 setup script to the one provided. Prior to calling |
| 208 | # this, the [saveTh1SetupFile] procedure should be called in order to |
| 209 | # preserve the existing TH1 setup script. Prior to completing the test, |
| 210 | # the [restoreTh1SetupFile] procedure should be called to restore the |
| 211 | # original TH1 setup script. |
| 212 | # |
| 213 | proc writeTh1SetupFile { data } { |
| 214 | return [write_file [getTh1SetupFileName] $data] |
| 215 | } |
| 216 | |
| 217 | # Saves the TH1 setup script file by renaming it, based on the current |
| 218 | # process ID. |
| 219 | # |
| 220 | proc saveTh1SetupFile {} { |
| 221 | set oldFileName [getTh1SetupFileName] |
| 222 | if {[file exists $oldFileName]} then { |
| 223 | set newFileName [getSavedTh1SetupFileName] |
| 224 | catch {file delete $newFileName} |
| 225 | file rename $oldFileName $newFileName |
| 226 | file delete $oldFileName |
| 227 | } |
| 228 | } |
| 229 | |
| 230 | # Restores the original TH1 setup script file by renaming it back, based |
| 231 | # on the current process ID. |
| 232 | # |
| 233 | proc restoreTh1SetupFile {} { |
| 234 | set oldFileName [getSavedTh1SetupFileName] |
| 235 | if {[file exists $oldFileName]} then { |
| 236 | set newFileName [getTh1SetupFileName] |
| 237 | catch {file delete $newFileName} |
| 238 | file rename $oldFileName $newFileName |
| 239 | file delete $oldFileName |
| 240 | } |
| 241 | } |
| 242 | |
| 243 | # Perform a test |
| 244 | # |
| 245 | set test_count 0 |
| 246 | proc test {name expr} { |
| 247 | |
| 248 | DDED test/th1-hooks-input.txt |
| 249 | DDED test/th1-hooks.test |
| --- a/test/th1-hooks-input.txt | ||
| +++ b/test/th1-hooks-input.txt | ||
| @@ -0,0 +1,4 @@ | ||
| 1 | +GET ${url} HTTP/1.1 | |
| 2 | +Host: localhost | |
| 3 | +User-Agent: Fossil | |
| 4 | + |
| --- a/test/th1-hooks-input.txt | |
| +++ b/test/th1-hooks-input.txt | |
| @@ -0,0 +1,4 @@ | |
| --- a/test/th1-hooks-input.txt | |
| +++ b/test/th1-hooks-input.txt | |
| @@ -0,0 +1,4 @@ | |
| 1 | GET ${url} HTTP/1.1 |
| 2 | Host: localhost |
| 3 | User-Agent: Fossil |
| 4 |
+83
| --- a/test/th1-hooks.test | ||
| +++ b/test/th1-hooks.test | ||
| @@ -0,0 +1,83 @@ | ||
| 1 | +# | |
| 2 | +# Co# | |
| 3 | +# Copyright (c) 2011 D. Richard Hipp | |
| 4 | +# | |
| 5 | +# This program is free software; you can redistribute i1 D. Richard Hipp | |
| 6 | +# | |
| 7 | +# This program is free software; you can redistribute it and/or | |
| 8 | +# modify it under the terms of the Simplified BSD License (also | |
| 9 | +# known as the "2-Clause License" or "FreeBSD License".) | |
| 10 | +# | |
| 11 | +# This program is distributed in the hope that it will be useful, | |
| 12 | +# but without any warranty; without even the implied warranty of | |
| 13 | +# merchantability or fitness for a particular purpose. | |
| 14 | +# | |
| 15 | +# Author contact information: | |
| 16 | +# [email protected] | |
| 17 | +# http://www.hwaci.com/drh/ | |
| 18 | +# | |
| 19 | +#################################$::RESULT | |
| 20 | +# TH1 Hooks | |
| 21 | +# | |
| 22 | + | |
| 23 | +fossil test-th-eval then "hasfeature th1Hooks" | |
| 24 | + | |
| 25 | +if {[normalize_result] ne "1"} { | |
| 26 | + ; compiled with TH1 hooks support." | |
| 27 | + test_cleanup_then_return | |
| 28 | +} | |
| 29 | + | |
| 30 | +proc pPath [appendArgs test-hmpPath [appendArgs test-http-ou set data [subst [read_fil]] | |
| 31 | + | |
| 32 | + write_file $inFileName $data | |
| 33 | + fossil http $inFileName $outFileName 127.0.0.1 $repository | |
| 34 | + set result [expr {[file exists $outFileName] ? [read_file $outFileName] : ""}] | |
| 35 | + | |
| 36 | + if {1} then { | |
| 37 | + catch {file delete $inFileName} | |
| 38 | + catch {frepository } | |
| 39 | + | |
| 40 | + return $result | |
| 41 | +} | |
| 42 | + | |
| 43 | +proc normat | |
| 44 | +} | |
| 45 | + | |
| 46 | +proc normalize_result {} { | |
| 47 | + return [string map [list \r\n \n] [string trim $::RESULT]] | |
| 48 | +} | |
| 49 | + | |
| 50 | +proc first_data_line {}\n] 0] | |
| 51 | +} | |
| 52 | + | |
| 53 | +proc second_data_line {}\n] 1] | |
| 54 | +} | |
| 55 | + | |
| 56 | +proc third_data_line {}\n] 2] | |
| 57 | +} | |
| 58 | + | |
| 59 | +proc lD. Richard Hipp | |
| 60 | +#\nlit \n] end-1] | |
| 61 | +} | |
| 62 | + | |
| 63 | +proc \rlit \n] end-1] | |
| 64 | +} | |
| 65 | + | |
| 66 | +proc \rlit \n] end-1] | |
| 67 | +} | |
| 68 | + | |
| 69 | +proc \rlit \n] end-1] | |
| 70 | +} | |
| 71 | + | |
| 72 | +proc \rlit \n] end-1] | |
| 73 | +} | |
| 74 | + | |
| 75 | +proc \r\n] end-1] | |
| 76 | +if {$::cmd_argsc {} { | |
| 77 | + return [lindex [split \n] end-1] | |
| 78 | +} | |
| 79 | + | |
| 80 | +proc # | |
| 81 | +# Co# | |
| 82 | +# Copyright (c)ght (c) 2lit \n] end-1RESULT]] eq | |
| 83 | +timeline}}2b {[secondtimeline}}2cthird_data_line]]}2dest3est4web-hooks-1b {[regexp |
| --- a/test/th1-hooks.test | |
| +++ b/test/th1-hooks.test | |
| @@ -0,0 +1,83 @@ | |
| --- a/test/th1-hooks.test | |
| +++ b/test/th1-hooks.test | |
| @@ -0,0 +1,83 @@ | |
| 1 | # |
| 2 | # Co# |
| 3 | # Copyright (c) 2011 D. Richard Hipp |
| 4 | # |
| 5 | # This program is free software; you can redistribute i1 D. Richard Hipp |
| 6 | # |
| 7 | # This program is free software; you can redistribute it and/or |
| 8 | # modify it under the terms of the Simplified BSD License (also |
| 9 | # known as the "2-Clause License" or "FreeBSD License".) |
| 10 | # |
| 11 | # This program is distributed in the hope that it will be useful, |
| 12 | # but without any warranty; without even the implied warranty of |
| 13 | # merchantability or fitness for a particular purpose. |
| 14 | # |
| 15 | # Author contact information: |
| 16 | # [email protected] |
| 17 | # http://www.hwaci.com/drh/ |
| 18 | # |
| 19 | #################################$::RESULT |
| 20 | # TH1 Hooks |
| 21 | # |
| 22 | |
| 23 | fossil test-th-eval then "hasfeature th1Hooks" |
| 24 | |
| 25 | if {[normalize_result] ne "1"} { |
| 26 | ; compiled with TH1 hooks support." |
| 27 | test_cleanup_then_return |
| 28 | } |
| 29 | |
| 30 | proc pPath [appendArgs test-hmpPath [appendArgs test-http-ou set data [subst [read_fil]] |
| 31 | |
| 32 | write_file $inFileName $data |
| 33 | fossil http $inFileName $outFileName 127.0.0.1 $repository |
| 34 | set result [expr {[file exists $outFileName] ? [read_file $outFileName] : ""}] |
| 35 | |
| 36 | if {1} then { |
| 37 | catch {file delete $inFileName} |
| 38 | catch {frepository } |
| 39 | |
| 40 | return $result |
| 41 | } |
| 42 | |
| 43 | proc normat |
| 44 | } |
| 45 | |
| 46 | proc normalize_result {} { |
| 47 | return [string map [list \r\n \n] [string trim $::RESULT]] |
| 48 | } |
| 49 | |
| 50 | proc first_data_line {}\n] 0] |
| 51 | } |
| 52 | |
| 53 | proc second_data_line {}\n] 1] |
| 54 | } |
| 55 | |
| 56 | proc third_data_line {}\n] 2] |
| 57 | } |
| 58 | |
| 59 | proc lD. Richard Hipp |
| 60 | #\nlit \n] end-1] |
| 61 | } |
| 62 | |
| 63 | proc \rlit \n] end-1] |
| 64 | } |
| 65 | |
| 66 | proc \rlit \n] end-1] |
| 67 | } |
| 68 | |
| 69 | proc \rlit \n] end-1] |
| 70 | } |
| 71 | |
| 72 | proc \rlit \n] end-1] |
| 73 | } |
| 74 | |
| 75 | proc \r\n] end-1] |
| 76 | if {$::cmd_argsc {} { |
| 77 | return [lindex [split \n] end-1] |
| 78 | } |
| 79 | |
| 80 | proc # |
| 81 | # Co# |
| 82 | # Copyright (c)ght (c) 2lit \n] end-1RESULT]] eq |
| 83 | timeline}}2b {[secondtimeline}}2cthird_data_line]]}2dest3est4web-hooks-1b {[regexp |
-11
| --- test/utf.test | ||
| +++ test/utf.test | ||
| @@ -16,14 +16,10 @@ | ||
| 16 | 16 | ############################################################################ |
| 17 | 17 | # |
| 18 | 18 | # Test UTF-8/UTF-16 detection |
| 19 | 19 | # |
| 20 | 20 | |
| 21 | -proc appendArgs {args} { | |
| 22 | - eval append result $args | |
| 23 | -} | |
| 24 | - | |
| 25 | 21 | proc swap_byte_order {str} { |
| 26 | 22 | set result "" |
| 27 | 23 | for {set i 0} {$i < [string length $str]} {incr i} { |
| 28 | 24 | set c [scan [string index $str $i] %c] |
| 29 | 25 | set c [expr {(($c << 8) & 0xFF00) | (($c >> 8) & 0xFF)}] |
| @@ -315,17 +311,10 @@ | ||
| 315 | 311 | } |
| 316 | 312 | } |
| 317 | 313 | flush $f; close $f |
| 318 | 314 | } |
| 319 | 315 | |
| 320 | -set tempPath [expr {[info exists env(TEMP)] ? \ | |
| 321 | - $env(TEMP) : [file dirname [info script]]}] | |
| 322 | - | |
| 323 | -if {$tcl_platform(platform) eq "windows"} then { | |
| 324 | - set tempPath [string map [list \\ /] $tempPath] | |
| 325 | -} | |
| 326 | - | |
| 327 | 316 | createTestFiles $tempPath 100 |
| 328 | 317 | # createTestResults $tempPath 100 |
| 329 | 318 | ########################### BEGIN GENERATED SECTION ########################### |
| 330 | 319 | |
| 331 | 320 | utf-check 100 utf-check-100-0-0-0.jnk \ |
| 332 | 321 |
| --- test/utf.test | |
| +++ test/utf.test | |
| @@ -16,14 +16,10 @@ | |
| 16 | ############################################################################ |
| 17 | # |
| 18 | # Test UTF-8/UTF-16 detection |
| 19 | # |
| 20 | |
| 21 | proc appendArgs {args} { |
| 22 | eval append result $args |
| 23 | } |
| 24 | |
| 25 | proc swap_byte_order {str} { |
| 26 | set result "" |
| 27 | for {set i 0} {$i < [string length $str]} {incr i} { |
| 28 | set c [scan [string index $str $i] %c] |
| 29 | set c [expr {(($c << 8) & 0xFF00) | (($c >> 8) & 0xFF)}] |
| @@ -315,17 +311,10 @@ | |
| 315 | } |
| 316 | } |
| 317 | flush $f; close $f |
| 318 | } |
| 319 | |
| 320 | set tempPath [expr {[info exists env(TEMP)] ? \ |
| 321 | $env(TEMP) : [file dirname [info script]]}] |
| 322 | |
| 323 | if {$tcl_platform(platform) eq "windows"} then { |
| 324 | set tempPath [string map [list \\ /] $tempPath] |
| 325 | } |
| 326 | |
| 327 | createTestFiles $tempPath 100 |
| 328 | # createTestResults $tempPath 100 |
| 329 | ########################### BEGIN GENERATED SECTION ########################### |
| 330 | |
| 331 | utf-check 100 utf-check-100-0-0-0.jnk \ |
| 332 |
| --- test/utf.test | |
| +++ test/utf.test | |
| @@ -16,14 +16,10 @@ | |
| 16 | ############################################################################ |
| 17 | # |
| 18 | # Test UTF-8/UTF-16 detection |
| 19 | # |
| 20 | |
| 21 | proc swap_byte_order {str} { |
| 22 | set result "" |
| 23 | for {set i 0} {$i < [string length $str]} {incr i} { |
| 24 | set c [scan [string index $str $i] %c] |
| 25 | set c [expr {(($c << 8) & 0xFF00) | (($c >> 8) & 0xFF)}] |
| @@ -315,17 +311,10 @@ | |
| 311 | } |
| 312 | } |
| 313 | flush $f; close $f |
| 314 | } |
| 315 | |
| 316 | createTestFiles $tempPath 100 |
| 317 | # createTestResults $tempPath 100 |
| 318 | ########################### BEGIN GENERATED SECTION ########################### |
| 319 | |
| 320 | utf-check 100 utf-check-100-0-0-0.jnk \ |
| 321 |