| | @@ -1,10 +1,11 @@ |
| 1 | 1 | /* This is single source file, bootstrap version of Jim Tcl. See http://jim.tcl.tk/ */ |
| 2 | 2 | #define JIM_TCL_COMPAT |
| 3 | 3 | #define JIM_ANSIC |
| 4 | 4 | #define JIM_REGEXP |
| 5 | 5 | #define HAVE_NO_AUTOCONF |
| 6 | +#define JIM_TINY |
| 6 | 7 | #define _JIMAUTOCONF_H |
| 7 | 8 | #define TCL_LIBRARY "." |
| 8 | 9 | #define jim_ext_bootstrap |
| 9 | 10 | #define jim_ext_aio |
| 10 | 11 | #define jim_ext_readdir |
| | @@ -60,11 +61,11 @@ |
| 60 | 61 | #define HAVE_UNISTD_H |
| 61 | 62 | #define HAVE_UMASK |
| 62 | 63 | #define HAVE_PIPE |
| 63 | 64 | #define _FILE_OFFSET_BITS 64 |
| 64 | 65 | #endif |
| 65 | | -#define JIM_VERSION 82 |
| 66 | +#define JIM_VERSION 83 |
| 66 | 67 | #ifndef JIM_WIN32COMPAT_H |
| 67 | 68 | #define JIM_WIN32COMPAT_H |
| 68 | 69 | |
| 69 | 70 | |
| 70 | 71 | |
| | @@ -574,11 +575,11 @@ |
| 574 | 575 | |
| 575 | 576 | typedef struct Jim_Interp { |
| 576 | 577 | Jim_Obj *result; |
| 577 | 578 | int unused_errorLine; |
| 578 | 579 | Jim_Obj *currentFilenameObj; |
| 579 | | - int unused_addStackTrace; |
| 580 | + int break_level; |
| 580 | 581 | int maxCallFrameDepth; |
| 581 | 582 | int maxEvalDepth; |
| 582 | 583 | int evalDepth; |
| 583 | 584 | int returnCode; |
| 584 | 585 | int returnLevel; |
| | @@ -716,10 +717,18 @@ |
| 716 | 717 | int objc, Jim_Obj *const *objv); |
| 717 | 718 | #define Jim_EvalPrefix(i, p, oc, ov) Jim_EvalObjPrefix((i), Jim_NewStringObj((i), (p), -1), (oc), (ov)) |
| 718 | 719 | JIM_EXPORT int Jim_EvalNamespace(Jim_Interp *interp, Jim_Obj *scriptObj, Jim_Obj *nsObj); |
| 719 | 720 | JIM_EXPORT int Jim_SubstObj (Jim_Interp *interp, Jim_Obj *substObjPtr, |
| 720 | 721 | Jim_Obj **resObjPtrPtr, int flags); |
| 722 | + |
| 723 | + |
| 724 | +JIM_EXPORT Jim_Obj *Jim_GetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr, |
| 725 | + int *lineptr); |
| 726 | + |
| 727 | +JIM_EXPORT void Jim_SetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr, |
| 728 | + Jim_Obj *fileNameObj, int lineNumber); |
| 729 | + |
| 721 | 730 | |
| 722 | 731 | |
| 723 | 732 | JIM_EXPORT void Jim_InitStack(Jim_Stack *stack); |
| 724 | 733 | JIM_EXPORT void Jim_FreeStack(Jim_Stack *stack); |
| 725 | 734 | JIM_EXPORT int Jim_StackLen(Jim_Stack *stack); |
| | @@ -2343,13 +2352,11 @@ |
| 2343 | 2352 | continue; |
| 2344 | 2353 | } |
| 2345 | 2354 | if (JimCheckStreamError(interp, af)) { |
| 2346 | 2355 | return JIM_ERR; |
| 2347 | 2356 | } |
| 2348 | | - if (nb || af->timeout) { |
| 2349 | | - return JIM_OK; |
| 2350 | | - } |
| 2357 | + break; |
| 2351 | 2358 | } |
| 2352 | 2359 | |
| 2353 | 2360 | return JIM_OK; |
| 2354 | 2361 | } |
| 2355 | 2362 | |
| | @@ -2617,18 +2624,13 @@ |
| 2617 | 2624 | } |
| 2618 | 2625 | |
| 2619 | 2626 | offset = len; |
| 2620 | 2627 | len = af->fops->reader(af, buf, AIO_BUF_LEN, nb); |
| 2621 | 2628 | if (len <= 0) { |
| 2622 | | - if (nb || af->timeout) { |
| 2623 | | - |
| 2624 | | - break; |
| 2625 | | - } |
| 2626 | | - } |
| 2627 | | - else { |
| 2628 | | - Jim_AppendString(interp, af->readbuf, buf, len); |
| 2629 | | - } |
| 2629 | + break; |
| 2630 | + } |
| 2631 | + Jim_AppendString(interp, af->readbuf, buf, len); |
| 2630 | 2632 | } |
| 2631 | 2633 | |
| 2632 | 2634 | aio_set_nonblocking(af, nb); |
| 2633 | 2635 | |
| 2634 | 2636 | if (!nl && aio_eof(af)) { |
| | @@ -3770,31 +3772,34 @@ |
| 3770 | 3772 | int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) |
| 3771 | 3773 | { |
| 3772 | 3774 | int regcomp_flags = 0; |
| 3773 | 3775 | int regexec_flags = 0; |
| 3774 | 3776 | int opt_all = 0; |
| 3777 | + int opt_command = 0; |
| 3775 | 3778 | int offset = 0; |
| 3776 | 3779 | regex_t *regex; |
| 3777 | 3780 | const char *p; |
| 3778 | | - int result; |
| 3781 | + int result = JIM_OK; |
| 3779 | 3782 | regmatch_t pmatch[MAX_SUB_MATCHES + 1]; |
| 3780 | 3783 | int num_matches = 0; |
| 3781 | 3784 | |
| 3782 | 3785 | int i, j, n; |
| 3783 | 3786 | Jim_Obj *varname; |
| 3784 | 3787 | Jim_Obj *resultObj; |
| 3788 | + Jim_Obj *cmd_prefix = NULL; |
| 3789 | + Jim_Obj *regcomp_obj = NULL; |
| 3785 | 3790 | const char *source_str; |
| 3786 | 3791 | int source_len; |
| 3787 | | - const char *replace_str; |
| 3792 | + const char *replace_str = NULL; |
| 3788 | 3793 | int replace_len; |
| 3789 | 3794 | const char *pattern; |
| 3790 | 3795 | int option; |
| 3791 | 3796 | enum { |
| 3792 | | - OPT_NOCASE, OPT_LINE, OPT_ALL, OPT_START, OPT_END |
| 3797 | + OPT_NOCASE, OPT_LINE, OPT_ALL, OPT_START, OPT_COMMAND, OPT_END |
| 3793 | 3798 | }; |
| 3794 | 3799 | static const char * const options[] = { |
| 3795 | | - "-nocase", "-line", "-all", "-start", "--", NULL |
| 3800 | + "-nocase", "-line", "-all", "-start", "-command", "--", NULL |
| 3796 | 3801 | }; |
| 3797 | 3802 | |
| 3798 | 3803 | if (argc < 4) { |
| 3799 | 3804 | wrongNumArgs: |
| 3800 | 3805 | Jim_WrongNumArgs(interp, 1, argv, |
| | @@ -3834,24 +3839,43 @@ |
| 3834 | 3839 | } |
| 3835 | 3840 | if (Jim_GetIndex(interp, argv[i], &offset) != JIM_OK) { |
| 3836 | 3841 | return JIM_ERR; |
| 3837 | 3842 | } |
| 3838 | 3843 | break; |
| 3844 | + |
| 3845 | + case OPT_COMMAND: |
| 3846 | + opt_command = 1; |
| 3847 | + break; |
| 3839 | 3848 | } |
| 3840 | 3849 | } |
| 3841 | 3850 | if (argc - i != 3 && argc - i != 4) { |
| 3842 | 3851 | goto wrongNumArgs; |
| 3843 | 3852 | } |
| 3844 | 3853 | |
| 3845 | | - regex = SetRegexpFromAny(interp, argv[i], regcomp_flags); |
| 3854 | + |
| 3855 | + regcomp_obj = Jim_DuplicateObj(interp, argv[i]); |
| 3856 | + Jim_IncrRefCount(regcomp_obj); |
| 3857 | + regex = SetRegexpFromAny(interp, regcomp_obj, regcomp_flags); |
| 3846 | 3858 | if (!regex) { |
| 3859 | + Jim_DecrRefCount(interp, regcomp_obj); |
| 3847 | 3860 | return JIM_ERR; |
| 3848 | 3861 | } |
| 3849 | 3862 | pattern = Jim_String(argv[i]); |
| 3850 | 3863 | |
| 3851 | 3864 | source_str = Jim_GetString(argv[i + 1], &source_len); |
| 3852 | | - replace_str = Jim_GetString(argv[i + 2], &replace_len); |
| 3865 | + if (opt_command) { |
| 3866 | + cmd_prefix = argv[i + 2]; |
| 3867 | + if (Jim_ListLength(interp, cmd_prefix) == 0) { |
| 3868 | + Jim_SetResultString(interp, "command prefix must be a list of at least one element", -1); |
| 3869 | + Jim_DecrRefCount(interp, regcomp_obj); |
| 3870 | + return JIM_ERR; |
| 3871 | + } |
| 3872 | + Jim_IncrRefCount(cmd_prefix); |
| 3873 | + } |
| 3874 | + else { |
| 3875 | + replace_str = Jim_GetString(argv[i + 2], &replace_len); |
| 3876 | + } |
| 3853 | 3877 | varname = argv[i + 3]; |
| 3854 | 3878 | |
| 3855 | 3879 | |
| 3856 | 3880 | resultObj = Jim_NewStringObj(interp, "", 0); |
| 3857 | 3881 | |
| | @@ -3891,39 +3915,62 @@ |
| 3891 | 3915 | |
| 3892 | 3916 | num_matches++; |
| 3893 | 3917 | |
| 3894 | 3918 | Jim_AppendString(interp, resultObj, p, pmatch[0].rm_so); |
| 3895 | 3919 | |
| 3896 | | - |
| 3897 | | - for (j = 0; j < replace_len; j++) { |
| 3898 | | - int idx; |
| 3899 | | - int c = replace_str[j]; |
| 3900 | | - |
| 3901 | | - if (c == '&') { |
| 3902 | | - idx = 0; |
| 3903 | | - } |
| 3904 | | - else if (c == '\\' && j < replace_len) { |
| 3905 | | - c = replace_str[++j]; |
| 3906 | | - if ((c >= '0') && (c <= '9')) { |
| 3907 | | - idx = c - '0'; |
| 3908 | | - } |
| 3909 | | - else if ((c == '\\') || (c == '&')) { |
| 3910 | | - Jim_AppendString(interp, resultObj, replace_str + j, 1); |
| 3911 | | - continue; |
| 3912 | | - } |
| 3913 | | - else { |
| 3914 | | - Jim_AppendString(interp, resultObj, replace_str + j - 1, (j == replace_len) ? 1 : 2); |
| 3915 | | - continue; |
| 3916 | | - } |
| 3917 | | - } |
| 3918 | | - else { |
| 3919 | | - Jim_AppendString(interp, resultObj, replace_str + j, 1); |
| 3920 | | - continue; |
| 3921 | | - } |
| 3922 | | - if ((idx < MAX_SUB_MATCHES) && pmatch[idx].rm_so != -1 && pmatch[idx].rm_eo != -1) { |
| 3923 | | - Jim_AppendString(interp, resultObj, p + pmatch[idx].rm_so, |
| 3924 | | - pmatch[idx].rm_eo - pmatch[idx].rm_so); |
| 3920 | + if (opt_command) { |
| 3921 | + |
| 3922 | + Jim_Obj *cmdListObj = Jim_DuplicateObj(interp, cmd_prefix); |
| 3923 | + for (j = 0; j < MAX_SUB_MATCHES; j++) { |
| 3924 | + if (pmatch[j].rm_so == -1) { |
| 3925 | + break; |
| 3926 | + } |
| 3927 | + else { |
| 3928 | + Jim_Obj *srcObj = Jim_NewStringObj(interp, p + pmatch[j].rm_so, pmatch[j].rm_eo - pmatch[j].rm_so); |
| 3929 | + Jim_ListAppendElement(interp, cmdListObj, srcObj); |
| 3930 | + } |
| 3931 | + } |
| 3932 | + Jim_IncrRefCount(cmdListObj); |
| 3933 | + |
| 3934 | + result = Jim_EvalObj(interp, cmdListObj); |
| 3935 | + Jim_DecrRefCount(interp, cmdListObj); |
| 3936 | + if (result != JIM_OK) { |
| 3937 | + goto cmd_error; |
| 3938 | + } |
| 3939 | + Jim_AppendString(interp, resultObj, Jim_String(Jim_GetResult(interp)), -1); |
| 3940 | + } |
| 3941 | + else { |
| 3942 | + |
| 3943 | + for (j = 0; j < replace_len; j++) { |
| 3944 | + int idx; |
| 3945 | + int c = replace_str[j]; |
| 3946 | + |
| 3947 | + if (c == '&') { |
| 3948 | + idx = 0; |
| 3949 | + } |
| 3950 | + else if (c == '\\' && j < replace_len) { |
| 3951 | + c = replace_str[++j]; |
| 3952 | + if ((c >= '0') && (c <= '9')) { |
| 3953 | + idx = c - '0'; |
| 3954 | + } |
| 3955 | + else if ((c == '\\') || (c == '&')) { |
| 3956 | + Jim_AppendString(interp, resultObj, replace_str + j, 1); |
| 3957 | + continue; |
| 3958 | + } |
| 3959 | + else { |
| 3960 | + Jim_AppendString(interp, resultObj, replace_str + j - 1, (j == replace_len) ? 1 : 2); |
| 3961 | + continue; |
| 3962 | + } |
| 3963 | + } |
| 3964 | + else { |
| 3965 | + Jim_AppendString(interp, resultObj, replace_str + j, 1); |
| 3966 | + continue; |
| 3967 | + } |
| 3968 | + if ((idx < MAX_SUB_MATCHES) && pmatch[idx].rm_so != -1 && pmatch[idx].rm_eo != -1) { |
| 3969 | + Jim_AppendString(interp, resultObj, p + pmatch[idx].rm_so, |
| 3970 | + pmatch[idx].rm_eo - pmatch[idx].rm_so); |
| 3971 | + } |
| 3925 | 3972 | } |
| 3926 | 3973 | } |
| 3927 | 3974 | |
| 3928 | 3975 | p += pmatch[0].rm_eo; |
| 3929 | 3976 | n -= pmatch[0].rm_eo; |
| | @@ -3956,25 +4003,37 @@ |
| 3956 | 4003 | |
| 3957 | 4004 | } while (n); |
| 3958 | 4005 | |
| 3959 | 4006 | Jim_AppendString(interp, resultObj, p, -1); |
| 3960 | 4007 | |
| 3961 | | - |
| 3962 | | - if (argc - i == 4) { |
| 3963 | | - result = Jim_SetVariable(interp, varname, resultObj); |
| 3964 | | - |
| 3965 | | - if (result == JIM_OK) { |
| 3966 | | - Jim_SetResultInt(interp, num_matches); |
| 3967 | | - } |
| 3968 | | - else { |
| 3969 | | - Jim_FreeObj(interp, resultObj); |
| 3970 | | - } |
| 3971 | | - } |
| 3972 | | - else { |
| 3973 | | - Jim_SetResult(interp, resultObj); |
| 3974 | | - result = JIM_OK; |
| 3975 | | - } |
| 4008 | +cmd_error: |
| 4009 | + if (result == JIM_OK) { |
| 4010 | + |
| 4011 | + if (argc - i == 4) { |
| 4012 | + result = Jim_SetVariable(interp, varname, resultObj); |
| 4013 | + |
| 4014 | + if (result == JIM_OK) { |
| 4015 | + Jim_SetResultInt(interp, num_matches); |
| 4016 | + } |
| 4017 | + else { |
| 4018 | + Jim_FreeObj(interp, resultObj); |
| 4019 | + } |
| 4020 | + } |
| 4021 | + else { |
| 4022 | + Jim_SetResult(interp, resultObj); |
| 4023 | + result = JIM_OK; |
| 4024 | + } |
| 4025 | + } |
| 4026 | + else { |
| 4027 | + Jim_FreeObj(interp, resultObj); |
| 4028 | + } |
| 4029 | + |
| 4030 | + if (opt_command) { |
| 4031 | + Jim_DecrRefCount(interp, cmd_prefix); |
| 4032 | + } |
| 4033 | + |
| 4034 | + Jim_DecrRefCount(interp, regcomp_obj); |
| 3976 | 4035 | |
| 3977 | 4036 | return result; |
| 3978 | 4037 | } |
| 3979 | 4038 | |
| 3980 | 4039 | int Jim_regexpInit(Jim_Interp *interp) |
| | @@ -6353,10 +6412,11 @@ |
| 6353 | 6412 | Jim_SetResultString(interp, "Failed to parse time according to format", -1); |
| 6354 | 6413 | return JIM_ERR; |
| 6355 | 6414 | } |
| 6356 | 6415 | |
| 6357 | 6416 | |
| 6417 | + tm.tm_isdst = options.gmt ? 0 : -1; |
| 6358 | 6418 | Jim_SetResultInt(interp, options.gmt ? jim_timegm(&tm) : mktime(&tm)); |
| 6359 | 6419 | |
| 6360 | 6420 | return JIM_OK; |
| 6361 | 6421 | } |
| 6362 | 6422 | #endif |
| | @@ -6732,11 +6792,13 @@ |
| 6732 | 6792 | Jim_arrayInit(interp); |
| 6733 | 6793 | Jim_stdlibInit(interp); |
| 6734 | 6794 | Jim_tclcompatInit(interp); |
| 6735 | 6795 | return JIM_OK; |
| 6736 | 6796 | } |
| 6797 | +#ifndef JIM_TINY |
| 6737 | 6798 | #define JIM_OPTIMIZATION |
| 6799 | +#endif |
| 6738 | 6800 | |
| 6739 | 6801 | #include <stdio.h> |
| 6740 | 6802 | #include <stdlib.h> |
| 6741 | 6803 | |
| 6742 | 6804 | #include <string.h> |
| | @@ -6792,11 +6854,13 @@ |
| 6792 | 6854 | |
| 6793 | 6855 | |
| 6794 | 6856 | |
| 6795 | 6857 | #define JIM_INTEGER_SPACE 24 |
| 6796 | 6858 | |
| 6797 | | -const char *jim_tt_name(int type); |
| 6859 | +#if defined(DEBUG_SHOW_SCRIPT) || defined(DEBUG_SHOW_SCRIPT_TOKENS) || defined(JIM_DEBUG_COMMAND) || defined(DEBUG_SHOW_SUBST) |
| 6860 | +static const char *jim_tt_name(int type); |
| 6861 | +#endif |
| 6798 | 6862 | |
| 6799 | 6863 | #ifdef JIM_DEBUG_PANIC |
| 6800 | 6864 | static void JimPanicDump(int fail_condition, const char *fmt, ...); |
| 6801 | 6865 | #define JimPanic(X) JimPanicDump X |
| 6802 | 6866 | #else |
| | @@ -6828,11 +6892,10 @@ |
| 6828 | 6892 | static int JimSign(jim_wide w); |
| 6829 | 6893 | static void JimPrngSeed(Jim_Interp *interp, unsigned char *seed, int seedLen); |
| 6830 | 6894 | static void JimRandomBytes(Jim_Interp *interp, void *dest, unsigned int len); |
| 6831 | 6895 | static int JimSetNewVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr, Jim_VarVal *vv); |
| 6832 | 6896 | static Jim_VarVal *JimFindVariable(Jim_HashTable *ht, Jim_Obj *nameObjPtr); |
| 6833 | | -static void JimSetErrorStack(Jim_Interp *interp); |
| 6834 | 6897 | static int SetVariableFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); |
| 6835 | 6898 | |
| 6836 | 6899 | #define JIM_DICT_SUGAR 100 |
| 6837 | 6900 | |
| 6838 | 6901 | |
| | @@ -7807,10 +7870,11 @@ |
| 7807 | 7870 | int tt; |
| 7808 | 7871 | int eof; |
| 7809 | 7872 | int inquote; |
| 7810 | 7873 | int comment; |
| 7811 | 7874 | struct JimParseMissing missing; |
| 7875 | + const char *errmsg; |
| 7812 | 7876 | }; |
| 7813 | 7877 | |
| 7814 | 7878 | static int JimParseScript(struct JimParserCtx *pc); |
| 7815 | 7879 | static int JimParseSep(struct JimParserCtx *pc); |
| 7816 | 7880 | static int JimParseEol(struct JimParserCtx *pc); |
| | @@ -9507,21 +9571,10 @@ |
| 9507 | 9571 | { |
| 9508 | 9572 | dupPtr->internalRep.sourceValue = srcPtr->internalRep.sourceValue; |
| 9509 | 9573 | Jim_IncrRefCount(dupPtr->internalRep.sourceValue.fileNameObj); |
| 9510 | 9574 | } |
| 9511 | 9575 | |
| 9512 | | -static void JimSetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr, |
| 9513 | | - Jim_Obj *fileNameObj, int lineNumber) |
| 9514 | | -{ |
| 9515 | | - JimPanic((Jim_IsShared(objPtr), "JimSetSourceInfo called with shared object")); |
| 9516 | | - JimPanic((objPtr->typePtr != NULL, "JimSetSourceInfo called with typed object")); |
| 9517 | | - Jim_IncrRefCount(fileNameObj); |
| 9518 | | - objPtr->internalRep.sourceValue.fileNameObj = fileNameObj; |
| 9519 | | - objPtr->internalRep.sourceValue.lineNumber = lineNumber; |
| 9520 | | - objPtr->typePtr = &sourceObjType; |
| 9521 | | -} |
| 9522 | | - |
| 9523 | 9576 | static const Jim_ObjType scriptLineObjType = { |
| 9524 | 9577 | "scriptline", |
| 9525 | 9578 | NULL, |
| 9526 | 9579 | NULL, |
| 9527 | 9580 | NULL, |
| | @@ -9578,10 +9631,11 @@ |
| 9578 | 9631 | } ScriptObj; |
| 9579 | 9632 | |
| 9580 | 9633 | static void JimSetScriptFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); |
| 9581 | 9634 | static int JimParseCheckMissing(Jim_Interp *interp, int ch); |
| 9582 | 9635 | static ScriptObj *JimGetScript(Jim_Interp *interp, Jim_Obj *objPtr); |
| 9636 | +static void JimSetErrorStack(Jim_Interp *interp, ScriptObj *script); |
| 9583 | 9637 | |
| 9584 | 9638 | void FreeScriptInternalRep(Jim_Interp *interp, Jim_Obj *objPtr) |
| 9585 | 9639 | { |
| 9586 | 9640 | int i; |
| 9587 | 9641 | struct ScriptObj *script = (void *)objPtr->internalRep.ptr; |
| | @@ -9793,11 +9847,11 @@ |
| 9793 | 9847 | |
| 9794 | 9848 | token->type = t->type; |
| 9795 | 9849 | token->objPtr = JimMakeScriptObj(interp, t); |
| 9796 | 9850 | Jim_IncrRefCount(token->objPtr); |
| 9797 | 9851 | |
| 9798 | | - JimSetSourceInfo(interp, token->objPtr, script->fileNameObj, t->line); |
| 9852 | + Jim_SetSourceInfo(interp, token->objPtr, script->fileNameObj, t->line); |
| 9799 | 9853 | token++; |
| 9800 | 9854 | } |
| 9801 | 9855 | } |
| 9802 | 9856 | |
| 9803 | 9857 | if (lineargs == 0) { |
| | @@ -9852,10 +9906,43 @@ |
| 9852 | 9906 | } |
| 9853 | 9907 | |
| 9854 | 9908 | Jim_SetResultString(interp, msg, -1); |
| 9855 | 9909 | return JIM_ERR; |
| 9856 | 9910 | } |
| 9911 | + |
| 9912 | +Jim_Obj *Jim_GetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr, int *lineptr) |
| 9913 | +{ |
| 9914 | + int line; |
| 9915 | + Jim_Obj *fileNameObj; |
| 9916 | + |
| 9917 | + if (objPtr->typePtr == &sourceObjType) { |
| 9918 | + fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; |
| 9919 | + line = objPtr->internalRep.sourceValue.lineNumber; |
| 9920 | + } |
| 9921 | + else if (objPtr->typePtr == &scriptObjType) { |
| 9922 | + ScriptObj *script = JimGetScript(interp, objPtr); |
| 9923 | + fileNameObj = script->fileNameObj; |
| 9924 | + line = script->firstline; |
| 9925 | + } |
| 9926 | + else { |
| 9927 | + fileNameObj = interp->emptyObj; |
| 9928 | + line = 1; |
| 9929 | + } |
| 9930 | + *lineptr = line; |
| 9931 | + return fileNameObj; |
| 9932 | +} |
| 9933 | + |
| 9934 | +void Jim_SetSourceInfo(Jim_Interp *interp, Jim_Obj *objPtr, |
| 9935 | + Jim_Obj *fileNameObj, int lineNumber) |
| 9936 | +{ |
| 9937 | + JimPanic((Jim_IsShared(objPtr), "Jim_SetSourceInfo called with shared object")); |
| 9938 | + Jim_FreeIntRep(interp, objPtr); |
| 9939 | + Jim_IncrRefCount(fileNameObj); |
| 9940 | + objPtr->internalRep.sourceValue.fileNameObj = fileNameObj; |
| 9941 | + objPtr->internalRep.sourceValue.lineNumber = lineNumber; |
| 9942 | + objPtr->typePtr = &sourceObjType; |
| 9943 | +} |
| 9857 | 9944 | |
| 9858 | 9945 | static void SubstObjAddTokens(Jim_Interp *interp, struct ScriptObj *script, |
| 9859 | 9946 | ParseTokenList *tokenlist) |
| 9860 | 9947 | { |
| 9861 | 9948 | int i; |
| | @@ -9881,16 +9968,15 @@ |
| 9881 | 9968 | int scriptTextLen; |
| 9882 | 9969 | const char *scriptText = Jim_GetString(objPtr, &scriptTextLen); |
| 9883 | 9970 | struct JimParserCtx parser; |
| 9884 | 9971 | struct ScriptObj *script; |
| 9885 | 9972 | ParseTokenList tokenlist; |
| 9886 | | - int line = 1; |
| 9973 | + Jim_Obj *fileNameObj; |
| 9974 | + int line; |
| 9887 | 9975 | |
| 9888 | 9976 | |
| 9889 | | - if (objPtr->typePtr == &sourceObjType) { |
| 9890 | | - line = objPtr->internalRep.sourceValue.lineNumber; |
| 9891 | | - } |
| 9977 | + fileNameObj = Jim_GetSourceInfo(interp, objPtr, &line); |
| 9892 | 9978 | |
| 9893 | 9979 | |
| 9894 | 9980 | ScriptTokenListInit(&tokenlist); |
| 9895 | 9981 | |
| 9896 | 9982 | JimParserInit(&parser, scriptText, scriptTextLen, line); |
| | @@ -9905,16 +9991,11 @@ |
| 9905 | 9991 | |
| 9906 | 9992 | |
| 9907 | 9993 | script = Jim_Alloc(sizeof(*script)); |
| 9908 | 9994 | memset(script, 0, sizeof(*script)); |
| 9909 | 9995 | script->inUse = 1; |
| 9910 | | - if (objPtr->typePtr == &sourceObjType) { |
| 9911 | | - script->fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; |
| 9912 | | - } |
| 9913 | | - else { |
| 9914 | | - script->fileNameObj = interp->emptyObj; |
| 9915 | | - } |
| 9996 | + script->fileNameObj = fileNameObj; |
| 9916 | 9997 | Jim_IncrRefCount(script->fileNameObj); |
| 9917 | 9998 | script->missing = parser.missing.ch; |
| 9918 | 9999 | script->linenr = parser.missing.line; |
| 9919 | 10000 | |
| 9920 | 10001 | ScriptObjAddTokens(interp, script, &tokenlist); |
| | @@ -11386,14 +11467,15 @@ |
| 11386 | 11467 | Jim_DecrRefCount(i, i->unknown); |
| 11387 | 11468 | Jim_DecrRefCount(i, i->defer); |
| 11388 | 11469 | Jim_DecrRefCount(i, i->nullScriptObj); |
| 11389 | 11470 | Jim_DecrRefCount(i, i->currentFilenameObj); |
| 11390 | 11471 | |
| 11472 | + Jim_FreeHashTable(&i->commands); |
| 11473 | + |
| 11391 | 11474 | |
| 11392 | 11475 | Jim_InterpIncrProcEpoch(i); |
| 11393 | 11476 | |
| 11394 | | - Jim_FreeHashTable(&i->commands); |
| 11395 | 11477 | #ifdef JIM_REFERENCES |
| 11396 | 11478 | Jim_FreeHashTable(&i->references); |
| 11397 | 11479 | #endif |
| 11398 | 11480 | Jim_FreeHashTable(&i->packages); |
| 11399 | 11481 | Jim_Free(i->prngState); |
| | @@ -11588,20 +11670,28 @@ |
| 11588 | 11670 | Jim_DecrRefCount(interp, interp->stackTrace); |
| 11589 | 11671 | interp->stackTrace = stackTraceObj; |
| 11590 | 11672 | interp->errorFlag = 1; |
| 11591 | 11673 | } |
| 11592 | 11674 | |
| 11593 | | -static void JimSetErrorStack(Jim_Interp *interp) |
| 11675 | +static void JimSetErrorStack(Jim_Interp *interp, ScriptObj *script) |
| 11594 | 11676 | { |
| 11595 | 11677 | if (!interp->errorFlag) { |
| 11596 | 11678 | int i; |
| 11597 | 11679 | Jim_Obj *stackTrace = Jim_NewListObj(interp, NULL, 0); |
| 11598 | 11680 | |
| 11599 | | - for (i = 0; i <= interp->procLevel; i++) { |
| 11600 | | - Jim_EvalFrame *frame = JimGetEvalFrameByProcLevel(interp, -i); |
| 11601 | | - if (frame) { |
| 11602 | | - JimAddStackFrame(interp, frame, stackTrace); |
| 11681 | + if (interp->procLevel == 0 && script) { |
| 11682 | + Jim_ListAppendElement(interp, stackTrace, interp->emptyObj); |
| 11683 | + Jim_ListAppendElement(interp, stackTrace, script->fileNameObj); |
| 11684 | + Jim_ListAppendElement(interp, stackTrace, Jim_NewIntObj(interp, script->linenr)); |
| 11685 | + Jim_ListAppendElement(interp, stackTrace, interp->emptyObj); |
| 11686 | + } |
| 11687 | + else { |
| 11688 | + for (i = 0; i <= interp->procLevel; i++) { |
| 11689 | + Jim_EvalFrame *frame = JimGetEvalFrameByProcLevel(interp, -i); |
| 11690 | + if (frame) { |
| 11691 | + JimAddStackFrame(interp, frame, stackTrace); |
| 11692 | + } |
| 11603 | 11693 | } |
| 11604 | 11694 | } |
| 11605 | 11695 | JimSetStackTrace(interp, stackTrace); |
| 11606 | 11696 | } |
| 11607 | 11697 | } |
| | @@ -12288,18 +12378,11 @@ |
| 12288 | 12378 | Jim_Free(dict); |
| 12289 | 12379 | return JIM_OK; |
| 12290 | 12380 | } |
| 12291 | 12381 | |
| 12292 | 12382 | |
| 12293 | | - if (objPtr->typePtr == &sourceObjType) { |
| 12294 | | - fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; |
| 12295 | | - linenr = objPtr->internalRep.sourceValue.lineNumber; |
| 12296 | | - } |
| 12297 | | - else { |
| 12298 | | - fileNameObj = interp->emptyObj; |
| 12299 | | - linenr = 1; |
| 12300 | | - } |
| 12383 | + fileNameObj = Jim_GetSourceInfo(interp, objPtr, &linenr); |
| 12301 | 12384 | Jim_IncrRefCount(fileNameObj); |
| 12302 | 12385 | |
| 12303 | 12386 | |
| 12304 | 12387 | str = Jim_GetString(objPtr, &strLen); |
| 12305 | 12388 | |
| | @@ -12317,11 +12400,11 @@ |
| 12317 | 12400 | |
| 12318 | 12401 | JimParseList(&parser); |
| 12319 | 12402 | if (parser.tt != JIM_TT_STR && parser.tt != JIM_TT_ESC) |
| 12320 | 12403 | continue; |
| 12321 | 12404 | elementPtr = JimParserGetTokenObj(interp, &parser); |
| 12322 | | - JimSetSourceInfo(interp, elementPtr, fileNameObj, parser.tline); |
| 12405 | + Jim_SetSourceInfo(interp, elementPtr, fileNameObj, parser.tline); |
| 12323 | 12406 | ListAppendElement(objPtr, elementPtr); |
| 12324 | 12407 | } |
| 12325 | 12408 | } |
| 12326 | 12409 | Jim_DecrRefCount(interp, fileNameObj); |
| 12327 | 12410 | return JIM_OK; |
| | @@ -12372,11 +12455,12 @@ |
| 12372 | 12455 | enum { |
| 12373 | 12456 | JIM_LSORT_ASCII, |
| 12374 | 12457 | JIM_LSORT_NOCASE, |
| 12375 | 12458 | JIM_LSORT_INTEGER, |
| 12376 | 12459 | JIM_LSORT_REAL, |
| 12377 | | - JIM_LSORT_COMMAND |
| 12460 | + JIM_LSORT_COMMAND, |
| 12461 | + JIM_LSORT_DICT |
| 12378 | 12462 | } type; |
| 12379 | 12463 | int order; |
| 12380 | 12464 | Jim_Obj **indexv; |
| 12381 | 12465 | int indexc; |
| 12382 | 12466 | int unique; |
| | @@ -12404,10 +12488,47 @@ |
| 12404 | 12488 | |
| 12405 | 12489 | static int ListSortStringNoCase(Jim_Obj **lhsObj, Jim_Obj **rhsObj) |
| 12406 | 12490 | { |
| 12407 | 12491 | return Jim_StringCompareObj(sort_info->interp, *lhsObj, *rhsObj, 1) * sort_info->order; |
| 12408 | 12492 | } |
| 12493 | + |
| 12494 | +static int ListSortDict(Jim_Obj **lhsObj, Jim_Obj **rhsObj) |
| 12495 | +{ |
| 12496 | + |
| 12497 | + const char *left = Jim_String(*lhsObj); |
| 12498 | + const char *right = Jim_String(*rhsObj); |
| 12499 | + |
| 12500 | + while (1) { |
| 12501 | + if (isdigit(UCHAR(*left)) && isdigit(UCHAR(*right))) { |
| 12502 | + |
| 12503 | + jim_wide lint, rint; |
| 12504 | + char *lend, *rend; |
| 12505 | + lint = jim_strtoull(left, &lend); |
| 12506 | + rint = jim_strtoull(right, &rend); |
| 12507 | + if (lint != rint) { |
| 12508 | + return JimSign(lint - rint) * sort_info->order; |
| 12509 | + } |
| 12510 | + if (lend -left != rend - right) { |
| 12511 | + return JimSign((lend - left) - (rend - right)) * sort_info->order; |
| 12512 | + } |
| 12513 | + left = lend; |
| 12514 | + right = rend; |
| 12515 | + } |
| 12516 | + else { |
| 12517 | + int cl, cr; |
| 12518 | + left += utf8_tounicode_case(left, &cl, 1); |
| 12519 | + right += utf8_tounicode_case(right, &cr, 1); |
| 12520 | + if (cl != cr) { |
| 12521 | + return JimSign(cl - cr) * sort_info->order; |
| 12522 | + } |
| 12523 | + if (cl == 0) { |
| 12524 | + |
| 12525 | + return Jim_StringCompareObj(sort_info->interp, *lhsObj, *rhsObj, 0) * sort_info->order; |
| 12526 | + } |
| 12527 | + } |
| 12528 | + } |
| 12529 | +} |
| 12409 | 12530 | |
| 12410 | 12531 | static int ListSortInteger(Jim_Obj **lhsObj, Jim_Obj **rhsObj) |
| 12411 | 12532 | { |
| 12412 | 12533 | jim_wide lhs = 0, rhs = 0; |
| 12413 | 12534 | |
| | @@ -12519,10 +12640,13 @@ |
| 12519 | 12640 | fn = ListSortReal; |
| 12520 | 12641 | break; |
| 12521 | 12642 | case JIM_LSORT_COMMAND: |
| 12522 | 12643 | fn = ListSortCommand; |
| 12523 | 12644 | break; |
| 12645 | + case JIM_LSORT_DICT: |
| 12646 | + fn = ListSortDict; |
| 12647 | + break; |
| 12524 | 12648 | default: |
| 12525 | 12649 | fn = NULL; |
| 12526 | 12650 | JimPanic((1, "ListSort called with invalid sort type")); |
| 12527 | 12651 | return -1; |
| 12528 | 12652 | } |
| | @@ -12567,10 +12691,15 @@ |
| 12567 | 12691 | { |
| 12568 | 12692 | int currentLen = listPtr->internalRep.listValue.len; |
| 12569 | 12693 | int requiredLen = currentLen + elemc; |
| 12570 | 12694 | int i; |
| 12571 | 12695 | Jim_Obj **point; |
| 12696 | + |
| 12697 | + if (elemc == 0) { |
| 12698 | + |
| 12699 | + return; |
| 12700 | + } |
| 12572 | 12701 | |
| 12573 | 12702 | if (requiredLen > listPtr->internalRep.listValue.maxLen) { |
| 12574 | 12703 | if (currentLen) { |
| 12575 | 12704 | |
| 12576 | 12705 | requiredLen *= 2; |
| | @@ -14332,10 +14461,12 @@ |
| 14332 | 14461 | #define JIM_EXPR_OPERATORS_NUM \ |
| 14333 | 14462 | (sizeof(Jim_ExprOperators)/sizeof(struct Jim_ExprOperator)) |
| 14334 | 14463 | |
| 14335 | 14464 | static int JimParseExpression(struct JimParserCtx *pc) |
| 14336 | 14465 | { |
| 14466 | + pc->errmsg = NULL; |
| 14467 | + |
| 14337 | 14468 | while (1) { |
| 14338 | 14469 | |
| 14339 | 14470 | while (isspace(UCHAR(*pc->p)) || (*(pc->p) == '\\' && *(pc->p + 1) == '\n')) { |
| 14340 | 14471 | if (*pc->p == '\n') { |
| 14341 | 14472 | pc->linenr++; |
| | @@ -14382,10 +14513,11 @@ |
| 14382 | 14513 | if (JimParseVar(pc) == JIM_ERR) |
| 14383 | 14514 | return JimParseExprOperator(pc); |
| 14384 | 14515 | else { |
| 14385 | 14516 | |
| 14386 | 14517 | if (pc->tt == JIM_TT_EXPRSUGAR) { |
| 14518 | + pc->errmsg = "nesting expr in expr is not allowed"; |
| 14387 | 14519 | return JIM_ERR; |
| 14388 | 14520 | } |
| 14389 | 14521 | return JIM_OK; |
| 14390 | 14522 | } |
| 14391 | 14523 | break; |
| | @@ -14526,10 +14658,11 @@ |
| 14526 | 14658 | while (len && isspace(UCHAR(*p))) { |
| 14527 | 14659 | len--; |
| 14528 | 14660 | p++; |
| 14529 | 14661 | } |
| 14530 | 14662 | if (*p != '(') { |
| 14663 | + pc->errmsg = "function requires parentheses"; |
| 14531 | 14664 | return JIM_ERR; |
| 14532 | 14665 | } |
| 14533 | 14666 | } |
| 14534 | 14667 | pc->tend = pc->p + bestLen - 1; |
| 14535 | 14668 | pc->p += bestLen; |
| | @@ -14537,35 +14670,10 @@ |
| 14537 | 14670 | |
| 14538 | 14671 | pc->tt = (bestOp - Jim_ExprOperators) + JIM_TT_EXPR_OP; |
| 14539 | 14672 | return JIM_OK; |
| 14540 | 14673 | } |
| 14541 | 14674 | |
| 14542 | | -const char *jim_tt_name(int type) |
| 14543 | | -{ |
| 14544 | | - static const char * const tt_names[JIM_TT_EXPR_OP] = |
| 14545 | | - { "NIL", "STR", "ESC", "VAR", "ARY", "CMD", "SEP", "EOL", "EOF", "LIN", "WRD", "(((", ")))", ",,,", "INT", |
| 14546 | | - "DBL", "BOO", "$()" }; |
| 14547 | | - if (type < JIM_TT_EXPR_OP) { |
| 14548 | | - return tt_names[type]; |
| 14549 | | - } |
| 14550 | | - else if (type == JIM_EXPROP_UNARYMINUS) { |
| 14551 | | - return "-VE"; |
| 14552 | | - } |
| 14553 | | - else if (type == JIM_EXPROP_UNARYPLUS) { |
| 14554 | | - return "+VE"; |
| 14555 | | - } |
| 14556 | | - else { |
| 14557 | | - const struct Jim_ExprOperator *op = JimExprOperatorInfoByOpcode(type); |
| 14558 | | - static char buf[20]; |
| 14559 | | - |
| 14560 | | - if (op->name) { |
| 14561 | | - return op->name; |
| 14562 | | - } |
| 14563 | | - sprintf(buf, "(%d)", type); |
| 14564 | | - return buf; |
| 14565 | | - } |
| 14566 | | -} |
| 14567 | 14675 | |
| 14568 | 14676 | static void FreeExprInternalRep(Jim_Interp *interp, Jim_Obj *objPtr); |
| 14569 | 14677 | static void DupExprInternalRep(Jim_Interp *interp, Jim_Obj *srcPtr, Jim_Obj *dupPtr); |
| 14570 | 14678 | static int SetExprFromAny(Jim_Interp *interp, struct Jim_Obj *objPtr); |
| 14571 | 14679 | |
| | @@ -14867,11 +14975,11 @@ |
| 14867 | 14975 | if (!objPtr) { |
| 14868 | 14976 | |
| 14869 | 14977 | objPtr = Jim_NewStringObj(interp, t->token, t->len); |
| 14870 | 14978 | if (t->type == JIM_TT_CMD) { |
| 14871 | 14979 | |
| 14872 | | - JimSetSourceInfo(interp, objPtr, builder->fileNameObj, t->line); |
| 14980 | + Jim_SetSourceInfo(interp, objPtr, builder->fileNameObj, t->line); |
| 14873 | 14981 | } |
| 14874 | 14982 | } |
| 14875 | 14983 | |
| 14876 | 14984 | |
| 14877 | 14985 | node = builder->next++; |
| | @@ -14965,18 +15073,11 @@ |
| 14965 | 15073 | int line; |
| 14966 | 15074 | Jim_Obj *fileNameObj; |
| 14967 | 15075 | int rc = JIM_ERR; |
| 14968 | 15076 | |
| 14969 | 15077 | |
| 14970 | | - if (objPtr->typePtr == &sourceObjType) { |
| 14971 | | - fileNameObj = objPtr->internalRep.sourceValue.fileNameObj; |
| 14972 | | - line = objPtr->internalRep.sourceValue.lineNumber; |
| 14973 | | - } |
| 14974 | | - else { |
| 14975 | | - fileNameObj = interp->emptyObj; |
| 14976 | | - line = 1; |
| 14977 | | - } |
| 15078 | + fileNameObj = Jim_GetSourceInfo(interp, objPtr, &line); |
| 14978 | 15079 | Jim_IncrRefCount(fileNameObj); |
| 14979 | 15080 | |
| 14980 | 15081 | exprText = Jim_GetString(objPtr, &exprTextLen); |
| 14981 | 15082 | |
| 14982 | 15083 | |
| | @@ -14985,10 +15086,13 @@ |
| 14985 | 15086 | JimParserInit(&parser, exprText, exprTextLen, line); |
| 14986 | 15087 | while (!parser.eof) { |
| 14987 | 15088 | if (JimParseExpression(&parser) != JIM_OK) { |
| 14988 | 15089 | ScriptTokenListFree(&tokenlist); |
| 14989 | 15090 | Jim_SetResultFormatted(interp, "syntax error in expression: \"%#s\"", objPtr); |
| 15091 | + if (parser.errmsg) { |
| 15092 | + Jim_AppendStrings(interp, Jim_GetResult(interp), ": ", parser.errmsg, NULL); |
| 15093 | + } |
| 14990 | 15094 | expr = NULL; |
| 14991 | 15095 | goto err; |
| 14992 | 15096 | } |
| 14993 | 15097 | |
| 14994 | 15098 | ScriptAddToken(&tokenlist, parser.tstart, parser.tend - parser.tstart + 1, parser.tt, |
| | @@ -15004,14 +15108,21 @@ |
| 15004 | 15108 | tokenlist.list[i].len, tokenlist.list[i].token); |
| 15005 | 15109 | } |
| 15006 | 15110 | } |
| 15007 | 15111 | #endif |
| 15008 | 15112 | |
| 15009 | | - if (JimParseCheckMissing(interp, parser.missing.ch) == JIM_ERR) { |
| 15113 | + if (tokenlist.count <= 1) { |
| 15114 | + Jim_SetResultString(interp, "empty expression", -1); |
| 15115 | + rc = JIM_ERR; |
| 15116 | + } |
| 15117 | + else { |
| 15118 | + rc = JimParseCheckMissing(interp, parser.missing.ch); |
| 15119 | + } |
| 15120 | + if (rc != JIM_OK) { |
| 15010 | 15121 | ScriptTokenListFree(&tokenlist); |
| 15011 | 15122 | Jim_DecrRefCount(interp, fileNameObj); |
| 15012 | | - return JIM_ERR; |
| 15123 | + return rc; |
| 15013 | 15124 | } |
| 15014 | 15125 | |
| 15015 | 15126 | |
| 15016 | 15127 | expr = ExprTreeCreateTree(interp, &tokenlist, objPtr, fileNameObj); |
| 15017 | 15128 | |
| | @@ -15858,17 +15969,22 @@ |
| 15858 | 15969 | |
| 15859 | 15970 | int ret; |
| 15860 | 15971 | Jim_Obj *nargv[7]; |
| 15861 | 15972 | Jim_Obj *traceCmdObj = interp->traceCmdObj; |
| 15862 | 15973 | Jim_Obj *resultObj = Jim_GetResult(interp); |
| 15974 | + ScriptObj *script = NULL; |
| 15863 | 15975 | |
| 15864 | | - ScriptObj *script = JimGetScript(interp, interp->evalFrame->scriptObj); |
| 15976 | + |
| 15977 | + |
| 15978 | + if (interp->evalFrame->scriptObj) { |
| 15979 | + script = JimGetScript(interp, interp->evalFrame->scriptObj); |
| 15980 | + } |
| 15865 | 15981 | |
| 15866 | 15982 | nargv[0] = traceCmdObj; |
| 15867 | 15983 | nargv[1] = Jim_NewStringObj(interp, type, -1); |
| 15868 | | - nargv[2] = script->fileNameObj; |
| 15869 | | - nargv[3] = Jim_NewIntObj(interp, script->linenr); |
| 15984 | + nargv[2] = script ? script->fileNameObj : interp->emptyObj; |
| 15985 | + nargv[3] = Jim_NewIntObj(interp, script ? script->linenr : 1); |
| 15870 | 15986 | nargv[4] = resultObj; |
| 15871 | 15987 | nargv[5] = argv[0]; |
| 15872 | 15988 | nargv[6] = Jim_NewListObj(interp, argv + 1, argc - 1); |
| 15873 | 15989 | |
| 15874 | 15990 | |
| | @@ -15986,11 +16102,11 @@ |
| 15986 | 16102 | else { |
| 15987 | 16103 | interp->cmdPrivData = cmdPtr->u.native.privData; |
| 15988 | 16104 | retcode = cmdPtr->u.native.cmdProc(interp, objc, objv); |
| 15989 | 16105 | } |
| 15990 | 16106 | if (retcode == JIM_ERR) { |
| 15991 | | - JimSetErrorStack(interp); |
| 16107 | + JimSetErrorStack(interp, NULL); |
| 15992 | 16108 | } |
| 15993 | 16109 | } |
| 15994 | 16110 | |
| 15995 | 16111 | if (tailcallObj) { |
| 15996 | 16112 | |
| | @@ -16021,11 +16137,11 @@ |
| 16021 | 16137 | |
| 16022 | 16138 | out: |
| 16023 | 16139 | JimDecrCmdRefCount(interp, cmdPtr); |
| 16024 | 16140 | |
| 16025 | 16141 | if (retcode == JIM_ERR) { |
| 16026 | | - JimSetErrorStack(interp); |
| 16142 | + JimSetErrorStack(interp, NULL); |
| 16027 | 16143 | } |
| 16028 | 16144 | |
| 16029 | 16145 | if (interp->framePtr->tailcallObj) { |
| 16030 | 16146 | JimDecrCmdRefCount(interp, interp->framePtr->tailcallCmd); |
| 16031 | 16147 | Jim_DecrRefCount(interp, interp->framePtr->tailcallObj); |
| | @@ -16042,10 +16158,11 @@ |
| 16042 | 16158 | Jim_EvalFrame frame; |
| 16043 | 16159 | |
| 16044 | 16160 | |
| 16045 | 16161 | for (i = 0; i < objc; i++) |
| 16046 | 16162 | Jim_IncrRefCount(objv[i]); |
| 16163 | + |
| 16047 | 16164 | |
| 16048 | 16165 | JimPushEvalFrame(interp, &frame, NULL); |
| 16049 | 16166 | |
| 16050 | 16167 | retcode = JimInvokeCommand(interp, objc, objv); |
| 16051 | 16168 | |
| | @@ -16181,11 +16298,13 @@ |
| 16181 | 16298 | objPtr->internalRep.dictSubstValue.indexObjPtr = intv[2]; |
| 16182 | 16299 | Jim_IncrRefCount(intv[2]); |
| 16183 | 16300 | } |
| 16184 | 16301 | else if (tokens && intv[0] && intv[0]->typePtr == &sourceObjType) { |
| 16185 | 16302 | |
| 16186 | | - JimSetSourceInfo(interp, objPtr, intv[0]->internalRep.sourceValue.fileNameObj, intv[0]->internalRep.sourceValue.lineNumber); |
| 16303 | + int line; |
| 16304 | + Jim_Obj *fileNameObj = Jim_GetSourceInfo(interp, intv[0], &line); |
| 16305 | + Jim_SetSourceInfo(interp, objPtr, fileNameObj, line); |
| 16187 | 16306 | } |
| 16188 | 16307 | |
| 16189 | 16308 | |
| 16190 | 16309 | s = objPtr->bytes = Jim_Alloc(totlen + 1); |
| 16191 | 16310 | objPtr->length = totlen; |
| | @@ -16248,11 +16367,11 @@ |
| 16248 | 16367 | } |
| 16249 | 16368 | |
| 16250 | 16369 | Jim_IncrRefCount(scriptObjPtr); |
| 16251 | 16370 | script = JimGetScript(interp, scriptObjPtr); |
| 16252 | 16371 | if (JimParseCheckMissing(interp, script->missing) == JIM_ERR) { |
| 16253 | | - JimSetErrorStack(interp); |
| 16372 | + JimSetErrorStack(interp, script); |
| 16254 | 16373 | Jim_DecrRefCount(interp, scriptObjPtr); |
| 16255 | 16374 | return JIM_ERR; |
| 16256 | 16375 | } |
| 16257 | 16376 | |
| 16258 | 16377 | Jim_SetEmptyResult(interp); |
| | @@ -16420,11 +16539,11 @@ |
| 16420 | 16539 | } |
| 16421 | 16540 | } |
| 16422 | 16541 | |
| 16423 | 16542 | |
| 16424 | 16543 | if (retcode == JIM_ERR) { |
| 16425 | | - JimSetErrorStack(interp); |
| 16544 | + JimSetErrorStack(interp, NULL); |
| 16426 | 16545 | } |
| 16427 | 16546 | |
| 16428 | 16547 | JimPopEvalFrame(interp); |
| 16429 | 16548 | |
| 16430 | 16549 | Jim_FreeIntRep(interp, scriptObjPtr); |
| | @@ -16648,11 +16767,11 @@ |
| 16648 | 16767 | Jim_Obj *scriptObjPtr; |
| 16649 | 16768 | |
| 16650 | 16769 | scriptObjPtr = Jim_NewStringObj(interp, script, -1); |
| 16651 | 16770 | Jim_IncrRefCount(scriptObjPtr); |
| 16652 | 16771 | if (filename) { |
| 16653 | | - JimSetSourceInfo(interp, scriptObjPtr, Jim_NewStringObj(interp, filename, -1), lineno); |
| 16772 | + Jim_SetSourceInfo(interp, scriptObjPtr, Jim_NewStringObj(interp, filename, -1), lineno); |
| 16654 | 16773 | } |
| 16655 | 16774 | retval = Jim_EvalObj(interp, scriptObjPtr); |
| 16656 | 16775 | Jim_DecrRefCount(interp, scriptObjPtr); |
| 16657 | 16776 | return retval; |
| 16658 | 16777 | } |
| | @@ -16730,11 +16849,11 @@ |
| 16730 | 16849 | if (!scriptObjPtr) { |
| 16731 | 16850 | return JIM_ERR; |
| 16732 | 16851 | } |
| 16733 | 16852 | |
| 16734 | 16853 | filenameObj = Jim_NewStringObj(interp, filename, -1); |
| 16735 | | - JimSetSourceInfo(interp, scriptObjPtr, filenameObj, 1); |
| 16854 | + Jim_SetSourceInfo(interp, scriptObjPtr, filenameObj, 1); |
| 16736 | 16855 | |
| 16737 | 16856 | oldFilenameObj = JimPushInterpObj(interp->currentFilenameObj, filenameObj); |
| 16738 | 16857 | |
| 16739 | 16858 | retcode = Jim_EvalObj(interp, scriptObjPtr); |
| 16740 | 16859 | |
| | @@ -16771,11 +16890,13 @@ |
| 16771 | 16890 | if (JimParseVar(pc) == JIM_OK) { |
| 16772 | 16891 | return; |
| 16773 | 16892 | } |
| 16774 | 16893 | |
| 16775 | 16894 | pc->tstart = pc->p; |
| 16776 | | - flags |= JIM_SUBST_NOVAR; |
| 16895 | + |
| 16896 | + pc->p++; |
| 16897 | + pc->len--; |
| 16777 | 16898 | } |
| 16778 | 16899 | while (pc->len) { |
| 16779 | 16900 | if (*pc->p == '$' && !(flags & JIM_SUBST_NOVAR)) { |
| 16780 | 16901 | break; |
| 16781 | 16902 | } |
| | @@ -17274,11 +17395,11 @@ |
| 17274 | 17395 | } |
| 17275 | 17396 | |
| 17276 | 17397 | static int JimCheckLoopRetcode(Jim_Interp *interp, int retval) |
| 17277 | 17398 | { |
| 17278 | 17399 | if (retval == JIM_BREAK || retval == JIM_CONTINUE) { |
| 17279 | | - if (--interp->returnLevel > 0) { |
| 17400 | + if (--interp->break_level > 0) { |
| 17280 | 17401 | return 1; |
| 17281 | 17402 | } |
| 17282 | 17403 | } |
| 17283 | 17404 | return 0; |
| 17284 | 17405 | } |
| | @@ -17464,19 +17585,18 @@ |
| 17464 | 17585 | #endif |
| 17465 | 17586 | |
| 17466 | 17587 | while (boolean && (retval == JIM_OK || retval == JIM_CONTINUE)) { |
| 17467 | 17588 | |
| 17468 | 17589 | retval = Jim_EvalObj(interp, argv[4]); |
| 17469 | | - |
| 17590 | + if (JimCheckLoopRetcode(interp, retval)) { |
| 17591 | + immediate++; |
| 17592 | + break; |
| 17593 | + } |
| 17470 | 17594 | if (retval == JIM_OK || retval == JIM_CONTINUE) { |
| 17471 | 17595 | |
| 17472 | 17596 | JIM_IF_OPTIM(evalnext:) |
| 17473 | 17597 | retval = Jim_EvalObj(interp, argv[3]); |
| 17474 | | - if (JimCheckLoopRetcode(interp, retval)) { |
| 17475 | | - immediate++; |
| 17476 | | - goto out; |
| 17477 | | - } |
| 17478 | 17598 | if (retval == JIM_OK || retval == JIM_CONTINUE) { |
| 17479 | 17599 | |
| 17480 | 17600 | JIM_IF_OPTIM(testcond:) |
| 17481 | 17601 | retval = Jim_GetBoolFromExpr(interp, argv[2], &boolean); |
| 17482 | 17602 | } |
| | @@ -18327,21 +18447,23 @@ |
| 18327 | 18447 | |
| 18328 | 18448 | static int Jim_LsortCoreCommand(Jim_Interp *interp, int argc, Jim_Obj *const argv[]) |
| 18329 | 18449 | { |
| 18330 | 18450 | static const char * const options[] = { |
| 18331 | 18451 | "-ascii", "-nocase", "-increasing", "-decreasing", "-command", "-integer", "-real", "-index", "-unique", |
| 18332 | | - "-stride", NULL |
| 18452 | + "-stride", "-dictionary", NULL |
| 18333 | 18453 | }; |
| 18334 | 18454 | enum { |
| 18335 | 18455 | OPT_ASCII, OPT_NOCASE, OPT_INCREASING, OPT_DECREASING, OPT_COMMAND, OPT_INTEGER, OPT_REAL, OPT_INDEX, OPT_UNIQUE, |
| 18336 | | - OPT_STRIDE |
| 18456 | + OPT_STRIDE, OPT_DICT |
| 18337 | 18457 | }; |
| 18338 | 18458 | Jim_Obj *resObj; |
| 18339 | 18459 | int i; |
| 18340 | 18460 | int retCode; |
| 18341 | 18461 | int shared; |
| 18342 | 18462 | long stride = 1; |
| 18463 | + Jim_Obj **elements; |
| 18464 | + int listlen; |
| 18343 | 18465 | |
| 18344 | 18466 | struct lsort_info info; |
| 18345 | 18467 | |
| 18346 | 18468 | if (argc < 2) { |
| 18347 | 18469 | wrongargs: |
| | @@ -18364,10 +18486,13 @@ |
| 18364 | 18486 | return JIM_ERR; |
| 18365 | 18487 | switch (option) { |
| 18366 | 18488 | case OPT_ASCII: |
| 18367 | 18489 | info.type = JIM_LSORT_ASCII; |
| 18368 | 18490 | break; |
| 18491 | + case OPT_DICT: |
| 18492 | + info.type = JIM_LSORT_DICT; |
| 18493 | + break; |
| 18369 | 18494 | case OPT_NOCASE: |
| 18370 | 18495 | info.type = JIM_LSORT_NOCASE; |
| 18371 | 18496 | break; |
| 18372 | 18497 | case OPT_INTEGER: |
| 18373 | 18498 | info.type = JIM_LSORT_INTEGER; |
| | @@ -18418,17 +18543,21 @@ |
| 18418 | 18543 | i++; |
| 18419 | 18544 | break; |
| 18420 | 18545 | } |
| 18421 | 18546 | } |
| 18422 | 18547 | resObj = argv[argc - 1]; |
| 18548 | + JimListGetElements(interp, resObj, &listlen, &elements); |
| 18549 | + if (listlen <= 1) { |
| 18550 | + |
| 18551 | + Jim_SetResult(interp, resObj); |
| 18552 | + return JIM_OK; |
| 18553 | + } |
| 18554 | + |
| 18423 | 18555 | if (stride > 1) { |
| 18424 | 18556 | Jim_Obj *tmpListObj; |
| 18425 | | - Jim_Obj **elements; |
| 18426 | | - int listlen; |
| 18427 | 18557 | int i; |
| 18428 | 18558 | |
| 18429 | | - JimListGetElements(interp, resObj, &listlen, &elements); |
| 18430 | 18559 | if (listlen % stride) { |
| 18431 | 18560 | Jim_SetResultString(interp, "list size must be a multiple of the stride length", -1); |
| 18432 | 18561 | return JIM_ERR; |
| 18433 | 18562 | } |
| 18434 | 18563 | |
| | @@ -18612,11 +18741,11 @@ |
| 18612 | 18741 | long level; |
| 18613 | 18742 | int ret = Jim_GetLong(interp, argv[1], &level); |
| 18614 | 18743 | if (ret != JIM_OK) { |
| 18615 | 18744 | return ret; |
| 18616 | 18745 | } |
| 18617 | | - interp->returnLevel = level; |
| 18746 | + interp->break_level = level; |
| 18618 | 18747 | } |
| 18619 | 18748 | return retcode; |
| 18620 | 18749 | } |
| 18621 | 18750 | |
| 18622 | 18751 | |
| | @@ -20330,39 +20459,28 @@ |
| 20330 | 20459 | } |
| 20331 | 20460 | Jim_SetResult(interp, interp->currentFilenameObj); |
| 20332 | 20461 | return JIM_OK; |
| 20333 | 20462 | |
| 20334 | 20463 | case INFO_SOURCE:{ |
| 20335 | | - jim_wide line; |
| 20336 | 20464 | Jim_Obj *resObjPtr; |
| 20337 | 20465 | Jim_Obj *fileNameObj; |
| 20338 | 20466 | |
| 20339 | 20467 | if (argc == 4) { |
| 20340 | 20468 | Jim_SubCmdArgError(interp, ct, argv[0]); |
| 20341 | 20469 | return JIM_ERR; |
| 20342 | 20470 | } |
| 20343 | 20471 | if (argc == 5) { |
| 20472 | + jim_wide line; |
| 20344 | 20473 | if (Jim_GetWide(interp, argv[4], &line) != JIM_OK) { |
| 20345 | 20474 | return JIM_ERR; |
| 20346 | 20475 | } |
| 20347 | 20476 | resObjPtr = Jim_NewStringObj(interp, Jim_String(argv[2]), Jim_Length(argv[2])); |
| 20348 | | - JimSetSourceInfo(interp, resObjPtr, argv[3], line); |
| 20349 | | - } |
| 20350 | | - else { |
| 20351 | | - if (argv[2]->typePtr == &sourceObjType) { |
| 20352 | | - fileNameObj = argv[2]->internalRep.sourceValue.fileNameObj; |
| 20353 | | - line = argv[2]->internalRep.sourceValue.lineNumber; |
| 20354 | | - } |
| 20355 | | - else if (argv[2]->typePtr == &scriptObjType) { |
| 20356 | | - ScriptObj *script = JimGetScript(interp, argv[2]); |
| 20357 | | - fileNameObj = script->fileNameObj; |
| 20358 | | - line = script->firstline; |
| 20359 | | - } |
| 20360 | | - else { |
| 20361 | | - fileNameObj = interp->emptyObj; |
| 20362 | | - line = 1; |
| 20363 | | - } |
| 20477 | + Jim_SetSourceInfo(interp, resObjPtr, argv[3], line); |
| 20478 | + } |
| 20479 | + else { |
| 20480 | + int line; |
| 20481 | + fileNameObj = Jim_GetSourceInfo(interp, argv[2], &line); |
| 20364 | 20482 | resObjPtr = Jim_NewListObj(interp, NULL, 0); |
| 20365 | 20483 | Jim_ListAppendElement(interp, resObjPtr, fileNameObj); |
| 20366 | 20484 | Jim_ListAppendElement(interp, resObjPtr, Jim_NewIntObj(interp, line)); |
| 20367 | 20485 | } |
| 20368 | 20486 | Jim_SetResult(interp, resObjPtr); |
| | @@ -23644,11 +23762,13 @@ |
| 23644 | 23762 | else { |
| 23645 | 23763 | filenameObj = Jim_NewStringObj(interp, filename_template, -1); |
| 23646 | 23764 | } |
| 23647 | 23765 | |
| 23648 | 23766 | |
| 23767 | +#ifdef HAVE_UMASK |
| 23649 | 23768 | mask = umask(S_IXUSR | S_IRWXG | S_IRWXO); |
| 23769 | +#endif |
| 23650 | 23770 | #ifdef HAVE_MKSTEMP |
| 23651 | 23771 | fd = mkstemp(filenameObj->bytes); |
| 23652 | 23772 | #else |
| 23653 | 23773 | if (mktemp(filenameObj->bytes) == NULL) { |
| 23654 | 23774 | fd = -1; |
| | @@ -23655,11 +23775,13 @@ |
| 23655 | 23775 | } |
| 23656 | 23776 | else { |
| 23657 | 23777 | fd = open(filenameObj->bytes, O_RDWR | O_CREAT | O_TRUNC); |
| 23658 | 23778 | } |
| 23659 | 23779 | #endif |
| 23780 | +#ifdef HAVE_UMASK |
| 23660 | 23781 | umask(mask); |
| 23782 | +#endif |
| 23661 | 23783 | if (fd < 0) { |
| 23662 | 23784 | Jim_SetResultErrno(interp, Jim_String(filenameObj)); |
| 23663 | 23785 | Jim_FreeNewObj(interp, filenameObj); |
| 23664 | 23786 | return -1; |
| 23665 | 23787 | } |
| | @@ -24258,10 +24380,15 @@ |
| 24258 | 24380 | JimPrintErrorMessage(interp); |
| 24259 | 24381 | } |
| 24260 | 24382 | |
| 24261 | 24383 | Jim_SetVariableStrWithStr(interp, "jim::argv0", orig_argv0); |
| 24262 | 24384 | Jim_SetVariableStrWithStr(interp, JIM_INTERACTIVE, argc == 1 ? "1" : "0"); |
| 24385 | +#ifdef USE_LINENOISE |
| 24386 | + Jim_SetVariableStrWithStr(interp, "jim::lineedit", "1"); |
| 24387 | +#else |
| 24388 | + Jim_SetVariableStrWithStr(interp, "jim::lineedit", "0"); |
| 24389 | +#endif |
| 24263 | 24390 | retcode = Jim_initjimshInit(interp); |
| 24264 | 24391 | |
| 24265 | 24392 | if (argc == 1) { |
| 24266 | 24393 | |
| 24267 | 24394 | if (retcode == JIM_ERR) { |
| 24268 | 24395 | |