Fossil SCM
Update the Jim Tcl included with autosetup to 0.76.
Commit
31c03de8f4259c80eef7126fcb7add8bf7c241b6
Parent
8f1e34bd731b44c…
1 file changed
+224
-121
+224
-121
| --- autosetup/jimsh0.c | ||
| +++ autosetup/jimsh0.c | ||
| @@ -38,15 +38,17 @@ | ||
| 38 | 38 | #define TCL_PLATFORM_PLATFORM "unix" |
| 39 | 39 | #define TCL_PLATFORM_PATH_SEPARATOR ":" |
| 40 | 40 | #define HAVE_VFORK |
| 41 | 41 | #define HAVE_WAITPID |
| 42 | 42 | #define HAVE_ISATTY |
| 43 | +#define HAVE_MKSTEMP | |
| 44 | +#define HAVE_LINK | |
| 43 | 45 | #define HAVE_SYS_TIME_H |
| 44 | 46 | #define HAVE_DIRENT_H |
| 45 | 47 | #define HAVE_UNISTD_H |
| 46 | 48 | #endif |
| 47 | -#define JIM_VERSION 75 | |
| 49 | +#define JIM_VERSION 76 | |
| 48 | 50 | #ifndef JIM_WIN32COMPAT_H |
| 49 | 51 | #define JIM_WIN32COMPAT_H |
| 50 | 52 | |
| 51 | 53 | |
| 52 | 54 | |
| @@ -113,10 +115,11 @@ | ||
| 113 | 115 | int closedir(DIR *dir); |
| 114 | 116 | struct dirent *readdir(DIR *dir); |
| 115 | 117 | |
| 116 | 118 | #elif defined(__MINGW32__) |
| 117 | 119 | |
| 120 | +#include <stdlib.h> | |
| 118 | 121 | #define strtod __strtod |
| 119 | 122 | |
| 120 | 123 | #endif |
| 121 | 124 | |
| 122 | 125 | #endif |
| @@ -1048,29 +1051,48 @@ | ||
| 1048 | 1051 | "\n" |
| 1049 | 1052 | "\n" |
| 1050 | 1053 | "\n" |
| 1051 | 1054 | "proc _jimsh_init {} {\n" |
| 1052 | 1055 | " rename _jimsh_init {}\n" |
| 1056 | +" global jim::exe jim::argv0 tcl_interactive auto_path tcl_platform\n" | |
| 1053 | 1057 | "\n" |
| 1054 | 1058 | "\n" |
| 1055 | -" lappend p {*}[split [env JIMLIB {}] $::tcl_platform(pathSeparator)]\n" | |
| 1056 | -" lappend p {*}$::auto_path\n" | |
| 1057 | -" lappend p [file dirname [info nameofexecutable]]\n" | |
| 1058 | -" set ::auto_path $p\n" | |
| 1059 | +" if {[exists jim::argv0]} {\n" | |
| 1060 | +" if {[string match \"*/*\" $jim::argv0]} {\n" | |
| 1061 | +" set jim::exe [file join [pwd] $jim::argv0]\n" | |
| 1062 | +" } else {\n" | |
| 1063 | +" foreach path [split [env PATH \"\"] $tcl_platform(pathSeparator)] {\n" | |
| 1064 | +" set exec [file join [pwd] [string map {\\\\ /} $path] $jim::argv0]\n" | |
| 1065 | +" if {[file executable $exec]} {\n" | |
| 1066 | +" set jim::exe $exec\n" | |
| 1067 | +" break\n" | |
| 1068 | +" }\n" | |
| 1069 | +" }\n" | |
| 1070 | +" }\n" | |
| 1071 | +" }\n" | |
| 1059 | 1072 | "\n" |
| 1060 | -" if {$::tcl_interactive && [env HOME {}] ne \"\"} {\n" | |
| 1073 | +"\n" | |
| 1074 | +" lappend p {*}[split [env JIMLIB {}] $tcl_platform(pathSeparator)]\n" | |
| 1075 | +" if {[exists jim::exe]} {\n" | |
| 1076 | +" lappend p [file dirname $jim::exe]\n" | |
| 1077 | +" }\n" | |
| 1078 | +" lappend p {*}$auto_path\n" | |
| 1079 | +" set auto_path $p\n" | |
| 1080 | +"\n" | |
| 1081 | +" if {$tcl_interactive && [env HOME {}] ne \"\"} {\n" | |
| 1061 | 1082 | " foreach src {.jimrc jimrc.tcl} {\n" |
| 1062 | 1083 | " if {[file exists [env HOME]/$src]} {\n" |
| 1063 | 1084 | " uplevel #0 source [env HOME]/$src\n" |
| 1064 | 1085 | " break\n" |
| 1065 | 1086 | " }\n" |
| 1066 | 1087 | " }\n" |
| 1067 | 1088 | " }\n" |
| 1089 | +" return \"\"\n" | |
| 1068 | 1090 | "}\n" |
| 1069 | 1091 | "\n" |
| 1070 | 1092 | "if {$tcl_platform(platform) eq \"windows\"} {\n" |
| 1071 | -" set jim_argv0 [string map {\\\\ /} $jim_argv0]\n" | |
| 1093 | +" set jim::argv0 [string map {\\\\ /} $jim::argv0]\n" | |
| 1072 | 1094 | "}\n" |
| 1073 | 1095 | "\n" |
| 1074 | 1096 | "_jimsh_init\n" |
| 1075 | 1097 | ); |
| 1076 | 1098 | } |
| @@ -1091,11 +1113,11 @@ | ||
| 1091 | 1113 | "\n" |
| 1092 | 1114 | "\n" |
| 1093 | 1115 | "proc glob.globdir {dir pattern} {\n" |
| 1094 | 1116 | " if {[file exists $dir/$pattern]} {\n" |
| 1095 | 1117 | "\n" |
| 1096 | -" return $pattern\n" | |
| 1118 | +" return [list $pattern]\n" | |
| 1097 | 1119 | " }\n" |
| 1098 | 1120 | "\n" |
| 1099 | 1121 | " set result {}\n" |
| 1100 | 1122 | " set files [readdir $dir]\n" |
| 1101 | 1123 | " lappend files . ..\n" |
| @@ -1153,11 +1175,11 @@ | ||
| 1153 | 1175 | " }\n" |
| 1154 | 1176 | "\n" |
| 1155 | 1177 | " foreach old $oldexp {\n" |
| 1156 | 1178 | " lappend newexp $old$suf\n" |
| 1157 | 1179 | " }\n" |
| 1158 | -" linsert $newexp 0 $rest\n" | |
| 1180 | +" list $rest {*}$newexp\n" | |
| 1159 | 1181 | "}\n" |
| 1160 | 1182 | "\n" |
| 1161 | 1183 | "\n" |
| 1162 | 1184 | "\n" |
| 1163 | 1185 | "proc glob.glob {base pattern} {\n" |
| @@ -1200,10 +1222,11 @@ | ||
| 1200 | 1222 | "\n" |
| 1201 | 1223 | "\n" |
| 1202 | 1224 | "proc glob {args} {\n" |
| 1203 | 1225 | " set nocomplain 0\n" |
| 1204 | 1226 | " set base \"\"\n" |
| 1227 | +" set tails 0\n" | |
| 1205 | 1228 | "\n" |
| 1206 | 1229 | " set n 0\n" |
| 1207 | 1230 | " foreach arg $args {\n" |
| 1208 | 1231 | " if {[info exists param]} {\n" |
| 1209 | 1232 | " set $param $arg\n" |
| @@ -1217,21 +1240,20 @@ | ||
| 1217 | 1240 | " set param base\n" |
| 1218 | 1241 | " }\n" |
| 1219 | 1242 | " -n* {\n" |
| 1220 | 1243 | " set nocomplain 1\n" |
| 1221 | 1244 | " }\n" |
| 1222 | -" -t* {\n" | |
| 1223 | -"\n" | |
| 1224 | -" }\n" | |
| 1225 | -"\n" | |
| 1226 | -" -* {\n" | |
| 1227 | -" return -code error \"bad option \\\"$switch\\\": must be -directory, -nocomplain, -tails, or --\"\n" | |
| 1245 | +" -ta* {\n" | |
| 1246 | +" set tails 1\n" | |
| 1228 | 1247 | " }\n" |
| 1229 | 1248 | " -- {\n" |
| 1230 | 1249 | " incr n\n" |
| 1231 | 1250 | " break\n" |
| 1232 | 1251 | " }\n" |
| 1252 | +" -* {\n" | |
| 1253 | +" return -code error \"bad option \\\"$arg\\\": must be -directory, -nocomplain, -tails, or --\"\n" | |
| 1254 | +" }\n" | |
| 1233 | 1255 | " * {\n" |
| 1234 | 1256 | " break\n" |
| 1235 | 1257 | " }\n" |
| 1236 | 1258 | " }\n" |
| 1237 | 1259 | " incr n\n" |
| @@ -1245,29 +1267,35 @@ | ||
| 1245 | 1267 | "\n" |
| 1246 | 1268 | " set args [lrange $args $n end]\n" |
| 1247 | 1269 | "\n" |
| 1248 | 1270 | " set result {}\n" |
| 1249 | 1271 | " foreach pattern $args {\n" |
| 1250 | -" set pattern [string map {\n" | |
| 1272 | +" set escpattern [string map {\n" | |
| 1251 | 1273 | " \\\\\\\\ \\x01 \\\\\\{ \\x02 \\\\\\} \\x03 \\\\, \\x04\n" |
| 1252 | 1274 | " } $pattern]\n" |
| 1253 | -" set patexps [lassign [glob.explode $pattern] rest]\n" | |
| 1275 | +" set patexps [lassign [glob.explode $escpattern] rest]\n" | |
| 1254 | 1276 | " if {$rest ne \"\"} {\n" |
| 1255 | 1277 | " return -code error \"unmatched close brace in glob pattern\"\n" |
| 1256 | 1278 | " }\n" |
| 1257 | 1279 | " foreach patexp $patexps {\n" |
| 1258 | 1280 | " set patexp [string map {\n" |
| 1259 | 1281 | " \\x01 \\\\\\\\ \\x02 \\{ \\x03 \\} \\x04 ,\n" |
| 1260 | 1282 | " } $patexp]\n" |
| 1261 | 1283 | " foreach {realname name} [glob.glob $base $patexp] {\n" |
| 1262 | -" lappend result $name\n" | |
| 1284 | +" incr n\n" | |
| 1285 | +" if {$tails} {\n" | |
| 1286 | +" lappend result $name\n" | |
| 1287 | +" } else {\n" | |
| 1288 | +" lappend result [file join $base $name]\n" | |
| 1289 | +" }\n" | |
| 1263 | 1290 | " }\n" |
| 1264 | 1291 | " }\n" |
| 1265 | 1292 | " }\n" |
| 1266 | 1293 | "\n" |
| 1267 | 1294 | " if {!$nocomplain && [llength $result] == 0} {\n" |
| 1268 | -" return -code error \"no files matched glob patterns\"\n" | |
| 1295 | +" set s $(([llength $args] > 1) ? \"s\" : \"\")\n" | |
| 1296 | +" return -code error \"no files matched glob pattern$s \\\"[join $args]\\\"\"\n" | |
| 1269 | 1297 | " }\n" |
| 1270 | 1298 | "\n" |
| 1271 | 1299 | " return $result\n" |
| 1272 | 1300 | "}\n" |
| 1273 | 1301 | ); |
| @@ -1348,11 +1376,11 @@ | ||
| 1348 | 1376 | "\n" |
| 1349 | 1377 | " lappend stacktrace {*}[stacktrace 1]\n" |
| 1350 | 1378 | " }\n" |
| 1351 | 1379 | " lassign $stacktrace p f l\n" |
| 1352 | 1380 | " if {$f ne \"\"} {\n" |
| 1353 | -" set result \"Runtime Error: $f:$l: \"\n" | |
| 1381 | +" set result \"$f:$l: Error: \"\n" | |
| 1354 | 1382 | " }\n" |
| 1355 | 1383 | " append result \"$msg\\n\"\n" |
| 1356 | 1384 | " append result [stackdump $stacktrace]\n" |
| 1357 | 1385 | "\n" |
| 1358 | 1386 | "\n" |
| @@ -1360,22 +1388,13 @@ | ||
| 1360 | 1388 | "}\n" |
| 1361 | 1389 | "\n" |
| 1362 | 1390 | "\n" |
| 1363 | 1391 | "\n" |
| 1364 | 1392 | "proc {info nameofexecutable} {} {\n" |
| 1365 | -" if {[info exists ::jim_argv0]} {\n" | |
| 1366 | -" if {[string match \"*/*\" $::jim_argv0]} {\n" | |
| 1367 | -" return [file join [pwd] $::jim_argv0]\n" | |
| 1368 | -" }\n" | |
| 1369 | -" foreach path [split [env PATH \"\"] $::tcl_platform(pathSeparator)] {\n" | |
| 1370 | -" set exec [file join [pwd] [string map {\\\\ /} $path] $::jim_argv0]\n" | |
| 1371 | -" if {[file executable $exec]} {\n" | |
| 1372 | -" return $exec\n" | |
| 1373 | -" }\n" | |
| 1374 | -" }\n" | |
| 1393 | +" if {[exists ::jim::exe]} {\n" | |
| 1394 | +" return $::jim::exe\n" | |
| 1375 | 1395 | " }\n" |
| 1376 | -" return \"\"\n" | |
| 1377 | 1396 | "}\n" |
| 1378 | 1397 | "\n" |
| 1379 | 1398 | "\n" |
| 1380 | 1399 | "proc {dict with} {&dictVar {args key} script} {\n" |
| 1381 | 1400 | " set keys {}\n" |
| @@ -1587,11 +1606,11 @@ | ||
| 1587 | 1606 | " try {\n" |
| 1588 | 1607 | " if {$force ni {{} -force}} {\n" |
| 1589 | 1608 | " error \"bad option \\\"$force\\\": should be -force\"\n" |
| 1590 | 1609 | " }\n" |
| 1591 | 1610 | "\n" |
| 1592 | -" set in [open $source]\n" | |
| 1611 | +" set in [open $source rb]\n" | |
| 1593 | 1612 | "\n" |
| 1594 | 1613 | " if {[file exists $target]} {\n" |
| 1595 | 1614 | " if {$force eq \"\"} {\n" |
| 1596 | 1615 | " error \"error copying \\\"$source\\\" to \\\"$target\\\": file already exists\"\n" |
| 1597 | 1616 | " }\n" |
| @@ -1605,11 +1624,11 @@ | ||
| 1605 | 1624 | " file stat $target ts\n" |
| 1606 | 1625 | " if {$ss(dev) == $ts(dev) && $ss(ino) == $ts(ino) && $ss(ino)} {\n" |
| 1607 | 1626 | " return\n" |
| 1608 | 1627 | " }\n" |
| 1609 | 1628 | " }\n" |
| 1610 | -" set out [open $target w]\n" | |
| 1629 | +" set out [open $target wb]\n" | |
| 1611 | 1630 | " $in copyto $out\n" |
| 1612 | 1631 | " $out close\n" |
| 1613 | 1632 | " } on error {msg opts} {\n" |
| 1614 | 1633 | " incr opts(-level)\n" |
| 1615 | 1634 | " return {*}$opts $msg\n" |
| @@ -1691,11 +1710,11 @@ | ||
| 1691 | 1710 | " }\n" |
| 1692 | 1711 | " if {[llength $args] == 0} {\n" |
| 1693 | 1712 | " return -code error {wrong # args: should be \"try ?options? script ?argument ...?\"}\n" |
| 1694 | 1713 | " }\n" |
| 1695 | 1714 | " set args [lassign $args script]\n" |
| 1696 | -" set code [catch -eval {*}$catchopts [list uplevel 1 $script] msg opts]\n" | |
| 1715 | +" set code [catch -eval {*}$catchopts {uplevel 1 $script} msg opts]\n" | |
| 1697 | 1716 | "\n" |
| 1698 | 1717 | " set handled 0\n" |
| 1699 | 1718 | "\n" |
| 1700 | 1719 | " foreach {on codes vars script} $args {\n" |
| 1701 | 1720 | " switch -- $on \\\n" |
| @@ -1709,16 +1728,16 @@ | ||
| 1709 | 1728 | " if {$optsvar ne \"\"} {\n" |
| 1710 | 1729 | " upvar $optsvar hopts\n" |
| 1711 | 1730 | " set hopts $opts\n" |
| 1712 | 1731 | " }\n" |
| 1713 | 1732 | "\n" |
| 1714 | -" set code [catch [list uplevel 1 $script] msg opts]\n" | |
| 1733 | +" set code [catch {uplevel 1 $script} msg opts]\n" | |
| 1715 | 1734 | " incr handled\n" |
| 1716 | 1735 | " }\n" |
| 1717 | 1736 | " } \\\n" |
| 1718 | 1737 | " finally {\n" |
| 1719 | -" set finalcode [catch [list uplevel 1 $codes] finalmsg finalopts]\n" | |
| 1738 | +" set finalcode [catch {uplevel 1 $codes} finalmsg finalopts]\n" | |
| 1720 | 1739 | " if {$finalcode} {\n" |
| 1721 | 1740 | "\n" |
| 1722 | 1741 | " set code $finalcode\n" |
| 1723 | 1742 | " set msg $finalmsg\n" |
| 1724 | 1743 | " set opts $finalopts\n" |
| @@ -2502,10 +2521,11 @@ | ||
| 2502 | 2521 | Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1))); |
| 2503 | 2522 | |
| 2504 | 2523 | return JIM_OK; |
| 2505 | 2524 | } |
| 2506 | 2525 | |
| 2526 | +#if defined(HAVE_PIPE) || (defined(HAVE_SOCKETPAIR) && defined(HAVE_SYS_UN_H)) | |
| 2507 | 2527 | static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename, |
| 2508 | 2528 | const char *hdlfmt, int family, const char *mode[2]) |
| 2509 | 2529 | { |
| 2510 | 2530 | if (JimMakeChannel(interp, NULL, p[0], filename, hdlfmt, family, mode[0]) == JIM_OK) { |
| 2511 | 2531 | Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0); |
| @@ -2522,10 +2542,11 @@ | ||
| 2522 | 2542 | close(p[0]); |
| 2523 | 2543 | close(p[1]); |
| 2524 | 2544 | JimAioSetError(interp, NULL); |
| 2525 | 2545 | return JIM_ERR; |
| 2526 | 2546 | } |
| 2547 | +#endif | |
| 2527 | 2548 | |
| 2528 | 2549 | |
| 2529 | 2550 | int Jim_MakeTempFile(Jim_Interp *interp, const char *template) |
| 2530 | 2551 | { |
| 2531 | 2552 | #ifdef HAVE_MKSTEMP |
| @@ -2552,19 +2573,19 @@ | ||
| 2552 | 2573 | |
| 2553 | 2574 | |
| 2554 | 2575 | fd = mkstemp(filenameObj->bytes); |
| 2555 | 2576 | umask(mask); |
| 2556 | 2577 | if (fd < 0) { |
| 2557 | - Jim_SetResultString(interp, "Failed to create tempfile", -1); | |
| 2578 | + JimAioSetError(interp, filenameObj); | |
| 2558 | 2579 | Jim_FreeNewObj(interp, filenameObj); |
| 2559 | 2580 | return -1; |
| 2560 | 2581 | } |
| 2561 | 2582 | |
| 2562 | 2583 | Jim_SetResult(interp, filenameObj); |
| 2563 | 2584 | return fd; |
| 2564 | 2585 | #else |
| 2565 | - Jim_SetResultString(interp, "tempfile not supported", -1); | |
| 2586 | + Jim_SetResultString(interp, "platform has no tempfile support", -1); | |
| 2566 | 2587 | return -1; |
| 2567 | 2588 | #endif |
| 2568 | 2589 | } |
| 2569 | 2590 | |
| 2570 | 2591 | FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command) |
| @@ -3176,10 +3197,16 @@ | ||
| 3176 | 3197 | |
| 3177 | 3198 | # ifndef MAXPATHLEN |
| 3178 | 3199 | # define MAXPATHLEN JIM_PATH_LEN |
| 3179 | 3200 | # endif |
| 3180 | 3201 | |
| 3202 | +#if defined(__MINGW32__) || defined(_MSC_VER) | |
| 3203 | +#define ISWINDOWS 1 | |
| 3204 | +#else | |
| 3205 | +#define ISWINDOWS 0 | |
| 3206 | +#endif | |
| 3207 | + | |
| 3181 | 3208 | |
| 3182 | 3209 | static const char *JimGetFileType(int mode) |
| 3183 | 3210 | { |
| 3184 | 3211 | if (S_ISREG(mode)) { |
| 3185 | 3212 | return "file"; |
| @@ -3281,16 +3308,14 @@ | ||
| 3281 | 3308 | Jim_SetResultString(interp, ".", -1); |
| 3282 | 3309 | } |
| 3283 | 3310 | else if (p == path) { |
| 3284 | 3311 | Jim_SetResultString(interp, "/", -1); |
| 3285 | 3312 | } |
| 3286 | -#if defined(__MINGW32__) || defined(_MSC_VER) | |
| 3287 | - else if (p[-1] == ':') { | |
| 3313 | + else if (ISWINDOWS && p[-1] == ':') { | |
| 3288 | 3314 | |
| 3289 | 3315 | Jim_SetResultString(interp, path, p - path + 1); |
| 3290 | 3316 | } |
| 3291 | -#endif | |
| 3292 | 3317 | else { |
| 3293 | 3318 | Jim_SetResultString(interp, path, p - path); |
| 3294 | 3319 | } |
| 3295 | 3320 | return JIM_OK; |
| 3296 | 3321 | } |
| @@ -3373,16 +3398,14 @@ | ||
| 3373 | 3398 | |
| 3374 | 3399 | if (*part == '/') { |
| 3375 | 3400 | |
| 3376 | 3401 | last = newname; |
| 3377 | 3402 | } |
| 3378 | -#if defined(__MINGW32__) || defined(_MSC_VER) | |
| 3379 | - else if (strchr(part, ':')) { | |
| 3403 | + else if (ISWINDOWS && strchr(part, ':')) { | |
| 3380 | 3404 | |
| 3381 | 3405 | last = newname; |
| 3382 | 3406 | } |
| 3383 | -#endif | |
| 3384 | 3407 | else if (part[0] == '.') { |
| 3385 | 3408 | if (part[1] == '/') { |
| 3386 | 3409 | part += 2; |
| 3387 | 3410 | len -= 2; |
| 3388 | 3411 | } |
| @@ -3407,11 +3430,14 @@ | ||
| 3407 | 3430 | last += len; |
| 3408 | 3431 | } |
| 3409 | 3432 | |
| 3410 | 3433 | |
| 3411 | 3434 | if (last > newname + 1 && last[-1] == '/') { |
| 3412 | - *--last = 0; | |
| 3435 | + | |
| 3436 | + if (!ISWINDOWS || !(last > newname + 2 && last[-2] == ':')) { | |
| 3437 | + *--last = 0; | |
| 3438 | + } | |
| 3413 | 3439 | } |
| 3414 | 3440 | } |
| 3415 | 3441 | |
| 3416 | 3442 | *last = 0; |
| 3417 | 3443 | |
| @@ -3591,10 +3617,48 @@ | ||
| 3591 | 3617 | return JIM_ERR; |
| 3592 | 3618 | } |
| 3593 | 3619 | |
| 3594 | 3620 | return JIM_OK; |
| 3595 | 3621 | } |
| 3622 | + | |
| 3623 | +#if defined(HAVE_LINK) && defined(HAVE_SYMLINK) | |
| 3624 | +static int file_cmd_link(Jim_Interp *interp, int argc, Jim_Obj *const *argv) | |
| 3625 | +{ | |
| 3626 | + int ret; | |
| 3627 | + const char *source; | |
| 3628 | + const char *dest; | |
| 3629 | + static const char * const options[] = { "-hard", "-symbolic", NULL }; | |
| 3630 | + enum { OPT_HARD, OPT_SYMBOLIC, }; | |
| 3631 | + int option = OPT_HARD; | |
| 3632 | + | |
| 3633 | + if (argc == 3) { | |
| 3634 | + if (Jim_GetEnum(interp, argv[0], options, &option, NULL, JIM_ENUM_ABBREV | JIM_ERRMSG) != JIM_OK) { | |
| 3635 | + return JIM_ERR; | |
| 3636 | + } | |
| 3637 | + argv++; | |
| 3638 | + argc--; | |
| 3639 | + } | |
| 3640 | + | |
| 3641 | + dest = Jim_String(argv[0]); | |
| 3642 | + source = Jim_String(argv[1]); | |
| 3643 | + | |
| 3644 | + if (option == OPT_HARD) { | |
| 3645 | + ret = link(source, dest); | |
| 3646 | + } | |
| 3647 | + else { | |
| 3648 | + ret = symlink(source, dest); | |
| 3649 | + } | |
| 3650 | + | |
| 3651 | + if (ret != 0) { | |
| 3652 | + Jim_SetResultFormatted(interp, "error linking \"%#s\" to \"%#s\": %s", argv[0], argv[1], | |
| 3653 | + strerror(errno)); | |
| 3654 | + return JIM_ERR; | |
| 3655 | + } | |
| 3656 | + | |
| 3657 | + return JIM_OK; | |
| 3658 | +} | |
| 3659 | +#endif | |
| 3596 | 3660 | |
| 3597 | 3661 | static int file_stat(Jim_Interp *interp, Jim_Obj *filename, struct stat *sb) |
| 3598 | 3662 | { |
| 3599 | 3663 | const char *path = Jim_String(filename); |
| 3600 | 3664 | |
| @@ -3889,10 +3953,19 @@ | ||
| 3889 | 3953 | file_cmd_rename, |
| 3890 | 3954 | 2, |
| 3891 | 3955 | 3, |
| 3892 | 3956 | |
| 3893 | 3957 | }, |
| 3958 | +#if defined(HAVE_LINK) && defined(HAVE_SYMLINK) | |
| 3959 | + { "link", | |
| 3960 | + "?-symbolic|-hard? newname target", | |
| 3961 | + file_cmd_link, | |
| 3962 | + 2, | |
| 3963 | + 3, | |
| 3964 | + | |
| 3965 | + }, | |
| 3966 | +#endif | |
| 3894 | 3967 | #if defined(HAVE_READLINK) |
| 3895 | 3968 | { "readlink", |
| 3896 | 3969 | "name", |
| 3897 | 3970 | file_cmd_readlink, |
| 3898 | 3971 | 1, |
| @@ -3982,19 +4055,17 @@ | ||
| 3982 | 4055 | if (getcwd(cwd, MAXPATHLEN) == NULL) { |
| 3983 | 4056 | Jim_SetResultString(interp, "Failed to get pwd", -1); |
| 3984 | 4057 | Jim_Free(cwd); |
| 3985 | 4058 | return JIM_ERR; |
| 3986 | 4059 | } |
| 3987 | -#if defined(__MINGW32__) || defined(_MSC_VER) | |
| 3988 | - { | |
| 4060 | + else if (ISWINDOWS) { | |
| 3989 | 4061 | |
| 3990 | 4062 | char *p = cwd; |
| 3991 | 4063 | while ((p = strchr(p, '\\')) != NULL) { |
| 3992 | 4064 | *p++ = '/'; |
| 3993 | 4065 | } |
| 3994 | 4066 | } |
| 3995 | -#endif | |
| 3996 | 4067 | |
| 3997 | 4068 | Jim_SetResultString(interp, cwd, -1); |
| 3998 | 4069 | |
| 3999 | 4070 | Jim_Free(cwd); |
| 4000 | 4071 | return JIM_OK; |
| @@ -5322,22 +5393,20 @@ | ||
| 5322 | 5393 | |
| 5323 | 5394 | static int JimCreateTemp(Jim_Interp *interp, const char *contents, int len) |
| 5324 | 5395 | { |
| 5325 | 5396 | int fd = Jim_MakeTempFile(interp, NULL); |
| 5326 | 5397 | |
| 5327 | - if (fd == JIM_BAD_FD) { | |
| 5328 | - Jim_SetResultErrno(interp, "couldn't create temp file"); | |
| 5329 | - return -1; | |
| 5330 | - } | |
| 5331 | - unlink(Jim_String(Jim_GetResult(interp))); | |
| 5332 | - if (contents) { | |
| 5333 | - if (write(fd, contents, len) != len) { | |
| 5334 | - Jim_SetResultErrno(interp, "couldn't write temp file"); | |
| 5335 | - close(fd); | |
| 5336 | - return -1; | |
| 5337 | - } | |
| 5338 | - lseek(fd, 0L, SEEK_SET); | |
| 5398 | + if (fd != JIM_BAD_FD) { | |
| 5399 | + unlink(Jim_String(Jim_GetResult(interp))); | |
| 5400 | + if (contents) { | |
| 5401 | + if (write(fd, contents, len) != len) { | |
| 5402 | + Jim_SetResultErrno(interp, "couldn't write temp file"); | |
| 5403 | + close(fd); | |
| 5404 | + return -1; | |
| 5405 | + } | |
| 5406 | + lseek(fd, 0L, SEEK_SET); | |
| 5407 | + } | |
| 5339 | 5408 | } |
| 5340 | 5409 | return fd; |
| 5341 | 5410 | } |
| 5342 | 5411 | |
| 5343 | 5412 | static char **JimSaveEnv(char **env) |
| @@ -7768,10 +7837,11 @@ | ||
| 7768 | 7837 | |
| 7769 | 7838 | const char *Jim_String(Jim_Obj *objPtr) |
| 7770 | 7839 | { |
| 7771 | 7840 | if (objPtr->bytes == NULL) { |
| 7772 | 7841 | |
| 7842 | + JimPanic((objPtr->typePtr == NULL, "UpdateStringProc called against typeless value.")); | |
| 7773 | 7843 | JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); |
| 7774 | 7844 | objPtr->typePtr->updateStringProc(objPtr); |
| 7775 | 7845 | } |
| 7776 | 7846 | return objPtr->bytes; |
| 7777 | 7847 | } |
| @@ -8530,11 +8600,11 @@ | ||
| 8530 | 8600 | return objPtr; |
| 8531 | 8601 | } |
| 8532 | 8602 | |
| 8533 | 8603 | static void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); |
| 8534 | 8604 | static void DupScriptInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); |
| 8535 | -static int JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); | |
| 8605 | +static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); | |
| 8536 | 8606 | static int JimParseCheckMissing(Jim_Interp *interp, int ch); |
| 8537 | 8607 | |
| 8538 | 8608 | static const Jim_ObjType scriptObjType = { |
| 8539 | 8609 | "script", |
| 8540 | 8610 | FreeScriptInternalRep, |
| @@ -8558,10 +8628,11 @@ | ||
| 8558 | 8628 | int inUse; /* Used to share a ScriptObj. Currently |
| 8559 | 8629 | only used by Jim_EvalObj() as protection against |
| 8560 | 8630 | shimmering of the currently evaluated object. */ |
| 8561 | 8631 | int firstline; |
| 8562 | 8632 | int linenr; |
| 8633 | + int missing; | |
| 8563 | 8634 | } ScriptObj; |
| 8564 | 8635 | |
| 8565 | 8636 | void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) |
| 8566 | 8637 | { |
| 8567 | 8638 | int i; |
| @@ -8836,19 +8907,18 @@ | ||
| 8836 | 8907 | } |
| 8837 | 8908 | |
| 8838 | 8909 | script->len = i; |
| 8839 | 8910 | } |
| 8840 | 8911 | |
| 8841 | -static int JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) | |
| 8912 | +static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) | |
| 8842 | 8913 | { |
| 8843 | 8914 | int scriptTextLen; |
| 8844 | 8915 | const char *scriptText = Jim_GetString(objPtr, &scriptTextLen); |
| 8845 | 8916 | struct JimParserCtx parser; |
| 8846 | 8917 | struct ScriptObj *script; |
| 8847 | 8918 | ParseTokenList tokenlist; |
| 8848 | 8919 | int line = 1; |
| 8849 | - int retcode = JIM_OK; | |
| 8850 | 8920 | |
| 8851 | 8921 | |
| 8852 | 8922 | if (objPtr->typePtr == &sourceObjType) { |
| 8853 | 8923 | line = objPtr->internalRep.sourceValue.lineNumber; |
| 8854 | 8924 | } |
| @@ -8861,12 +8931,10 @@ | ||
| 8861 | 8931 | JimParseScript(&parser); |
| 8862 | 8932 | ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, |
| 8863 | 8933 | parser.tline); |
| 8864 | 8934 | } |
| 8865 | 8935 | |
| 8866 | - retcode = JimParseCheckMissing(interp, parser.missing.ch); | |
| 8867 | - | |
| 8868 | 8936 | |
| 8869 | 8937 | ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0); |
| 8870 | 8938 | |
| 8871 | 8939 | |
| 8872 | 8940 | script = Jim_Alloc(sizeof(*script)); |
| @@ -8876,12 +8944,13 @@ | ||
| 8876 | 8944 | script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; |
| 8877 | 8945 | } |
| 8878 | 8946 | else { |
| 8879 | 8947 | script->fileNameObj = interp->emptyObj; |
| 8880 | 8948 | } |
| 8881 | - script->linenr = parser.missing.line; | |
| 8882 | 8949 | Jim_IncrRefCount(script->fileNameObj); |
| 8950 | + script->missing = parser.missing.ch; | |
| 8951 | + script->linenr = parser.missing.line; | |
| 8883 | 8952 | |
| 8884 | 8953 | ScriptObjAddTokens(interp, script, &tokenlist); |
| 8885 | 8954 | |
| 8886 | 8955 | |
| 8887 | 8956 | ScriptTokenListFree(&tokenlist); |
| @@ -8888,28 +8957,37 @@ | ||
| 8888 | 8957 | |
| 8889 | 8958 | |
| 8890 | 8959 | Jim_FreeIntRep(interp, objPtr); |
| 8891 | 8960 | Jim_SetIntRepPtr(objPtr, script); |
| 8892 | 8961 | objPtr->typePtr = &scriptObjType; |
| 8893 | - | |
| 8894 | - return retcode; | |
| 8895 | 8962 | } |
| 8896 | 8963 | |
| 8897 | -ScriptObj *Jim_GetScript(Jim_Interp *interp, Jim_Obj *objPtr) | |
| 8964 | +static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script); | |
| 8965 | + | |
| 8966 | +ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr) | |
| 8898 | 8967 | { |
| 8899 | 8968 | if (objPtr == interp->emptyObj) { |
| 8900 | 8969 | |
| 8901 | 8970 | objPtr = interp->nullScriptObj; |
| 8902 | 8971 | } |
| 8903 | 8972 | |
| 8904 | 8973 | if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) { |
| 8905 | - if (JimSetScriptFromAny(interp, objPtr) == JIM_ERR) { | |
| 8906 | - return NULL; | |
| 8907 | - } | |
| 8974 | + JimSetScriptFromAny(interp, objPtr); | |
| 8908 | 8975 | } |
| 8909 | - return (ScriptObj *) Jim_GetIntRepPtr(objPtr); | |
| 8976 | + | |
| 8977 | + return (ScriptObj *)Jim_GetIntRepPtr(objPtr); | |
| 8910 | 8978 | } |
| 8979 | + | |
| 8980 | +static int JimScriptValid(Jim_Interp *interp, ScriptObj *script) | |
| 8981 | +{ | |
| 8982 | + if (JimParseCheckMissing(interp, script->missing) == JIM_ERR) { | |
| 8983 | + JimAddErrorToStack(interp, script); | |
| 8984 | + return 0; | |
| 8985 | + } | |
| 8986 | + return 1; | |
| 8987 | +} | |
| 8988 | + | |
| 8911 | 8989 | |
| 8912 | 8990 | static void JimIncrCmdRefCount(Jim_Cmd *cmdPtr) |
| 8913 | 8991 | { |
| 8914 | 8992 | cmdPtr->inUse++; |
| 8915 | 8993 | } |
| @@ -10901,11 +10979,11 @@ | ||
| 10901 | 10979 | return JIM_OK; |
| 10902 | 10980 | } |
| 10903 | 10981 | else { |
| 10904 | 10982 | |
| 10905 | 10983 | if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) { |
| 10906 | - Jim_SetResultFormatted(interp, "expected number but got \"%#s\"", objPtr); | |
| 10984 | + Jim_SetResultFormatted(interp, "expected floating-point number but got \"%#s\"", objPtr); | |
| 10907 | 10985 | return JIM_ERR; |
| 10908 | 10986 | } |
| 10909 | 10987 | |
| 10910 | 10988 | Jim_FreeIntRep(interp, objPtr); |
| 10911 | 10989 | } |
| @@ -12331,10 +12409,11 @@ | ||
| 12331 | 12409 | JIM_EXPROP_UNARYPLUS, |
| 12332 | 12410 | |
| 12333 | 12411 | |
| 12334 | 12412 | JIM_EXPROP_FUNC_FIRST, |
| 12335 | 12413 | JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST, |
| 12414 | + JIM_EXPROP_FUNC_WIDE, | |
| 12336 | 12415 | JIM_EXPROP_FUNC_ABS, |
| 12337 | 12416 | JIM_EXPROP_FUNC_DOUBLE, |
| 12338 | 12417 | JIM_EXPROP_FUNC_ROUND, |
| 12339 | 12418 | JIM_EXPROP_FUNC_RAND, |
| 12340 | 12419 | JIM_EXPROP_FUNC_SRAND, |
| @@ -12397,10 +12476,11 @@ | ||
| 12397 | 12476 | jim_wide wA, wC = 0; |
| 12398 | 12477 | |
| 12399 | 12478 | if ((A->typePtr != &doubleObjType || A->bytes) && JimGetWideNoErr(interp, A, &wA) == JIM_OK) { |
| 12400 | 12479 | switch (e->opcode) { |
| 12401 | 12480 | case JIM_EXPROP_FUNC_INT: |
| 12481 | + case JIM_EXPROP_FUNC_WIDE: | |
| 12402 | 12482 | case JIM_EXPROP_FUNC_ROUND: |
| 12403 | 12483 | case JIM_EXPROP_UNARYPLUS: |
| 12404 | 12484 | wC = wA; |
| 12405 | 12485 | break; |
| 12406 | 12486 | case JIM_EXPROP_FUNC_DOUBLE: |
| @@ -12421,10 +12501,11 @@ | ||
| 12421 | 12501 | } |
| 12422 | 12502 | } |
| 12423 | 12503 | else if ((rc = Jim_GetDouble(interp, A, &dA)) == JIM_OK) { |
| 12424 | 12504 | switch (e->opcode) { |
| 12425 | 12505 | case JIM_EXPROP_FUNC_INT: |
| 12506 | + case JIM_EXPROP_FUNC_WIDE: | |
| 12426 | 12507 | wC = dA; |
| 12427 | 12508 | break; |
| 12428 | 12509 | case JIM_EXPROP_FUNC_ROUND: |
| 12429 | 12510 | wC = dA < 0 ? (dA - 0.5) : (dA + 0.5); |
| 12430 | 12511 | break; |
| @@ -13093,10 +13174,11 @@ | ||
| 13093 | 13174 | OPRINIT(NULL, 150, 1, JimExprOpNumUnary), |
| 13094 | 13175 | |
| 13095 | 13176 | |
| 13096 | 13177 | |
| 13097 | 13178 | OPRINIT("int", 200, 1, JimExprOpNumUnary), |
| 13179 | + OPRINIT("wide", 200, 1, JimExprOpNumUnary), | |
| 13098 | 13180 | OPRINIT("abs", 200, 1, JimExprOpNumUnary), |
| 13099 | 13181 | OPRINIT("double", 200, 1, JimExprOpNumUnary), |
| 13100 | 13182 | OPRINIT("round", 200, 1, JimExprOpNumUnary), |
| 13101 | 13183 | OPRINIT("rand", 200, 0, JimExprOpNone), |
| 13102 | 13184 | OPRINIT("srand", 200, 1, JimExprOpIntUnary), |
| @@ -14750,15 +14832,13 @@ | ||
| 14750 | 14832 | ret = Jim_EvalObjVector(interp, objc + 1, nargv); |
| 14751 | 14833 | Jim_Free(nargv); |
| 14752 | 14834 | return ret; |
| 14753 | 14835 | } |
| 14754 | 14836 | |
| 14755 | -static void JimAddErrorToStack(Jim_Interp *interp, int retcode, ScriptObj *script) | |
| 14837 | +static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script) | |
| 14756 | 14838 | { |
| 14757 | - int rc = retcode; | |
| 14758 | - | |
| 14759 | - if (rc == JIM_ERR && !interp->errorFlag) { | |
| 14839 | + if (!interp->errorFlag) { | |
| 14760 | 14840 | |
| 14761 | 14841 | interp->errorFlag = 1; |
| 14762 | 14842 | Jim_IncrRefCount(script->fileNameObj); |
| 14763 | 14843 | Jim_DecrRefCount(interp, interp->errorFileNameObj); |
| 14764 | 14844 | interp->errorFileNameObj = script->fileNameObj; |
| @@ -14768,11 +14848,11 @@ | ||
| 14768 | 14848 | |
| 14769 | 14849 | interp->addStackTrace++; |
| 14770 | 14850 | } |
| 14771 | 14851 | |
| 14772 | 14852 | |
| 14773 | - if (rc == JIM_ERR && interp->addStackTrace > 0) { | |
| 14853 | + if (interp->addStackTrace > 0) { | |
| 14774 | 14854 | |
| 14775 | 14855 | |
| 14776 | 14856 | JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr); |
| 14777 | 14857 | |
| 14778 | 14858 | if (Jim_Length(script->fileNameObj)) { |
| @@ -14781,16 +14861,10 @@ | ||
| 14781 | 14861 | |
| 14782 | 14862 | Jim_DecrRefCount(interp, interp->errorProc); |
| 14783 | 14863 | interp->errorProc = interp->emptyObj; |
| 14784 | 14864 | Jim_IncrRefCount(interp->errorProc); |
| 14785 | 14865 | } |
| 14786 | - else if (rc == JIM_RETURN && interp->returnCode == JIM_ERR) { | |
| 14787 | - | |
| 14788 | - } | |
| 14789 | - else { | |
| 14790 | - interp->addStackTrace = 0; | |
| 14791 | - } | |
| 14792 | 14866 | } |
| 14793 | 14867 | |
| 14794 | 14868 | static int JimSubstOneToken(Jim_Interp *interp, const ScriptToken *token, Jim_Obj **objPtrPtr) |
| 14795 | 14869 | { |
| 14796 | 14870 | Jim_Obj *objPtr; |
| @@ -14928,10 +15002,12 @@ | ||
| 14928 | 15002 | |
| 14929 | 15003 | static int JimEvalObjList(Jim_Interp *interp, Jim_Obj *listPtr) |
| 14930 | 15004 | { |
| 14931 | 15005 | int retcode = JIM_OK; |
| 14932 | 15006 | |
| 15007 | + JimPanic((Jim_IsList(listPtr) == 0, "JimEvalObjList() invoked on non-list.")); | |
| 15008 | + | |
| 14933 | 15009 | if (listPtr->internalRep.listValue.len) { |
| 14934 | 15010 | Jim_IncrRefCount(listPtr); |
| 14935 | 15011 | retcode = JimInvokeCommand(interp, |
| 14936 | 15012 | listPtr->internalRep.listValue.len, |
| 14937 | 15013 | listPtr->internalRep.listValue.ele); |
| @@ -14958,12 +15034,12 @@ | ||
| 14958 | 15034 | if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) { |
| 14959 | 15035 | return JimEvalObjList(interp, scriptObjPtr); |
| 14960 | 15036 | } |
| 14961 | 15037 | |
| 14962 | 15038 | Jim_IncrRefCount(scriptObjPtr); |
| 14963 | - script = Jim_GetScript(interp, scriptObjPtr); | |
| 14964 | - if (script == NULL) { | |
| 15039 | + script = JimGetScript(interp, scriptObjPtr); | |
| 15040 | + if (!JimScriptValid(interp, script)) { | |
| 14965 | 15041 | Jim_DecrRefCount(interp, scriptObjPtr); |
| 14966 | 15042 | return JIM_ERR; |
| 14967 | 15043 | } |
| 14968 | 15044 | |
| 14969 | 15045 | Jim_SetEmptyResult(interp); |
| @@ -15125,11 +15201,18 @@ | ||
| 15125 | 15201 | argv = sargv; |
| 15126 | 15202 | } |
| 15127 | 15203 | } |
| 15128 | 15204 | |
| 15129 | 15205 | |
| 15130 | - JimAddErrorToStack(interp, retcode, script); | |
| 15206 | + if (retcode == JIM_ERR) { | |
| 15207 | + JimAddErrorToStack(interp, script); | |
| 15208 | + } | |
| 15209 | + | |
| 15210 | + else if (retcode != JIM_RETURN || interp->returnCode != JIM_ERR) { | |
| 15211 | + | |
| 15212 | + interp->addStackTrace = 0; | |
| 15213 | + } | |
| 15131 | 15214 | |
| 15132 | 15215 | |
| 15133 | 15216 | interp->currentScriptObj = prevScriptObj; |
| 15134 | 15217 | |
| 15135 | 15218 | Jim_FreeIntRep(interp, scriptObjPtr); |
| @@ -15276,11 +15359,11 @@ | ||
| 15276 | 15359 | callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr; |
| 15277 | 15360 | callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr; |
| 15278 | 15361 | callFramePtr->staticVars = cmd->u.proc.staticVars; |
| 15279 | 15362 | |
| 15280 | 15363 | |
| 15281 | - script = Jim_GetScript(interp, interp->currentScriptObj); | |
| 15364 | + script = JimGetScript(interp, interp->currentScriptObj); | |
| 15282 | 15365 | callFramePtr->fileNameObj = script->fileNameObj; |
| 15283 | 15366 | callFramePtr->line = script->linenr; |
| 15284 | 15367 | |
| 15285 | 15368 | Jim_IncrRefCount(cmd->u.proc.argListObjPtr); |
| 15286 | 15369 | Jim_IncrRefCount(cmd->u.proc.bodyObjPtr); |
| @@ -15473,18 +15556,10 @@ | ||
| 15473 | 15556 | |
| 15474 | 15557 | scriptObjPtr = Jim_NewStringObjNoAlloc(interp, buf, readlen); |
| 15475 | 15558 | JimSetSourceInfo(interp, scriptObjPtr, Jim_NewStringObj(interp, filename, -1), 1); |
| 15476 | 15559 | Jim_IncrRefCount(scriptObjPtr); |
| 15477 | 15560 | |
| 15478 | - | |
| 15479 | - if (Jim_GetScript(interp, scriptObjPtr) == NULL) { | |
| 15480 | - | |
| 15481 | - JimAddErrorToStack(interp, JIM_ERR, (ScriptObj *)Jim_GetIntRepPtr(scriptObjPtr)); | |
| 15482 | - Jim_DecrRefCount(interp, scriptObjPtr); | |
| 15483 | - return JIM_ERR; | |
| 15484 | - } | |
| 15485 | - | |
| 15486 | 15561 | prevScriptObj = interp->currentScriptObj; |
| 15487 | 15562 | interp->currentScriptObj = scriptObjPtr; |
| 15488 | 15563 | |
| 15489 | 15564 | retcode = Jim_EvalObj(interp, scriptObjPtr); |
| 15490 | 15565 | |
| @@ -16030,11 +16105,11 @@ | ||
| 16030 | 16105 | Jim_Obj *objPtr; |
| 16031 | 16106 | int cmpOffset; |
| 16032 | 16107 | |
| 16033 | 16108 | |
| 16034 | 16109 | expr = JimGetExpression(interp, argv[2]); |
| 16035 | - incrScript = Jim_GetScript(interp, argv[3]); | |
| 16110 | + incrScript = JimGetScript(interp, argv[3]); | |
| 16036 | 16111 | |
| 16037 | 16112 | |
| 16038 | 16113 | if (incrScript == NULL || incrScript->len != 3 || !expr || expr->len != 3) { |
| 16039 | 16114 | goto evalstart; |
| 16040 | 16115 | } |
| @@ -17017,11 +17092,11 @@ | ||
| 17017 | 17092 | { |
| 17018 | 17093 | Jim_Obj *stringObjPtr; |
| 17019 | 17094 | int i; |
| 17020 | 17095 | |
| 17021 | 17096 | if (argc < 2) { |
| 17022 | - Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?"); | |
| 17097 | + Jim_WrongNumArgs(interp, 1, argv, "varName ?value ...?"); | |
| 17023 | 17098 | return JIM_ERR; |
| 17024 | 17099 | } |
| 17025 | 17100 | if (argc == 2) { |
| 17026 | 17101 | stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); |
| 17027 | 17102 | if (!stringObjPtr) |
| @@ -17066,11 +17141,11 @@ | ||
| 17066 | 17141 | static int Jim_EvalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) |
| 17067 | 17142 | { |
| 17068 | 17143 | int rc; |
| 17069 | 17144 | |
| 17070 | 17145 | if (argc < 2) { |
| 17071 | - Jim_WrongNumArgs(interp, 1, argv, "script ?...?"); | |
| 17146 | + Jim_WrongNumArgs(interp, 1, argv, "arg ?arg ...?"); | |
| 17072 | 17147 | return JIM_ERR; |
| 17073 | 17148 | } |
| 17074 | 17149 | |
| 17075 | 17150 | if (argc == 2) { |
| 17076 | 17151 | rc = Jim_EvalObj(interp, argv[1]); |
| @@ -17277,11 +17352,11 @@ | ||
| 17277 | 17352 | Jim_Obj *cmdList; |
| 17278 | 17353 | Jim_Obj *prefixListObj = Jim_CmdPrivData(interp); |
| 17279 | 17354 | |
| 17280 | 17355 | |
| 17281 | 17356 | cmdList = Jim_DuplicateObj(interp, prefixListObj); |
| 17282 | - ListInsertElements(cmdList, -1, argc - 1, argv + 1); | |
| 17357 | + Jim_ListInsertElements(interp, cmdList, Jim_ListLength(interp, cmdList), argc - 1, argv + 1); | |
| 17283 | 17358 | |
| 17284 | 17359 | return JimEvalObjList(interp, cmdList); |
| 17285 | 17360 | } |
| 17286 | 17361 | |
| 17287 | 17362 | static void JimAliasCmdDelete(Jim_Interp *interp, void *privData) |
| @@ -17597,17 +17672,17 @@ | ||
| 17597 | 17672 | int len; |
| 17598 | 17673 | int opt_case = 1; |
| 17599 | 17674 | int option; |
| 17600 | 17675 | static const char * const options[] = { |
| 17601 | 17676 | "bytelength", "length", "compare", "match", "equal", "is", "byterange", "range", "replace", |
| 17602 | - "map", "repeat", "reverse", "index", "first", "last", | |
| 17677 | + "map", "repeat", "reverse", "index", "first", "last", "cat", | |
| 17603 | 17678 | "trim", "trimleft", "trimright", "tolower", "toupper", "totitle", NULL |
| 17604 | 17679 | }; |
| 17605 | 17680 | enum |
| 17606 | 17681 | { |
| 17607 | 17682 | OPT_BYTELENGTH, OPT_LENGTH, OPT_COMPARE, OPT_MATCH, OPT_EQUAL, OPT_IS, OPT_BYTERANGE, OPT_RANGE, OPT_REPLACE, |
| 17608 | - OPT_MAP, OPT_REPEAT, OPT_REVERSE, OPT_INDEX, OPT_FIRST, OPT_LAST, | |
| 17683 | + OPT_MAP, OPT_REPEAT, OPT_REVERSE, OPT_INDEX, OPT_FIRST, OPT_LAST, OPT_CAT, | |
| 17609 | 17684 | OPT_TRIM, OPT_TRIMLEFT, OPT_TRIMRIGHT, OPT_TOLOWER, OPT_TOUPPER, OPT_TOTITLE |
| 17610 | 17685 | }; |
| 17611 | 17686 | static const char * const nocase_options[] = { |
| 17612 | 17687 | "-nocase", NULL |
| 17613 | 17688 | }; |
| @@ -17636,10 +17711,29 @@ | ||
| 17636 | 17711 | else { |
| 17637 | 17712 | len = Jim_Length(argv[2]); |
| 17638 | 17713 | } |
| 17639 | 17714 | Jim_SetResultInt(interp, len); |
| 17640 | 17715 | return JIM_OK; |
| 17716 | + | |
| 17717 | + case OPT_CAT:{ | |
| 17718 | + Jim_Obj *objPtr; | |
| 17719 | + if (argc == 3) { | |
| 17720 | + | |
| 17721 | + objPtr = argv[2]; | |
| 17722 | + } | |
| 17723 | + else { | |
| 17724 | + int i; | |
| 17725 | + | |
| 17726 | + objPtr = Jim_NewStringObj(interp, "", 0); | |
| 17727 | + | |
| 17728 | + for (i = 2; i < argc; i++) { | |
| 17729 | + Jim_AppendObj(interp, objPtr, argv[i]); | |
| 17730 | + } | |
| 17731 | + } | |
| 17732 | + Jim_SetResult(interp, objPtr); | |
| 17733 | + return JIM_OK; | |
| 17734 | + } | |
| 17641 | 17735 | |
| 17642 | 17736 | case OPT_COMPARE: |
| 17643 | 17737 | case OPT_EQUAL: |
| 17644 | 17738 | { |
| 17645 | 17739 | |
| @@ -18619,38 +18713,47 @@ | ||
| 18619 | 18713 | case INFO_SCRIPT: |
| 18620 | 18714 | if (argc != 2) { |
| 18621 | 18715 | Jim_WrongNumArgs(interp, 2, argv, ""); |
| 18622 | 18716 | return JIM_ERR; |
| 18623 | 18717 | } |
| 18624 | - Jim_SetResult(interp, Jim_GetScript(interp, interp->currentScriptObj)->fileNameObj); | |
| 18718 | + Jim_SetResult(interp, JimGetScript(interp, interp->currentScriptObj)->fileNameObj); | |
| 18625 | 18719 | break; |
| 18626 | 18720 | |
| 18627 | 18721 | case INFO_SOURCE:{ |
| 18628 | - int line; | |
| 18722 | + jim_wide line; | |
| 18629 | 18723 | Jim_Obj *resObjPtr; |
| 18630 | 18724 | Jim_Obj *fileNameObj; |
| 18631 | 18725 | |
| 18632 | - if (argc != 3) { | |
| 18633 | - Jim_WrongNumArgs(interp, 2, argv, "source"); | |
| 18726 | + if (argc != 3 && argc != 5) { | |
| 18727 | + Jim_WrongNumArgs(interp, 2, argv, "source ?filename line?"); | |
| 18634 | 18728 | return JIM_ERR; |
| 18635 | 18729 | } |
| 18636 | - if (argv[2]->typePtr == &sourceObjType) { | |
| 18637 | - fileNameObj = argv[2]->internalRep.sourceValue.fileNameObj; | |
| 18638 | - line = argv[2]->internalRep.sourceValue.lineNumber; | |
| 18639 | - } | |
| 18640 | - else if (argv[2]->typePtr == &scriptObjType) { | |
| 18641 | - ScriptObj *script = Jim_GetScript(interp, argv[2]); | |
| 18642 | - fileNameObj = script->fileNameObj; | |
| 18643 | - line = script->firstline; | |
| 18730 | + if (argc == 5) { | |
| 18731 | + if (Jim_GetWide(interp, argv[4], &line) != JIM_OK) { | |
| 18732 | + return JIM_ERR; | |
| 18733 | + } | |
| 18734 | + resObjPtr = Jim_NewStringObj(interp, Jim_String(argv[2]), Jim_Length(argv[2])); | |
| 18735 | + JimSetSourceInfo(interp, resObjPtr, argv[3], line); | |
| 18644 | 18736 | } |
| 18645 | 18737 | else { |
| 18646 | - fileNameObj = interp->emptyObj; | |
| 18647 | - line = 1; | |
| 18738 | + if (argv[2]->typePtr == &sourceObjType) { | |
| 18739 | + fileNameObj = argv[2]->internalRep.sourceValue.fileNameObj; | |
| 18740 | + line = argv[2]->internalRep.sourceValue.lineNumber; | |
| 18741 | + } | |
| 18742 | + else if (argv[2]->typePtr == &scriptObjType) { | |
| 18743 | + ScriptObj *script = JimGetScript(interp, argv[2]); | |
| 18744 | + fileNameObj = script->fileNameObj; | |
| 18745 | + line = script->firstline; | |
| 18746 | + } | |
| 18747 | + else { | |
| 18748 | + fileNameObj = interp->emptyObj; | |
| 18749 | + line = 1; | |
| 18750 | + } | |
| 18751 | + resObjPtr = Jim_NewListObj(interp, NULL, 0); | |
| 18752 | + Jim_ListAppendElement(interp, resObjPtr, fileNameObj); | |
| 18753 | + Jim_ListAppendElement(interp, resObjPtr, Jim_NewIntObj(interp, line)); | |
| 18648 | 18754 | } |
| 18649 | - resObjPtr = Jim_NewListObj(interp, NULL, 0); | |
| 18650 | - Jim_ListAppendElement(interp, resObjPtr, fileNameObj); | |
| 18651 | - Jim_ListAppendElement(interp, resObjPtr, Jim_NewIntObj(interp, line)); | |
| 18652 | 18755 | Jim_SetResult(interp, resObjPtr); |
| 18653 | 18756 | break; |
| 18654 | 18757 | } |
| 18655 | 18758 | |
| 18656 | 18759 | case INFO_STACKTRACE: |
| @@ -21843,11 +21946,11 @@ | ||
| 21843 | 21946 | |
| 21844 | 21947 | if (Jim_InitStaticExtensions(interp) != JIM_OK) { |
| 21845 | 21948 | JimPrintErrorMessage(interp); |
| 21846 | 21949 | } |
| 21847 | 21950 | |
| 21848 | - Jim_SetVariableStrWithStr(interp, "jim_argv0", argv[0]); | |
| 21951 | + Jim_SetVariableStrWithStr(interp, "jim::argv0", argv[0]); | |
| 21849 | 21952 | Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0"); |
| 21850 | 21953 | retcode = Jim_initjimshInit(interp); |
| 21851 | 21954 | |
| 21852 | 21955 | if (argc == 1) { |
| 21853 | 21956 | if (retcode == JIM_ERR) { |
| 21854 | 21957 |
| --- autosetup/jimsh0.c | |
| +++ autosetup/jimsh0.c | |
| @@ -38,15 +38,17 @@ | |
| 38 | #define TCL_PLATFORM_PLATFORM "unix" |
| 39 | #define TCL_PLATFORM_PATH_SEPARATOR ":" |
| 40 | #define HAVE_VFORK |
| 41 | #define HAVE_WAITPID |
| 42 | #define HAVE_ISATTY |
| 43 | #define HAVE_SYS_TIME_H |
| 44 | #define HAVE_DIRENT_H |
| 45 | #define HAVE_UNISTD_H |
| 46 | #endif |
| 47 | #define JIM_VERSION 75 |
| 48 | #ifndef JIM_WIN32COMPAT_H |
| 49 | #define JIM_WIN32COMPAT_H |
| 50 | |
| 51 | |
| 52 | |
| @@ -113,10 +115,11 @@ | |
| 113 | int closedir(DIR *dir); |
| 114 | struct dirent *readdir(DIR *dir); |
| 115 | |
| 116 | #elif defined(__MINGW32__) |
| 117 | |
| 118 | #define strtod __strtod |
| 119 | |
| 120 | #endif |
| 121 | |
| 122 | #endif |
| @@ -1048,29 +1051,48 @@ | |
| 1048 | "\n" |
| 1049 | "\n" |
| 1050 | "\n" |
| 1051 | "proc _jimsh_init {} {\n" |
| 1052 | " rename _jimsh_init {}\n" |
| 1053 | "\n" |
| 1054 | "\n" |
| 1055 | " lappend p {*}[split [env JIMLIB {}] $::tcl_platform(pathSeparator)]\n" |
| 1056 | " lappend p {*}$::auto_path\n" |
| 1057 | " lappend p [file dirname [info nameofexecutable]]\n" |
| 1058 | " set ::auto_path $p\n" |
| 1059 | "\n" |
| 1060 | " if {$::tcl_interactive && [env HOME {}] ne \"\"} {\n" |
| 1061 | " foreach src {.jimrc jimrc.tcl} {\n" |
| 1062 | " if {[file exists [env HOME]/$src]} {\n" |
| 1063 | " uplevel #0 source [env HOME]/$src\n" |
| 1064 | " break\n" |
| 1065 | " }\n" |
| 1066 | " }\n" |
| 1067 | " }\n" |
| 1068 | "}\n" |
| 1069 | "\n" |
| 1070 | "if {$tcl_platform(platform) eq \"windows\"} {\n" |
| 1071 | " set jim_argv0 [string map {\\\\ /} $jim_argv0]\n" |
| 1072 | "}\n" |
| 1073 | "\n" |
| 1074 | "_jimsh_init\n" |
| 1075 | ); |
| 1076 | } |
| @@ -1091,11 +1113,11 @@ | |
| 1091 | "\n" |
| 1092 | "\n" |
| 1093 | "proc glob.globdir {dir pattern} {\n" |
| 1094 | " if {[file exists $dir/$pattern]} {\n" |
| 1095 | "\n" |
| 1096 | " return $pattern\n" |
| 1097 | " }\n" |
| 1098 | "\n" |
| 1099 | " set result {}\n" |
| 1100 | " set files [readdir $dir]\n" |
| 1101 | " lappend files . ..\n" |
| @@ -1153,11 +1175,11 @@ | |
| 1153 | " }\n" |
| 1154 | "\n" |
| 1155 | " foreach old $oldexp {\n" |
| 1156 | " lappend newexp $old$suf\n" |
| 1157 | " }\n" |
| 1158 | " linsert $newexp 0 $rest\n" |
| 1159 | "}\n" |
| 1160 | "\n" |
| 1161 | "\n" |
| 1162 | "\n" |
| 1163 | "proc glob.glob {base pattern} {\n" |
| @@ -1200,10 +1222,11 @@ | |
| 1200 | "\n" |
| 1201 | "\n" |
| 1202 | "proc glob {args} {\n" |
| 1203 | " set nocomplain 0\n" |
| 1204 | " set base \"\"\n" |
| 1205 | "\n" |
| 1206 | " set n 0\n" |
| 1207 | " foreach arg $args {\n" |
| 1208 | " if {[info exists param]} {\n" |
| 1209 | " set $param $arg\n" |
| @@ -1217,21 +1240,20 @@ | |
| 1217 | " set param base\n" |
| 1218 | " }\n" |
| 1219 | " -n* {\n" |
| 1220 | " set nocomplain 1\n" |
| 1221 | " }\n" |
| 1222 | " -t* {\n" |
| 1223 | "\n" |
| 1224 | " }\n" |
| 1225 | "\n" |
| 1226 | " -* {\n" |
| 1227 | " return -code error \"bad option \\\"$switch\\\": must be -directory, -nocomplain, -tails, or --\"\n" |
| 1228 | " }\n" |
| 1229 | " -- {\n" |
| 1230 | " incr n\n" |
| 1231 | " break\n" |
| 1232 | " }\n" |
| 1233 | " * {\n" |
| 1234 | " break\n" |
| 1235 | " }\n" |
| 1236 | " }\n" |
| 1237 | " incr n\n" |
| @@ -1245,29 +1267,35 @@ | |
| 1245 | "\n" |
| 1246 | " set args [lrange $args $n end]\n" |
| 1247 | "\n" |
| 1248 | " set result {}\n" |
| 1249 | " foreach pattern $args {\n" |
| 1250 | " set pattern [string map {\n" |
| 1251 | " \\\\\\\\ \\x01 \\\\\\{ \\x02 \\\\\\} \\x03 \\\\, \\x04\n" |
| 1252 | " } $pattern]\n" |
| 1253 | " set patexps [lassign [glob.explode $pattern] rest]\n" |
| 1254 | " if {$rest ne \"\"} {\n" |
| 1255 | " return -code error \"unmatched close brace in glob pattern\"\n" |
| 1256 | " }\n" |
| 1257 | " foreach patexp $patexps {\n" |
| 1258 | " set patexp [string map {\n" |
| 1259 | " \\x01 \\\\\\\\ \\x02 \\{ \\x03 \\} \\x04 ,\n" |
| 1260 | " } $patexp]\n" |
| 1261 | " foreach {realname name} [glob.glob $base $patexp] {\n" |
| 1262 | " lappend result $name\n" |
| 1263 | " }\n" |
| 1264 | " }\n" |
| 1265 | " }\n" |
| 1266 | "\n" |
| 1267 | " if {!$nocomplain && [llength $result] == 0} {\n" |
| 1268 | " return -code error \"no files matched glob patterns\"\n" |
| 1269 | " }\n" |
| 1270 | "\n" |
| 1271 | " return $result\n" |
| 1272 | "}\n" |
| 1273 | ); |
| @@ -1348,11 +1376,11 @@ | |
| 1348 | "\n" |
| 1349 | " lappend stacktrace {*}[stacktrace 1]\n" |
| 1350 | " }\n" |
| 1351 | " lassign $stacktrace p f l\n" |
| 1352 | " if {$f ne \"\"} {\n" |
| 1353 | " set result \"Runtime Error: $f:$l: \"\n" |
| 1354 | " }\n" |
| 1355 | " append result \"$msg\\n\"\n" |
| 1356 | " append result [stackdump $stacktrace]\n" |
| 1357 | "\n" |
| 1358 | "\n" |
| @@ -1360,22 +1388,13 @@ | |
| 1360 | "}\n" |
| 1361 | "\n" |
| 1362 | "\n" |
| 1363 | "\n" |
| 1364 | "proc {info nameofexecutable} {} {\n" |
| 1365 | " if {[info exists ::jim_argv0]} {\n" |
| 1366 | " if {[string match \"*/*\" $::jim_argv0]} {\n" |
| 1367 | " return [file join [pwd] $::jim_argv0]\n" |
| 1368 | " }\n" |
| 1369 | " foreach path [split [env PATH \"\"] $::tcl_platform(pathSeparator)] {\n" |
| 1370 | " set exec [file join [pwd] [string map {\\\\ /} $path] $::jim_argv0]\n" |
| 1371 | " if {[file executable $exec]} {\n" |
| 1372 | " return $exec\n" |
| 1373 | " }\n" |
| 1374 | " }\n" |
| 1375 | " }\n" |
| 1376 | " return \"\"\n" |
| 1377 | "}\n" |
| 1378 | "\n" |
| 1379 | "\n" |
| 1380 | "proc {dict with} {&dictVar {args key} script} {\n" |
| 1381 | " set keys {}\n" |
| @@ -1587,11 +1606,11 @@ | |
| 1587 | " try {\n" |
| 1588 | " if {$force ni {{} -force}} {\n" |
| 1589 | " error \"bad option \\\"$force\\\": should be -force\"\n" |
| 1590 | " }\n" |
| 1591 | "\n" |
| 1592 | " set in [open $source]\n" |
| 1593 | "\n" |
| 1594 | " if {[file exists $target]} {\n" |
| 1595 | " if {$force eq \"\"} {\n" |
| 1596 | " error \"error copying \\\"$source\\\" to \\\"$target\\\": file already exists\"\n" |
| 1597 | " }\n" |
| @@ -1605,11 +1624,11 @@ | |
| 1605 | " file stat $target ts\n" |
| 1606 | " if {$ss(dev) == $ts(dev) && $ss(ino) == $ts(ino) && $ss(ino)} {\n" |
| 1607 | " return\n" |
| 1608 | " }\n" |
| 1609 | " }\n" |
| 1610 | " set out [open $target w]\n" |
| 1611 | " $in copyto $out\n" |
| 1612 | " $out close\n" |
| 1613 | " } on error {msg opts} {\n" |
| 1614 | " incr opts(-level)\n" |
| 1615 | " return {*}$opts $msg\n" |
| @@ -1691,11 +1710,11 @@ | |
| 1691 | " }\n" |
| 1692 | " if {[llength $args] == 0} {\n" |
| 1693 | " return -code error {wrong # args: should be \"try ?options? script ?argument ...?\"}\n" |
| 1694 | " }\n" |
| 1695 | " set args [lassign $args script]\n" |
| 1696 | " set code [catch -eval {*}$catchopts [list uplevel 1 $script] msg opts]\n" |
| 1697 | "\n" |
| 1698 | " set handled 0\n" |
| 1699 | "\n" |
| 1700 | " foreach {on codes vars script} $args {\n" |
| 1701 | " switch -- $on \\\n" |
| @@ -1709,16 +1728,16 @@ | |
| 1709 | " if {$optsvar ne \"\"} {\n" |
| 1710 | " upvar $optsvar hopts\n" |
| 1711 | " set hopts $opts\n" |
| 1712 | " }\n" |
| 1713 | "\n" |
| 1714 | " set code [catch [list uplevel 1 $script] msg opts]\n" |
| 1715 | " incr handled\n" |
| 1716 | " }\n" |
| 1717 | " } \\\n" |
| 1718 | " finally {\n" |
| 1719 | " set finalcode [catch [list uplevel 1 $codes] finalmsg finalopts]\n" |
| 1720 | " if {$finalcode} {\n" |
| 1721 | "\n" |
| 1722 | " set code $finalcode\n" |
| 1723 | " set msg $finalmsg\n" |
| 1724 | " set opts $finalopts\n" |
| @@ -2502,10 +2521,11 @@ | |
| 2502 | Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1))); |
| 2503 | |
| 2504 | return JIM_OK; |
| 2505 | } |
| 2506 | |
| 2507 | static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename, |
| 2508 | const char *hdlfmt, int family, const char *mode[2]) |
| 2509 | { |
| 2510 | if (JimMakeChannel(interp, NULL, p[0], filename, hdlfmt, family, mode[0]) == JIM_OK) { |
| 2511 | Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0); |
| @@ -2522,10 +2542,11 @@ | |
| 2522 | close(p[0]); |
| 2523 | close(p[1]); |
| 2524 | JimAioSetError(interp, NULL); |
| 2525 | return JIM_ERR; |
| 2526 | } |
| 2527 | |
| 2528 | |
| 2529 | int Jim_MakeTempFile(Jim_Interp *interp, const char *template) |
| 2530 | { |
| 2531 | #ifdef HAVE_MKSTEMP |
| @@ -2552,19 +2573,19 @@ | |
| 2552 | |
| 2553 | |
| 2554 | fd = mkstemp(filenameObj->bytes); |
| 2555 | umask(mask); |
| 2556 | if (fd < 0) { |
| 2557 | Jim_SetResultString(interp, "Failed to create tempfile", -1); |
| 2558 | Jim_FreeNewObj(interp, filenameObj); |
| 2559 | return -1; |
| 2560 | } |
| 2561 | |
| 2562 | Jim_SetResult(interp, filenameObj); |
| 2563 | return fd; |
| 2564 | #else |
| 2565 | Jim_SetResultString(interp, "tempfile not supported", -1); |
| 2566 | return -1; |
| 2567 | #endif |
| 2568 | } |
| 2569 | |
| 2570 | FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command) |
| @@ -3176,10 +3197,16 @@ | |
| 3176 | |
| 3177 | # ifndef MAXPATHLEN |
| 3178 | # define MAXPATHLEN JIM_PATH_LEN |
| 3179 | # endif |
| 3180 | |
| 3181 | |
| 3182 | static const char *JimGetFileType(int mode) |
| 3183 | { |
| 3184 | if (S_ISREG(mode)) { |
| 3185 | return "file"; |
| @@ -3281,16 +3308,14 @@ | |
| 3281 | Jim_SetResultString(interp, ".", -1); |
| 3282 | } |
| 3283 | else if (p == path) { |
| 3284 | Jim_SetResultString(interp, "/", -1); |
| 3285 | } |
| 3286 | #if defined(__MINGW32__) || defined(_MSC_VER) |
| 3287 | else if (p[-1] == ':') { |
| 3288 | |
| 3289 | Jim_SetResultString(interp, path, p - path + 1); |
| 3290 | } |
| 3291 | #endif |
| 3292 | else { |
| 3293 | Jim_SetResultString(interp, path, p - path); |
| 3294 | } |
| 3295 | return JIM_OK; |
| 3296 | } |
| @@ -3373,16 +3398,14 @@ | |
| 3373 | |
| 3374 | if (*part == '/') { |
| 3375 | |
| 3376 | last = newname; |
| 3377 | } |
| 3378 | #if defined(__MINGW32__) || defined(_MSC_VER) |
| 3379 | else if (strchr(part, ':')) { |
| 3380 | |
| 3381 | last = newname; |
| 3382 | } |
| 3383 | #endif |
| 3384 | else if (part[0] == '.') { |
| 3385 | if (part[1] == '/') { |
| 3386 | part += 2; |
| 3387 | len -= 2; |
| 3388 | } |
| @@ -3407,11 +3430,14 @@ | |
| 3407 | last += len; |
| 3408 | } |
| 3409 | |
| 3410 | |
| 3411 | if (last > newname + 1 && last[-1] == '/') { |
| 3412 | *--last = 0; |
| 3413 | } |
| 3414 | } |
| 3415 | |
| 3416 | *last = 0; |
| 3417 | |
| @@ -3591,10 +3617,48 @@ | |
| 3591 | return JIM_ERR; |
| 3592 | } |
| 3593 | |
| 3594 | return JIM_OK; |
| 3595 | } |
| 3596 | |
| 3597 | static int file_stat(Jim_Interp *interp, Jim_Obj *filename, struct stat *sb) |
| 3598 | { |
| 3599 | const char *path = Jim_String(filename); |
| 3600 | |
| @@ -3889,10 +3953,19 @@ | |
| 3889 | file_cmd_rename, |
| 3890 | 2, |
| 3891 | 3, |
| 3892 | |
| 3893 | }, |
| 3894 | #if defined(HAVE_READLINK) |
| 3895 | { "readlink", |
| 3896 | "name", |
| 3897 | file_cmd_readlink, |
| 3898 | 1, |
| @@ -3982,19 +4055,17 @@ | |
| 3982 | if (getcwd(cwd, MAXPATHLEN) == NULL) { |
| 3983 | Jim_SetResultString(interp, "Failed to get pwd", -1); |
| 3984 | Jim_Free(cwd); |
| 3985 | return JIM_ERR; |
| 3986 | } |
| 3987 | #if defined(__MINGW32__) || defined(_MSC_VER) |
| 3988 | { |
| 3989 | |
| 3990 | char *p = cwd; |
| 3991 | while ((p = strchr(p, '\\')) != NULL) { |
| 3992 | *p++ = '/'; |
| 3993 | } |
| 3994 | } |
| 3995 | #endif |
| 3996 | |
| 3997 | Jim_SetResultString(interp, cwd, -1); |
| 3998 | |
| 3999 | Jim_Free(cwd); |
| 4000 | return JIM_OK; |
| @@ -5322,22 +5393,20 @@ | |
| 5322 | |
| 5323 | static int JimCreateTemp(Jim_Interp *interp, const char *contents, int len) |
| 5324 | { |
| 5325 | int fd = Jim_MakeTempFile(interp, NULL); |
| 5326 | |
| 5327 | if (fd == JIM_BAD_FD) { |
| 5328 | Jim_SetResultErrno(interp, "couldn't create temp file"); |
| 5329 | return -1; |
| 5330 | } |
| 5331 | unlink(Jim_String(Jim_GetResult(interp))); |
| 5332 | if (contents) { |
| 5333 | if (write(fd, contents, len) != len) { |
| 5334 | Jim_SetResultErrno(interp, "couldn't write temp file"); |
| 5335 | close(fd); |
| 5336 | return -1; |
| 5337 | } |
| 5338 | lseek(fd, 0L, SEEK_SET); |
| 5339 | } |
| 5340 | return fd; |
| 5341 | } |
| 5342 | |
| 5343 | static char **JimSaveEnv(char **env) |
| @@ -7768,10 +7837,11 @@ | |
| 7768 | |
| 7769 | const char *Jim_String(Jim_Obj *objPtr) |
| 7770 | { |
| 7771 | if (objPtr->bytes == NULL) { |
| 7772 | |
| 7773 | JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); |
| 7774 | objPtr->typePtr->updateStringProc(objPtr); |
| 7775 | } |
| 7776 | return objPtr->bytes; |
| 7777 | } |
| @@ -8530,11 +8600,11 @@ | |
| 8530 | return objPtr; |
| 8531 | } |
| 8532 | |
| 8533 | static void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); |
| 8534 | static void DupScriptInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); |
| 8535 | static int JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); |
| 8536 | static int JimParseCheckMissing(Jim_Interp *interp, int ch); |
| 8537 | |
| 8538 | static const Jim_ObjType scriptObjType = { |
| 8539 | "script", |
| 8540 | FreeScriptInternalRep, |
| @@ -8558,10 +8628,11 @@ | |
| 8558 | int inUse; /* Used to share a ScriptObj. Currently |
| 8559 | only used by Jim_EvalObj() as protection against |
| 8560 | shimmering of the currently evaluated object. */ |
| 8561 | int firstline; |
| 8562 | int linenr; |
| 8563 | } ScriptObj; |
| 8564 | |
| 8565 | void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) |
| 8566 | { |
| 8567 | int i; |
| @@ -8836,19 +8907,18 @@ | |
| 8836 | } |
| 8837 | |
| 8838 | script->len = i; |
| 8839 | } |
| 8840 | |
| 8841 | static int JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) |
| 8842 | { |
| 8843 | int scriptTextLen; |
| 8844 | const char *scriptText = Jim_GetString(objPtr, &scriptTextLen); |
| 8845 | struct JimParserCtx parser; |
| 8846 | struct ScriptObj *script; |
| 8847 | ParseTokenList tokenlist; |
| 8848 | int line = 1; |
| 8849 | int retcode = JIM_OK; |
| 8850 | |
| 8851 | |
| 8852 | if (objPtr->typePtr == &sourceObjType) { |
| 8853 | line = objPtr->internalRep.sourceValue.lineNumber; |
| 8854 | } |
| @@ -8861,12 +8931,10 @@ | |
| 8861 | JimParseScript(&parser); |
| 8862 | ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, |
| 8863 | parser.tline); |
| 8864 | } |
| 8865 | |
| 8866 | retcode = JimParseCheckMissing(interp, parser.missing.ch); |
| 8867 | |
| 8868 | |
| 8869 | ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0); |
| 8870 | |
| 8871 | |
| 8872 | script = Jim_Alloc(sizeof(*script)); |
| @@ -8876,12 +8944,13 @@ | |
| 8876 | script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; |
| 8877 | } |
| 8878 | else { |
| 8879 | script->fileNameObj = interp->emptyObj; |
| 8880 | } |
| 8881 | script->linenr = parser.missing.line; |
| 8882 | Jim_IncrRefCount(script->fileNameObj); |
| 8883 | |
| 8884 | ScriptObjAddTokens(interp, script, &tokenlist); |
| 8885 | |
| 8886 | |
| 8887 | ScriptTokenListFree(&tokenlist); |
| @@ -8888,28 +8957,37 @@ | |
| 8888 | |
| 8889 | |
| 8890 | Jim_FreeIntRep(interp, objPtr); |
| 8891 | Jim_SetIntRepPtr(objPtr, script); |
| 8892 | objPtr->typePtr = &scriptObjType; |
| 8893 | |
| 8894 | return retcode; |
| 8895 | } |
| 8896 | |
| 8897 | ScriptObj *Jim_GetScript(Jim_Interp *interp, Jim_Obj *objPtr) |
| 8898 | { |
| 8899 | if (objPtr == interp->emptyObj) { |
| 8900 | |
| 8901 | objPtr = interp->nullScriptObj; |
| 8902 | } |
| 8903 | |
| 8904 | if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) { |
| 8905 | if (JimSetScriptFromAny(interp, objPtr) == JIM_ERR) { |
| 8906 | return NULL; |
| 8907 | } |
| 8908 | } |
| 8909 | return (ScriptObj *) Jim_GetIntRepPtr(objPtr); |
| 8910 | } |
| 8911 | |
| 8912 | static void JimIncrCmdRefCount(Jim_Cmd *cmdPtr) |
| 8913 | { |
| 8914 | cmdPtr->inUse++; |
| 8915 | } |
| @@ -10901,11 +10979,11 @@ | |
| 10901 | return JIM_OK; |
| 10902 | } |
| 10903 | else { |
| 10904 | |
| 10905 | if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) { |
| 10906 | Jim_SetResultFormatted(interp, "expected number but got \"%#s\"", objPtr); |
| 10907 | return JIM_ERR; |
| 10908 | } |
| 10909 | |
| 10910 | Jim_FreeIntRep(interp, objPtr); |
| 10911 | } |
| @@ -12331,10 +12409,11 @@ | |
| 12331 | JIM_EXPROP_UNARYPLUS, |
| 12332 | |
| 12333 | |
| 12334 | JIM_EXPROP_FUNC_FIRST, |
| 12335 | JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST, |
| 12336 | JIM_EXPROP_FUNC_ABS, |
| 12337 | JIM_EXPROP_FUNC_DOUBLE, |
| 12338 | JIM_EXPROP_FUNC_ROUND, |
| 12339 | JIM_EXPROP_FUNC_RAND, |
| 12340 | JIM_EXPROP_FUNC_SRAND, |
| @@ -12397,10 +12476,11 @@ | |
| 12397 | jim_wide wA, wC = 0; |
| 12398 | |
| 12399 | if ((A->typePtr != &doubleObjType || A->bytes) && JimGetWideNoErr(interp, A, &wA) == JIM_OK) { |
| 12400 | switch (e->opcode) { |
| 12401 | case JIM_EXPROP_FUNC_INT: |
| 12402 | case JIM_EXPROP_FUNC_ROUND: |
| 12403 | case JIM_EXPROP_UNARYPLUS: |
| 12404 | wC = wA; |
| 12405 | break; |
| 12406 | case JIM_EXPROP_FUNC_DOUBLE: |
| @@ -12421,10 +12501,11 @@ | |
| 12421 | } |
| 12422 | } |
| 12423 | else if ((rc = Jim_GetDouble(interp, A, &dA)) == JIM_OK) { |
| 12424 | switch (e->opcode) { |
| 12425 | case JIM_EXPROP_FUNC_INT: |
| 12426 | wC = dA; |
| 12427 | break; |
| 12428 | case JIM_EXPROP_FUNC_ROUND: |
| 12429 | wC = dA < 0 ? (dA - 0.5) : (dA + 0.5); |
| 12430 | break; |
| @@ -13093,10 +13174,11 @@ | |
| 13093 | OPRINIT(NULL, 150, 1, JimExprOpNumUnary), |
| 13094 | |
| 13095 | |
| 13096 | |
| 13097 | OPRINIT("int", 200, 1, JimExprOpNumUnary), |
| 13098 | OPRINIT("abs", 200, 1, JimExprOpNumUnary), |
| 13099 | OPRINIT("double", 200, 1, JimExprOpNumUnary), |
| 13100 | OPRINIT("round", 200, 1, JimExprOpNumUnary), |
| 13101 | OPRINIT("rand", 200, 0, JimExprOpNone), |
| 13102 | OPRINIT("srand", 200, 1, JimExprOpIntUnary), |
| @@ -14750,15 +14832,13 @@ | |
| 14750 | ret = Jim_EvalObjVector(interp, objc + 1, nargv); |
| 14751 | Jim_Free(nargv); |
| 14752 | return ret; |
| 14753 | } |
| 14754 | |
| 14755 | static void JimAddErrorToStack(Jim_Interp *interp, int retcode, ScriptObj *script) |
| 14756 | { |
| 14757 | int rc = retcode; |
| 14758 | |
| 14759 | if (rc == JIM_ERR && !interp->errorFlag) { |
| 14760 | |
| 14761 | interp->errorFlag = 1; |
| 14762 | Jim_IncrRefCount(script->fileNameObj); |
| 14763 | Jim_DecrRefCount(interp, interp->errorFileNameObj); |
| 14764 | interp->errorFileNameObj = script->fileNameObj; |
| @@ -14768,11 +14848,11 @@ | |
| 14768 | |
| 14769 | interp->addStackTrace++; |
| 14770 | } |
| 14771 | |
| 14772 | |
| 14773 | if (rc == JIM_ERR && interp->addStackTrace > 0) { |
| 14774 | |
| 14775 | |
| 14776 | JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr); |
| 14777 | |
| 14778 | if (Jim_Length(script->fileNameObj)) { |
| @@ -14781,16 +14861,10 @@ | |
| 14781 | |
| 14782 | Jim_DecrRefCount(interp, interp->errorProc); |
| 14783 | interp->errorProc = interp->emptyObj; |
| 14784 | Jim_IncrRefCount(interp->errorProc); |
| 14785 | } |
| 14786 | else if (rc == JIM_RETURN && interp->returnCode == JIM_ERR) { |
| 14787 | |
| 14788 | } |
| 14789 | else { |
| 14790 | interp->addStackTrace = 0; |
| 14791 | } |
| 14792 | } |
| 14793 | |
| 14794 | static int JimSubstOneToken(Jim_Interp *interp, const ScriptToken *token, Jim_Obj **objPtrPtr) |
| 14795 | { |
| 14796 | Jim_Obj *objPtr; |
| @@ -14928,10 +15002,12 @@ | |
| 14928 | |
| 14929 | static int JimEvalObjList(Jim_Interp *interp, Jim_Obj *listPtr) |
| 14930 | { |
| 14931 | int retcode = JIM_OK; |
| 14932 | |
| 14933 | if (listPtr->internalRep.listValue.len) { |
| 14934 | Jim_IncrRefCount(listPtr); |
| 14935 | retcode = JimInvokeCommand(interp, |
| 14936 | listPtr->internalRep.listValue.len, |
| 14937 | listPtr->internalRep.listValue.ele); |
| @@ -14958,12 +15034,12 @@ | |
| 14958 | if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) { |
| 14959 | return JimEvalObjList(interp, scriptObjPtr); |
| 14960 | } |
| 14961 | |
| 14962 | Jim_IncrRefCount(scriptObjPtr); |
| 14963 | script = Jim_GetScript(interp, scriptObjPtr); |
| 14964 | if (script == NULL) { |
| 14965 | Jim_DecrRefCount(interp, scriptObjPtr); |
| 14966 | return JIM_ERR; |
| 14967 | } |
| 14968 | |
| 14969 | Jim_SetEmptyResult(interp); |
| @@ -15125,11 +15201,18 @@ | |
| 15125 | argv = sargv; |
| 15126 | } |
| 15127 | } |
| 15128 | |
| 15129 | |
| 15130 | JimAddErrorToStack(interp, retcode, script); |
| 15131 | |
| 15132 | |
| 15133 | interp->currentScriptObj = prevScriptObj; |
| 15134 | |
| 15135 | Jim_FreeIntRep(interp, scriptObjPtr); |
| @@ -15276,11 +15359,11 @@ | |
| 15276 | callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr; |
| 15277 | callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr; |
| 15278 | callFramePtr->staticVars = cmd->u.proc.staticVars; |
| 15279 | |
| 15280 | |
| 15281 | script = Jim_GetScript(interp, interp->currentScriptObj); |
| 15282 | callFramePtr->fileNameObj = script->fileNameObj; |
| 15283 | callFramePtr->line = script->linenr; |
| 15284 | |
| 15285 | Jim_IncrRefCount(cmd->u.proc.argListObjPtr); |
| 15286 | Jim_IncrRefCount(cmd->u.proc.bodyObjPtr); |
| @@ -15473,18 +15556,10 @@ | |
| 15473 | |
| 15474 | scriptObjPtr = Jim_NewStringObjNoAlloc(interp, buf, readlen); |
| 15475 | JimSetSourceInfo(interp, scriptObjPtr, Jim_NewStringObj(interp, filename, -1), 1); |
| 15476 | Jim_IncrRefCount(scriptObjPtr); |
| 15477 | |
| 15478 | |
| 15479 | if (Jim_GetScript(interp, scriptObjPtr) == NULL) { |
| 15480 | |
| 15481 | JimAddErrorToStack(interp, JIM_ERR, (ScriptObj *)Jim_GetIntRepPtr(scriptObjPtr)); |
| 15482 | Jim_DecrRefCount(interp, scriptObjPtr); |
| 15483 | return JIM_ERR; |
| 15484 | } |
| 15485 | |
| 15486 | prevScriptObj = interp->currentScriptObj; |
| 15487 | interp->currentScriptObj = scriptObjPtr; |
| 15488 | |
| 15489 | retcode = Jim_EvalObj(interp, scriptObjPtr); |
| 15490 | |
| @@ -16030,11 +16105,11 @@ | |
| 16030 | Jim_Obj *objPtr; |
| 16031 | int cmpOffset; |
| 16032 | |
| 16033 | |
| 16034 | expr = JimGetExpression(interp, argv[2]); |
| 16035 | incrScript = Jim_GetScript(interp, argv[3]); |
| 16036 | |
| 16037 | |
| 16038 | if (incrScript == NULL || incrScript->len != 3 || !expr || expr->len != 3) { |
| 16039 | goto evalstart; |
| 16040 | } |
| @@ -17017,11 +17092,11 @@ | |
| 17017 | { |
| 17018 | Jim_Obj *stringObjPtr; |
| 17019 | int i; |
| 17020 | |
| 17021 | if (argc < 2) { |
| 17022 | Jim_WrongNumArgs(interp, 1, argv, "varName ?value value ...?"); |
| 17023 | return JIM_ERR; |
| 17024 | } |
| 17025 | if (argc == 2) { |
| 17026 | stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); |
| 17027 | if (!stringObjPtr) |
| @@ -17066,11 +17141,11 @@ | |
| 17066 | static int Jim_EvalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) |
| 17067 | { |
| 17068 | int rc; |
| 17069 | |
| 17070 | if (argc < 2) { |
| 17071 | Jim_WrongNumArgs(interp, 1, argv, "script ?...?"); |
| 17072 | return JIM_ERR; |
| 17073 | } |
| 17074 | |
| 17075 | if (argc == 2) { |
| 17076 | rc = Jim_EvalObj(interp, argv[1]); |
| @@ -17277,11 +17352,11 @@ | |
| 17277 | Jim_Obj *cmdList; |
| 17278 | Jim_Obj *prefixListObj = Jim_CmdPrivData(interp); |
| 17279 | |
| 17280 | |
| 17281 | cmdList = Jim_DuplicateObj(interp, prefixListObj); |
| 17282 | ListInsertElements(cmdList, -1, argc - 1, argv + 1); |
| 17283 | |
| 17284 | return JimEvalObjList(interp, cmdList); |
| 17285 | } |
| 17286 | |
| 17287 | static void JimAliasCmdDelete(Jim_Interp *interp, void *privData) |
| @@ -17597,17 +17672,17 @@ | |
| 17597 | int len; |
| 17598 | int opt_case = 1; |
| 17599 | int option; |
| 17600 | static const char * const options[] = { |
| 17601 | "bytelength", "length", "compare", "match", "equal", "is", "byterange", "range", "replace", |
| 17602 | "map", "repeat", "reverse", "index", "first", "last", |
| 17603 | "trim", "trimleft", "trimright", "tolower", "toupper", "totitle", NULL |
| 17604 | }; |
| 17605 | enum |
| 17606 | { |
| 17607 | OPT_BYTELENGTH, OPT_LENGTH, OPT_COMPARE, OPT_MATCH, OPT_EQUAL, OPT_IS, OPT_BYTERANGE, OPT_RANGE, OPT_REPLACE, |
| 17608 | OPT_MAP, OPT_REPEAT, OPT_REVERSE, OPT_INDEX, OPT_FIRST, OPT_LAST, |
| 17609 | OPT_TRIM, OPT_TRIMLEFT, OPT_TRIMRIGHT, OPT_TOLOWER, OPT_TOUPPER, OPT_TOTITLE |
| 17610 | }; |
| 17611 | static const char * const nocase_options[] = { |
| 17612 | "-nocase", NULL |
| 17613 | }; |
| @@ -17636,10 +17711,29 @@ | |
| 17636 | else { |
| 17637 | len = Jim_Length(argv[2]); |
| 17638 | } |
| 17639 | Jim_SetResultInt(interp, len); |
| 17640 | return JIM_OK; |
| 17641 | |
| 17642 | case OPT_COMPARE: |
| 17643 | case OPT_EQUAL: |
| 17644 | { |
| 17645 | |
| @@ -18619,38 +18713,47 @@ | |
| 18619 | case INFO_SCRIPT: |
| 18620 | if (argc != 2) { |
| 18621 | Jim_WrongNumArgs(interp, 2, argv, ""); |
| 18622 | return JIM_ERR; |
| 18623 | } |
| 18624 | Jim_SetResult(interp, Jim_GetScript(interp, interp->currentScriptObj)->fileNameObj); |
| 18625 | break; |
| 18626 | |
| 18627 | case INFO_SOURCE:{ |
| 18628 | int line; |
| 18629 | Jim_Obj *resObjPtr; |
| 18630 | Jim_Obj *fileNameObj; |
| 18631 | |
| 18632 | if (argc != 3) { |
| 18633 | Jim_WrongNumArgs(interp, 2, argv, "source"); |
| 18634 | return JIM_ERR; |
| 18635 | } |
| 18636 | if (argv[2]->typePtr == &sourceObjType) { |
| 18637 | fileNameObj = argv[2]->internalRep.sourceValue.fileNameObj; |
| 18638 | line = argv[2]->internalRep.sourceValue.lineNumber; |
| 18639 | } |
| 18640 | else if (argv[2]->typePtr == &scriptObjType) { |
| 18641 | ScriptObj *script = Jim_GetScript(interp, argv[2]); |
| 18642 | fileNameObj = script->fileNameObj; |
| 18643 | line = script->firstline; |
| 18644 | } |
| 18645 | else { |
| 18646 | fileNameObj = interp->emptyObj; |
| 18647 | line = 1; |
| 18648 | } |
| 18649 | resObjPtr = Jim_NewListObj(interp, NULL, 0); |
| 18650 | Jim_ListAppendElement(interp, resObjPtr, fileNameObj); |
| 18651 | Jim_ListAppendElement(interp, resObjPtr, Jim_NewIntObj(interp, line)); |
| 18652 | Jim_SetResult(interp, resObjPtr); |
| 18653 | break; |
| 18654 | } |
| 18655 | |
| 18656 | case INFO_STACKTRACE: |
| @@ -21843,11 +21946,11 @@ | |
| 21843 | |
| 21844 | if (Jim_InitStaticExtensions(interp) != JIM_OK) { |
| 21845 | JimPrintErrorMessage(interp); |
| 21846 | } |
| 21847 | |
| 21848 | Jim_SetVariableStrWithStr(interp, "jim_argv0", argv[0]); |
| 21849 | Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0"); |
| 21850 | retcode = Jim_initjimshInit(interp); |
| 21851 | |
| 21852 | if (argc == 1) { |
| 21853 | if (retcode == JIM_ERR) { |
| 21854 |
| --- autosetup/jimsh0.c | |
| +++ autosetup/jimsh0.c | |
| @@ -38,15 +38,17 @@ | |
| 38 | #define TCL_PLATFORM_PLATFORM "unix" |
| 39 | #define TCL_PLATFORM_PATH_SEPARATOR ":" |
| 40 | #define HAVE_VFORK |
| 41 | #define HAVE_WAITPID |
| 42 | #define HAVE_ISATTY |
| 43 | #define HAVE_MKSTEMP |
| 44 | #define HAVE_LINK |
| 45 | #define HAVE_SYS_TIME_H |
| 46 | #define HAVE_DIRENT_H |
| 47 | #define HAVE_UNISTD_H |
| 48 | #endif |
| 49 | #define JIM_VERSION 76 |
| 50 | #ifndef JIM_WIN32COMPAT_H |
| 51 | #define JIM_WIN32COMPAT_H |
| 52 | |
| 53 | |
| 54 | |
| @@ -113,10 +115,11 @@ | |
| 115 | int closedir(DIR *dir); |
| 116 | struct dirent *readdir(DIR *dir); |
| 117 | |
| 118 | #elif defined(__MINGW32__) |
| 119 | |
| 120 | #include <stdlib.h> |
| 121 | #define strtod __strtod |
| 122 | |
| 123 | #endif |
| 124 | |
| 125 | #endif |
| @@ -1048,29 +1051,48 @@ | |
| 1051 | "\n" |
| 1052 | "\n" |
| 1053 | "\n" |
| 1054 | "proc _jimsh_init {} {\n" |
| 1055 | " rename _jimsh_init {}\n" |
| 1056 | " global jim::exe jim::argv0 tcl_interactive auto_path tcl_platform\n" |
| 1057 | "\n" |
| 1058 | "\n" |
| 1059 | " if {[exists jim::argv0]} {\n" |
| 1060 | " if {[string match \"*/*\" $jim::argv0]} {\n" |
| 1061 | " set jim::exe [file join [pwd] $jim::argv0]\n" |
| 1062 | " } else {\n" |
| 1063 | " foreach path [split [env PATH \"\"] $tcl_platform(pathSeparator)] {\n" |
| 1064 | " set exec [file join [pwd] [string map {\\\\ /} $path] $jim::argv0]\n" |
| 1065 | " if {[file executable $exec]} {\n" |
| 1066 | " set jim::exe $exec\n" |
| 1067 | " break\n" |
| 1068 | " }\n" |
| 1069 | " }\n" |
| 1070 | " }\n" |
| 1071 | " }\n" |
| 1072 | "\n" |
| 1073 | "\n" |
| 1074 | " lappend p {*}[split [env JIMLIB {}] $tcl_platform(pathSeparator)]\n" |
| 1075 | " if {[exists jim::exe]} {\n" |
| 1076 | " lappend p [file dirname $jim::exe]\n" |
| 1077 | " }\n" |
| 1078 | " lappend p {*}$auto_path\n" |
| 1079 | " set auto_path $p\n" |
| 1080 | "\n" |
| 1081 | " if {$tcl_interactive && [env HOME {}] ne \"\"} {\n" |
| 1082 | " foreach src {.jimrc jimrc.tcl} {\n" |
| 1083 | " if {[file exists [env HOME]/$src]} {\n" |
| 1084 | " uplevel #0 source [env HOME]/$src\n" |
| 1085 | " break\n" |
| 1086 | " }\n" |
| 1087 | " }\n" |
| 1088 | " }\n" |
| 1089 | " return \"\"\n" |
| 1090 | "}\n" |
| 1091 | "\n" |
| 1092 | "if {$tcl_platform(platform) eq \"windows\"} {\n" |
| 1093 | " set jim::argv0 [string map {\\\\ /} $jim::argv0]\n" |
| 1094 | "}\n" |
| 1095 | "\n" |
| 1096 | "_jimsh_init\n" |
| 1097 | ); |
| 1098 | } |
| @@ -1091,11 +1113,11 @@ | |
| 1113 | "\n" |
| 1114 | "\n" |
| 1115 | "proc glob.globdir {dir pattern} {\n" |
| 1116 | " if {[file exists $dir/$pattern]} {\n" |
| 1117 | "\n" |
| 1118 | " return [list $pattern]\n" |
| 1119 | " }\n" |
| 1120 | "\n" |
| 1121 | " set result {}\n" |
| 1122 | " set files [readdir $dir]\n" |
| 1123 | " lappend files . ..\n" |
| @@ -1153,11 +1175,11 @@ | |
| 1175 | " }\n" |
| 1176 | "\n" |
| 1177 | " foreach old $oldexp {\n" |
| 1178 | " lappend newexp $old$suf\n" |
| 1179 | " }\n" |
| 1180 | " list $rest {*}$newexp\n" |
| 1181 | "}\n" |
| 1182 | "\n" |
| 1183 | "\n" |
| 1184 | "\n" |
| 1185 | "proc glob.glob {base pattern} {\n" |
| @@ -1200,10 +1222,11 @@ | |
| 1222 | "\n" |
| 1223 | "\n" |
| 1224 | "proc glob {args} {\n" |
| 1225 | " set nocomplain 0\n" |
| 1226 | " set base \"\"\n" |
| 1227 | " set tails 0\n" |
| 1228 | "\n" |
| 1229 | " set n 0\n" |
| 1230 | " foreach arg $args {\n" |
| 1231 | " if {[info exists param]} {\n" |
| 1232 | " set $param $arg\n" |
| @@ -1217,21 +1240,20 @@ | |
| 1240 | " set param base\n" |
| 1241 | " }\n" |
| 1242 | " -n* {\n" |
| 1243 | " set nocomplain 1\n" |
| 1244 | " }\n" |
| 1245 | " -ta* {\n" |
| 1246 | " set tails 1\n" |
| 1247 | " }\n" |
| 1248 | " -- {\n" |
| 1249 | " incr n\n" |
| 1250 | " break\n" |
| 1251 | " }\n" |
| 1252 | " -* {\n" |
| 1253 | " return -code error \"bad option \\\"$arg\\\": must be -directory, -nocomplain, -tails, or --\"\n" |
| 1254 | " }\n" |
| 1255 | " * {\n" |
| 1256 | " break\n" |
| 1257 | " }\n" |
| 1258 | " }\n" |
| 1259 | " incr n\n" |
| @@ -1245,29 +1267,35 @@ | |
| 1267 | "\n" |
| 1268 | " set args [lrange $args $n end]\n" |
| 1269 | "\n" |
| 1270 | " set result {}\n" |
| 1271 | " foreach pattern $args {\n" |
| 1272 | " set escpattern [string map {\n" |
| 1273 | " \\\\\\\\ \\x01 \\\\\\{ \\x02 \\\\\\} \\x03 \\\\, \\x04\n" |
| 1274 | " } $pattern]\n" |
| 1275 | " set patexps [lassign [glob.explode $escpattern] rest]\n" |
| 1276 | " if {$rest ne \"\"} {\n" |
| 1277 | " return -code error \"unmatched close brace in glob pattern\"\n" |
| 1278 | " }\n" |
| 1279 | " foreach patexp $patexps {\n" |
| 1280 | " set patexp [string map {\n" |
| 1281 | " \\x01 \\\\\\\\ \\x02 \\{ \\x03 \\} \\x04 ,\n" |
| 1282 | " } $patexp]\n" |
| 1283 | " foreach {realname name} [glob.glob $base $patexp] {\n" |
| 1284 | " incr n\n" |
| 1285 | " if {$tails} {\n" |
| 1286 | " lappend result $name\n" |
| 1287 | " } else {\n" |
| 1288 | " lappend result [file join $base $name]\n" |
| 1289 | " }\n" |
| 1290 | " }\n" |
| 1291 | " }\n" |
| 1292 | " }\n" |
| 1293 | "\n" |
| 1294 | " if {!$nocomplain && [llength $result] == 0} {\n" |
| 1295 | " set s $(([llength $args] > 1) ? \"s\" : \"\")\n" |
| 1296 | " return -code error \"no files matched glob pattern$s \\\"[join $args]\\\"\"\n" |
| 1297 | " }\n" |
| 1298 | "\n" |
| 1299 | " return $result\n" |
| 1300 | "}\n" |
| 1301 | ); |
| @@ -1348,11 +1376,11 @@ | |
| 1376 | "\n" |
| 1377 | " lappend stacktrace {*}[stacktrace 1]\n" |
| 1378 | " }\n" |
| 1379 | " lassign $stacktrace p f l\n" |
| 1380 | " if {$f ne \"\"} {\n" |
| 1381 | " set result \"$f:$l: Error: \"\n" |
| 1382 | " }\n" |
| 1383 | " append result \"$msg\\n\"\n" |
| 1384 | " append result [stackdump $stacktrace]\n" |
| 1385 | "\n" |
| 1386 | "\n" |
| @@ -1360,22 +1388,13 @@ | |
| 1388 | "}\n" |
| 1389 | "\n" |
| 1390 | "\n" |
| 1391 | "\n" |
| 1392 | "proc {info nameofexecutable} {} {\n" |
| 1393 | " if {[exists ::jim::exe]} {\n" |
| 1394 | " return $::jim::exe\n" |
| 1395 | " }\n" |
| 1396 | "}\n" |
| 1397 | "\n" |
| 1398 | "\n" |
| 1399 | "proc {dict with} {&dictVar {args key} script} {\n" |
| 1400 | " set keys {}\n" |
| @@ -1587,11 +1606,11 @@ | |
| 1606 | " try {\n" |
| 1607 | " if {$force ni {{} -force}} {\n" |
| 1608 | " error \"bad option \\\"$force\\\": should be -force\"\n" |
| 1609 | " }\n" |
| 1610 | "\n" |
| 1611 | " set in [open $source rb]\n" |
| 1612 | "\n" |
| 1613 | " if {[file exists $target]} {\n" |
| 1614 | " if {$force eq \"\"} {\n" |
| 1615 | " error \"error copying \\\"$source\\\" to \\\"$target\\\": file already exists\"\n" |
| 1616 | " }\n" |
| @@ -1605,11 +1624,11 @@ | |
| 1624 | " file stat $target ts\n" |
| 1625 | " if {$ss(dev) == $ts(dev) && $ss(ino) == $ts(ino) && $ss(ino)} {\n" |
| 1626 | " return\n" |
| 1627 | " }\n" |
| 1628 | " }\n" |
| 1629 | " set out [open $target wb]\n" |
| 1630 | " $in copyto $out\n" |
| 1631 | " $out close\n" |
| 1632 | " } on error {msg opts} {\n" |
| 1633 | " incr opts(-level)\n" |
| 1634 | " return {*}$opts $msg\n" |
| @@ -1691,11 +1710,11 @@ | |
| 1710 | " }\n" |
| 1711 | " if {[llength $args] == 0} {\n" |
| 1712 | " return -code error {wrong # args: should be \"try ?options? script ?argument ...?\"}\n" |
| 1713 | " }\n" |
| 1714 | " set args [lassign $args script]\n" |
| 1715 | " set code [catch -eval {*}$catchopts {uplevel 1 $script} msg opts]\n" |
| 1716 | "\n" |
| 1717 | " set handled 0\n" |
| 1718 | "\n" |
| 1719 | " foreach {on codes vars script} $args {\n" |
| 1720 | " switch -- $on \\\n" |
| @@ -1709,16 +1728,16 @@ | |
| 1728 | " if {$optsvar ne \"\"} {\n" |
| 1729 | " upvar $optsvar hopts\n" |
| 1730 | " set hopts $opts\n" |
| 1731 | " }\n" |
| 1732 | "\n" |
| 1733 | " set code [catch {uplevel 1 $script} msg opts]\n" |
| 1734 | " incr handled\n" |
| 1735 | " }\n" |
| 1736 | " } \\\n" |
| 1737 | " finally {\n" |
| 1738 | " set finalcode [catch {uplevel 1 $codes} finalmsg finalopts]\n" |
| 1739 | " if {$finalcode} {\n" |
| 1740 | "\n" |
| 1741 | " set code $finalcode\n" |
| 1742 | " set msg $finalmsg\n" |
| 1743 | " set opts $finalopts\n" |
| @@ -2502,10 +2521,11 @@ | |
| 2521 | Jim_SetResult(interp, Jim_MakeGlobalNamespaceName(interp, Jim_NewStringObj(interp, buf, -1))); |
| 2522 | |
| 2523 | return JIM_OK; |
| 2524 | } |
| 2525 | |
| 2526 | #if defined(HAVE_PIPE) || (defined(HAVE_SOCKETPAIR) && defined(HAVE_SYS_UN_H)) |
| 2527 | static int JimMakeChannelPair(Jim_Interp *interp, int p[2], Jim_Obj *filename, |
| 2528 | const char *hdlfmt, int family, const char *mode[2]) |
| 2529 | { |
| 2530 | if (JimMakeChannel(interp, NULL, p[0], filename, hdlfmt, family, mode[0]) == JIM_OK) { |
| 2531 | Jim_Obj *objPtr = Jim_NewListObj(interp, NULL, 0); |
| @@ -2522,10 +2542,11 @@ | |
| 2542 | close(p[0]); |
| 2543 | close(p[1]); |
| 2544 | JimAioSetError(interp, NULL); |
| 2545 | return JIM_ERR; |
| 2546 | } |
| 2547 | #endif |
| 2548 | |
| 2549 | |
| 2550 | int Jim_MakeTempFile(Jim_Interp *interp, const char *template) |
| 2551 | { |
| 2552 | #ifdef HAVE_MKSTEMP |
| @@ -2552,19 +2573,19 @@ | |
| 2573 | |
| 2574 | |
| 2575 | fd = mkstemp(filenameObj->bytes); |
| 2576 | umask(mask); |
| 2577 | if (fd < 0) { |
| 2578 | JimAioSetError(interp, filenameObj); |
| 2579 | Jim_FreeNewObj(interp, filenameObj); |
| 2580 | return -1; |
| 2581 | } |
| 2582 | |
| 2583 | Jim_SetResult(interp, filenameObj); |
| 2584 | return fd; |
| 2585 | #else |
| 2586 | Jim_SetResultString(interp, "platform has no tempfile support", -1); |
| 2587 | return -1; |
| 2588 | #endif |
| 2589 | } |
| 2590 | |
| 2591 | FILE *Jim_AioFilehandle(Jim_Interp *interp, Jim_Obj *command) |
| @@ -3176,10 +3197,16 @@ | |
| 3197 | |
| 3198 | # ifndef MAXPATHLEN |
| 3199 | # define MAXPATHLEN JIM_PATH_LEN |
| 3200 | # endif |
| 3201 | |
| 3202 | #if defined(__MINGW32__) || defined(_MSC_VER) |
| 3203 | #define ISWINDOWS 1 |
| 3204 | #else |
| 3205 | #define ISWINDOWS 0 |
| 3206 | #endif |
| 3207 | |
| 3208 | |
| 3209 | static const char *JimGetFileType(int mode) |
| 3210 | { |
| 3211 | if (S_ISREG(mode)) { |
| 3212 | return "file"; |
| @@ -3281,16 +3308,14 @@ | |
| 3308 | Jim_SetResultString(interp, ".", -1); |
| 3309 | } |
| 3310 | else if (p == path) { |
| 3311 | Jim_SetResultString(interp, "/", -1); |
| 3312 | } |
| 3313 | else if (ISWINDOWS && p[-1] == ':') { |
| 3314 | |
| 3315 | Jim_SetResultString(interp, path, p - path + 1); |
| 3316 | } |
| 3317 | else { |
| 3318 | Jim_SetResultString(interp, path, p - path); |
| 3319 | } |
| 3320 | return JIM_OK; |
| 3321 | } |
| @@ -3373,16 +3398,14 @@ | |
| 3398 | |
| 3399 | if (*part == '/') { |
| 3400 | |
| 3401 | last = newname; |
| 3402 | } |
| 3403 | else if (ISWINDOWS && strchr(part, ':')) { |
| 3404 | |
| 3405 | last = newname; |
| 3406 | } |
| 3407 | else if (part[0] == '.') { |
| 3408 | if (part[1] == '/') { |
| 3409 | part += 2; |
| 3410 | len -= 2; |
| 3411 | } |
| @@ -3407,11 +3430,14 @@ | |
| 3430 | last += len; |
| 3431 | } |
| 3432 | |
| 3433 | |
| 3434 | if (last > newname + 1 && last[-1] == '/') { |
| 3435 | |
| 3436 | if (!ISWINDOWS || !(last > newname + 2 && last[-2] == ':')) { |
| 3437 | *--last = 0; |
| 3438 | } |
| 3439 | } |
| 3440 | } |
| 3441 | |
| 3442 | *last = 0; |
| 3443 | |
| @@ -3591,10 +3617,48 @@ | |
| 3617 | return JIM_ERR; |
| 3618 | } |
| 3619 | |
| 3620 | return JIM_OK; |
| 3621 | } |
| 3622 | |
| 3623 | #if defined(HAVE_LINK) && defined(HAVE_SYMLINK) |
| 3624 | static int file_cmd_link(Jim_Interp *interp, int argc, Jim_Obj *const *argv) |
| 3625 | { |
| 3626 | int ret; |
| 3627 | const char *source; |
| 3628 | const char *dest; |
| 3629 | static const char * const options[] = { "-hard", "-symbolic", NULL }; |
| 3630 | enum { OPT_HARD, OPT_SYMBOLIC, }; |
| 3631 | int option = OPT_HARD; |
| 3632 | |
| 3633 | if (argc == 3) { |
| 3634 | if (Jim_GetEnum(interp, argv[0], options, &option, NULL, JIM_ENUM_ABBREV | JIM_ERRMSG) != JIM_OK) { |
| 3635 | return JIM_ERR; |
| 3636 | } |
| 3637 | argv++; |
| 3638 | argc--; |
| 3639 | } |
| 3640 | |
| 3641 | dest = Jim_String(argv[0]); |
| 3642 | source = Jim_String(argv[1]); |
| 3643 | |
| 3644 | if (option == OPT_HARD) { |
| 3645 | ret = link(source, dest); |
| 3646 | } |
| 3647 | else { |
| 3648 | ret = symlink(source, dest); |
| 3649 | } |
| 3650 | |
| 3651 | if (ret != 0) { |
| 3652 | Jim_SetResultFormatted(interp, "error linking \"%#s\" to \"%#s\": %s", argv[0], argv[1], |
| 3653 | strerror(errno)); |
| 3654 | return JIM_ERR; |
| 3655 | } |
| 3656 | |
| 3657 | return JIM_OK; |
| 3658 | } |
| 3659 | #endif |
| 3660 | |
| 3661 | static int file_stat(Jim_Interp *interp, Jim_Obj *filename, struct stat *sb) |
| 3662 | { |
| 3663 | const char *path = Jim_String(filename); |
| 3664 | |
| @@ -3889,10 +3953,19 @@ | |
| 3953 | file_cmd_rename, |
| 3954 | 2, |
| 3955 | 3, |
| 3956 | |
| 3957 | }, |
| 3958 | #if defined(HAVE_LINK) && defined(HAVE_SYMLINK) |
| 3959 | { "link", |
| 3960 | "?-symbolic|-hard? newname target", |
| 3961 | file_cmd_link, |
| 3962 | 2, |
| 3963 | 3, |
| 3964 | |
| 3965 | }, |
| 3966 | #endif |
| 3967 | #if defined(HAVE_READLINK) |
| 3968 | { "readlink", |
| 3969 | "name", |
| 3970 | file_cmd_readlink, |
| 3971 | 1, |
| @@ -3982,19 +4055,17 @@ | |
| 4055 | if (getcwd(cwd, MAXPATHLEN) == NULL) { |
| 4056 | Jim_SetResultString(interp, "Failed to get pwd", -1); |
| 4057 | Jim_Free(cwd); |
| 4058 | return JIM_ERR; |
| 4059 | } |
| 4060 | else if (ISWINDOWS) { |
| 4061 | |
| 4062 | char *p = cwd; |
| 4063 | while ((p = strchr(p, '\\')) != NULL) { |
| 4064 | *p++ = '/'; |
| 4065 | } |
| 4066 | } |
| 4067 | |
| 4068 | Jim_SetResultString(interp, cwd, -1); |
| 4069 | |
| 4070 | Jim_Free(cwd); |
| 4071 | return JIM_OK; |
| @@ -5322,22 +5393,20 @@ | |
| 5393 | |
| 5394 | static int JimCreateTemp(Jim_Interp *interp, const char *contents, int len) |
| 5395 | { |
| 5396 | int fd = Jim_MakeTempFile(interp, NULL); |
| 5397 | |
| 5398 | if (fd != JIM_BAD_FD) { |
| 5399 | unlink(Jim_String(Jim_GetResult(interp))); |
| 5400 | if (contents) { |
| 5401 | if (write(fd, contents, len) != len) { |
| 5402 | Jim_SetResultErrno(interp, "couldn't write temp file"); |
| 5403 | close(fd); |
| 5404 | return -1; |
| 5405 | } |
| 5406 | lseek(fd, 0L, SEEK_SET); |
| 5407 | } |
| 5408 | } |
| 5409 | return fd; |
| 5410 | } |
| 5411 | |
| 5412 | static char **JimSaveEnv(char **env) |
| @@ -7768,10 +7837,11 @@ | |
| 7837 | |
| 7838 | const char *Jim_String(Jim_Obj *objPtr) |
| 7839 | { |
| 7840 | if (objPtr->bytes == NULL) { |
| 7841 | |
| 7842 | JimPanic((objPtr->typePtr == NULL, "UpdateStringProc called against typeless value.")); |
| 7843 | JimPanic((objPtr->typePtr->updateStringProc == NULL, "UpdateStringProc called against '%s' type.", objPtr->typePtr->name)); |
| 7844 | objPtr->typePtr->updateStringProc(objPtr); |
| 7845 | } |
| 7846 | return objPtr->bytes; |
| 7847 | } |
| @@ -8530,11 +8600,11 @@ | |
| 8600 | return objPtr; |
| 8601 | } |
| 8602 | |
| 8603 | static void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); |
| 8604 | static void DupScriptInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); |
| 8605 | static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); |
| 8606 | static int JimParseCheckMissing(Jim_Interp *interp, int ch); |
| 8607 | |
| 8608 | static const Jim_ObjType scriptObjType = { |
| 8609 | "script", |
| 8610 | FreeScriptInternalRep, |
| @@ -8558,10 +8628,11 @@ | |
| 8628 | int inUse; /* Used to share a ScriptObj. Currently |
| 8629 | only used by Jim_EvalObj() as protection against |
| 8630 | shimmering of the currently evaluated object. */ |
| 8631 | int firstline; |
| 8632 | int linenr; |
| 8633 | int missing; |
| 8634 | } ScriptObj; |
| 8635 | |
| 8636 | void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) |
| 8637 | { |
| 8638 | int i; |
| @@ -8836,19 +8907,18 @@ | |
| 8907 | } |
| 8908 | |
| 8909 | script->len = i; |
| 8910 | } |
| 8911 | |
| 8912 | static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr) |
| 8913 | { |
| 8914 | int scriptTextLen; |
| 8915 | const char *scriptText = Jim_GetString(objPtr, &scriptTextLen); |
| 8916 | struct JimParserCtx parser; |
| 8917 | struct ScriptObj *script; |
| 8918 | ParseTokenList tokenlist; |
| 8919 | int line = 1; |
| 8920 | |
| 8921 | |
| 8922 | if (objPtr->typePtr == &sourceObjType) { |
| 8923 | line = objPtr->internalRep.sourceValue.lineNumber; |
| 8924 | } |
| @@ -8861,12 +8931,10 @@ | |
| 8931 | JimParseScript(&parser); |
| 8932 | ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, |
| 8933 | parser.tline); |
| 8934 | } |
| 8935 | |
| 8936 | |
| 8937 | ScriptAddToken(&tokenlist, scriptText + scriptTextLen, 0, JIM_TT_EOF, 0); |
| 8938 | |
| 8939 | |
| 8940 | script = Jim_Alloc(sizeof(*script)); |
| @@ -8876,12 +8944,13 @@ | |
| 8944 | script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; |
| 8945 | } |
| 8946 | else { |
| 8947 | script->fileNameObj = interp->emptyObj; |
| 8948 | } |
| 8949 | Jim_IncrRefCount(script->fileNameObj); |
| 8950 | script->missing = parser.missing.ch; |
| 8951 | script->linenr = parser.missing.line; |
| 8952 | |
| 8953 | ScriptObjAddTokens(interp, script, &tokenlist); |
| 8954 | |
| 8955 | |
| 8956 | ScriptTokenListFree(&tokenlist); |
| @@ -8888,28 +8957,37 @@ | |
| 8957 | |
| 8958 | |
| 8959 | Jim_FreeIntRep(interp, objPtr); |
| 8960 | Jim_SetIntRepPtr(objPtr, script); |
| 8961 | objPtr->typePtr = &scriptObjType; |
| 8962 | } |
| 8963 | |
| 8964 | static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script); |
| 8965 | |
| 8966 | ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr) |
| 8967 | { |
| 8968 | if (objPtr == interp->emptyObj) { |
| 8969 | |
| 8970 | objPtr = interp->nullScriptObj; |
| 8971 | } |
| 8972 | |
| 8973 | if (objPtr->typePtr != &scriptObjType || ((struct ScriptObj *)Jim_GetIntRepPtr(objPtr))->substFlags) { |
| 8974 | JimSetScriptFromAny(interp, objPtr); |
| 8975 | } |
| 8976 | |
| 8977 | return (ScriptObj *)Jim_GetIntRepPtr(objPtr); |
| 8978 | } |
| 8979 | |
| 8980 | static int JimScriptValid(Jim_Interp *interp, ScriptObj *script) |
| 8981 | { |
| 8982 | if (JimParseCheckMissing(interp, script->missing) == JIM_ERR) { |
| 8983 | JimAddErrorToStack(interp, script); |
| 8984 | return 0; |
| 8985 | } |
| 8986 | return 1; |
| 8987 | } |
| 8988 | |
| 8989 | |
| 8990 | static void JimIncrCmdRefCount(Jim_Cmd *cmdPtr) |
| 8991 | { |
| 8992 | cmdPtr->inUse++; |
| 8993 | } |
| @@ -10901,11 +10979,11 @@ | |
| 10979 | return JIM_OK; |
| 10980 | } |
| 10981 | else { |
| 10982 | |
| 10983 | if (Jim_StringToDouble(str, &doubleValue) != JIM_OK) { |
| 10984 | Jim_SetResultFormatted(interp, "expected floating-point number but got \"%#s\"", objPtr); |
| 10985 | return JIM_ERR; |
| 10986 | } |
| 10987 | |
| 10988 | Jim_FreeIntRep(interp, objPtr); |
| 10989 | } |
| @@ -12331,10 +12409,11 @@ | |
| 12409 | JIM_EXPROP_UNARYPLUS, |
| 12410 | |
| 12411 | |
| 12412 | JIM_EXPROP_FUNC_FIRST, |
| 12413 | JIM_EXPROP_FUNC_INT = JIM_EXPROP_FUNC_FIRST, |
| 12414 | JIM_EXPROP_FUNC_WIDE, |
| 12415 | JIM_EXPROP_FUNC_ABS, |
| 12416 | JIM_EXPROP_FUNC_DOUBLE, |
| 12417 | JIM_EXPROP_FUNC_ROUND, |
| 12418 | JIM_EXPROP_FUNC_RAND, |
| 12419 | JIM_EXPROP_FUNC_SRAND, |
| @@ -12397,10 +12476,11 @@ | |
| 12476 | jim_wide wA, wC = 0; |
| 12477 | |
| 12478 | if ((A->typePtr != &doubleObjType || A->bytes) && JimGetWideNoErr(interp, A, &wA) == JIM_OK) { |
| 12479 | switch (e->opcode) { |
| 12480 | case JIM_EXPROP_FUNC_INT: |
| 12481 | case JIM_EXPROP_FUNC_WIDE: |
| 12482 | case JIM_EXPROP_FUNC_ROUND: |
| 12483 | case JIM_EXPROP_UNARYPLUS: |
| 12484 | wC = wA; |
| 12485 | break; |
| 12486 | case JIM_EXPROP_FUNC_DOUBLE: |
| @@ -12421,10 +12501,11 @@ | |
| 12501 | } |
| 12502 | } |
| 12503 | else if ((rc = Jim_GetDouble(interp, A, &dA)) == JIM_OK) { |
| 12504 | switch (e->opcode) { |
| 12505 | case JIM_EXPROP_FUNC_INT: |
| 12506 | case JIM_EXPROP_FUNC_WIDE: |
| 12507 | wC = dA; |
| 12508 | break; |
| 12509 | case JIM_EXPROP_FUNC_ROUND: |
| 12510 | wC = dA < 0 ? (dA - 0.5) : (dA + 0.5); |
| 12511 | break; |
| @@ -13093,10 +13174,11 @@ | |
| 13174 | OPRINIT(NULL, 150, 1, JimExprOpNumUnary), |
| 13175 | |
| 13176 | |
| 13177 | |
| 13178 | OPRINIT("int", 200, 1, JimExprOpNumUnary), |
| 13179 | OPRINIT("wide", 200, 1, JimExprOpNumUnary), |
| 13180 | OPRINIT("abs", 200, 1, JimExprOpNumUnary), |
| 13181 | OPRINIT("double", 200, 1, JimExprOpNumUnary), |
| 13182 | OPRINIT("round", 200, 1, JimExprOpNumUnary), |
| 13183 | OPRINIT("rand", 200, 0, JimExprOpNone), |
| 13184 | OPRINIT("srand", 200, 1, JimExprOpIntUnary), |
| @@ -14750,15 +14832,13 @@ | |
| 14832 | ret = Jim_EvalObjVector(interp, objc + 1, nargv); |
| 14833 | Jim_Free(nargv); |
| 14834 | return ret; |
| 14835 | } |
| 14836 | |
| 14837 | static void JimAddErrorToStack(Jim_Interp *interp, ScriptObj *script) |
| 14838 | { |
| 14839 | if (!interp->errorFlag) { |
| 14840 | |
| 14841 | interp->errorFlag = 1; |
| 14842 | Jim_IncrRefCount(script->fileNameObj); |
| 14843 | Jim_DecrRefCount(interp, interp->errorFileNameObj); |
| 14844 | interp->errorFileNameObj = script->fileNameObj; |
| @@ -14768,11 +14848,11 @@ | |
| 14848 | |
| 14849 | interp->addStackTrace++; |
| 14850 | } |
| 14851 | |
| 14852 | |
| 14853 | if (interp->addStackTrace > 0) { |
| 14854 | |
| 14855 | |
| 14856 | JimAppendStackTrace(interp, Jim_String(interp->errorProc), script->fileNameObj, script->linenr); |
| 14857 | |
| 14858 | if (Jim_Length(script->fileNameObj)) { |
| @@ -14781,16 +14861,10 @@ | |
| 14861 | |
| 14862 | Jim_DecrRefCount(interp, interp->errorProc); |
| 14863 | interp->errorProc = interp->emptyObj; |
| 14864 | Jim_IncrRefCount(interp->errorProc); |
| 14865 | } |
| 14866 | } |
| 14867 | |
| 14868 | static int JimSubstOneToken(Jim_Interp *interp, const ScriptToken *token, Jim_Obj **objPtrPtr) |
| 14869 | { |
| 14870 | Jim_Obj *objPtr; |
| @@ -14928,10 +15002,12 @@ | |
| 15002 | |
| 15003 | static int JimEvalObjList(Jim_Interp *interp, Jim_Obj *listPtr) |
| 15004 | { |
| 15005 | int retcode = JIM_OK; |
| 15006 | |
| 15007 | JimPanic((Jim_IsList(listPtr) == 0, "JimEvalObjList() invoked on non-list.")); |
| 15008 | |
| 15009 | if (listPtr->internalRep.listValue.len) { |
| 15010 | Jim_IncrRefCount(listPtr); |
| 15011 | retcode = JimInvokeCommand(interp, |
| 15012 | listPtr->internalRep.listValue.len, |
| 15013 | listPtr->internalRep.listValue.ele); |
| @@ -14958,12 +15034,12 @@ | |
| 15034 | if (Jim_IsList(scriptObjPtr) && scriptObjPtr->bytes == NULL) { |
| 15035 | return JimEvalObjList(interp, scriptObjPtr); |
| 15036 | } |
| 15037 | |
| 15038 | Jim_IncrRefCount(scriptObjPtr); |
| 15039 | script = JimGetScript(interp, scriptObjPtr); |
| 15040 | if (!JimScriptValid(interp, script)) { |
| 15041 | Jim_DecrRefCount(interp, scriptObjPtr); |
| 15042 | return JIM_ERR; |
| 15043 | } |
| 15044 | |
| 15045 | Jim_SetEmptyResult(interp); |
| @@ -15125,11 +15201,18 @@ | |
| 15201 | argv = sargv; |
| 15202 | } |
| 15203 | } |
| 15204 | |
| 15205 | |
| 15206 | if (retcode == JIM_ERR) { |
| 15207 | JimAddErrorToStack(interp, script); |
| 15208 | } |
| 15209 | |
| 15210 | else if (retcode != JIM_RETURN || interp->returnCode != JIM_ERR) { |
| 15211 | |
| 15212 | interp->addStackTrace = 0; |
| 15213 | } |
| 15214 | |
| 15215 | |
| 15216 | interp->currentScriptObj = prevScriptObj; |
| 15217 | |
| 15218 | Jim_FreeIntRep(interp, scriptObjPtr); |
| @@ -15276,11 +15359,11 @@ | |
| 15359 | callFramePtr->procArgsObjPtr = cmd->u.proc.argListObjPtr; |
| 15360 | callFramePtr->procBodyObjPtr = cmd->u.proc.bodyObjPtr; |
| 15361 | callFramePtr->staticVars = cmd->u.proc.staticVars; |
| 15362 | |
| 15363 | |
| 15364 | script = JimGetScript(interp, interp->currentScriptObj); |
| 15365 | callFramePtr->fileNameObj = script->fileNameObj; |
| 15366 | callFramePtr->line = script->linenr; |
| 15367 | |
| 15368 | Jim_IncrRefCount(cmd->u.proc.argListObjPtr); |
| 15369 | Jim_IncrRefCount(cmd->u.proc.bodyObjPtr); |
| @@ -15473,18 +15556,10 @@ | |
| 15556 | |
| 15557 | scriptObjPtr = Jim_NewStringObjNoAlloc(interp, buf, readlen); |
| 15558 | JimSetSourceInfo(interp, scriptObjPtr, Jim_NewStringObj(interp, filename, -1), 1); |
| 15559 | Jim_IncrRefCount(scriptObjPtr); |
| 15560 | |
| 15561 | prevScriptObj = interp->currentScriptObj; |
| 15562 | interp->currentScriptObj = scriptObjPtr; |
| 15563 | |
| 15564 | retcode = Jim_EvalObj(interp, scriptObjPtr); |
| 15565 | |
| @@ -16030,11 +16105,11 @@ | |
| 16105 | Jim_Obj *objPtr; |
| 16106 | int cmpOffset; |
| 16107 | |
| 16108 | |
| 16109 | expr = JimGetExpression(interp, argv[2]); |
| 16110 | incrScript = JimGetScript(interp, argv[3]); |
| 16111 | |
| 16112 | |
| 16113 | if (incrScript == NULL || incrScript->len != 3 || !expr || expr->len != 3) { |
| 16114 | goto evalstart; |
| 16115 | } |
| @@ -17017,11 +17092,11 @@ | |
| 17092 | { |
| 17093 | Jim_Obj *stringObjPtr; |
| 17094 | int i; |
| 17095 | |
| 17096 | if (argc < 2) { |
| 17097 | Jim_WrongNumArgs(interp, 1, argv, "varName ?value ...?"); |
| 17098 | return JIM_ERR; |
| 17099 | } |
| 17100 | if (argc == 2) { |
| 17101 | stringObjPtr = Jim_GetVariable(interp, argv[1], JIM_ERRMSG); |
| 17102 | if (!stringObjPtr) |
| @@ -17066,11 +17141,11 @@ | |
| 17141 | static int Jim_EvalCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const *argv) |
| 17142 | { |
| 17143 | int rc; |
| 17144 | |
| 17145 | if (argc < 2) { |
| 17146 | Jim_WrongNumArgs(interp, 1, argv, "arg ?arg ...?"); |
| 17147 | return JIM_ERR; |
| 17148 | } |
| 17149 | |
| 17150 | if (argc == 2) { |
| 17151 | rc = Jim_EvalObj(interp, argv[1]); |
| @@ -17277,11 +17352,11 @@ | |
| 17352 | Jim_Obj *cmdList; |
| 17353 | Jim_Obj *prefixListObj = Jim_CmdPrivData(interp); |
| 17354 | |
| 17355 | |
| 17356 | cmdList = Jim_DuplicateObj(interp, prefixListObj); |
| 17357 | Jim_ListInsertElements(interp, cmdList, Jim_ListLength(interp, cmdList), argc - 1, argv + 1); |
| 17358 | |
| 17359 | return JimEvalObjList(interp, cmdList); |
| 17360 | } |
| 17361 | |
| 17362 | static void JimAliasCmdDelete(Jim_Interp *interp, void *privData) |
| @@ -17597,17 +17672,17 @@ | |
| 17672 | int len; |
| 17673 | int opt_case = 1; |
| 17674 | int option; |
| 17675 | static const char * const options[] = { |
| 17676 | "bytelength", "length", "compare", "match", "equal", "is", "byterange", "range", "replace", |
| 17677 | "map", "repeat", "reverse", "index", "first", "last", "cat", |
| 17678 | "trim", "trimleft", "trimright", "tolower", "toupper", "totitle", NULL |
| 17679 | }; |
| 17680 | enum |
| 17681 | { |
| 17682 | OPT_BYTELENGTH, OPT_LENGTH, OPT_COMPARE, OPT_MATCH, OPT_EQUAL, OPT_IS, OPT_BYTERANGE, OPT_RANGE, OPT_REPLACE, |
| 17683 | OPT_MAP, OPT_REPEAT, OPT_REVERSE, OPT_INDEX, OPT_FIRST, OPT_LAST, OPT_CAT, |
| 17684 | OPT_TRIM, OPT_TRIMLEFT, OPT_TRIMRIGHT, OPT_TOLOWER, OPT_TOUPPER, OPT_TOTITLE |
| 17685 | }; |
| 17686 | static const char * const nocase_options[] = { |
| 17687 | "-nocase", NULL |
| 17688 | }; |
| @@ -17636,10 +17711,29 @@ | |
| 17711 | else { |
| 17712 | len = Jim_Length(argv[2]); |
| 17713 | } |
| 17714 | Jim_SetResultInt(interp, len); |
| 17715 | return JIM_OK; |
| 17716 | |
| 17717 | case OPT_CAT:{ |
| 17718 | Jim_Obj *objPtr; |
| 17719 | if (argc == 3) { |
| 17720 | |
| 17721 | objPtr = argv[2]; |
| 17722 | } |
| 17723 | else { |
| 17724 | int i; |
| 17725 | |
| 17726 | objPtr = Jim_NewStringObj(interp, "", 0); |
| 17727 | |
| 17728 | for (i = 2; i < argc; i++) { |
| 17729 | Jim_AppendObj(interp, objPtr, argv[i]); |
| 17730 | } |
| 17731 | } |
| 17732 | Jim_SetResult(interp, objPtr); |
| 17733 | return JIM_OK; |
| 17734 | } |
| 17735 | |
| 17736 | case OPT_COMPARE: |
| 17737 | case OPT_EQUAL: |
| 17738 | { |
| 17739 | |
| @@ -18619,38 +18713,47 @@ | |
| 18713 | case INFO_SCRIPT: |
| 18714 | if (argc != 2) { |
| 18715 | Jim_WrongNumArgs(interp, 2, argv, ""); |
| 18716 | return JIM_ERR; |
| 18717 | } |
| 18718 | Jim_SetResult(interp, JimGetScript(interp, interp->currentScriptObj)->fileNameObj); |
| 18719 | break; |
| 18720 | |
| 18721 | case INFO_SOURCE:{ |
| 18722 | jim_wide line; |
| 18723 | Jim_Obj *resObjPtr; |
| 18724 | Jim_Obj *fileNameObj; |
| 18725 | |
| 18726 | if (argc != 3 && argc != 5) { |
| 18727 | Jim_WrongNumArgs(interp, 2, argv, "source ?filename line?"); |
| 18728 | return JIM_ERR; |
| 18729 | } |
| 18730 | if (argc == 5) { |
| 18731 | if (Jim_GetWide(interp, argv[4], &line) != JIM_OK) { |
| 18732 | return JIM_ERR; |
| 18733 | } |
| 18734 | resObjPtr = Jim_NewStringObj(interp, Jim_String(argv[2]), Jim_Length(argv[2])); |
| 18735 | JimSetSourceInfo(interp, resObjPtr, argv[3], line); |
| 18736 | } |
| 18737 | else { |
| 18738 | if (argv[2]->typePtr == &sourceObjType) { |
| 18739 | fileNameObj = argv[2]->internalRep.sourceValue.fileNameObj; |
| 18740 | line = argv[2]->internalRep.sourceValue.lineNumber; |
| 18741 | } |
| 18742 | else if (argv[2]->typePtr == &scriptObjType) { |
| 18743 | ScriptObj *script = JimGetScript(interp, argv[2]); |
| 18744 | fileNameObj = script->fileNameObj; |
| 18745 | line = script->firstline; |
| 18746 | } |
| 18747 | else { |
| 18748 | fileNameObj = interp->emptyObj; |
| 18749 | line = 1; |
| 18750 | } |
| 18751 | resObjPtr = Jim_NewListObj(interp, NULL, 0); |
| 18752 | Jim_ListAppendElement(interp, resObjPtr, fileNameObj); |
| 18753 | Jim_ListAppendElement(interp, resObjPtr, Jim_NewIntObj(interp, line)); |
| 18754 | } |
| 18755 | Jim_SetResult(interp, resObjPtr); |
| 18756 | break; |
| 18757 | } |
| 18758 | |
| 18759 | case INFO_STACKTRACE: |
| @@ -21843,11 +21946,11 @@ | |
| 21946 | |
| 21947 | if (Jim_InitStaticExtensions(interp) != JIM_OK) { |
| 21948 | JimPrintErrorMessage(interp); |
| 21949 | } |
| 21950 | |
| 21951 | Jim_SetVariableStrWithStr(interp, "jim::argv0", argv[0]); |
| 21952 | Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0"); |
| 21953 | retcode = Jim_initjimshInit(interp); |
| 21954 | |
| 21955 | if (argc == 1) { |
| 21956 | if (retcode == JIM_ERR) { |
| 21957 |