annotate src/blob.c @ 32936:c517845bd10e v9.0.1776

patch 9.0.1776: No support for stable Python 3 ABI Commit: https://github.com/vim/vim/commit/c13b3d1350b60b94fe87f0761ea31c0e7fb6ebf3 Author: Yee Cheng Chin <ychin.git@gmail.com> Date: Sun Aug 20 21:18:38 2023 +0200 patch 9.0.1776: No support for stable Python 3 ABI Problem: No support for stable Python 3 ABI Solution: Support Python 3 stable ABI Commits: 1) Support Python 3 stable ABI to allow mixed version interoperatbility Vim currently supports embedding Python for use with plugins, and the "dynamic" linking option allows the user to specify a locally installed version of Python by setting `pythonthreedll`. However, one caveat is that the Python 3 libs are not binary compatible across minor versions, and mixing versions can potentially be dangerous (e.g. let's say Vim was linked against the Python 3.10 SDK, but the user sets `pythonthreedll` to a 3.11 lib). Usually, nothing bad happens, but in theory this could lead to crashes, memory corruption, and other unpredictable behaviors. It's also difficult for the user to tell something is wrong because Vim has no way of reporting what Python 3 version Vim was linked with. For Vim installed via a package manager, this usually isn't an issue because all the dependencies would already be figured out. For prebuilt Vim binaries like MacVim (my motivation for working on this), AppImage, and Win32 installer this could potentially be an issue as usually a single binary is distributed. This is more tricky when a new Python version is released, as there's a chicken-and-egg issue with deciding what Python version to build against and hard to keep in sync when a new Python version just drops and we have a mix of users of different Python versions, and a user just blindly upgrading to a new Python could lead to bad interactions with Vim. Python 3 does have a solution for this problem: stable ABI / limited API (see https://docs.python.org/3/c-api/stable.html). The C SDK limits the API to a set of functions that are promised to be stable across versions. This pull request adds an ifdef config that allows us to turn it on when building Vim. Vim binaries built with this option should be safe to freely link with any Python 3 libraies without having the constraint of having to use the same minor version. Note: Python 2 has no such concept and this doesn't change how Python 2 integration works (not that there is going to be a new version of Python 2 that would cause compatibility issues in the future anyway). --- Technical details: ====== The stable ABI can be accessed when we compile with the Python 3 limited API (by defining `Py_LIMITED_API`). The Python 3 code (in `if_python3.c` and `if_py_both.h`) would now handle this and switch to limited API mode. Without it set, Vim will still use the full API as before so this is an opt-in change. The main difference is that `PyType_Object` is now an opaque struct that we can't directly create "static types" out of, and we have to create type objects as "heap types" instead. This is because the struct is not stable and changes from version to version (e.g. 3.8 added a `tp_vectorcall` field to it). I had to change all the types to be allocated on the heap instead with just a pointer to them. Other functions are also simply missing in limited API, or they are introduced too late (e.g. `PyUnicode_AsUTF8AndSize` in 3.10) to it that we need some other ways to do the same thing, so I had to abstract a few things into macros, and sometimes re-implement functions like `PyObject_NEW`. One caveat is that in limited API, `OutputType` (used for replacing `sys.stdout`) no longer inherits from `PyStdPrinter_Type` which I don't think has any real issue other than minor differences in how they convert to a string and missing a couple functions like `mode()` and `fileno()`. Also fixed an existing bug where `tp_basicsize` was set incorrectly for `BufferObject`, `TabListObject, `WinListObject`. Technically, there could be a small performance drop, there is a little more indirection with accessing type objects, and some APIs like `PyUnicode_AsUTF8AndSize` are missing, but in practice I didn't see any difference, and any well-written Python plugin should try to avoid excessing callbacks to the `vim` module in Python anyway. I only tested limited API mode down to Python 3.7, which seemes to compile and work fine. I haven't tried earlier Python versions. 2) Fix PyIter_Check on older Python vers / type##Ptr unused warning For PyIter_Check, older versions exposed them as either macros (used in full API), or a function (for use in limited API). A previous change exposed PyIter_Check to the dynamic build because Python just moved it to function-only in 3.10 anyway. Because of that, just make sure we always grab the function in dynamic builds in earlier versions since that's what Python eventually did anyway. 3) Move Py_LIMITED_API define to configure script Can now use --with-python-stable-abi flag to customize what stable ABI version to target. Can also use an env var to do so as well. 4) Show +python/dyn-stable in :version, and allow has() feature query Not sure if the "/dyn-stable" suffix would break things, or whether we should do it another way. Or just don't show it in version and rely on has() feature checking. 5) Documentation first draft. Still need to implement v:python3_version 6) Fix PyIter_Check build breaks when compiling against Python 3.8 7) Add CI coverage stable ABI on Linux/Windows / make configurable on Windows This adds configurable options for Windows make files (both MinGW and MSVC). CI will also now exercise both traditional full API and stable ABI for Linux and Windows in the matrix for coverage. Also added a "dynamic" option to Linux matrix as a drive-by change to make other scripting languages like Ruby / Perl testable under both static and dynamic builds. 8) Fix inaccuracy in Windows docs Python's own docs are confusing but you don't actually want to use `python3.dll` for the dynamic linkage. 9) Add generated autoconf file 10) Add v:python3_version support This variable indicates the version of Python3 that Vim was built against (PY_VERSION_HEX), and will be useful to check whether the Python library you are loading in dynamically actually fits it. When built with stable ABI, it will be the limited ABI version instead (`Py_LIMITED_API`), which indicates the minimum version of Python 3 the user should have, rather than the exact match. When stable ABI is used, we won't be exposing PY_VERSION_HEX in this var because it just doesn't seem necessary to do so (the whole point of stable ABI is the promise that it will work across versions), and I don't want to confuse the user with too many variables. Also, cleaned up some documentation, and added help tags. 11) Fix Python 3.7 compat issues Fix a couple issues when using limited API < 3.8 - Crash on exit: In Python 3.7, if a heap-allocated type is destroyed before all instances are, it would cause a crash later. This happens when we destroyed `OptionsType` before calling `Py_Finalize` when using the limited API. To make it worse, later versions changed the semantics and now each instance has a strong reference to its own type and the recommendation has changed to have each instance de-ref its own type and have its type in GC traversal. To avoid dealing with these cross-version variations, we just don't free the heap type. They are static types in non-limited-API anyway and are designed to last through the entirety of the app, and we also don't restart the Python runtime and therefore do not need it to have absolutely 0 leaks. See: - https://docs.python.org/3/whatsnew/3.8.html#changes-in-the-c-api - https://docs.python.org/3/whatsnew/3.9.html#changes-in-the-c-api - PyIter_Check: This function is not provided in limited APIs older than 3.8. Previously I was trying to mock it out using manual PyType_GetSlot() but it was brittle and also does not actually work properly for static types (it will generate a Python error). Just return false. It does mean using limited API < 3.8 is not recommended as you lose the functionality to handle iterators, but from playing with plugins I couldn't find it to be an issue. - Fix loading of PyIter_Check so it will be done when limited API < 3.8. Otherwise loading a 3.7 Python lib will fail even if limited API was specified to use it. 12) Make sure to only load `PyUnicode_AsUTF8AndSize` in needed in limited API We don't use this function unless limited API >= 3.10, but we were loading it regardless. Usually it's ok in Unix-like systems where Python just has a single lib that we load from, but in Windows where there is a separate python3.dll this would not work as the symbol would not have been exposed in this more limited DLL file. This makes it much clearer under what condition is this function needed. closes: #12032 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Yee Cheng Chin <ychin.git@gmail.com>
author Christian Brabandt <cb@256bit.org>
date Sun, 20 Aug 2023 21:30:04 +0200
parents 705d0e1329a5
children da670b1549b3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
1 /* vi:set ts=8 sts=4 sw=4 noet:
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
2 *
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
3 * VIM - Vi IMproved by Bram Moolenaar
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
4 *
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
5 * Do ":help uganda" in Vim to read copying and usage conditions.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
6 * Do ":help credits" in Vim to see a list of people who contributed.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
7 * See README.txt for an overview of the Vim source code.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
8 */
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
9
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
10 /*
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
11 * blob.c: Blob support by Yasuhiro Matsumoto
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
12 */
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
13
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
14 #include "vim.h"
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
15
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
16 #if defined(FEAT_EVAL) || defined(PROTO)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
17
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
18 /*
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
19 * Allocate an empty blob.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
20 * Caller should take care of the reference count.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
21 */
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
22 blob_T *
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
23 blob_alloc(void)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
24 {
28289
cdaff4db7760 patch 8.2.4670: memory allocation failures for new tab page not tested
Bram Moolenaar <Bram@vim.org>
parents: 27426
diff changeset
25 blob_T *blob = ALLOC_CLEAR_ONE_ID(blob_T, aid_blob_alloc);
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
26
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
27 if (blob != NULL)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
28 ga_init2(&blob->bv_ga, 1, 100);
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
29 return blob;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
30 }
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
31
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
32 /*
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
33 * Allocate an empty blob for a return value, with reference count set.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
34 * Returns OK or FAIL.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
35 */
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
36 int
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
37 rettv_blob_alloc(typval_T *rettv)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
38 {
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
39 blob_T *b = blob_alloc();
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
40
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
41 if (b == NULL)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
42 return FAIL;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
43
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
44 rettv_blob_set(rettv, b);
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
45 return OK;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
46 }
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
47
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
48 /*
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
49 * Set a blob as the return value.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
50 */
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
51 void
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
52 rettv_blob_set(typval_T *rettv, blob_T *b)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
53 {
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
54 rettv->v_type = VAR_BLOB;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
55 rettv->vval.v_blob = b;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
56 if (b != NULL)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
57 ++b->bv_refcount;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
58 }
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
59
15581
c2382f0d1279 patch 8.1.0798: changing a blob while iterating over it works strangely
Bram Moolenaar <Bram@vim.org>
parents: 15515
diff changeset
60 int
19181
94eda51ba9ba patch 8.2.0149: maintaining a Vim9 branch separately is more work
Bram Moolenaar <Bram@vim.org>
parents: 18757
diff changeset
61 blob_copy(blob_T *from, typval_T *to)
15581
c2382f0d1279 patch 8.1.0798: changing a blob while iterating over it works strangely
Bram Moolenaar <Bram@vim.org>
parents: 15515
diff changeset
62 {
30531
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
63 int len;
15581
c2382f0d1279 patch 8.1.0798: changing a blob while iterating over it works strangely
Bram Moolenaar <Bram@vim.org>
parents: 15515
diff changeset
64
c2382f0d1279 patch 8.1.0798: changing a blob while iterating over it works strangely
Bram Moolenaar <Bram@vim.org>
parents: 15515
diff changeset
65 to->v_type = VAR_BLOB;
17344
a0eb2ff0f297 patch 8.1.1671: copying a blob may result in it being locked
Bram Moolenaar <Bram@vim.org>
parents: 16825
diff changeset
66 to->v_lock = 0;
19181
94eda51ba9ba patch 8.2.0149: maintaining a Vim9 branch separately is more work
Bram Moolenaar <Bram@vim.org>
parents: 18757
diff changeset
67 if (from == NULL)
30531
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
68 {
15581
c2382f0d1279 patch 8.1.0798: changing a blob while iterating over it works strangely
Bram Moolenaar <Bram@vim.org>
parents: 15515
diff changeset
69 to->vval.v_blob = NULL;
30531
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
70 return OK;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
71 }
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
72
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
73 if (rettv_blob_alloc(to) == FAIL)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
74 return FAIL;
15581
c2382f0d1279 patch 8.1.0798: changing a blob while iterating over it works strangely
Bram Moolenaar <Bram@vim.org>
parents: 15515
diff changeset
75
30531
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
76 len = from->bv_ga.ga_len;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
77 if (len > 0)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
78 {
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
79 to->vval.v_blob->bv_ga.ga_data =
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
80 vim_memsave(from->bv_ga.ga_data, len);
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
81 if (to->vval.v_blob->bv_ga.ga_data == NULL)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
82 len = 0;
15581
c2382f0d1279 patch 8.1.0798: changing a blob while iterating over it works strangely
Bram Moolenaar <Bram@vim.org>
parents: 15515
diff changeset
83 }
30531
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
84 to->vval.v_blob->bv_ga.ga_len = len;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
85 to->vval.v_blob->bv_ga.ga_maxlen = len;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
86
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
87 return OK;
15581
c2382f0d1279 patch 8.1.0798: changing a blob while iterating over it works strangely
Bram Moolenaar <Bram@vim.org>
parents: 15515
diff changeset
88 }
c2382f0d1279 patch 8.1.0798: changing a blob while iterating over it works strangely
Bram Moolenaar <Bram@vim.org>
parents: 15515
diff changeset
89
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
90 void
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
91 blob_free(blob_T *b)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
92 {
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
93 ga_clear(&b->bv_ga);
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
94 vim_free(b);
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
95 }
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
96
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
97 /*
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
98 * Unreference a blob: decrement the reference count and free it when it
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
99 * becomes zero.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
100 */
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
101 void
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
102 blob_unref(blob_T *b)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
103 {
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
104 if (b != NULL && --b->bv_refcount <= 0)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
105 blob_free(b);
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
106 }
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
107
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
108 /*
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
109 * Get the length of data.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
110 */
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
111 long
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
112 blob_len(blob_T *b)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
113 {
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
114 if (b == NULL)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
115 return 0L;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
116 return b->bv_ga.ga_len;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
117 }
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
118
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
119 /*
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
120 * Get byte "idx" in blob "b".
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
121 * Caller must check that "idx" is valid.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
122 */
15589
44ea60ca593b patch 8.1.0802: negative index doesn't work for Blob
Bram Moolenaar <Bram@vim.org>
parents: 15581
diff changeset
123 int
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
124 blob_get(blob_T *b, int idx)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
125 {
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
126 return ((char_u*)b->bv_ga.ga_data)[idx];
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
127 }
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
128
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
129 /*
24475
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
130 * Store one byte "byte" in blob "blob" at "idx".
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
131 * Caller must make sure that "idx" is valid.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
132 */
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
133 void
24475
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
134 blob_set(blob_T *blob, int idx, int byte)
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
135 {
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
136 ((char_u*)blob->bv_ga.ga_data)[idx] = byte;
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
137 }
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
138
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
139 /*
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
140 * Store one byte "byte" in blob "blob" at "idx".
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
141 * Append one byte if needed.
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
142 */
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
143 void
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
144 blob_set_append(blob_T *blob, int idx, int byte)
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
145 {
24475
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
146 garray_T *gap = &blob->bv_ga;
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
147
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
148 // Allow for appending a byte. Setting a byte beyond
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
149 // the end is an error otherwise.
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
150 if (idx < gap->ga_len
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
151 || (idx == gap->ga_len && ga_grow(gap, 1) == OK))
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
152 {
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
153 blob_set(blob, idx, byte);
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
154 if (idx == gap->ga_len)
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
155 ++gap->ga_len;
96905804bf5a patch 8.2.2777: Vim9: blob operations not tested in all ways
Bram Moolenaar <Bram@vim.org>
parents: 24454
diff changeset
156 }
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
157 }
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
158
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
159 /*
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
160 * Return TRUE when two blobs have exactly the same values.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
161 */
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
162 int
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
163 blob_equal(
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
164 blob_T *b1,
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
165 blob_T *b2)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
166 {
15456
f01eb1aed348 patch 8.1.0736: code for Blob not sufficiently tested
Bram Moolenaar <Bram@vim.org>
parents: 15454
diff changeset
167 int i;
f01eb1aed348 patch 8.1.0736: code for Blob not sufficiently tested
Bram Moolenaar <Bram@vim.org>
parents: 15454
diff changeset
168 int len1 = blob_len(b1);
f01eb1aed348 patch 8.1.0736: code for Blob not sufficiently tested
Bram Moolenaar <Bram@vim.org>
parents: 15454
diff changeset
169 int len2 = blob_len(b2);
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
170
15456
f01eb1aed348 patch 8.1.0736: code for Blob not sufficiently tested
Bram Moolenaar <Bram@vim.org>
parents: 15454
diff changeset
171 // empty and NULL are considered the same
f01eb1aed348 patch 8.1.0736: code for Blob not sufficiently tested
Bram Moolenaar <Bram@vim.org>
parents: 15454
diff changeset
172 if (len1 == 0 && len2 == 0)
f01eb1aed348 patch 8.1.0736: code for Blob not sufficiently tested
Bram Moolenaar <Bram@vim.org>
parents: 15454
diff changeset
173 return TRUE;
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
174 if (b1 == b2)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
175 return TRUE;
15456
f01eb1aed348 patch 8.1.0736: code for Blob not sufficiently tested
Bram Moolenaar <Bram@vim.org>
parents: 15454
diff changeset
176 if (len1 != len2)
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
177 return FALSE;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
178
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
179 for (i = 0; i < b1->bv_ga.ga_len; i++)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
180 if (blob_get(b1, i) != blob_get(b2, i)) return FALSE;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
181 return TRUE;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
182 }
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
183
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
184 /*
30922
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
185 * Read blob from file "fd".
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
186 * Caller has allocated a blob in "rettv".
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
187 * Return OK or FAIL.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
188 */
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
189 int
30922
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
190 read_blob(FILE *fd, typval_T *rettv, off_T offset, off_T size_arg)
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
191 {
30922
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
192 blob_T *blob = rettv->vval.v_blob;
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
193 struct stat st;
30922
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
194 int whence;
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
195 off_T size = size_arg;
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
196
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
197 if (fstat(fileno(fd), &st) < 0)
30922
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
198 return FAIL; // can't read the file, error
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
199
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
200 if (offset >= 0)
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
201 {
30952
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
202 // The size defaults to the whole file. If a size is given it is
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
203 // limited to not go past the end of the file.
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
204 if (size == -1 || (size > st.st_size - offset
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
205 #ifdef S_ISCHR
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
206 && !S_ISCHR(st.st_mode)
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
207 #endif
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
208 ))
30922
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
209 // size may become negative, checked below
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
210 size = st.st_size - offset;
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
211 whence = SEEK_SET;
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
212 }
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
213 else
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
214 {
30952
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
215 // limit the offset to not go before the start of the file
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
216 if (-offset > st.st_size
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
217 #ifdef S_ISCHR
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
218 && !S_ISCHR(st.st_mode)
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
219 #endif
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
220 )
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
221 offset = -st.st_size;
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
222 // Size defaults to reading until the end of the file.
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
223 if (size == -1 || size > -offset)
30922
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
224 size = -offset;
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
225 whence = SEEK_END;
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
226 }
30952
61558a67630a patch 9.0.0810: readblob() returns empty when trying to read too much
Bram Moolenaar <Bram@vim.org>
parents: 30938
diff changeset
227 if (size <= 0)
30922
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
228 return OK;
30938
84f6f91ca02a patch 9.0.0803: readblob() cannot read from character device
Bram Moolenaar <Bram@vim.org>
parents: 30922
diff changeset
229 if (offset != 0 && vim_fseek(fd, offset, whence) != 0)
30922
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
230 return OK;
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
231
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
232 if (ga_grow(&blob->bv_ga, (int)size) == FAIL)
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
233 return FAIL;
30922
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
234 blob->bv_ga.ga_len = (int)size;
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
235 if (fread(blob->bv_ga.ga_data, 1, blob->bv_ga.ga_len, fd)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
236 < (size_t)blob->bv_ga.ga_len)
30922
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
237 {
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
238 // An empty blob is returned on error.
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
239 blob_free(rettv->vval.v_blob);
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
240 rettv->vval.v_blob = NULL;
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
241 return FAIL;
30922
ed6acfafa17e patch 9.0.0795: readblob() always reads the whole file
Bram Moolenaar <Bram@vim.org>
parents: 30566
diff changeset
242 }
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
243 return OK;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
244 }
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
245
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
246 /*
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
247 * Write "blob" to file "fd".
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
248 * Return OK or FAIL.
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
249 */
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
250 int
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
251 write_blob(FILE *fd, blob_T *blob)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
252 {
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
253 if (fwrite(blob->bv_ga.ga_data, 1, blob->bv_ga.ga_len, fd)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
254 < (size_t)blob->bv_ga.ga_len)
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
255 {
26439
b18f3b0f317c patch 8.2.3750: error messages are everywhere
Bram Moolenaar <Bram@vim.org>
parents: 26394
diff changeset
256 emsg(_(e_error_while_writing));
15454
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
257 return FAIL;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
258 }
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
259 return OK;
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
260 }
1d2b5c016f17 patch 8.1.0735: cannot handle binary data
Bram Moolenaar <Bram@vim.org>
parents:
diff changeset
261
15466
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
262 /*
15515
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
263 * Convert a blob to a readable form: "0z00112233.44556677.8899"
15466
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
264 */
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
265 char_u *
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
266 blob2string(blob_T *blob, char_u **tofree, char_u *numbuf)
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
267 {
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
268 int i;
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
269 garray_T ga;
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
270
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
271 if (blob == NULL)
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
272 {
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
273 *tofree = NULL;
15515
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
274 return (char_u *)"0z";
15466
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
275 }
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
276
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
277 // Store bytes in the growarray.
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
278 ga_init2(&ga, 1, 4000);
15515
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
279 ga_concat(&ga, (char_u *)"0z");
15466
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
280 for (i = 0; i < blob_len(blob); i++)
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
281 {
15515
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
282 if (i > 0 && (i & 3) == 0)
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
283 ga_concat(&ga, (char_u *)".");
27426
41e0dcf38521 patch 8.2.4241: some type casts are redundant
Bram Moolenaar <Bram@vim.org>
parents: 26877
diff changeset
284 vim_snprintf((char *)numbuf, NUMBUFLEN, "%02X", blob_get(blob, i));
15466
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
285 ga_concat(&ga, numbuf);
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
286 }
26652
a3f38923c037 patch 8.2.3855: illegal memory access when displaying a blob
Bram Moolenaar <Bram@vim.org>
parents: 26439
diff changeset
287 ga_append(&ga, NUL); // append a NUL at the end
15466
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
288 *tofree = ga.ga_data;
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
289 return *tofree;
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
290 }
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
291
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
292 /*
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
293 * Convert a string variable, in the format of blob2string(), to a blob.
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
294 * Return NULL when conversion failed.
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
295 */
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
296 blob_T *
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
297 string2blob(char_u *str)
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
298 {
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
299 blob_T *blob = blob_alloc();
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
300 char_u *s = str;
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
301
16034
27f9f4c1400b patch 8.1.1022: may use NULL pointer when out of memory
Bram Moolenaar <Bram@vim.org>
parents: 15589
diff changeset
302 if (blob == NULL)
27f9f4c1400b patch 8.1.1022: may use NULL pointer when out of memory
Bram Moolenaar <Bram@vim.org>
parents: 15589
diff changeset
303 return NULL;
15515
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
304 if (s[0] != '0' || (s[1] != 'z' && s[1] != 'Z'))
15466
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
305 goto failed;
15515
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
306 s += 2;
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
307 while (vim_isxdigit(*s))
15466
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
308 {
15515
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
309 if (!vim_isxdigit(s[1]))
15466
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
310 goto failed;
15515
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
311 ga_append(&blob->bv_ga, (hex2nr(s[0]) << 4) + hex2nr(s[1]));
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
312 s += 2;
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
313 if (*s == '.' && vim_isxdigit(s[1]))
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
314 ++s;
15466
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
315 }
15515
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
316 if (*skipwhite(s) != NUL)
99a4cc4782ac patch 8.1.0765: string format of a Blob can't be parsed back
Bram Moolenaar <Bram@vim.org>
parents: 15470
diff changeset
317 goto failed; // text after final digit
15466
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
318
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
319 ++blob->bv_refcount;
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
320 return blob;
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
321
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
322 failed:
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
323 blob_free(blob);
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
324 return NULL;
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
325 }
435fcefd2c8e patch 8.1.0741: viminfo with Blob is not tested
Bram Moolenaar <Bram@vim.org>
parents: 15456
diff changeset
326
30531
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
327 /*
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
328 * Returns a slice of 'blob' from index 'n1' to 'n2' in 'rettv'. The length of
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
329 * the blob is 'len'. Returns an empty blob if the indexes are out of range.
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
330 */
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
331 static int
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
332 blob_slice(
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
333 blob_T *blob,
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
334 long len,
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
335 varnumber_T n1,
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
336 varnumber_T n2,
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
337 int exclusive,
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
338 typval_T *rettv)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
339 {
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
340 if (n1 < 0)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
341 {
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
342 n1 = len + n1;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
343 if (n1 < 0)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
344 n1 = 0;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
345 }
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
346 if (n2 < 0)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
347 n2 = len + n2;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
348 else if (n2 >= len)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
349 n2 = len - (exclusive ? 0 : 1);
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
350 if (exclusive)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
351 --n2;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
352 if (n1 >= len || n2 < 0 || n1 > n2)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
353 {
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
354 clear_tv(rettv);
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
355 rettv->v_type = VAR_BLOB;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
356 rettv->vval.v_blob = NULL;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
357 }
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
358 else
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
359 {
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
360 blob_T *new_blob = blob_alloc();
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
361 long i;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
362
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
363 if (new_blob != NULL)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
364 {
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
365 if (ga_grow(&new_blob->bv_ga, n2 - n1 + 1) == FAIL)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
366 {
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
367 blob_free(new_blob);
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
368 return FAIL;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
369 }
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
370 new_blob->bv_ga.ga_len = n2 - n1 + 1;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
371 for (i = n1; i <= n2; i++)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
372 blob_set(new_blob, i - n1, blob_get(blob, i));
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
373
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
374 clear_tv(rettv);
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
375 rettv_blob_set(rettv, new_blob);
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
376 }
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
377 }
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
378
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
379 return OK;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
380 }
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
381
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
382 /*
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
383 * Return the byte value in 'blob' at index 'idx' in 'rettv'. If the index is
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
384 * too big or negative that is an error. The length of the blob is 'len'.
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
385 */
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
386 static int
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
387 blob_index(
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
388 blob_T *blob,
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
389 int len,
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
390 varnumber_T idx,
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
391 typval_T *rettv)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
392 {
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
393 // The resulting variable is a byte value.
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
394 // If the index is too big or negative that is an error.
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
395 if (idx < 0)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
396 idx = len + idx;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
397 if (idx < len && idx >= 0)
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
398 {
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
399 int v = blob_get(blob, idx);
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
400
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
401 clear_tv(rettv);
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
402 rettv->v_type = VAR_NUMBER;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
403 rettv->vval.v_number = v;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
404 }
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
405 else
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
406 {
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
407 semsg(_(e_blob_index_out_of_range_nr), idx);
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
408 return FAIL;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
409 }
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
410
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
411 return OK;
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
412 }
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
413
24432
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
414 int
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
415 blob_slice_or_index(
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
416 blob_T *blob,
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
417 int is_range,
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
418 varnumber_T n1,
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
419 varnumber_T n2,
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
420 int exclusive,
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
421 typval_T *rettv)
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
422 {
30531
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
423 long len = blob_len(blob);
24432
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
424
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
425 if (is_range)
30531
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
426 return blob_slice(blob, len, n1, n2, exclusive, rettv);
24432
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
427 else
30531
2650a01b8bbc patch 9.0.0601: too much indent
Bram Moolenaar <Bram@vim.org>
parents: 30425
diff changeset
428 return blob_index(blob, len, n1, rettv);
24432
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
429 return OK;
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
430 }
aa150abca273 patch 8.2.2756: Vim9: blob index and slice not implemented yet
Bram Moolenaar <Bram@vim.org>
parents: 22635
diff changeset
431
17530
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
432 /*
24450
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
433 * Check if "n1"- is a valid index for a blobl with length "bloblen".
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
434 */
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
435 int
24454
53216e87f21c patch 8.2.2767: compiler warning for unused argument
Bram Moolenaar <Bram@vim.org>
parents: 24450
diff changeset
436 check_blob_index(long bloblen, varnumber_T n1, int quiet)
24450
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
437 {
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
438 if (n1 < 0 || n1 > bloblen)
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
439 {
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
440 if (!quiet)
26877
06a137af96f8 patch 8.2.3967: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents: 26865
diff changeset
441 semsg(_(e_blob_index_out_of_range_nr), n1);
24450
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
442 return FAIL;
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
443 }
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
444 return OK;
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
445 }
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
446
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
447 /*
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
448 * Check if "n1"-"n2" is a valid range for a blob with length "bloblen".
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
449 */
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
450 int
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
451 check_blob_range(long bloblen, varnumber_T n1, varnumber_T n2, int quiet)
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
452 {
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
453 if (n2 < 0 || n2 >= bloblen || n2 < n1)
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
454 {
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
455 if (!quiet)
26877
06a137af96f8 patch 8.2.3967: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents: 26865
diff changeset
456 semsg(_(e_blob_index_out_of_range_nr), n2);
24450
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
457 return FAIL;
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
458 }
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
459 return OK;
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
460 }
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
461
3e1886f1e875 patch 8.2.2765: Vim9: not all blob operations work
Bram Moolenaar <Bram@vim.org>
parents: 24434
diff changeset
462 /*
24434
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
463 * Set bytes "n1" to "n2" (inclusive) in "dest" to the value of "src".
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
464 * Caller must make sure "src" is a blob.
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
465 * Returns FAIL if the number of bytes does not match.
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
466 */
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
467 int
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
468 blob_set_range(blob_T *dest, long n1, long n2, typval_T *src)
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
469 {
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
470 int il, ir;
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
471
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
472 if (n2 - n1 + 1 != blob_len(src->vval.v_blob))
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
473 {
26863
6ee19c6ae8a2 patch 8.2.3960: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents: 26684
diff changeset
474 emsg(_(e_blob_value_does_not_have_right_number_of_bytes));
24434
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
475 return FAIL;
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
476 }
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
477
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
478 ir = 0;
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
479 for (il = n1; il <= n2; il++)
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
480 blob_set(dest, il, blob_get(src->vval.v_blob, ir++));
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
481 return OK;
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
482 }
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
483
602e528a8e43 patch 8.2.2757: Vim9: blob tests for legacy and Vim9 script are separate
Bram Moolenaar <Bram@vim.org>
parents: 24432
diff changeset
484 /*
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
485 * "add(blob, item)" function
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
486 */
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
487 void
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
488 blob_add(typval_T *argvars, typval_T *rettv)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
489 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
490 blob_T *b = argvars[0].vval.v_blob;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
491 int error = FALSE;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
492 varnumber_T n;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
493
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
494 if (b == NULL)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
495 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
496 if (in_vim9script())
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
497 emsg(_(e_cannot_add_to_null_blob));
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
498 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
499 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
500
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
501 if (value_check_lock(b->bv_lock, (char_u *)N_("add() argument"), TRUE))
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
502 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
503
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
504 n = tv_get_number_chk(&argvars[1], &error);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
505 if (error)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
506 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
507
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
508 ga_append(&b->bv_ga, (int)n);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
509 copy_tv(&argvars[0], rettv);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
510 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
511
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
512 /*
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
513 * "remove({blob}, {idx} [, {end}])" function
17530
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
514 */
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
515 void
25495
7144d2ffc86b patch 8.2.3284: no error for insert() or remove() changing a locked blob
Bram Moolenaar <Bram@vim.org>
parents: 25338
diff changeset
516 blob_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg)
17530
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
517 {
25495
7144d2ffc86b patch 8.2.3284: no error for insert() or remove() changing a locked blob
Bram Moolenaar <Bram@vim.org>
parents: 25338
diff changeset
518 blob_T *b = argvars[0].vval.v_blob;
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
519 blob_T *newblob;
17530
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
520 int error = FALSE;
25302
4d3c68196d05 patch 8.2.3188: Vim9: argument types are not checked at compile time
Bram Moolenaar <Bram@vim.org>
parents: 24478
diff changeset
521 long idx;
17530
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
522 long end;
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
523 int len;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
524 char_u *p;
17530
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
525
25495
7144d2ffc86b patch 8.2.3284: no error for insert() or remove() changing a locked blob
Bram Moolenaar <Bram@vim.org>
parents: 25338
diff changeset
526 if (b != NULL && value_check_lock(b->bv_lock, arg_errmsg, TRUE))
7144d2ffc86b patch 8.2.3284: no error for insert() or remove() changing a locked blob
Bram Moolenaar <Bram@vim.org>
parents: 25338
diff changeset
527 return;
7144d2ffc86b patch 8.2.3284: no error for insert() or remove() changing a locked blob
Bram Moolenaar <Bram@vim.org>
parents: 25338
diff changeset
528
25302
4d3c68196d05 patch 8.2.3188: Vim9: argument types are not checked at compile time
Bram Moolenaar <Bram@vim.org>
parents: 24478
diff changeset
529 idx = (long)tv_get_number_chk(&argvars[1], &error);
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
530 if (error)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
531 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
532
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
533 len = blob_len(b);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
534
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
535 if (idx < 0)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
536 // count from the end
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
537 idx = len + idx;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
538 if (idx < 0 || idx >= len)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
539 {
26877
06a137af96f8 patch 8.2.3967: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents: 26865
diff changeset
540 semsg(_(e_blob_index_out_of_range_nr), idx);
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
541 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
542 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
543 if (argvars[2].v_type == VAR_UNKNOWN)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
544 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
545 // Remove one item, return its value.
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
546 p = (char_u *)b->bv_ga.ga_data;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
547 rettv->vval.v_number = (varnumber_T) *(p + idx);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
548 mch_memmove(p + idx, p + idx + 1, (size_t)len - idx - 1);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
549 --b->bv_ga.ga_len;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
550 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
551 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
552
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
553 // Remove range of items, return blob with values.
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
554 end = (long)tv_get_number_chk(&argvars[2], &error);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
555 if (error)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
556 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
557 if (end < 0)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
558 // count from the end
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
559 end = len + end;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
560 if (end >= len || idx > end)
17530
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
561 {
26877
06a137af96f8 patch 8.2.3967: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents: 26865
diff changeset
562 semsg(_(e_blob_index_out_of_range_nr), end);
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
563 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
564 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
565 newblob = blob_alloc();
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
566 if (newblob == NULL)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
567 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
568 newblob->bv_ga.ga_len = end - idx + 1;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
569 if (ga_grow(&newblob->bv_ga, end - idx + 1) == FAIL)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
570 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
571 vim_free(newblob);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
572 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
573 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
574 p = (char_u *)b->bv_ga.ga_data;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
575 mch_memmove((char_u *)newblob->bv_ga.ga_data, p + idx,
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
576 (size_t)(end - idx + 1));
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
577 ++newblob->bv_refcount;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
578 rettv->v_type = VAR_BLOB;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
579 rettv->vval.v_blob = newblob;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
580
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
581 if (len - end - 1 > 0)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
582 mch_memmove(p + idx, p + end + 1, (size_t)(len - end - 1));
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
583 b->bv_ga.ga_len -= end - idx + 1;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
584 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
585
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
586 /*
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
587 * Implementation of map() and filter() for a Blob. Apply "expr" to every
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
588 * number in Blob "blob_arg" and return the result in "rettv".
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
589 */
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
590 void
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
591 blob_filter_map(
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
592 blob_T *blob_arg,
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
593 filtermap_T filtermap,
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
594 typval_T *expr,
32170
5848a0867b26 patch 9.0.1416: crash when collection is modified when using filter()
Bram Moolenaar <Bram@vim.org>
parents: 30986
diff changeset
595 char_u *arg_errmsg,
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
596 typval_T *rettv)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
597 {
32170
5848a0867b26 patch 9.0.1416: crash when collection is modified when using filter()
Bram Moolenaar <Bram@vim.org>
parents: 30986
diff changeset
598 blob_T *b = blob_arg;
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
599 int i;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
600 typval_T tv;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
601 varnumber_T val;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
602 blob_T *b_ret;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
603 int idx = 0;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
604 int rem;
30566
b3de17181c19 patch 9.0.0618: calling function for reduce() has too much overhead
Bram Moolenaar <Bram@vim.org>
parents: 30531
diff changeset
605 typval_T newtv;
b3de17181c19 patch 9.0.0618: calling function for reduce() has too much overhead
Bram Moolenaar <Bram@vim.org>
parents: 30531
diff changeset
606 funccall_T *fc;
17530
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
607
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
608 if (filtermap == FILTERMAP_MAPNEW)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
609 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
610 rettv->v_type = VAR_BLOB;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
611 rettv->vval.v_blob = NULL;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
612 }
32170
5848a0867b26 patch 9.0.1416: crash when collection is modified when using filter()
Bram Moolenaar <Bram@vim.org>
parents: 30986
diff changeset
613 if (b == NULL || (filtermap == FILTERMAP_FILTER
5848a0867b26 patch 9.0.1416: crash when collection is modified when using filter()
Bram Moolenaar <Bram@vim.org>
parents: 30986
diff changeset
614 && value_check_lock(b->bv_lock, arg_errmsg, TRUE)))
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
615 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
616
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
617 b_ret = b;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
618 if (filtermap == FILTERMAP_MAPNEW)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
619 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
620 if (blob_copy(b, rettv) == FAIL)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
621 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
622 b_ret = rettv->vval.v_blob;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
623 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
624
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
625 // set_vim_var_nr() doesn't set the type
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
626 set_vim_var_type(VV_KEY, VAR_NUMBER);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
627
32170
5848a0867b26 patch 9.0.1416: crash when collection is modified when using filter()
Bram Moolenaar <Bram@vim.org>
parents: 30986
diff changeset
628 int prev_lock = b->bv_lock;
5848a0867b26 patch 9.0.1416: crash when collection is modified when using filter()
Bram Moolenaar <Bram@vim.org>
parents: 30986
diff changeset
629 if (b->bv_lock == 0)
5848a0867b26 patch 9.0.1416: crash when collection is modified when using filter()
Bram Moolenaar <Bram@vim.org>
parents: 30986
diff changeset
630 b->bv_lock = VAR_LOCKED;
5848a0867b26 patch 9.0.1416: crash when collection is modified when using filter()
Bram Moolenaar <Bram@vim.org>
parents: 30986
diff changeset
631
32256
252b06c87796 patch 9.0.1459: typo in name of type
Bram Moolenaar <Bram@vim.org>
parents: 32170
diff changeset
632 // Create one funccall_T for all eval_expr_typval() calls.
30566
b3de17181c19 patch 9.0.0618: calling function for reduce() has too much overhead
Bram Moolenaar <Bram@vim.org>
parents: 30531
diff changeset
633 fc = eval_expr_get_funccal(expr, &newtv);
b3de17181c19 patch 9.0.0618: calling function for reduce() has too much overhead
Bram Moolenaar <Bram@vim.org>
parents: 30531
diff changeset
634
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
635 for (i = 0; i < b->bv_ga.ga_len; i++)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
636 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
637 tv.v_type = VAR_NUMBER;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
638 val = blob_get(b, i);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
639 tv.vval.v_number = val;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
640 set_vim_var_nr(VV_KEY, idx);
30566
b3de17181c19 patch 9.0.0618: calling function for reduce() has too much overhead
Bram Moolenaar <Bram@vim.org>
parents: 30531
diff changeset
641 if (filter_map_one(&tv, expr, filtermap, fc, &newtv, &rem) == FAIL
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
642 || did_emsg)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
643 break;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
644 if (newtv.v_type != VAR_NUMBER && newtv.v_type != VAR_BOOL)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
645 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
646 clear_tv(&newtv);
26877
06a137af96f8 patch 8.2.3967: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents: 26865
diff changeset
647 emsg(_(e_invalid_operation_for_blob));
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
648 break;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
649 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
650 if (filtermap != FILTERMAP_FILTER)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
651 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
652 if (newtv.vval.v_number != val)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
653 blob_set(b_ret, i, newtv.vval.v_number);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
654 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
655 else if (rem)
17530
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
656 {
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
657 char_u *p = (char_u *)blob_arg->bv_ga.ga_data;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
658
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
659 mch_memmove(p + i, p + i + 1,
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
660 (size_t)b->bv_ga.ga_len - i - 1);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
661 --b->bv_ga.ga_len;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
662 --i;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
663 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
664 ++idx;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
665 }
30566
b3de17181c19 patch 9.0.0618: calling function for reduce() has too much overhead
Bram Moolenaar <Bram@vim.org>
parents: 30531
diff changeset
666
32170
5848a0867b26 patch 9.0.1416: crash when collection is modified when using filter()
Bram Moolenaar <Bram@vim.org>
parents: 30986
diff changeset
667 b->bv_lock = prev_lock;
30566
b3de17181c19 patch 9.0.0618: calling function for reduce() has too much overhead
Bram Moolenaar <Bram@vim.org>
parents: 30531
diff changeset
668 if (fc != NULL)
b3de17181c19 patch 9.0.0618: calling function for reduce() has too much overhead
Bram Moolenaar <Bram@vim.org>
parents: 30531
diff changeset
669 remove_funccal();
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
670 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
671
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
672 /*
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
673 * "insert(blob, {item} [, {idx}])" function
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
674 */
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
675 void
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
676 blob_insert_func(typval_T *argvars, typval_T *rettv)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
677 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
678 blob_T *b = argvars[0].vval.v_blob;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
679 long before = 0;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
680 int error = FALSE;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
681 int val, len;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
682 char_u *p;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
683
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
684 if (b == NULL)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
685 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
686 if (in_vim9script())
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
687 emsg(_(e_cannot_add_to_null_blob));
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
688 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
689 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
690
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
691 if (value_check_lock(b->bv_lock, (char_u *)N_("insert() argument"), TRUE))
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
692 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
693
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
694 len = blob_len(b);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
695 if (argvars[2].v_type != VAR_UNKNOWN)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
696 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
697 before = (long)tv_get_number_chk(&argvars[2], &error);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
698 if (error)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
699 return; // type error; errmsg already given
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
700 if (before < 0 || before > len)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
701 {
26865
bce848ec8b1b patch 8.2.3961: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents: 26863
diff changeset
702 semsg(_(e_invalid_argument_str), tv_get_string(&argvars[2]));
17530
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
703 return;
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
704 }
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
705 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
706 val = tv_get_number_chk(&argvars[1], &error);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
707 if (error)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
708 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
709 if (val < 0 || val > 255)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
710 {
26865
bce848ec8b1b patch 8.2.3961: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents: 26863
diff changeset
711 semsg(_(e_invalid_argument_str), tv_get_string(&argvars[1]));
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
712 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
713 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
714
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
715 if (ga_grow(&b->bv_ga, 1) == FAIL)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
716 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
717 p = (char_u *)b->bv_ga.ga_data;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
718 mch_memmove(p + before + 1, p + before, (size_t)len - before);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
719 *(p + before) = val;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
720 ++b->bv_ga.ga_len;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
721
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
722 copy_tv(&argvars[0], rettv);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
723 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
724
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
725 /*
30986
360f286b5869 patch 9.0.0828: various typos
Bram Moolenaar <Bram@vim.org>
parents: 30952
diff changeset
726 * Implementation of reduce() for Blob "argvars[0]" using the function "expr"
30425
6c2bbd7d9217 patch 9.0.0548: reduce() with a compiled lambda could be faster
Bram Moolenaar <Bram@vim.org>
parents: 30043
diff changeset
727 * starting with the optional initial value "argvars[2]" and return the result
6c2bbd7d9217 patch 9.0.0548: reduce() with a compiled lambda could be faster
Bram Moolenaar <Bram@vim.org>
parents: 30043
diff changeset
728 * in "rettv".
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
729 */
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
730 void
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
731 blob_reduce(
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
732 typval_T *argvars,
30425
6c2bbd7d9217 patch 9.0.0548: reduce() with a compiled lambda could be faster
Bram Moolenaar <Bram@vim.org>
parents: 30043
diff changeset
733 typval_T *expr,
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
734 typval_T *rettv)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
735 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
736 blob_T *b = argvars[0].vval.v_blob;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
737 int called_emsg_start = called_emsg;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
738 int r;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
739 typval_T initial;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
740 typval_T argv[3];
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
741 int i;
17530
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
742
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
743 if (argvars[2].v_type == VAR_UNKNOWN)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
744 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
745 if (b == NULL || b->bv_ga.ga_len == 0)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
746 {
26877
06a137af96f8 patch 8.2.3967: error messages are spread out
Bram Moolenaar <Bram@vim.org>
parents: 26865
diff changeset
747 semsg(_(e_reduce_of_an_empty_str_with_no_initial_value), "Blob");
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
748 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
749 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
750 initial.v_type = VAR_NUMBER;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
751 initial.vval.v_number = blob_get(b, 0);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
752 i = 1;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
753 }
30043
fd855ad74887 patch 9.0.0359: error message for wrong argument type is not specific
Bram Moolenaar <Bram@vim.org>
parents: 28289
diff changeset
754 else if (check_for_number_arg(argvars, 2) == FAIL)
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
755 return;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
756 else
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
757 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
758 initial = argvars[2];
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
759 i = 0;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
760 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
761
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
762 copy_tv(&initial, rettv);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
763 if (b == NULL)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
764 return;
17530
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
765
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
766 for ( ; i < b->bv_ga.ga_len; i++)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
767 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
768 argv[0] = *rettv;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
769 argv[1].v_type = VAR_NUMBER;
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
770 argv[1].vval.v_number = blob_get(b, i);
30425
6c2bbd7d9217 patch 9.0.0548: reduce() with a compiled lambda could be faster
Bram Moolenaar <Bram@vim.org>
parents: 30043
diff changeset
771
32818
705d0e1329a5 patch 9.0.1723: Fix regression in {func} argument of reduce()
Christian Brabandt <cb@256bit.org>
parents: 32256
diff changeset
772 r = eval_expr_typval(expr, TRUE, argv, 2, NULL, rettv);
30425
6c2bbd7d9217 patch 9.0.0548: reduce() with a compiled lambda could be faster
Bram Moolenaar <Bram@vim.org>
parents: 30043
diff changeset
773
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
774 clear_tv(&argv[0]);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
775 if (r == FAIL || called_emsg != called_emsg_start)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
776 return;
17530
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
777 }
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
778 }
ef23ec1eee54 patch 8.1.1763: evalfunc.c is still too big
Bram Moolenaar <Bram@vim.org>
parents: 17344
diff changeset
779
25806
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
780 /*
26684
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
781 * "reverse({blob})" function
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
782 */
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
783 void
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
784 blob_reverse(blob_T *b, typval_T *rettv)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
785 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
786 int i, len = blob_len(b);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
787
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
788 for (i = 0; i < len / 2; i++)
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
789 {
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
790 int tmp = blob_get(b, i);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
791
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
792 blob_set(b, i, blob_get(b, len - i - 1));
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
793 blob_set(b, len - i - 1, tmp);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
794 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
795 rettv_blob_set(rettv, b);
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
796 }
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
797
2126feddeda6 patch 8.2.3871: list.c contains code for dict and blob
Bram Moolenaar <Bram@vim.org>
parents: 26652
diff changeset
798 /*
25806
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
799 * blob2list() function
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
800 */
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
801 void
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
802 f_blob2list(typval_T *argvars, typval_T *rettv)
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
803 {
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
804 blob_T *blob;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
805 list_T *l;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
806 int i;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
807
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
808 if (rettv_list_alloc(rettv) == FAIL)
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
809 return;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
810
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
811 if (check_for_blob_arg(argvars, 0) == FAIL)
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
812 return;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
813
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
814 blob = argvars->vval.v_blob;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
815 l = rettv->vval.v_list;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
816 for (i = 0; i < blob_len(blob); i++)
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
817 list_append_number(l, blob_get(blob, i));
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
818 }
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
819
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
820 /*
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
821 * list2blob() function
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
822 */
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
823 void
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
824 f_list2blob(typval_T *argvars, typval_T *rettv)
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
825 {
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
826 list_T *l;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
827 listitem_T *li;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
828 blob_T *blob;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
829
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
830 if (rettv_blob_alloc(rettv) == FAIL)
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
831 return;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
832 blob = rettv->vval.v_blob;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
833
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
834 if (check_for_list_arg(argvars, 0) == FAIL)
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
835 return;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
836
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
837 l = argvars->vval.v_list;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
838 if (l == NULL)
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
839 return;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
840
26394
43d196ca5e7a patch 8.2.3728: internal error when passing range() to list2blob()
Bram Moolenaar <Bram@vim.org>
parents: 25806
diff changeset
841 CHECK_LIST_MATERIALIZE(l);
25806
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
842 FOR_ALL_LIST_ITEMS(l, li)
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
843 {
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
844 int error;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
845 varnumber_T n;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
846
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
847 error = FALSE;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
848 n = tv_get_number_chk(&li->li_tv, &error);
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
849 if (error == TRUE || n < 0 || n > 255)
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
850 {
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
851 if (!error)
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
852 semsg(_(e_invalid_value_for_blob_nr), n);
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
853 ga_clear(&blob->bv_ga);
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
854 return;
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
855 }
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
856 ga_append(&blob->bv_ga, n);
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
857 }
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
858 }
8d55e978f95b patch 8.2.3438: cannot manipulate blobs
Bram Moolenaar <Bram@vim.org>
parents: 25495
diff changeset
859
18757
c469e1930456 patch 8.1.2368: using old C style comments
Bram Moolenaar <Bram@vim.org>
parents: 17530
diff changeset
860 #endif // defined(FEAT_EVAL)