Patch 7.4.1154
Problem: No support for JSON.
Solution: Add jsonencode() and jsondecode(). Also add v:false, v:true,
v:null and v:none.
Files: src/json.c, src/eval.c, src/proto.h, src/structs.h, src/vim.h,
src/if_lua.c, src/if_mzsch.c, src/if_ruby.c, src/if_py_both.h,
src/globals.h, src/Makefile, src/Make_bc3.mak, src/Make_bc5.mak,
src/Make_cyg_ming.mak, src/Make_dice.mak, src/Make_ivc.mak,
src/Make_manx.mak, src/Make_morph.mak, src/Make_mvc.mak,
src/Make_sas.mak, src/Make_vms.mms, src/proto/json.pro,
src/proto/eval.pro, src/testdir/test_json.vim,
src/testdir/test_alot.vim, Filelist, runtime/doc/eval.txt
*** ../vim-7.4.1153/src/json.c 2016-01-23 19:32:31.331223590 +0100
--- src/json.c 2016-01-23 19:17:42.068467887 +0100
***************
*** 0 ****
--- 1,509 ----
+ /* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+ /*
+ * json.c: Encoding and decoding JSON.
+ *
+ * Follows this standard: http://www.ietf.org/rfc/rfc4627.txt
+ */
+
+ #include "vim.h"
+
+ #if defined(FEAT_EVAL) || defined(PROTO)
+ static void json_decode_item(js_read_T *reader, typval_T *res);
+
+ /*
+ * Encode "val" into a JSON format string.
+ */
+ char_u *
+ json_encode(typval_T *val)
+ {
+ garray_T ga;
+
+ /* Store bytes in the growarray. */
+ ga_init2(&ga, 1, 4000);
+ json_encode_item(&ga, val, get_copyID());
+ return ga.ga_data;
+ }
+
+ static void
+ write_string(garray_T *gap, char_u *str)
+ {
+ char_u *res = str;
+ char_u numbuf[NUMBUFLEN];
+
+ if (res == NULL)
+ ga_concat(gap, (char_u *)"null");
+ else
+ {
+ ga_append(gap, '"');
+ while (*res != NUL)
+ {
+ int c = PTR2CHAR(res);
+
+ switch (c)
+ {
+ case 0x08:
+ ga_append(gap, '\\'); ga_append(gap, 'b'); break;
+ case 0x09:
+ ga_append(gap, '\\'); ga_append(gap, 't'); break;
+ case 0x0a:
+ ga_append(gap, '\\'); ga_append(gap, 'n'); break;
+ case 0x0c:
+ ga_append(gap, '\\'); ga_append(gap, 'f'); break;
+ case 0x0d:
+ ga_append(gap, '\\'); ga_append(gap, 'r'); break;
+ case 0x22: /* " */
+ case 0x5c: /* \ */
+ ga_append(gap, '\\');
+ ga_append(gap, c);
+ break;
+ default:
+ if (c >= 0x20)
+ {
+ numbuf[mb_char2bytes(c, numbuf)] = NUL;
+ ga_concat(gap, numbuf);
+ }
+ else
+ {
+ vim_snprintf((char *)numbuf, NUMBUFLEN,
+ "\\u%04lx", (long)c);
+ ga_concat(gap, numbuf);
+ }
+ }
+ mb_cptr_adv(res);
+ }
+ ga_append(gap, '"');
+ }
+ }
+
+ void
+ json_encode_item(garray_T *gap, typval_T *val, int copyID)
+ {
+ char_u numbuf[NUMBUFLEN];
+ char_u *res;
+ list_T *l;
+ dict_T *d;
+
+ switch (val->v_type)
+ {
+ case VAR_SPECIAL:
+ switch(val->vval.v_number)
+ {
+ case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break;
+ case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break;
+ case VVAL_NONE: break;
+ case VVAL_NULL: ga_concat(gap, (char_u *)"null"); break;
+ }
+ break;
+
+ case VAR_NUMBER:
+ vim_snprintf((char *)numbuf, NUMBUFLEN, "%ld",
+ (long)val->vval.v_number);
+ ga_concat(gap, numbuf);
+ break;
+
+ case VAR_STRING:
+ res = val->vval.v_string;
+ write_string(gap, res);
+ break;
+
+ case VAR_FUNC:
+ /* no JSON equivalent, skip */
+ break;
+
+ case VAR_LIST:
+ l = val->vval.v_list;
+ if (l == NULL)
+ ga_concat(gap, (char_u *)"null");
+ else
+ {
+ if (l->lv_copyID == copyID)
+ ga_concat(gap, (char_u *)"[]");
+ else
+ {
+ listitem_T *li;
+
+ l->lv_copyID = copyID;
+ ga_append(gap, '[');
+ for (li = l->lv_first; li != NULL && !got_int; )
+ {
+ json_encode_item(gap, &li->li_tv, copyID);
+ li = li->li_next;
+ if (li != NULL)
+ ga_append(gap, ',');
+ }
+ ga_append(gap, ']');
+ }
+ }
+ break;
+
+ case VAR_DICT:
+ d = val->vval.v_dict;
+ if (d == NULL)
+ ga_concat(gap, (char_u *)"null");
+ else
+ {
+ if (d->dv_copyID == copyID)
+ ga_concat(gap, (char_u *)"{}");
+ else
+ {
+ int first = TRUE;
+ int todo = (int)d->dv_hashtab.ht_used;
+ hashitem_T *hi;
+
+ d->dv_copyID = copyID;
+ ga_append(gap, '{');
+
+ for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int;
+ ++hi)
+ if (!HASHITEM_EMPTY(hi))
+ {
+ --todo;
+ if (first)
+ first = FALSE;
+ else
+ ga_append(gap, ',');
+ write_string(gap, hi->hi_key);
+ ga_append(gap, ':');
+ json_encode_item(gap, &dict_lookup(hi)->di_tv,
+ copyID);
+ }
+ ga_append(gap, '}');
+ }
+ }
+ break;
+
+ #ifdef FEAT_FLOAT
+ case VAR_FLOAT:
+ vim_snprintf((char *)numbuf, NUMBUFLEN, "%g", val->vval.v_float);
+ ga_concat(gap, numbuf);
+ break;
+ #endif
+ default: EMSG2(_(e_intern2), "json_encode_item()"); break;
+ }
+ }
+
+ /*
+ * Skip white space in "reader".
+ */
+ static void
+ json_skip_white(js_read_T *reader)
+ {
+ int c;
+
+ while ((c = reader->js_buf[reader->js_used]) == ' '
+ || c == TAB || c == NL || c == CAR)
+ ++reader->js_used;
+ }
+
+ /*
+ * Make sure there are at least enough characters buffered to read a number.
+ */
+ static void
+ json_fill_buffer(js_read_T *reader UNUSED)
+ {
+ /* TODO */
+ }
+
+ static void
+ json_decode_array(js_read_T *reader, typval_T *res)
+ {
+ char_u *p;
+ typval_T item;
+ listitem_T *li;
+
+ if (rettv_list_alloc(res) == FAIL)
+ goto fail;
+ ++reader->js_used; /* consume the '[' */
+
+ while (TRUE)
+ {
+ json_skip_white(reader);
+ p = reader->js_buf + reader->js_used;
+ if (*p == NUL)
+ goto fail;
+ if (*p == ']')
+ {
+ ++reader->js_used; /* consume the ']' */
+ return;
+ }
+
+ if (!reader->js_eof && (int)(reader->js_end - p) < NUMBUFLEN)
+ json_fill_buffer(reader);
+
+ json_decode_item(reader, &item);
+ li = listitem_alloc();
+ if (li == NULL)
+ return;
+ li->li_tv = item;
+ list_append(res->vval.v_list, li);
+
+ json_skip_white(reader);
+ p = reader->js_buf + reader->js_used;
+ if (*p == ',')
+ ++reader->js_used;
+ else if (*p != ']')
+ goto fail;
+ }
+ fail:
+ res->v_type = VAR_SPECIAL;
+ res->vval.v_number = VVAL_NONE;
+ }
+
+ static void
+ json_decode_object(js_read_T *reader, typval_T *res)
+ {
+ char_u *p;
+ typval_T tvkey;
+ typval_T item;
+ dictitem_T *di;
+ char_u buf[NUMBUFLEN];
+ char_u *key;
+
+ if (rettv_dict_alloc(res) == FAIL)
+ goto fail;
+ ++reader->js_used; /* consume the '{' */
+
+ while (TRUE)
+ {
+ json_skip_white(reader);
+ p = reader->js_buf + reader->js_used;
+ if (*p == NUL)
+ goto fail;
+ if (*p == '}')
+ {
+ ++reader->js_used; /* consume the '}' */
+ return;
+ }
+
+ if (!reader->js_eof && (int)(reader->js_end - p) < NUMBUFLEN)
+ json_fill_buffer(reader);
+ json_decode_item(reader, &tvkey);
+ key = get_tv_string_buf_chk(&tvkey, buf);
+ if (key == NULL || *key == NUL)
+ {
+ /* "key" is NULL when get_tv_string_buf_chk() gave an errmsg */
+ if (key != NULL)
+ EMSG(_(e_emptykey));
+ clear_tv(&tvkey);
+ goto fail;
+ }
+
+ json_skip_white(reader);
+ p = reader->js_buf + reader->js_used;
+ if (*p != ':')
+ {
+ clear_tv(&tvkey);
+ goto fail;
+ }
+ ++reader->js_used;
+ json_skip_white(reader);
+
+ if (!reader->js_eof && (int)(reader->js_end - p) < NUMBUFLEN)
+ json_fill_buffer(reader);
+ json_decode_item(reader, &item);
+
+ di = dictitem_alloc(key);
+ clear_tv(&tvkey);
+ if (di == NULL)
+ {
+ clear_tv(&item);
+ goto fail;
+ }
+ di->di_tv = item;
+ dict_add(res->vval.v_dict, di);
+
+ json_skip_white(reader);
+ p = reader->js_buf + reader->js_used;
+ if (*p == ',')
+ ++reader->js_used;
+ else if (*p != '}')
+ goto fail;
+ }
+ fail:
+ res->v_type = VAR_SPECIAL;
+ res->vval.v_number = VVAL_NONE;
+ }
+
+ static void
+ json_decode_string(js_read_T *reader, typval_T *res)
+ {
+ garray_T ga;
+ int len;
+ char_u *p = reader->js_buf + reader->js_used + 1;
+ int c;
+ long nr;
+ char_u buf[NUMBUFLEN];
+
+ ga_init2(&ga, 1, 200);
+
+ /* TODO: fill buffer when needed. */
+ while (*p != NUL && *p != '"')
+ {
+ if (*p == '\\')
+ {
+ c = -1;
+ switch (p[1])
+ {
+ case 'b': c = BS; break;
+ case 't': c = TAB; break;
+ case 'n': c = NL; break;
+ case 'f': c = FF; break;
+ case 'r': c = CAR; break;
+ case 'u':
+ vim_str2nr(p + 2, NULL, &len,
+ STR2NR_HEX + STR2NR_FORCE, &nr, NULL, 4);
+ p += len + 2;
+ #ifdef FEAT_MBYTE
+ buf[(*mb_char2bytes)((int)nr, buf)] = NUL;
+ ga_concat(&ga, buf);
+ #else
+ ga_append(&ga, nr);
+ #endif
+ break;
+ default: c = p[1]; break;
+ }
+ if (c > 0)
+ {
+ p += 2;
+ ga_append(&ga, c);
+ }
+ }
+ else
+ {
+ len = MB_PTR2LEN(p);
+ if (ga_grow(&ga, len) == OK)
+ {
+ mch_memmove((char *)ga.ga_data + ga.ga_len, p, (size_t)len);
+ ga.ga_len += len;
+ }
+ p += len;
+ }
+ if (!reader->js_eof && (int)(reader->js_end - p) < NUMBUFLEN)
+ {
+ reader->js_used = (int)(p - reader->js_buf);
+ json_fill_buffer(reader);
+ p = reader->js_buf + reader->js_used;
+ }
+ }
+ reader->js_used = (int)(p - reader->js_buf);
+ if (*p == '"')
+ {
+ ++reader->js_used;
+ res->v_type = VAR_STRING;
+ res->vval.v_string = vim_strsave(ga.ga_data);
+ }
+ else
+ {
+ res->v_type = VAR_SPECIAL;
+ res->vval.v_number = VVAL_NONE;
+ }
+ ga_clear(&ga);
+ }
+
+ /*
+ * Decode one item and put it in "result".
+ * Must already have skipped white space.
+ */
+ static void
+ json_decode_item(js_read_T *reader, typval_T *res)
+ {
+ char_u *p = reader->js_buf + reader->js_used;
+
+ switch (*p)
+ {
+ case '[': /* array */
+ json_decode_array(reader, res);
+ return;
+
+ case '{': /* object */
+ json_decode_object(reader, res);
+ return;
+
+ case '"': /* string */
+ json_decode_string(reader, res);
+ return;
+
+ case ',': /* comma: empty item */
+ case NUL: /* empty */
+ res->v_type = VAR_SPECIAL;
+ res->vval.v_number = VVAL_NONE;
+ return;
+
+ default:
+ if (VIM_ISDIGIT(*p) || *p == '-')
+ {
+ int len;
+ char_u *sp = p;
+ #ifdef FEAT_FLOAT
+ if (*sp == '-')
+ ++sp;
+ sp = skipdigits(sp);
+ if (*sp == '.' || *sp == 'e' || *sp == 'E')
+ {
+ res->v_type = VAR_FLOAT;
+ len = string2float(p, &res->vval.v_float);
+ }
+ else
+ #endif
+ {
+ long nr;
+
+ res->v_type = VAR_NUMBER;
+ vim_str2nr(reader->js_buf + reader->js_used,
+ NULL, &len, 0, /* what */
+ &nr, NULL, 0);
+ res->vval.v_number = nr;
+ }
+ reader->js_used += len;
+ return;
+ }
+ if (STRNICMP((char *)p, "false", 5) == 0)
+ {
+ reader->js_used += 5;
+ res->v_type = VAR_SPECIAL;
+ res->vval.v_number = VVAL_FALSE;
+ return;
+ }
+ if (STRNICMP((char *)p, "true", 4) == 0)
+ {
+ reader->js_used += 4;
+ res->v_type = VAR_SPECIAL;
+ res->vval.v_number = VVAL_TRUE;
+ return;
+ }
+ if (STRNICMP((char *)p, "null", 4) == 0)
+ {
+ reader->js_used += 4;
+ res->v_type = VAR_SPECIAL;
+ res->vval.v_number = VVAL_NULL;
+ return;
+ }
+ break;
+ }
+
+ EMSG(_(e_invarg));
+ res->v_type = VAR_SPECIAL;
+ res->vval.v_number = VVAL_NONE;
+ }
+
+ /*
+ * Decode the JSON from "reader" and store the result in "res".
+ */
+ void
+ json_decode(js_read_T *reader, typval_T *res)
+ {
+ json_skip_white(reader);
+ json_decode_item(reader, res);
+ json_skip_white(reader);
+ if (reader->js_buf[reader->js_used] != NUL)
+ EMSG(_(e_invarg));
+ }
+ #endif
*** ../vim-7.4.1153/src/eval.c 2016-01-21 23:34:54.244356654 +0100
--- src/eval.c 2016-01-23 19:42:48.960799020 +0100
***************
*** 99,105 ****
static char *e_missbrac = N_("E111: Missing ']'");
static char *e_listarg = N_("E686: Argument of %s must be a List");
static char *e_listdictarg = N_("E712: Argument of %s must be a List or
Dictionary");
- static char *e_emptykey = N_("E713: Cannot use empty key for Dictionary");
static char *e_listreq = N_("E714: List required");
static char *e_dictreq = N_("E715: Dictionary required");
static char *e_toomanyarg = N_("E118: Too many arguments for function: %s");
--- 99,104 ----
***************
*** 371,376 ****
--- 370,379 ----
{VV_NAME("option_old", VAR_STRING), VV_RO},
{VV_NAME("option_type", VAR_STRING), VV_RO},
{VV_NAME("errors", VAR_LIST), 0},
+ {VV_NAME("false", VAR_SPECIAL), VV_RO},
+ {VV_NAME("true", VAR_SPECIAL), VV_RO},
+ {VV_NAME("null", VAR_SPECIAL), VV_RO},
+ {VV_NAME("none", VAR_SPECIAL), VV_RO},
};
/* shorthand */
***************
*** 428,434 ****
static int get_string_tv __ARGS((char_u **arg, typval_T *rettv, int
evaluate));
static int get_lit_string_tv __ARGS((char_u **arg, typval_T *rettv, int
evaluate));
static int get_list_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
- static int rettv_list_alloc __ARGS((typval_T *rettv));
static long list_len __ARGS((list_T *l));
static int list_equal __ARGS((list_T *l1, list_T *l2, int ic, int recursive));
static int dict_equal __ARGS((dict_T *d1, dict_T *d2, int ic, int recursive));
--- 431,436 ----
***************
*** 443,449 ****
static int list_join_inner __ARGS((garray_T *gap, list_T *l, char_u *sep, int
echo_style, int copyID, garray_T *join_gap));
static int list_join __ARGS((garray_T *gap, list_T *l, char_u *sep, int echo,
int copyID));
static int free_unref_items __ARGS((int copyID));
- static int rettv_dict_alloc __ARGS((typval_T *rettv));
static dictitem_T *dictitem_copy __ARGS((dictitem_T *org));
static void dictitem_remove __ARGS((dict_T *dict, dictitem_T *item));
static dict_T *dict_copy __ARGS((dict_T *orig, int deep, int copyID));
--- 445,450 ----
***************
*** 453,461 ****
static char_u *echo_string __ARGS((typval_T *tv, char_u **tofree, char_u
*numbuf, int copyID));
static char_u *tv2string __ARGS((typval_T *tv, char_u **tofree, char_u
*numbuf, int copyID));
static char_u *string_quote __ARGS((char_u *str, int function));
- #ifdef FEAT_FLOAT
- static int string2float __ARGS((char_u *text, float_T *value));
- #endif
static int get_env_tv __ARGS((char_u **arg, typval_T *rettv, int evaluate));
static int find_internal_func __ARGS((char_u *name));
static char_u *deref_func_name __ARGS((char_u *name, int *lenp, int
no_autoload));
--- 454,459 ----
***************
*** 617,622 ****
--- 615,622 ----
static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv));
static void f_items __ARGS((typval_T *argvars, typval_T *rettv));
static void f_join __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_jsondecode __ARGS((typval_T *argvars, typval_T *rettv));
+ static void f_jsonencode __ARGS((typval_T *argvars, typval_T *rettv));
static void f_keys __ARGS((typval_T *argvars, typval_T *rettv));
static void f_last_buffer_nr __ARGS((typval_T *argvars, typval_T *rettv));
static void f_len __ARGS((typval_T *argvars, typval_T *rettv));
***************
*** 816,822 ****
static linenr_T get_tv_lnum_buf __ARGS((typval_T *argvars, buf_T *buf));
static char_u *get_tv_string __ARGS((typval_T *varp));
static char_u *get_tv_string_buf __ARGS((typval_T *varp, char_u *buf));
- static char_u *get_tv_string_buf_chk __ARGS((typval_T *varp, char_u *buf));
static dictitem_T *find_var __ARGS((char_u *name, hashtab_T **htp, int
no_autoload));
static dictitem_T *find_var_in_ht __ARGS((hashtab_T *ht, int htname, char_u
*varname, int no_autoload));
static hashtab_T *find_var_ht __ARGS((char_u *name, char_u **varname));
--- 816,821 ----
***************
*** 915,920 ****
--- 914,925 ----
set_vim_var_nr(VV_HLSEARCH, 1L);
set_vim_var_dict(VV_COMPLETED_ITEM, dict_alloc());
set_vim_var_list(VV_ERRORS, list_alloc());
+
+ set_vim_var_nr(VV_FALSE, VVAL_FALSE);
+ set_vim_var_nr(VV_TRUE, VVAL_TRUE);
+ set_vim_var_nr(VV_NONE, VVAL_NONE);
+ set_vim_var_nr(VV_NULL, VVAL_NULL);
+
set_reg_var(0); /* default for v:register is not 0 but '"' */
#ifdef EBCDIC
***************
*** 3080,3092 ****
char_u numbuf[NUMBUFLEN];
char_u *s;
! /* Can't do anything with a Funcref or a Dict on the right. */
! if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT)
{
switch (tv1->v_type)
{
case VAR_DICT:
case VAR_FUNC:
break;
case VAR_LIST:
--- 3085,3099 ----
char_u numbuf[NUMBUFLEN];
char_u *s;
! /* Can't do anything with a Funcref, Dict, v:true on the right. */
! if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT
! && tv2->v_type != VAR_SPECIAL)
{
switch (tv1->v_type)
{
case VAR_DICT:
case VAR_FUNC:
+ case VAR_SPECIAL:
break;
case VAR_LIST:
***************
*** 5390,5395 ****
--- 5397,5406 ----
return FAIL;
}
#endif
+ else if (rettv->v_type == VAR_SPECIAL)
+ {
+ return FAIL;
+ }
init_tv(&var1);
init_tv(&var2);
***************
*** 5999,6005 ****
* Allocate an empty list for a return value.
* Returns OK or FAIL.
*/
! static int
rettv_list_alloc(rettv)
typval_T *rettv;
{
--- 6010,6016 ----
* Allocate an empty list for a return value.
* Returns OK or FAIL.
*/
! int
rettv_list_alloc(rettv)
typval_T *rettv;
{
***************
*** 6246,6251 ****
--- 6257,6265 ----
s1 = get_tv_string_buf(tv1, buf1);
s2 = get_tv_string_buf(tv2, buf2);
return ((ic ? MB_STRICMP(s1, s2) : STRCMP(s1, s2)) == 0);
+
+ case VAR_SPECIAL:
+ return tv1->vval.v_number == tv2->vval.v_number;
}
EMSG2(_(e_intern2), "tv_equal()");
***************
*** 6838,6843 ****
--- 6852,6868 ----
}
/*
+ * Return the next (unique) copy ID.
+ * Used for serializing nested structures.
+ */
+ int
+ get_copyID()
+ {
+ current_copyID += COPYID_INC;
+ return current_copyID;
+ }
+
+ /*
* Garbage collection for lists and dictionaries.
*
* We use reference counts to be able to free most items right away when they
***************
*** 6883,6890 ****
/* We advance by two because we add one for items referenced through
* previous_funccal. */
! current_copyID += COPYID_INC;
! copyID = current_copyID;
/*
* 1. Go through all accessible variables and mark all lists and dicts
--- 6908,6914 ----
/* We advance by two because we add one for items referenced through
* previous_funccal. */
! copyID = get_copyID();
/*
* 1. Go through all accessible variables and mark all lists and dicts
***************
*** 7236,7242 ****
* Allocate an empty dict for a return value.
* Returns OK or FAIL.
*/
! static int
rettv_dict_alloc(rettv)
typval_T *rettv;
{
--- 7260,7266 ----
* Allocate an empty dict for a return value.
* Returns OK or FAIL.
*/
! int
rettv_dict_alloc(rettv)
typval_T *rettv;
{
***************
*** 7891,7896 ****
--- 7915,7932 ----
break;
#endif
+ case VAR_SPECIAL:
+ *tofree = NULL;
+ switch (tv->vval.v_number)
+ {
+ case VVAL_FALSE: r = (char_u *)"false"; break;
+ case VVAL_TRUE: r = (char_u *)"true"; break;
+ case VVAL_NONE: r = (char_u *)"none"; break;
+ case VVAL_NULL: r = (char_u *)"null"; break;
+ default: EMSG2(_(e_intern2), "echo_string(special)");
+ }
+ break;
+
default:
EMSG2(_(e_intern2), "echo_string()");
*tofree = NULL;
***************
*** 7932,7937 ****
--- 7968,7974 ----
case VAR_NUMBER:
case VAR_LIST:
case VAR_DICT:
+ case VAR_SPECIAL:
break;
default:
EMSG2(_(e_intern2), "tv2string()");
***************
*** 7985,7998 ****
return s;
}
! #ifdef FEAT_FLOAT
/*
* Convert the string "text" to a floating point number.
* This uses strtod(). setlocale(LC_NUMERIC, "C") has been used to make sure
* this always uses a decimal point.
* Returns the length of the text that was consumed.
*/
! static int
string2float(text, value)
char_u *text;
float_T *value; /* result stored here */
--- 8022,8035 ----
return s;
}
! #if defined(FEAT_FLOAT) || defined(PROTO)
/*
* Convert the string "text" to a floating point number.
* This uses strtod(). setlocale(LC_NUMERIC, "C") has been used to make sure
* this always uses a decimal point.
* Returns the length of the text that was consumed.
*/
! int
string2float(text, value)
char_u *text;
float_T *value; /* result stored here */
***************
*** 8237,8242 ****
--- 8274,8281 ----
{"islocked", 1, 1, f_islocked},
{"items", 1, 1, f_items},
{"join", 1, 2, f_join},
+ {"jsondecode", 1, 1, f_jsondecode},
+ {"jsonencode", 1, 1, f_jsonencode},
{"keys", 1, 1, f_keys},
{"last_buffer_nr", 0, 0, f_last_buffer_nr},/* obsolete */
{"len", 1, 1, f_len},
***************
*** 14394,14399 ****
--- 14433,14466 ----
}
/*
+ * "jsondecode()" function
+ */
+ static void
+ f_jsondecode(argvars, rettv)
+ typval_T *argvars;
+ typval_T *rettv;
+ {
+ js_read_T reader;
+
+ reader.js_buf = get_tv_string(&argvars[0]);
+ reader.js_eof = TRUE;
+ reader.js_used = 0;
+ json_decode(&reader, rettv);
+ }
+
+ /*
+ * "jsonencode()" function
+ */
+ static void
+ f_jsonencode(argvars, rettv)
+ typval_T *argvars;
+ typval_T *rettv;
+ {
+ rettv->v_type = VAR_STRING;
+ rettv->vval.v_string = json_encode(&argvars[0]);
+ }
+
+ /*
* "keys()" function
*/
static void
***************
*** 21558,21563 ****
--- 21625,21631 ----
varp->vval.v_dict = NULL;
break;
case VAR_NUMBER:
+ case VAR_SPECIAL:
varp->vval.v_number = 0;
break;
#ifdef FEAT_FLOAT
***************
*** 21759,21765 ****
return get_tv_string_buf_chk(varp, mybuf);
}
! static char_u *
get_tv_string_buf_chk(varp, buf)
typval_T *varp;
char_u *buf;
--- 21827,21833 ----
return get_tv_string_buf_chk(varp, mybuf);
}
! char_u *
get_tv_string_buf_chk(varp, buf)
typval_T *varp;
char_u *buf;
***************
*** 22120,22127 ****
char_u *s;
char_u numbuf[NUMBUFLEN];
! current_copyID += COPYID_INC;
! s = echo_string(&v->di_tv, &tofree, numbuf, current_copyID);
list_one_var_a(prefix, v->di_key, v->di_tv.v_type,
s == NULL ? (char_u *)"" : s, first);
vim_free(tofree);
--- 22188,22194 ----
char_u *s;
char_u numbuf[NUMBUFLEN];
! s = echo_string(&v->di_tv, &tofree, numbuf, get_copyID());
list_one_var_a(prefix, v->di_key, v->di_tv.v_type,
s == NULL ? (char_u *)"" : s, first);
vim_free(tofree);
***************
*** 22435,22440 ****
--- 22502,22508 ----
switch (from->v_type)
{
case VAR_NUMBER:
+ case VAR_SPECIAL:
to->vval.v_number = from->vval.v_number;
break;
#ifdef FEAT_FLOAT
***************
*** 22609,22616 ****
}
else if (eap->cmdidx == CMD_echo)
msg_puts_attr((char_u *)" ", echo_attr);
! current_copyID += COPYID_INC;
! p = echo_string(&rettv, &tofree, numbuf, current_copyID);
if (p != NULL)
for ( ; *p != NUL && !got_int; ++p)
{
--- 22677,22683 ----
}
else if (eap->cmdidx == CMD_echo)
msg_puts_attr((char_u *)" ", echo_attr);
! p = echo_string(&rettv, &tofree, numbuf, get_copyID());
if (p != NULL)
for ( ; *p != NUL && !got_int; ++p)
{
*** ../vim-7.4.1153/src/proto.h 2014-08-10 13:34:59.060785459 +0200
--- src/proto.h 2016-01-22 20:33:01.384289200 +0100
***************
*** 95,100 ****
--- 95,101 ----
# endif
# include "hardcopy.pro"
# include "hashtab.pro"
+ # include "json.pro"
# include "main.pro"
# include "mark.pro"
# include "memfile.pro"
*** ../vim-7.4.1153/src/structs.h 2016-01-19 22:28:54.611593027 +0100
--- src/structs.h 2016-01-23 18:48:44.534435105 +0100
***************
*** 1138,1143 ****
--- 1138,1144 ----
#define VAR_LIST 4 /* "v_list" is used */
#define VAR_DICT 5 /* "v_dict" is used */
#define VAR_FLOAT 6 /* "v_float" is used */
+ #define VAR_SPECIAL 7 /* "v_number" is used */
/* Values for "dv_scope". */
#define VAR_SCOPE 1 /* a:, v:, s:, etc. scope dictionaries */
***************
*** 2682,2684 ****
--- 2683,2697 ----
UINT32_T state[8];
char_u buffer[64];
} context_sha256_T;
+
+ /*
+ * Structure used for reading in json_decode().
+ */
+ typedef struct
+ {
+ char_u *js_buf; /* text to be decoded */
+ char_u *js_end; /* NUL in js_buf when js_eof is FALSE */
+ int js_used; /* bytes used from js_buf */
+ int js_eof; /* when TRUE js_buf is all there is */
+ FILE *js_fd; /* file descriptor to read more from */
+ } js_read_T;
*** ../vim-7.4.1153/src/vim.h 2016-01-20 22:47:57.665335718 +0100
--- src/vim.h 2016-01-23 19:38:58.939190501 +0100
***************
*** 1896,1902 ****
#define VV_OPTION_OLD 60
#define VV_OPTION_TYPE 61
#define VV_ERRORS 62
! #define VV_LEN 63 /* number of v: vars */
#ifdef FEAT_CLIPBOARD
--- 1896,1912 ----
#define VV_OPTION_OLD 60
#define VV_OPTION_TYPE 61
#define VV_ERRORS 62
! #define VV_FALSE 63
! #define VV_TRUE 64
! #define VV_NULL 65
! #define VV_NONE 66
! #define VV_LEN 67 /* number of v: vars */
!
! /* used for v_number in VAR_SPECIAL */
! #define VVAL_FALSE 0L
! #define VVAL_TRUE 1L
! #define VVAL_NONE 2L
! #define VVAL_NULL 3L
#ifdef FEAT_CLIPBOARD
*** ../vim-7.4.1153/src/if_lua.c 2016-01-09 14:57:10.504884946 +0100
--- src/if_lua.c 2016-01-23 15:16:47.542331948 +0100
***************
*** 499,504 ****
--- 499,510 ----
case VAR_DICT:
luaV_pushdict(L, tv->vval.v_dict);
break;
+ case VAR_SPECIAL:
+ if (tv->vval.v_number <= VVAL_TRUE)
+ lua_pushinteger(L, (int) tv->vval.v_number);
+ else
+ lua_pushnil(L);
+ break;
default:
lua_pushnil(L);
}
***************
*** 510,516 ****
{
switch(lua_type(L, pos)) {
case LUA_TBOOLEAN:
! tv->v_type = VAR_NUMBER;
tv->vval.v_number = (varnumber_T) lua_toboolean(L, pos);
break;
case LUA_TSTRING:
--- 516,522 ----
{
switch(lua_type(L, pos)) {
case LUA_TBOOLEAN:
! tv->v_type = VAR_SPECIAL;
tv->vval.v_number = (varnumber_T) lua_toboolean(L, pos);
break;
case LUA_TSTRING:
*** ../vim-7.4.1153/src/if_mzsch.c 2016-01-16 16:20:23.712823243 +0100
--- src/if_mzsch.c 2016-01-23 15:19:22.464702083 +0100
***************
*** 3084,3089 ****
--- 3084,3097 ----
MZ_GC_UNREG();
}
+ else if (vim_value->v_type == VAR_SPECIAL)
+ {
+ if (vim_value->vval.v_number <= VVAL_TRUE)
+ result = scheme_make_integer((long)vim_value->vval.v_number);
+ else
+ result = scheme_null;
+ MZ_GC_CHECK();
+ }
else
{
result = scheme_void;
***************
*** 3148,3155 ****
copy_tv(found, tv);
else if (SCHEME_VOIDP(obj))
{
! tv->v_type = VAR_NUMBER;
! tv->vval.v_number = 0;
}
else if (SCHEME_INTP(obj))
{
--- 3156,3163 ----
copy_tv(found, tv);
else if (SCHEME_VOIDP(obj))
{
! tv->v_type = VAR_SPECIAL;
! tv->vval.v_number = VVAL_NULL;
}
else if (SCHEME_INTP(obj))
{
***************
*** 3158,3164 ****
}
else if (SCHEME_BOOLP(obj))
{
! tv->v_type = VAR_NUMBER;
tv->vval.v_number = SCHEME_TRUEP(obj);
}
# ifdef FEAT_FLOAT
--- 3166,3172 ----
}
else if (SCHEME_BOOLP(obj))
{
! tv->v_type = VAR_SPECIAL;
tv->vval.v_number = SCHEME_TRUEP(obj);
}
# ifdef FEAT_FLOAT
*** ../vim-7.4.1153/src/if_ruby.c 2016-01-19 13:21:55.829334463 +0100
--- src/if_ruby.c 2016-01-23 15:22:03.583007468 +0100
***************
*** 1032,1037 ****
--- 1032,1042 ----
}
}
}
+ }
+ else if (tv->v_type == VAR_SPECIAL)
+ {
+ if (tv->vval.v_number <= VVAL_TRUE)
+ result = INT2NUM(tv->vval.v_number);
} /* else return Qnil; */
return result;
*** ../vim-7.4.1153/src/if_py_both.h 2016-01-17 22:36:56.017417164 +0100
--- src/if_py_both.h 2016-01-23 15:26:35.948143016 +0100
***************
*** 810,815 ****
--- 810,834 ----
}
}
}
+ else if (our_tv->v_type == VAR_SPECIAL)
+ {
+ if (our_tv->vval.v_number == VVAL_FALSE)
+ {
+ ret = Py_False;
+ Py_INCREF(ret);
+ }
+ else if (our_tv->vval.v_number == VVAL_TRUE)
+ {
+ ret = Py_True;
+ Py_INCREF(ret);
+ }
+ else
+ {
+ Py_INCREF(Py_None);
+ ret = Py_None;
+ }
+ return ret;
+ }
else
{
Py_INCREF(Py_None);
*** ../vim-7.4.1153/src/globals.h 2016-01-20 22:47:57.657335800 +0100
--- src/globals.h 2016-01-23 19:04:37.064586103 +0100
***************
*** 1523,1528 ****
--- 1523,1529 ----
#ifdef FEAT_EVAL
EXTERN char_u e_readonlyvar[] INIT(= N_("E46: Cannot change read-only
variable \"%s\""));
EXTERN char_u e_readonlysbx[] INIT(= N_("E794: Cannot set variable in the
sandbox: \"%s\""));
+ EXTERN char_u e_emptykey[] INIT(= N_("E713: Cannot use empty key for
Dictionary"));
#endif
#ifdef FEAT_QUICKFIX
EXTERN char_u e_readerrf[] INIT(= N_("E47: Error while reading
errorfile"));
*** ../vim-7.4.1153/src/Makefile 2016-01-19 13:21:55.829334463 +0100
--- src/Makefile 2016-01-23 19:40:15.862390712 +0100
***************
*** 1487,1492 ****
--- 1487,1493 ----
hashtab.c \
if_cscope.c \
if_xcmdsrv.c \
+ json.c \
main.c \
mark.c \
memfile.c \
***************
*** 1580,1585 ****
--- 1581,1587 ----
$(HANGULIN_OBJ) \
objects/if_cscope.o \
objects/if_xcmdsrv.o \
+ objects/json.o \
objects/mark.o \
objects/memline.o \
objects/menu.o \
***************
*** 1654,1659 ****
--- 1656,1662 ----
if_python.pro \
if_python3.pro \
if_ruby.pro \
+ json.pro \
main.pro \
mark.pro \
memfile.pro \
***************
*** 1986,1991 ****
--- 1989,1996 ----
test_expand \
test_hardcopy \
test_increment \
+ test_json \
+ test_langmap \
test_lispwords \
test_menu \
test_perl \
***************
*** 1993,1998 ****
--- 1998,2004 ----
test_searchpos \
test_set \
test_sort \
+ test_syntax \
test_undolevels \
test_unlet \
test_viminfo \
***************
*** 2770,2775 ****
--- 2776,2784 ----
objects/integration.o: integration.c
$(CCC) -o $@ integration.c
+ objects/json.o: json.c
+ $(CCC) -o $@ json.c
+
objects/main.o: main.c
$(CCC) -o $@ main.c
***************
*** 3060,3065 ****
--- 3069,3078 ----
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
globals.h farsi.h arabic.h version.h
+ objects/json.o: json.c vim.h auto/config.h feature.h os_unix.h auto/osdef.h \
+ ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
+ gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
+ arabic.h
objects/main.o: main.c vim.h auto/config.h feature.h os_unix.h auto/osdef.h \
ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
***************
*** 3114,3120 ****
objects/os_unix.o: os_unix.c vim.h auto/config.h feature.h os_unix.h
auto/osdef.h \
ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
! arabic.h if_mzsch.h os_unixx.h
objects/pathdef.o: auto/pathdef.c vim.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
--- 3127,3133 ----
objects/os_unix.o: os_unix.c vim.h auto/config.h feature.h os_unix.h
auto/osdef.h \
ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
! arabic.h os_unixx.h
objects/pathdef.o: auto/pathdef.c vim.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
***************
*** 3179,3185 ****
objects/gui_gtk.o: gui_gtk.c gui_gtk_f.h vim.h auto/config.h feature.h
os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
! globals.h farsi.h arabic.h ../pixmaps/stock_icons.h
objects/gui_gtk_f.o: gui_gtk_f.c vim.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
--- 3192,3198 ----
objects/gui_gtk.o: gui_gtk.c gui_gtk_f.h vim.h auto/config.h feature.h
os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
! globals.h farsi.h arabic.h
objects/gui_gtk_f.o: gui_gtk_f.c vim.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
***************
*** 3245,3252 ****
objects/gui_gtk_x11.o: gui_gtk_x11.c vim.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
! globals.h farsi.h arabic.h gui_gtk_f.h ../runtime/vim32x32.xpm \
! ../runtime/vim16x16.xpm ../runtime/vim48x48.xpm $(GRESOURCE_HDR)
objects/gui_x11.o: gui_x11.c vim.h auto/config.h feature.h os_unix.h
auto/osdef.h \
ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
--- 3258,3265 ----
objects/gui_gtk_x11.o: gui_gtk_x11.c vim.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
! globals.h farsi.h arabic.h auto/gui_gtk_gresources.h gui_gtk_f.h \
! ../runtime/vim32x32.xpm ../runtime/vim16x16.xpm ../runtime/vim48x48.xpm
objects/gui_x11.o: gui_x11.c vim.h auto/config.h feature.h os_unix.h
auto/osdef.h \
ascii.h keymap.h term.h macros.h option.h structs.h regexp.h gui.h \
gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h globals.h farsi.h \
***************
*** 3278,3284 ****
objects/if_mzsch.o: if_mzsch.c vim.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
! globals.h farsi.h arabic.h if_mzsch.h mzscheme_base.c
objects/if_perl.o: auto/if_perl.c vim.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
--- 3291,3297 ----
objects/if_mzsch.o: if_mzsch.c vim.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
! globals.h farsi.h arabic.h if_mzsch.h
objects/if_perl.o: auto/if_perl.c vim.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h proto.h \
*** ../vim-7.4.1153/src/Make_bc3.mak 2016-01-01 17:56:13.405342815 +0100
--- src/Make_bc3.mak 2016-01-22 20:33:39.219891292 +0100
***************
*** 72,77 ****
--- 72,78 ----
getchar.obj \
hardcopy.obj \
hashtab.obj \
+ json.obj \
main.obj \
mark.obj \
memfile.obj \
*** ../vim-7.4.1153/src/Make_bc5.mak 2016-01-01 17:56:13.405342815 +0100
--- src/Make_bc5.mak 2016-01-22 20:34:07.235596694 +0100
***************
*** 598,603 ****
--- 598,604 ----
$(OBJDIR)\getchar.obj \
$(OBJDIR)\hardcopy.obj \
$(OBJDIR)\hashtab.obj \
+ $(OBJDIR)\json.obj \
$(OBJDIR)\main.obj \
$(OBJDIR)\mark.obj \
$(OBJDIR)\memfile.obj \
*** ../vim-7.4.1153/src/Make_cyg_ming.mak 2016-01-21 20:24:30.524467216
+0100
--- src/Make_cyg_ming.mak 2016-01-22 20:34:34.503309989 +0100
***************
*** 601,606 ****
--- 601,607 ----
$(OUTDIR)/getchar.o \
$(OUTDIR)/hardcopy.o \
$(OUTDIR)/hashtab.o \
+ $(OUTDIR)/json.o \
$(OUTDIR)/main.o \
$(OUTDIR)/mark.o \
$(OUTDIR)/memfile.o \
*** ../vim-7.4.1153/src/Make_dice.mak 2014-08-10 16:31:47.372709213 +0200
--- src/Make_dice.mak 2016-01-22 20:35:26.646761816 +0100
***************
*** 45,50 ****
--- 45,51 ----
getchar.c \
hardcopy.c \
hashtab.c \
+ json.c \
main.c \
mark.c \
memfile.c \
***************
*** 93,98 ****
--- 94,100 ----
o/getchar.o \
o/hardcopy.o \
o/hashtab.o \
+ o/json.o \
o/main.o \
o/mark.o \
o/memfile.o \
***************
*** 179,184 ****
--- 181,188 ----
o/hashtab.o: hashtab.c $(SYMS)
+ o/json.o: json.c $(SYMS)
+
o/main.o: main.c $(SYMS)
o/mark.o: mark.c $(SYMS)
*** ../vim-7.4.1153/src/Make_ivc.mak 2014-08-10 16:31:47.372709213 +0200
--- src/Make_ivc.mak 2016-01-22 20:36:27.882118188 +0100
***************
*** 229,234 ****
--- 229,235 ----
"$(INTDIR)/getchar.obj" \
"$(INTDIR)/hardcopy.obj" \
"$(INTDIR)/hashtab.obj" \
+ "$(INTDIR)/json.obj" \
"$(INTDIR)/main.obj" \
"$(INTDIR)/mark.obj" \
"$(INTDIR)/mbyte.obj" \
***************
*** 555,560 ****
--- 556,565 ----
# End Source File
# Begin Source File
+ SOURCE=.\json.c
+ # End Source File
+ # Begin Source File
+
SOURCE=.\main.c
# End Source File
# Begin Source File
*** ../vim-7.4.1153/src/Make_manx.mak 2016-01-01 17:56:13.405342815 +0100
--- src/Make_manx.mak 2016-01-22 20:37:07.693699816 +0100
***************
*** 55,60 ****
--- 55,61 ----
getchar.c \
hardcopy.c \
hashtab.c \
+ json.c \
main.c \
mark.c \
memfile.c \
***************
*** 105,110 ****
--- 106,112 ----
obj/getchar.o \
obj/hardcopy.o \
obj/hashtab.o \
+ obj/json.o \
obj/main.o \
obj/mark.o \
obj/memfile.o \
***************
*** 153,158 ****
--- 155,161 ----
proto/getchar.pro \
proto/hardcopy.pro \
proto/hashtab.pro \
+ proto/json.pro \
proto/main.pro \
proto/mark.pro \
proto/memfile.pro \
***************
*** 284,289 ****
--- 287,295 ----
obj/hashtab.o: hashtab.c
$(CCSYM) $@ hashtab.c
+ obj/json.o: json.c
+ $(CCSYM) $@ json.c
+
# Don't use $(SYMS) here, because main.c defines EXTERN
obj/main.o: main.c option.h globals.h
$(CCNOSYM) $@ main.c
*** ../vim-7.4.1153/src/Make_morph.mak 2014-08-10 16:31:47.376709213 +0200
--- src/Make_morph.mak 2016-01-22 20:37:36.097401362 +0100
***************
*** 43,48 ****
--- 43,49 ----
getchar.c \
hardcopy.c \
hashtab.c \
+ json.c \
main.c \
mark.c \
mbyte.c \
*** ../vim-7.4.1153/src/Make_mvc.mak 2016-01-21 20:24:30.524467216 +0100
--- src/Make_mvc.mak 2016-01-22 20:38:21.608923214 +0100
***************
*** 536,541 ****
--- 536,542 ----
$(OUTDIR)\getchar.obj \
$(OUTDIR)\hardcopy.obj \
$(OUTDIR)\hashtab.obj \
+ $(OUTDIR)\json.obj \
$(OUTDIR)\main.obj \
$(OUTDIR)\mark.obj \
$(OUTDIR)\mbyte.obj \
***************
*** 1202,1207 ****
--- 1203,1210 ----
$(OUTDIR)/if_tcl.obj: $(OUTDIR) if_tcl.c $(INCL)
$(CC) $(CFLAGS) $(TCL_INC) if_tcl.c
+ $(OUTDIR)/json.obj: $(OUTDIR) json.c $(INCL)
+
$(OUTDIR)/main.obj: $(OUTDIR) main.c $(INCL)
$(OUTDIR)/mark.obj: $(OUTDIR) mark.c $(INCL)
***************
*** 1329,1334 ****
--- 1332,1338 ----
proto/getchar.pro \
proto/hardcopy.pro \
proto/hashtab.pro \
+ proto/json.pro \
proto/main.pro \
proto/mark.pro \
proto/memfile.pro \
*** ../vim-7.4.1153/src/Make_sas.mak 2014-08-10 16:31:47.376709213 +0200
--- src/Make_sas.mak 2016-01-22 20:39:00.324516517 +0100
***************
*** 108,113 ****
--- 108,114 ----
getchar.c \
hardcopy.c \
hashtab.c \
+ json.c \
main.c \
mark.c \
memfile.c \
***************
*** 157,162 ****
--- 158,164 ----
getchar.o \
hardcopy.o \
hashtab.o \
+ json.o \
main.o \
mark.o \
memfile.o \
***************
*** 206,211 ****
--- 208,214 ----
proto/getchar.pro \
proto/hardcopy.pro \
proto/hashtab.pro \
+ proto/json.pro \
proto/main.pro \
proto/mark.pro \
proto/memfile.pro \
***************
*** 328,333 ****
--- 331,338 ----
proto/hardcopy.pro: hardcopy.c
hashtab.o: hashtab.c
proto/hashtab.pro: hashtab.c
+ json.o: json.c
+ proto/json.pro: json.c
main.o: main.c
proto/main.pro: main.c
mark.o: mark.c
*** ../vim-7.4.1153/src/Make_vms.mms 2014-12-17 14:36:10.367090935 +0100
--- src/Make_vms.mms 2016-01-22 20:40:07.259813515 +0100
***************
*** 2,8 ****
# Makefile for Vim on OpenVMS
#
# Maintainer: Zoltan Arpadffy <[email protected]>
! # Last change: 2014 Aug 10
#
# This has script been tested on VMS 6.2 to 8.2 on DEC Alpha, VAX and IA64
# with MMS and MMK
--- 2,8 ----
# Makefile for Vim on OpenVMS
#
# Maintainer: Zoltan Arpadffy <[email protected]>
! # Last change: 2016 Jan 22
#
# This has script been tested on VMS 6.2 to 8.2 on DEC Alpha, VAX and IA64
# with MMS and MMK
***************
*** 311,317 ****
SRC = blowfish.c buffer.c charset.c crypt.c, crypt_zip.c diff.c digraph.c
edit.c eval.c ex_cmds.c ex_cmds2.c \
ex_docmd.c ex_eval.c ex_getln.c if_xcmdsrv.c fileio.c fold.c getchar.c \
! hardcopy.c hashtab.c main.c mark.c menu.c mbyte.c memfile.c memline.c
message.c misc1.c \
misc2.c move.c normal.c ops.c option.c popupmnu.c quickfix.c regexp.c
search.c sha256.c\
spell.c syntax.c tag.c term.c termlib.c ui.c undo.c version.c screen.c \
window.c os_unix.c os_vms.c pathdef.c \
--- 311,317 ----
SRC = blowfish.c buffer.c charset.c crypt.c, crypt_zip.c diff.c digraph.c
edit.c eval.c ex_cmds.c ex_cmds2.c \
ex_docmd.c ex_eval.c ex_getln.c if_xcmdsrv.c fileio.c fold.c getchar.c \
! hardcopy.c hashtab.c json.c main.c mark.c menu.c mbyte.c memfile.c
memline.c message.c misc1.c \
misc2.c move.c normal.c ops.c option.c popupmnu.c quickfix.c regexp.c
search.c sha256.c\
spell.c syntax.c tag.c term.c termlib.c ui.c undo.c version.c screen.c \
window.c os_unix.c os_vms.c pathdef.c \
***************
*** 320,326 ****
OBJ = blowfish.obj buffer.obj charset.obj crypt.obj, crypt_zip.obj diff.obj
digraph.obj edit.obj eval.obj \
ex_cmds.obj ex_cmds2.obj ex_docmd.obj ex_eval.obj ex_getln.obj \
! if_xcmdsrv.obj fileio.obj fold.obj getchar.obj hardcopy.obj hashtab.obj
main.obj mark.obj \
menu.obj memfile.obj memline.obj message.obj misc1.obj misc2.obj \
move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj
quickfix.obj \
regexp.obj search.obj sha256.obj spell.obj syntax.obj tag.obj term.obj
termlib.obj \
--- 320,326 ----
OBJ = blowfish.obj buffer.obj charset.obj crypt.obj, crypt_zip.obj diff.obj
digraph.obj edit.obj eval.obj \
ex_cmds.obj ex_cmds2.obj ex_docmd.obj ex_eval.obj ex_getln.obj \
! if_xcmdsrv.obj fileio.obj fold.obj getchar.obj hardcopy.obj hashtab.obj
json.obj main.obj mark.obj \
menu.obj memfile.obj memline.obj message.obj misc1.obj misc2.obj \
move.obj mbyte.obj normal.obj ops.obj option.obj popupmnu.obj
quickfix.obj \
regexp.obj search.obj sha256.obj spell.obj syntax.obj tag.obj term.obj
termlib.obj \
***************
*** 572,577 ****
--- 572,581 ----
ascii.h keymap.h term.h macros.h option.h structs.h \
regexp.h gui.h gui_beval.h [.proto]gui_beval.pro ex_cmds.h proto.h \
globals.h farsi.h arabic.h if_mzsch.h
+ json.obj : json.c vim.h [.auto]config.h feature.h os_unix.h \
+ ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h gui_beval.h \
+ [.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h farsi.h \
+ arabic.h version.h
main.obj : main.c vim.h [.auto]config.h feature.h os_unix.h \
ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h gui_beval.h \
[.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h farsi.h \
*** ../vim-7.4.1153/src/proto/json.pro 2016-01-23 19:32:31.439222465 +0100
--- src/proto/json.pro 2016-01-23 18:11:31.185430495 +0100
***************
*** 0 ****
--- 1,5 ----
+ /* json.c */
+ char_u *json_encode(typval_T *val);
+ void json_encode_item(garray_T *gap, typval_T *val, int copyID);
+ void json_decode(js_read_T *reader, typval_T *res);
+ /* vim: set ft=c : */
*** ../vim-7.4.1153/src/proto/eval.pro 2016-01-19 13:21:55.833334420 +0100
--- src/proto/eval.pro 2016-01-23 19:42:51.788769620 +0100
***************
*** 46,51 ****
--- 46,52 ----
void del_menutrans_vars(void);
char_u *get_user_var_name(expand_T *xp, int idx);
list_T *list_alloc(void);
+ int rettv_list_alloc(typval_T *rettv);
void list_unref(list_T *l);
void list_free(list_T *l, int recurse);
listitem_T *listitem_alloc(void);
***************
*** 61,71 ****
--- 62,74 ----
int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item);
void list_insert(list_T *l, listitem_T *ni, listitem_T *item);
void vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2);
+ int get_copyID(void);
int garbage_collect(void);
int set_ref_in_ht(hashtab_T *ht, int copyID, list_stack_T **list_stack);
int set_ref_in_list(list_T *l, int copyID, ht_stack_T **ht_stack);
int set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack,
list_stack_T **list_stack);
dict_T *dict_alloc(void);
+ int rettv_dict_alloc(typval_T *rettv);
void dict_unref(dict_T *d);
void dict_free(dict_T *d, int recurse);
dictitem_T *dictitem_alloc(char_u *key);
***************
*** 76,81 ****
--- 79,85 ----
dictitem_T *dict_find(dict_T *d, char_u *key, int len);
char_u *get_dict_string(dict_T *d, char_u *key, int save);
long get_dict_number(dict_T *d, char_u *key);
+ int string2float(char_u *text, float_T *value);
char_u *get_function_name(expand_T *xp, int idx);
char_u *get_expr_name(expand_T *xp, int idx);
int func_call(char_u *name, typval_T *args, dict_T *selfdict, typval_T
*rettv);
***************
*** 100,105 ****
--- 104,110 ----
void clear_tv(typval_T *varp);
long get_tv_number_chk(typval_T *varp, int *denote);
char_u *get_tv_string_chk(typval_T *varp);
+ char_u *get_tv_string_buf_chk(typval_T *varp, char_u *buf);
char_u *get_var_value(char_u *name);
void new_script_vars(scid_T id);
void init_var_dict(dict_T *dict, dictitem_T *dict_var, int scope);
*** ../vim-7.4.1153/src/testdir/test_json.vim 2016-01-23 19:32:31.447222383
+0100
--- src/testdir/test_json.vim 2016-01-23 19:24:46.212065256 +0100
***************
*** 0 ****
--- 1,91 ----
+ " Test for JSON functions.
+
+ let s:json1 = '"str\"in\\g"'
+ let s:var1 = "str\"in\\g"
+ let s:json2 = '"\u0001\u0002\u0003\u0004\u0005\u0006\u0007"'
+ let s:var2 = "\x01\x02\x03\x04\x05\x06\x07"
+ let s:json3 = '"\b\t\n\u000b\f\r\u000e\u000f"'
+ let s:var3 = "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ let s:json4 = '"\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017"'
+ let s:var4 = "\x10\x11\x12\x13\x14\x15\x16\x17"
+ let s:json5 = '"\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f"'
+ let s:var5 = "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+
+ let s:jsonmb = '"s¢cĴgё"'
+ let s:varmb = "s¢cĴgё"
+ let s:jsonnr = '1234'
+ let s:varnr = 1234
+ let s:jsonfl = '12.34'
+ let s:varfl = 12.34
+
+ let s:jsonl1 = '[1,"a",3]'
+ let s:varl1 = [1, "a", 3]
+ let s:jsonl2 = '[1,["a",[],"c"],3]'
+ let s:jsonl2s = " [\r1 , [ \"a\" , [ ] , \"c\" ] , 3\<Tab>]\r\n"
+ let s:varl2 = [1, 2, 3]
+ let l2 = ['a', s:varl2, 'c']
+ let s:varl2[1] = l2
+ let s:varl2x = [1, ["a", [], "c"], 3]
+
+ let s:jsond1 = '{"a":1,"b":"bee","c":[1,2]}'
+ let s:vard1 = {"a": 1, "b": "bee","c": [1,2]}
+ let s:jsond2 = '{"1":1,"2":{"a":"aa","b":{},"c":"cc"},"3":3}'
+ let s:jsond2s = " { \"1\" : 1 , \"2\" :\n{ \"a\"\r: \"aa\" , \"b\" :
{\<Tab>} , \"c\" : \"cc\" } , \"3\" : 3 }\r\n"
+ let s:vard2 = {"1": 1, "2": 2, "3": 3}
+ let d2 = {"a": "aa", "b": s:vard2, "c": "cc"}
+ let s:vard2["2"] = d2
+ let s:vard2x = {"1": 1, "2": {"a": "aa", "b": {}, "c": "cc"}, "3": 3}
+
+ let s:jsonvals = '[true,false,,null]'
+ let s:varvals = [v:true, v:false, v:none, v:null]
+
+ func Test_encode()
+ call assert_equal(s:json1, jsonencode(s:var1))
+ call assert_equal(s:json2, jsonencode(s:var2))
+ call assert_equal(s:json3, jsonencode(s:var3))
+ call assert_equal(s:json4, jsonencode(s:var4))
+ call assert_equal(s:json5, jsonencode(s:var5))
+
+ if has('multi_byte')
+ call assert_equal(s:jsonmb, jsonencode(s:varmb))
+ endif
+
+ call assert_equal(s:jsonnr, jsonencode(s:varnr))
+ if has('float')
+ call assert_equal(s:jsonfl, jsonencode(s:varfl))
+ endif
+
+ call assert_equal(s:jsonl1, jsonencode(s:varl1))
+ call assert_equal(s:jsonl2, jsonencode(s:varl2))
+
+ call assert_equal(s:jsond1, jsonencode(s:vard1))
+ call assert_equal(s:jsond2, jsonencode(s:vard2))
+
+ call assert_equal(s:jsonvals, jsonencode(s:varvals))
+ endfunc
+
+ func Test_decode()
+ call assert_equal(s:var1, jsondecode(s:json1))
+ call assert_equal(s:var2, jsondecode(s:json2))
+ call assert_equal(s:var3, jsondecode(s:json3))
+ call assert_equal(s:var4, jsondecode(s:json4))
+ call assert_equal(s:var5, jsondecode(s:json5))
+
+ if has('multi_byte')
+ call assert_equal(s:varmb, jsondecode(s:jsonmb))
+ endif
+
+ call assert_equal(s:varnr, jsondecode(s:jsonnr))
+ if has('float')
+ call assert_equal(s:varfl, jsondecode(s:jsonfl))
+ endif
+
+ call assert_equal(s:varl1, jsondecode(s:jsonl1))
+ call assert_equal(s:varl2x, jsondecode(s:jsonl2))
+ call assert_equal(s:varl2x, jsondecode(s:jsonl2s))
+
+ call assert_equal(s:vard1, jsondecode(s:jsond1))
+ call assert_equal(s:vard2x, jsondecode(s:jsond2))
+
+ call assert_equal(s:varvals, jsondecode(s:jsonvals))
+ endfunc
*** ../vim-7.4.1153/src/testdir/test_alot.vim 2016-01-16 21:50:32.582161520
+0100
--- src/testdir/test_alot.vim 2016-01-22 20:46:04.516063988 +0100
***************
*** 5,10 ****
--- 5,11 ----
source test_cursor_func.vim
source test_delete.vim
source test_expand.vim
+ source test_json.vim
source test_lispwords.vim
source test_menu.vim
source test_searchpos.vim
*** ../vim-7.4.1153/Filelist 2016-01-16 15:45:09.999436846 +0100
--- Filelist 2016-01-22 20:40:57.799282821 +0100
***************
*** 40,45 ****
--- 40,46 ----
src/hardcopy.c \
src/hashtab.c \
src/keymap.h \
+ src/json.c \
src/macros.h \
src/main.c \
src/mark.c \
***************
*** 132,137 ****
--- 133,139 ----
src/proto/gui_beval.pro \
src/proto/hardcopy.pro \
src/proto/hashtab.pro \
+ src/proto/json.pro \
src/proto/main.pro \
src/proto/mark.pro \
src/proto/mbyte.pro \
*** ../vim-7.4.1153/runtime/doc/eval.txt 2016-01-21 23:32:14.154035915
+0100
--- runtime/doc/eval.txt 2016-01-23 14:05:58.107086430 +0100
***************
*** 1399,1404 ****
--- 1409,1418 ----
:endtry
< Output: "caught oops".
+ *v:false* *false-variable*
+ v:false A Number with value zero. Used to put "false" in JSON.
See
+ |jsonencode()|.
+
*v:fcs_reason* *fcs_reason-variable*
v:fcs_reason The reason why the |FileChangedShell| event was triggered.
Can be used in an autocommand to decide what to do and/or what
***************
*** 1530,1535 ****
--- 1546,1559 ----
This is the screen column number, like with |virtcol()|. The
value is zero when there was no mouse button click.
+ *v:none* *none-variable*
+ v:none An empty String. Used to put an empty item in JSON. See
+ |jsonencode()|.
+
+ *v:null* *null-variable*
+ v:null An empty String. Used to put "null" in JSON. See
+ |jsonencode()|.
+
*v:oldfiles* *oldfiles-variable*
v:oldfiles List of file names that is loaded from the |viminfo| file on
startup. These are the files that Vim remembers marks for.
***************
*** 1695,1700 ****
--- 1719,1728 ----
:endtry
< Output: "Exception from test.vim, line 2"
+ *v:true* *true-variable*
+ v:true A Number with value one. Used to put "true" in JSON.
See
+ |jsonencode()|.
+
*v:val* *val-variable*
v:val Value of the current item of a |List| or |Dictionary|. Only
valid while evaluating the expression used with |map()| and
***************
*** 1901,1906 ****
--- 1929,1936 ----
islocked( {expr}) Number TRUE if {expr} is locked
items( {dict}) List key-value pairs in {dict}
join( {list} [, {sep}]) String join {list} items into one
String
+ jsondecode( {string}) any decode JSON
+ jsonencode( {expr}) String encode JSON
keys( {dict}) List keys in {dict}
len( {expr}) Number the length of {expr}
libcall( {lib}, {func}, {arg}) String call {func} in library {lib}
with {arg}
***************
*** 4145,4150 ****
--- 4233,4259 ----
converted into a string like with |string()|.
The opposite function is |split()|.
+ jsondecode({string}) *jsondecode()*
+ TODO
+
+ jsonencode({expr}) *jsonencode()*
+ Encodode {expr} as JSON and return this as a string.
+ The encoding is specified in:
+ http://www.ietf.org/rfc/rfc4627.txt
+ Vim values are converted as follows:
+ Number decimal number
+ Float floating point number
+ String in double quotes (possibly null)
+ Funcref nothing
+ List as an array (possibly null); when
+ used recursively: []
+ Dict as an object (possibly null); when
+ used recursively: {}
+ v:false "false"
+ v:true "true"
+ v:none nothing
+ v:null "null"
+
keys({dict}) *keys()*
Return a |List| with all the keys of {dict}. The |List| is in
arbitrary order.
*** ../vim-7.4.1153/src/version.c 2016-01-22 22:44:06.377407641 +0100
--- src/version.c 2016-01-23 19:25:13.427781898 +0100
***************
*** 743,744 ****
--- 743,746 ----
{ /* Add new patch number below this line */
+ /**/
+ 1154,
/**/
--
How To Keep A Healthy Level Of Insanity:
7. Finish all your sentences with "in accordance with the prophecy".
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.