comparison src/if_lua.c @ 16076:a2f0e93a5857 v8.1.1043

patch 8.1.1043: Lua interface does not support Blob commit https://github.com/vim/vim/commit/b78286903300477bb8578a47b8170b4551e290c8 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Mar 23 13:57:02 2019 +0100 patch 8.1.1043: Lua interface does not support Blob Problem: Lua interface does not support Blob. Solution: Add support to Blob. (Ozaki Kiichi, closes https://github.com/vim/vim/issues/4151)
author Bram Moolenaar <Bram@vim.org>
date Sat, 23 Mar 2019 14:00:06 +0100
parents 8ad2cda3757d
children 643fe07aa0e2
comparison
equal deleted inserted replaced
16075:5ca428f99af9 16076:a2f0e93a5857
26 26
27 typedef buf_T *luaV_Buffer; 27 typedef buf_T *luaV_Buffer;
28 typedef win_T *luaV_Window; 28 typedef win_T *luaV_Window;
29 typedef dict_T *luaV_Dict; 29 typedef dict_T *luaV_Dict;
30 typedef list_T *luaV_List; 30 typedef list_T *luaV_List;
31 typedef blob_T *luaV_Blob;
31 typedef struct { 32 typedef struct {
32 char_u *name; // funcref 33 char_u *name; // funcref
33 dict_T *self; // selfdict 34 dict_T *self; // selfdict
34 } luaV_Funcref; 35 } luaV_Funcref;
35 typedef void (*msgfunc_T)(char_u *); 36 typedef void (*msgfunc_T)(char_u *);
36 37
37 static const char LUAVIM_DICT[] = "dict"; 38 static const char LUAVIM_DICT[] = "dict";
38 static const char LUAVIM_LIST[] = "list"; 39 static const char LUAVIM_LIST[] = "list";
40 static const char LUAVIM_BLOB[] = "blob";
39 static const char LUAVIM_FUNCREF[] = "funcref"; 41 static const char LUAVIM_FUNCREF[] = "funcref";
40 static const char LUAVIM_BUFFER[] = "buffer"; 42 static const char LUAVIM_BUFFER[] = "buffer";
41 static const char LUAVIM_WINDOW[] = "window"; 43 static const char LUAVIM_WINDOW[] = "window";
42 static const char LUAVIM_FREE[] = "luaV_free"; 44 static const char LUAVIM_FREE[] = "luaV_free";
43 static const char LUAVIM_LUAEVAL[] = "luaV_luaeval"; 45 static const char LUAVIM_LUAEVAL[] = "luaV_luaeval";
66 luaL_error(L, msg ": cannot convert value"); \ 68 luaL_error(L, msg ": cannot convert value"); \
67 } while (0) 69 } while (0)
68 70
69 static luaV_List *luaV_pushlist(lua_State *L, list_T *lis); 71 static luaV_List *luaV_pushlist(lua_State *L, list_T *lis);
70 static luaV_Dict *luaV_pushdict(lua_State *L, dict_T *dic); 72 static luaV_Dict *luaV_pushdict(lua_State *L, dict_T *dic);
73 static luaV_Blob *luaV_pushblob(lua_State *L, blob_T *blo);
71 static luaV_Funcref *luaV_pushfuncref(lua_State *L, char_u *name); 74 static luaV_Funcref *luaV_pushfuncref(lua_State *L, char_u *name);
72 75
73 #if LUA_VERSION_NUM <= 501 76 #if LUA_VERSION_NUM <= 501
74 #define luaV_openlib(L, l, n) luaL_openlib(L, NULL, l, n) 77 #define luaV_openlib(L, l, n) luaL_openlib(L, NULL, l, n)
75 #define luaL_typeerror luaL_typerror 78 #define luaL_typeerror luaL_typerror
539 lua_pushnil(L); 542 lua_pushnil(L);
540 break; 543 break;
541 case VAR_FUNC: 544 case VAR_FUNC:
542 luaV_pushfuncref(L, tv->vval.v_string); 545 luaV_pushfuncref(L, tv->vval.v_string);
543 break; 546 break;
547 case VAR_BLOB:
548 luaV_pushblob(L, tv->vval.v_blob);
549 break;
544 default: 550 default:
545 lua_pushnil(L); 551 lua_pushnil(L);
546 } 552 }
547 } 553 }
548 554
580 break; 586 break;
581 case LUA_TUSERDATA: 587 case LUA_TUSERDATA:
582 { 588 {
583 void *p = lua_touserdata(L, pos); 589 void *p = lua_touserdata(L, pos);
584 590
585 if (lua_getmetatable(L, pos)) /* has metatable? */ 591 if (lua_getmetatable(L, pos)) // has metatable?
586 { 592 {
587 /* check list */ 593 // check list
588 luaV_getfield(L, LUAVIM_LIST); 594 luaV_getfield(L, LUAVIM_LIST);
589 if (lua_rawequal(L, -1, -2)) 595 if (lua_rawequal(L, -1, -2))
590 { 596 {
591 tv->v_type = VAR_LIST; 597 tv->v_type = VAR_LIST;
592 tv->vval.v_list = *((luaV_List *) p); 598 tv->vval.v_list = *((luaV_List *) p);
593 ++tv->vval.v_list->lv_refcount; 599 ++tv->vval.v_list->lv_refcount;
594 lua_pop(L, 2); /* MTs */ 600 lua_pop(L, 2); // MTs
595 break; 601 break;
596 } 602 }
597 /* check dict */ 603 // check dict
598 luaV_getfield(L, LUAVIM_DICT); 604 luaV_getfield(L, LUAVIM_DICT);
599 if (lua_rawequal(L, -1, -3)) 605 if (lua_rawequal(L, -1, -3))
600 { 606 {
601 tv->v_type = VAR_DICT; 607 tv->v_type = VAR_DICT;
602 tv->vval.v_dict = *((luaV_Dict *) p); 608 tv->vval.v_dict = *((luaV_Dict *) p);
603 ++tv->vval.v_dict->dv_refcount; 609 ++tv->vval.v_dict->dv_refcount;
604 lua_pop(L, 3); /* MTs */ 610 lua_pop(L, 3); // MTs
605 break; 611 break;
606 } 612 }
607 /* check funcref */ 613 // check blob
614 luaV_getfield(L, LUAVIM_BLOB);
615 if (lua_rawequal(L, -1, -4))
616 {
617 tv->v_type = VAR_BLOB;
618 tv->vval.v_blob = *((luaV_Blob *) p);
619 ++tv->vval.v_blob->bv_refcount;
620 lua_pop(L, 4); // MTs
621 break;
622 }
623 // check funcref
608 luaV_getfield(L, LUAVIM_FUNCREF); 624 luaV_getfield(L, LUAVIM_FUNCREF);
609 if (lua_rawequal(L, -1, -4)) 625 if (lua_rawequal(L, -1, -5))
610 { 626 {
611 luaV_Funcref *f = (luaV_Funcref *) p; 627 luaV_Funcref *f = (luaV_Funcref *) p;
612 func_ref(f->name); 628 func_ref(f->name);
613 tv->v_type = VAR_FUNC; 629 tv->v_type = VAR_FUNC;
614 tv->vval.v_string = vim_strsave(f->name); 630 tv->vval.v_string = vim_strsave(f->name);
615 lua_pop(L, 4); /* MTs */ 631 lua_pop(L, 5); // MTs
616 break; 632 break;
617 } 633 }
618 lua_pop(L, 4); /* MTs */ 634 lua_pop(L, 4); // MTs
619 } 635 }
620 } 636 }
621 /* FALLTHROUGH */ 637 // FALLTHROUGH
622 default: 638 default:
623 tv->v_type = VAR_NUMBER; 639 tv->v_type = VAR_NUMBER;
624 tv->vval.v_number = 0; 640 tv->vval.v_number = 0;
625 status = FAIL; 641 status = FAIL;
626 } 642 }
751 767
752 static int 768 static int
753 luaV_list_len(lua_State *L) 769 luaV_list_len(lua_State *L)
754 { 770 {
755 list_T *l = luaV_unbox(L, luaV_List, 1); 771 list_T *l = luaV_unbox(L, luaV_List, 1);
756 lua_pushinteger(L, (l == NULL) ? 0 : (int) l->lv_len); 772 lua_pushinteger(L, (int) list_len(l));
757 return 1; 773 return 1;
758 } 774 }
759 775
760 static int 776 static int
761 luaV_list_iter(lua_State *L) 777 luaV_list_iter(lua_State *L)
907 923
908 static int 924 static int
909 luaV_dict_len(lua_State *L) 925 luaV_dict_len(lua_State *L)
910 { 926 {
911 dict_T *d = luaV_unbox(L, luaV_Dict, 1); 927 dict_T *d = luaV_unbox(L, luaV_Dict, 1);
912 lua_pushinteger(L, (d == NULL) ? 0 : (int) d->dv_hashtab.ht_used); 928 lua_pushinteger(L, (int) dict_len(d));
913 return 1; 929 return 1;
914 } 930 }
915 931
916 static int 932 static int
917 luaV_dict_iter(lua_State *L UNUSED) 933 luaV_dict_iter(lua_State *L UNUSED)
1023 {"__tostring", luaV_dict_tostring}, 1039 {"__tostring", luaV_dict_tostring},
1024 {"__len", luaV_dict_len}, 1040 {"__len", luaV_dict_len},
1025 {"__call", luaV_dict_call}, 1041 {"__call", luaV_dict_call},
1026 {"__index", luaV_dict_index}, 1042 {"__index", luaV_dict_index},
1027 {"__newindex", luaV_dict_newindex}, 1043 {"__newindex", luaV_dict_newindex},
1044 {NULL, NULL}
1045 };
1046
1047
1048 /* ======= Blob type ======= */
1049
1050 static luaV_Blob *
1051 luaV_newblob(lua_State *L, blob_T *blo)
1052 {
1053 luaV_Blob *b = (luaV_Blob *) lua_newuserdata(L, sizeof(luaV_Blob));
1054 *b = blo;
1055 blo->bv_refcount++; /* reference in Lua */
1056 luaV_setudata(L, blo); /* cache[blo] = udata */
1057 luaV_getfield(L, LUAVIM_BLOB);
1058 lua_setmetatable(L, -2);
1059 return b;
1060 }
1061
1062 luaV_pushtype(blob_T, blob, luaV_Blob)
1063 luaV_type_tostring(blob, LUAVIM_BLOB)
1064
1065 static int
1066 luaV_blob_gc(lua_State *L)
1067 {
1068 blob_T *b = luaV_unbox(L, luaV_Blob, 1);
1069 blob_unref(b);
1070 return 0;
1071 }
1072
1073 static int
1074 luaV_blob_len(lua_State *L)
1075 {
1076 blob_T *b = luaV_unbox(L, luaV_Blob, 1);
1077 lua_pushinteger(L, (int) blob_len(b));
1078 return 1;
1079 }
1080
1081 static int
1082 luaV_blob_index(lua_State *L)
1083 {
1084 blob_T *b = luaV_unbox(L, luaV_Blob, 1);
1085 if (lua_isnumber(L, 2))
1086 {
1087 int idx = luaL_checkinteger(L, 2);
1088 if (idx < blob_len(b))
1089 lua_pushnumber(L, (lua_Number) blob_get(b, idx));
1090 else
1091 lua_pushnil(L);
1092 }
1093 else if (lua_isstring(L, 2))
1094 {
1095 const char *s = lua_tostring(L, 2);
1096 if (strncmp(s, "add", 3) == 0)
1097 {
1098 lua_getmetatable(L, 1);
1099 lua_getfield(L, -1, s);
1100 }
1101 else
1102 lua_pushnil(L);
1103 }
1104 else
1105 lua_pushnil(L);
1106 return 1;
1107 }
1108
1109 static int
1110 luaV_blob_newindex(lua_State *L)
1111 {
1112 blob_T *b = luaV_unbox(L, luaV_Blob, 1);
1113 if (b->bv_lock)
1114 luaL_error(L, "blob is locked");
1115 if (lua_isnumber(L, 2))
1116 {
1117 long len = blob_len(b);
1118 int idx = luaL_checkinteger(L, 2);
1119 int val = luaL_checkinteger(L, 3);
1120 if (idx < len || (idx == len && ga_grow(&b->bv_ga, 1) == OK))
1121 {
1122 blob_set(b, idx, (char_u) val);
1123 if (idx == len)
1124 ++b->bv_ga.ga_len;
1125 }
1126 else
1127 luaL_error(L, "index out of range");
1128 }
1129 return 0;
1130 }
1131
1132 static int
1133 luaV_blob_add(lua_State *L)
1134 {
1135 luaV_Blob *blo = luaV_checkudata(L, 1, LUAVIM_BLOB);
1136 blob_T *b = (blob_T *) luaV_checkcache(L, (void *) *blo);
1137 if (b->bv_lock)
1138 luaL_error(L, "blob is locked");
1139 lua_settop(L, 2);
1140 if (!lua_isstring(L, 2))
1141 luaL_error(L, "string expected, got %s", luaL_typename(L, 2));
1142 else
1143 {
1144 size_t i, l = 0;
1145 const char *s = lua_tolstring(L, 2, &l);
1146
1147 ga_grow(&b->bv_ga, l);
1148 for (i = 0; i < l; ++i)
1149 ga_append(&b->bv_ga, s[i]);
1150 }
1151 lua_settop(L, 1);
1152 return 1;
1153 }
1154
1155 static const luaL_Reg luaV_Blob_mt[] = {
1156 {"__tostring", luaV_blob_tostring},
1157 {"__gc", luaV_blob_gc},
1158 {"__len", luaV_blob_len},
1159 {"__index", luaV_blob_index},
1160 {"__newindex", luaV_blob_newindex},
1161 {"add", luaV_blob_add},
1028 {NULL, NULL} 1162 {NULL, NULL}
1029 }; 1163 };
1030 1164
1031 1165
1032 /* ======= Funcref type ======= */ 1166 /* ======= Funcref type ======= */
1622 } 1756 }
1623 return 1; 1757 return 1;
1624 } 1758 }
1625 1759
1626 static int 1760 static int
1761 luaV_blob(lua_State *L)
1762 {
1763 blob_T *b;
1764 int initarg = !lua_isnoneornil(L, 1);
1765
1766 if (initarg && !lua_isstring(L, 1))
1767 luaL_error(L, "string expected, got %s", luaL_typename(L, 1));
1768 b = blob_alloc();
1769 if (b == NULL)
1770 lua_pushnil(L);
1771 else
1772 {
1773 luaV_newblob(L, b);
1774 if (initarg)
1775 {
1776 size_t i, l = 0;
1777 const char *s = lua_tolstring(L, 1, &l);
1778
1779 ga_grow(&b->bv_ga, l);
1780 for (i = 0; i < l; ++i)
1781 ga_append(&b->bv_ga, s[i]);
1782 }
1783 }
1784 return 1;
1785 }
1786
1787 static int
1627 luaV_funcref(lua_State *L) 1788 luaV_funcref(lua_State *L)
1628 { 1789 {
1629 const char *name = luaL_checkstring(L, 1); 1790 const char *name = luaL_checkstring(L, 1);
1630 /* note: not checking if function exists (needs function_exists) */ 1791 /* note: not checking if function exists (needs function_exists) */
1631 if (name == NULL || *name == NUL || VIM_ISDIGIT(*name)) 1792 if (name == NULL || *name == NUL || VIM_ISDIGIT(*name))
1713 } 1874 }
1714 luaV_getfield(L, LUAVIM_DICT); 1875 luaV_getfield(L, LUAVIM_DICT);
1715 if (lua_rawequal(L, -1, 2)) 1876 if (lua_rawequal(L, -1, 2))
1716 { 1877 {
1717 lua_pushstring(L, "dict"); 1878 lua_pushstring(L, "dict");
1879 return 1;
1880 }
1881 luaV_getfield(L, LUAVIM_BLOB);
1882 if (lua_rawequal(L, -1, 2))
1883 {
1884 lua_pushstring(L, "blob");
1718 return 1; 1885 return 1;
1719 } 1886 }
1720 luaV_getfield(L, LUAVIM_FUNCREF); 1887 luaV_getfield(L, LUAVIM_FUNCREF);
1721 if (lua_rawequal(L, -1, 2)) 1888 if (lua_rawequal(L, -1, 2))
1722 { 1889 {
1746 {"eval", luaV_eval}, 1913 {"eval", luaV_eval},
1747 {"beep", luaV_beep}, 1914 {"beep", luaV_beep},
1748 {"line", luaV_line}, 1915 {"line", luaV_line},
1749 {"list", luaV_list}, 1916 {"list", luaV_list},
1750 {"dict", luaV_dict}, 1917 {"dict", luaV_dict},
1918 {"blob", luaV_blob},
1751 {"funcref", luaV_funcref}, 1919 {"funcref", luaV_funcref},
1752 {"buffer", luaV_buffer}, 1920 {"buffer", luaV_buffer},
1753 {"window", luaV_window}, 1921 {"window", luaV_window},
1754 {"open", luaV_open}, 1922 {"open", luaV_open},
1755 {"type", luaV_type}, 1923 {"type", luaV_type},
1881 lua_pushvalue(L, 1); 2049 lua_pushvalue(L, 1);
1882 luaV_openlib(L, luaV_List_mt, 1); 2050 luaV_openlib(L, luaV_List_mt, 1);
1883 luaV_newmetatable(L, LUAVIM_DICT); 2051 luaV_newmetatable(L, LUAVIM_DICT);
1884 lua_pushvalue(L, 1); 2052 lua_pushvalue(L, 1);
1885 luaV_openlib(L, luaV_Dict_mt, 1); 2053 luaV_openlib(L, luaV_Dict_mt, 1);
2054 luaV_newmetatable(L, LUAVIM_BLOB);
2055 lua_pushvalue(L, 1);
2056 luaV_openlib(L, luaV_Blob_mt, 1);
1886 luaV_newmetatable(L, LUAVIM_FUNCREF); 2057 luaV_newmetatable(L, LUAVIM_FUNCREF);
1887 lua_pushvalue(L, 1); 2058 lua_pushvalue(L, 1);
1888 luaV_openlib(L, luaV_Funcref_mt, 1); 2059 luaV_openlib(L, luaV_Funcref_mt, 1);
1889 luaV_newmetatable(L, LUAVIM_BUFFER); 2060 luaV_newmetatable(L, LUAVIM_BUFFER);
1890 lua_pushvalue(L, 1); /* cache table */ 2061 lua_pushvalue(L, 1); /* cache table */