Mercurial > vim
comparison src/eval.c @ 9560:1e68dfd7931b v7.4.2057
commit https://github.com/vim/vim/commit/da861d631d7e22654faee2789286c685ad548911
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jul 17 15:46:27 2016 +0200
patch 7.4.2057
Problem: eval.c is too big.
Solution: Move List functions to list.c
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Sun, 17 Jul 2016 16:00:05 +0200 |
parents | afaff1d283d3 |
children | 86af4a48c00a |
comparison
equal
deleted
inserted
replaced
9559:354168ab1997 | 9560:1e68dfd7931b |
---|---|
77 dictitem_T *ll_di; /* The dictitem or NULL */ | 77 dictitem_T *ll_di; /* The dictitem or NULL */ |
78 char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */ | 78 char_u *ll_newkey; /* New key for Dict in alloc. mem or NULL. */ |
79 } lval_T; | 79 } lval_T; |
80 | 80 |
81 static char *e_letunexp = N_("E18: Unexpected characters in :let"); | 81 static char *e_letunexp = N_("E18: Unexpected characters in :let"); |
82 static char *e_listidx = N_("E684: list index out of range: %ld"); | |
83 static char *e_undefvar = N_("E121: Undefined variable: %s"); | 82 static char *e_undefvar = N_("E121: Undefined variable: %s"); |
84 static char *e_missbrac = N_("E111: Missing ']'"); | 83 static char *e_missbrac = N_("E111: Missing ']'"); |
85 static char *e_listarg = N_("E686: Argument of %s must be a List"); | 84 static char *e_listarg = N_("E686: Argument of %s must be a List"); |
86 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary"); | 85 static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary"); |
87 static char *e_listreq = N_("E714: List required"); | 86 static char *e_listreq = N_("E714: List required"); |
191 */ | 190 */ |
192 static hashtab_T func_hashtab; | 191 static hashtab_T func_hashtab; |
193 | 192 |
194 /* The names of packages that once were loaded are remembered. */ | 193 /* The names of packages that once were loaded are remembered. */ |
195 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; | 194 static garray_T ga_loaded = {0, 0, sizeof(char_u *), 4, NULL}; |
196 | |
197 /* List heads for garbage collection. Although there can be a reference loop | |
198 * from partial to dict to partial, we don't need to keep track of the partial, | |
199 * since it will get freed when the dict is unused and gets freed. */ | |
200 static list_T *first_list = NULL; /* list of all lists */ | |
201 | 195 |
202 /* From user function to hashitem and back. */ | 196 /* From user function to hashitem and back. */ |
203 static ufunc_T dumuf; | 197 static ufunc_T dumuf; |
204 #define UF2HIKEY(fp) ((fp)->uf_name) | 198 #define UF2HIKEY(fp) ((fp)->uf_name) |
205 #define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf))) | 199 #define HIKEY2UF(p) ((ufunc_T *)(p - (dumuf.uf_name - (char_u *)&dumuf))) |
394 static int check_changedtick(char_u *arg); | 388 static int check_changedtick(char_u *arg); |
395 static char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags); | 389 static char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags); |
396 static void clear_lval(lval_T *lp); | 390 static void clear_lval(lval_T *lp); |
397 static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op); | 391 static void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, char_u *op); |
398 static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op); | 392 static int tv_op(typval_T *tv1, typval_T *tv2, char_u *op); |
399 static void list_fix_watch(list_T *l, listitem_T *item); | |
400 static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep); | 393 static void ex_unletlock(exarg_T *eap, char_u *argstart, int deep); |
401 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit); | 394 static int do_unlet_var(lval_T *lp, char_u *name_end, int forceit); |
402 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock); | 395 static int do_lock_var(lval_T *lp, char_u *name_end, int deep, int lock); |
403 static void item_lock(typval_T *tv, int deep, int lock); | 396 static void item_lock(typval_T *tv, int deep, int lock); |
404 static int tv_islocked(typval_T *tv); | 397 static int tv_islocked(typval_T *tv); |
413 | 406 |
414 static int eval_index(char_u **arg, typval_T *rettv, int evaluate, int verbose); | 407 static int eval_index(char_u **arg, typval_T *rettv, int evaluate, int verbose); |
415 static int get_option_tv(char_u **arg, typval_T *rettv, int evaluate); | 408 static int get_option_tv(char_u **arg, typval_T *rettv, int evaluate); |
416 static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate); | 409 static int get_string_tv(char_u **arg, typval_T *rettv, int evaluate); |
417 static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate); | 410 static int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate); |
418 static int get_list_tv(char_u **arg, typval_T *rettv, int evaluate); | |
419 static void list_free_contents(list_T *l); | |
420 static void list_free_list(list_T *l); | |
421 static long list_len(list_T *l); | |
422 static int list_equal(list_T *l1, list_T *l2, int ic, int recursive); | |
423 static long list_find_nr(list_T *l, long idx, int *errorp); | |
424 static long list_idx_of_item(list_T *l, listitem_T *item); | |
425 static int list_extend(list_T *l1, list_T *l2, listitem_T *bef); | |
426 static int list_concat(list_T *l1, list_T *l2, typval_T *tv); | |
427 static list_T *list_copy(list_T *orig, int deep, int copyID); | |
428 static char_u *list2string(typval_T *tv, int copyID, int restore_copyID); | |
429 static int list_join_inner(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID, garray_T *join_gap); | |
430 static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID); | |
431 static int free_unref_items(int copyID); | 411 static int free_unref_items(int copyID); |
432 static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, int *varargs, int skip); | 412 static int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, int *varargs, int skip); |
433 static int get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate); | 413 static int get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate); |
434 static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); | 414 static char_u *echo_string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID); |
435 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); | 415 static int get_env_tv(char_u **arg, typval_T *rettv, int evaluate); |
3195 EMSG2(_(e_letwrong), op); | 3175 EMSG2(_(e_letwrong), op); |
3196 return FAIL; | 3176 return FAIL; |
3197 } | 3177 } |
3198 | 3178 |
3199 /* | 3179 /* |
3200 * Add a watcher to a list. | |
3201 */ | |
3202 void | |
3203 list_add_watch(list_T *l, listwatch_T *lw) | |
3204 { | |
3205 lw->lw_next = l->lv_watch; | |
3206 l->lv_watch = lw; | |
3207 } | |
3208 | |
3209 /* | |
3210 * Remove a watcher from a list. | |
3211 * No warning when it isn't found... | |
3212 */ | |
3213 void | |
3214 list_rem_watch(list_T *l, listwatch_T *lwrem) | |
3215 { | |
3216 listwatch_T *lw, **lwp; | |
3217 | |
3218 lwp = &l->lv_watch; | |
3219 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) | |
3220 { | |
3221 if (lw == lwrem) | |
3222 { | |
3223 *lwp = lw->lw_next; | |
3224 break; | |
3225 } | |
3226 lwp = &lw->lw_next; | |
3227 } | |
3228 } | |
3229 | |
3230 /* | |
3231 * Just before removing an item from a list: advance watchers to the next | |
3232 * item. | |
3233 */ | |
3234 static void | |
3235 list_fix_watch(list_T *l, listitem_T *item) | |
3236 { | |
3237 listwatch_T *lw; | |
3238 | |
3239 for (lw = l->lv_watch; lw != NULL; lw = lw->lw_next) | |
3240 if (lw->lw_item == item) | |
3241 lw->lw_item = item->li_next; | |
3242 } | |
3243 | |
3244 /* | |
3245 * Evaluate the expression used in a ":for var in expr" command. | 3180 * Evaluate the expression used in a ":for var in expr" command. |
3246 * "arg" points to "var". | 3181 * "arg" points to "var". |
3247 * Set "*errp" to TRUE for an error, FALSE otherwise; | 3182 * Set "*errp" to TRUE for an error, FALSE otherwise; |
3248 * Return a pointer that holds the info. Null when there is an error. | 3183 * Return a pointer that holds the info. Null when there is an error. |
3249 */ | 3184 */ |
5991 { | 5926 { |
5992 if (pt != NULL && --pt->pt_refcount <= 0) | 5927 if (pt != NULL && --pt->pt_refcount <= 0) |
5993 partial_free(pt); | 5928 partial_free(pt); |
5994 } | 5929 } |
5995 | 5930 |
5996 /* | |
5997 * Allocate a variable for a List and fill it from "*arg". | |
5998 * Return OK or FAIL. | |
5999 */ | |
6000 static int | |
6001 get_list_tv(char_u **arg, typval_T *rettv, int evaluate) | |
6002 { | |
6003 list_T *l = NULL; | |
6004 typval_T tv; | |
6005 listitem_T *item; | |
6006 | |
6007 if (evaluate) | |
6008 { | |
6009 l = list_alloc(); | |
6010 if (l == NULL) | |
6011 return FAIL; | |
6012 } | |
6013 | |
6014 *arg = skipwhite(*arg + 1); | |
6015 while (**arg != ']' && **arg != NUL) | |
6016 { | |
6017 if (eval1(arg, &tv, evaluate) == FAIL) /* recursive! */ | |
6018 goto failret; | |
6019 if (evaluate) | |
6020 { | |
6021 item = listitem_alloc(); | |
6022 if (item != NULL) | |
6023 { | |
6024 item->li_tv = tv; | |
6025 item->li_tv.v_lock = 0; | |
6026 list_append(l, item); | |
6027 } | |
6028 else | |
6029 clear_tv(&tv); | |
6030 } | |
6031 | |
6032 if (**arg == ']') | |
6033 break; | |
6034 if (**arg != ',') | |
6035 { | |
6036 EMSG2(_("E696: Missing comma in List: %s"), *arg); | |
6037 goto failret; | |
6038 } | |
6039 *arg = skipwhite(*arg + 1); | |
6040 } | |
6041 | |
6042 if (**arg != ']') | |
6043 { | |
6044 EMSG2(_("E697: Missing end of List ']': %s"), *arg); | |
6045 failret: | |
6046 if (evaluate) | |
6047 list_free(l); | |
6048 return FAIL; | |
6049 } | |
6050 | |
6051 *arg = skipwhite(*arg + 1); | |
6052 if (evaluate) | |
6053 { | |
6054 rettv->v_type = VAR_LIST; | |
6055 rettv->vval.v_list = l; | |
6056 ++l->lv_refcount; | |
6057 } | |
6058 | |
6059 return OK; | |
6060 } | |
6061 | |
6062 /* | |
6063 * Allocate an empty header for a list. | |
6064 * Caller should take care of the reference count. | |
6065 */ | |
6066 list_T * | |
6067 list_alloc(void) | |
6068 { | |
6069 list_T *l; | |
6070 | |
6071 l = (list_T *)alloc_clear(sizeof(list_T)); | |
6072 if (l != NULL) | |
6073 { | |
6074 /* Prepend the list to the list of lists for garbage collection. */ | |
6075 if (first_list != NULL) | |
6076 first_list->lv_used_prev = l; | |
6077 l->lv_used_prev = NULL; | |
6078 l->lv_used_next = first_list; | |
6079 first_list = l; | |
6080 } | |
6081 return l; | |
6082 } | |
6083 | |
6084 /* | |
6085 * Allocate an empty list for a return value, with reference count set. | |
6086 * Returns OK or FAIL. | |
6087 */ | |
6088 int | |
6089 rettv_list_alloc(typval_T *rettv) | |
6090 { | |
6091 list_T *l = list_alloc(); | |
6092 | |
6093 if (l == NULL) | |
6094 return FAIL; | |
6095 | |
6096 rettv->vval.v_list = l; | |
6097 rettv->v_type = VAR_LIST; | |
6098 rettv->v_lock = 0; | |
6099 ++l->lv_refcount; | |
6100 return OK; | |
6101 } | |
6102 | |
6103 /* | |
6104 * Unreference a list: decrement the reference count and free it when it | |
6105 * becomes zero. | |
6106 */ | |
6107 void | |
6108 list_unref(list_T *l) | |
6109 { | |
6110 if (l != NULL && --l->lv_refcount <= 0) | |
6111 list_free(l); | |
6112 } | |
6113 | |
6114 /* | |
6115 * Free a list, including all non-container items it points to. | |
6116 * Ignores the reference count. | |
6117 */ | |
6118 static void | |
6119 list_free_contents(list_T *l) | |
6120 { | |
6121 listitem_T *item; | |
6122 | |
6123 for (item = l->lv_first; item != NULL; item = l->lv_first) | |
6124 { | |
6125 /* Remove the item before deleting it. */ | |
6126 l->lv_first = item->li_next; | |
6127 clear_tv(&item->li_tv); | |
6128 vim_free(item); | |
6129 } | |
6130 } | |
6131 | |
6132 static void | |
6133 list_free_list(list_T *l) | |
6134 { | |
6135 /* Remove the list from the list of lists for garbage collection. */ | |
6136 if (l->lv_used_prev == NULL) | |
6137 first_list = l->lv_used_next; | |
6138 else | |
6139 l->lv_used_prev->lv_used_next = l->lv_used_next; | |
6140 if (l->lv_used_next != NULL) | |
6141 l->lv_used_next->lv_used_prev = l->lv_used_prev; | |
6142 | |
6143 vim_free(l); | |
6144 } | |
6145 | |
6146 void | |
6147 list_free(list_T *l) | |
6148 { | |
6149 if (!in_free_unref_items) | |
6150 { | |
6151 list_free_contents(l); | |
6152 list_free_list(l); | |
6153 } | |
6154 } | |
6155 | |
6156 /* | |
6157 * Allocate a list item. | |
6158 * It is not initialized, don't forget to set v_lock. | |
6159 */ | |
6160 listitem_T * | |
6161 listitem_alloc(void) | |
6162 { | |
6163 return (listitem_T *)alloc(sizeof(listitem_T)); | |
6164 } | |
6165 | |
6166 /* | |
6167 * Free a list item. Also clears the value. Does not notify watchers. | |
6168 */ | |
6169 void | |
6170 listitem_free(listitem_T *item) | |
6171 { | |
6172 clear_tv(&item->li_tv); | |
6173 vim_free(item); | |
6174 } | |
6175 | |
6176 /* | |
6177 * Remove a list item from a List and free it. Also clears the value. | |
6178 */ | |
6179 void | |
6180 listitem_remove(list_T *l, listitem_T *item) | |
6181 { | |
6182 vimlist_remove(l, item, item); | |
6183 listitem_free(item); | |
6184 } | |
6185 | |
6186 /* | |
6187 * Get the number of items in a list. | |
6188 */ | |
6189 static long | |
6190 list_len(list_T *l) | |
6191 { | |
6192 if (l == NULL) | |
6193 return 0L; | |
6194 return l->lv_len; | |
6195 } | |
6196 | |
6197 /* | |
6198 * Return TRUE when two lists have exactly the same values. | |
6199 */ | |
6200 static int | |
6201 list_equal( | |
6202 list_T *l1, | |
6203 list_T *l2, | |
6204 int ic, /* ignore case for strings */ | |
6205 int recursive) /* TRUE when used recursively */ | |
6206 { | |
6207 listitem_T *item1, *item2; | |
6208 | |
6209 if (l1 == NULL || l2 == NULL) | |
6210 return FALSE; | |
6211 if (l1 == l2) | |
6212 return TRUE; | |
6213 if (list_len(l1) != list_len(l2)) | |
6214 return FALSE; | |
6215 | |
6216 for (item1 = l1->lv_first, item2 = l2->lv_first; | |
6217 item1 != NULL && item2 != NULL; | |
6218 item1 = item1->li_next, item2 = item2->li_next) | |
6219 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic, recursive)) | |
6220 return FALSE; | |
6221 return item1 == NULL && item2 == NULL; | |
6222 } | |
6223 | |
6224 static int tv_equal_recurse_limit; | 5931 static int tv_equal_recurse_limit; |
6225 | 5932 |
6226 static int | 5933 static int |
6227 func_equal( | 5934 func_equal( |
6228 typval_T *tv1, | 5935 typval_T *tv1, |
6366 } | 6073 } |
6367 | 6074 |
6368 /* VAR_UNKNOWN can be the result of a invalid expression, let's say it | 6075 /* VAR_UNKNOWN can be the result of a invalid expression, let's say it |
6369 * does not equal anything, not even itself. */ | 6076 * does not equal anything, not even itself. */ |
6370 return FALSE; | 6077 return FALSE; |
6371 } | |
6372 | |
6373 /* | |
6374 * Locate item with index "n" in list "l" and return it. | |
6375 * A negative index is counted from the end; -1 is the last item. | |
6376 * Returns NULL when "n" is out of range. | |
6377 */ | |
6378 listitem_T * | |
6379 list_find(list_T *l, long n) | |
6380 { | |
6381 listitem_T *item; | |
6382 long idx; | |
6383 | |
6384 if (l == NULL) | |
6385 return NULL; | |
6386 | |
6387 /* Negative index is relative to the end. */ | |
6388 if (n < 0) | |
6389 n = l->lv_len + n; | |
6390 | |
6391 /* Check for index out of range. */ | |
6392 if (n < 0 || n >= l->lv_len) | |
6393 return NULL; | |
6394 | |
6395 /* When there is a cached index may start search from there. */ | |
6396 if (l->lv_idx_item != NULL) | |
6397 { | |
6398 if (n < l->lv_idx / 2) | |
6399 { | |
6400 /* closest to the start of the list */ | |
6401 item = l->lv_first; | |
6402 idx = 0; | |
6403 } | |
6404 else if (n > (l->lv_idx + l->lv_len) / 2) | |
6405 { | |
6406 /* closest to the end of the list */ | |
6407 item = l->lv_last; | |
6408 idx = l->lv_len - 1; | |
6409 } | |
6410 else | |
6411 { | |
6412 /* closest to the cached index */ | |
6413 item = l->lv_idx_item; | |
6414 idx = l->lv_idx; | |
6415 } | |
6416 } | |
6417 else | |
6418 { | |
6419 if (n < l->lv_len / 2) | |
6420 { | |
6421 /* closest to the start of the list */ | |
6422 item = l->lv_first; | |
6423 idx = 0; | |
6424 } | |
6425 else | |
6426 { | |
6427 /* closest to the end of the list */ | |
6428 item = l->lv_last; | |
6429 idx = l->lv_len - 1; | |
6430 } | |
6431 } | |
6432 | |
6433 while (n > idx) | |
6434 { | |
6435 /* search forward */ | |
6436 item = item->li_next; | |
6437 ++idx; | |
6438 } | |
6439 while (n < idx) | |
6440 { | |
6441 /* search backward */ | |
6442 item = item->li_prev; | |
6443 --idx; | |
6444 } | |
6445 | |
6446 /* cache the used index */ | |
6447 l->lv_idx = idx; | |
6448 l->lv_idx_item = item; | |
6449 | |
6450 return item; | |
6451 } | |
6452 | |
6453 /* | |
6454 * Get list item "l[idx]" as a number. | |
6455 */ | |
6456 static long | |
6457 list_find_nr( | |
6458 list_T *l, | |
6459 long idx, | |
6460 int *errorp) /* set to TRUE when something wrong */ | |
6461 { | |
6462 listitem_T *li; | |
6463 | |
6464 li = list_find(l, idx); | |
6465 if (li == NULL) | |
6466 { | |
6467 if (errorp != NULL) | |
6468 *errorp = TRUE; | |
6469 return -1L; | |
6470 } | |
6471 return (long)get_tv_number_chk(&li->li_tv, errorp); | |
6472 } | |
6473 | |
6474 /* | |
6475 * Get list item "l[idx - 1]" as a string. Returns NULL for failure. | |
6476 */ | |
6477 char_u * | |
6478 list_find_str(list_T *l, long idx) | |
6479 { | |
6480 listitem_T *li; | |
6481 | |
6482 li = list_find(l, idx - 1); | |
6483 if (li == NULL) | |
6484 { | |
6485 EMSGN(_(e_listidx), idx); | |
6486 return NULL; | |
6487 } | |
6488 return get_tv_string(&li->li_tv); | |
6489 } | |
6490 | |
6491 /* | |
6492 * Locate "item" list "l" and return its index. | |
6493 * Returns -1 when "item" is not in the list. | |
6494 */ | |
6495 static long | |
6496 list_idx_of_item(list_T *l, listitem_T *item) | |
6497 { | |
6498 long idx = 0; | |
6499 listitem_T *li; | |
6500 | |
6501 if (l == NULL) | |
6502 return -1; | |
6503 idx = 0; | |
6504 for (li = l->lv_first; li != NULL && li != item; li = li->li_next) | |
6505 ++idx; | |
6506 if (li == NULL) | |
6507 return -1; | |
6508 return idx; | |
6509 } | |
6510 | |
6511 /* | |
6512 * Append item "item" to the end of list "l". | |
6513 */ | |
6514 void | |
6515 list_append(list_T *l, listitem_T *item) | |
6516 { | |
6517 if (l->lv_last == NULL) | |
6518 { | |
6519 /* empty list */ | |
6520 l->lv_first = item; | |
6521 l->lv_last = item; | |
6522 item->li_prev = NULL; | |
6523 } | |
6524 else | |
6525 { | |
6526 l->lv_last->li_next = item; | |
6527 item->li_prev = l->lv_last; | |
6528 l->lv_last = item; | |
6529 } | |
6530 ++l->lv_len; | |
6531 item->li_next = NULL; | |
6532 } | |
6533 | |
6534 /* | |
6535 * Append typval_T "tv" to the end of list "l". | |
6536 * Return FAIL when out of memory. | |
6537 */ | |
6538 int | |
6539 list_append_tv(list_T *l, typval_T *tv) | |
6540 { | |
6541 listitem_T *li = listitem_alloc(); | |
6542 | |
6543 if (li == NULL) | |
6544 return FAIL; | |
6545 copy_tv(tv, &li->li_tv); | |
6546 list_append(l, li); | |
6547 return OK; | |
6548 } | |
6549 | |
6550 /* | |
6551 * Add a dictionary to a list. Used by getqflist(). | |
6552 * Return FAIL when out of memory. | |
6553 */ | |
6554 int | |
6555 list_append_dict(list_T *list, dict_T *dict) | |
6556 { | |
6557 listitem_T *li = listitem_alloc(); | |
6558 | |
6559 if (li == NULL) | |
6560 return FAIL; | |
6561 li->li_tv.v_type = VAR_DICT; | |
6562 li->li_tv.v_lock = 0; | |
6563 li->li_tv.vval.v_dict = dict; | |
6564 list_append(list, li); | |
6565 ++dict->dv_refcount; | |
6566 return OK; | |
6567 } | |
6568 | |
6569 /* | |
6570 * Make a copy of "str" and append it as an item to list "l". | |
6571 * When "len" >= 0 use "str[len]". | |
6572 * Returns FAIL when out of memory. | |
6573 */ | |
6574 int | |
6575 list_append_string(list_T *l, char_u *str, int len) | |
6576 { | |
6577 listitem_T *li = listitem_alloc(); | |
6578 | |
6579 if (li == NULL) | |
6580 return FAIL; | |
6581 list_append(l, li); | |
6582 li->li_tv.v_type = VAR_STRING; | |
6583 li->li_tv.v_lock = 0; | |
6584 if (str == NULL) | |
6585 li->li_tv.vval.v_string = NULL; | |
6586 else if ((li->li_tv.vval.v_string = (len >= 0 ? vim_strnsave(str, len) | |
6587 : vim_strsave(str))) == NULL) | |
6588 return FAIL; | |
6589 return OK; | |
6590 } | |
6591 | |
6592 /* | |
6593 * Append "n" to list "l". | |
6594 * Returns FAIL when out of memory. | |
6595 */ | |
6596 int | |
6597 list_append_number(list_T *l, varnumber_T n) | |
6598 { | |
6599 listitem_T *li; | |
6600 | |
6601 li = listitem_alloc(); | |
6602 if (li == NULL) | |
6603 return FAIL; | |
6604 li->li_tv.v_type = VAR_NUMBER; | |
6605 li->li_tv.v_lock = 0; | |
6606 li->li_tv.vval.v_number = n; | |
6607 list_append(l, li); | |
6608 return OK; | |
6609 } | |
6610 | |
6611 /* | |
6612 * Insert typval_T "tv" in list "l" before "item". | |
6613 * If "item" is NULL append at the end. | |
6614 * Return FAIL when out of memory. | |
6615 */ | |
6616 int | |
6617 list_insert_tv(list_T *l, typval_T *tv, listitem_T *item) | |
6618 { | |
6619 listitem_T *ni = listitem_alloc(); | |
6620 | |
6621 if (ni == NULL) | |
6622 return FAIL; | |
6623 copy_tv(tv, &ni->li_tv); | |
6624 list_insert(l, ni, item); | |
6625 return OK; | |
6626 } | |
6627 | |
6628 void | |
6629 list_insert(list_T *l, listitem_T *ni, listitem_T *item) | |
6630 { | |
6631 if (item == NULL) | |
6632 /* Append new item at end of list. */ | |
6633 list_append(l, ni); | |
6634 else | |
6635 { | |
6636 /* Insert new item before existing item. */ | |
6637 ni->li_prev = item->li_prev; | |
6638 ni->li_next = item; | |
6639 if (item->li_prev == NULL) | |
6640 { | |
6641 l->lv_first = ni; | |
6642 ++l->lv_idx; | |
6643 } | |
6644 else | |
6645 { | |
6646 item->li_prev->li_next = ni; | |
6647 l->lv_idx_item = NULL; | |
6648 } | |
6649 item->li_prev = ni; | |
6650 ++l->lv_len; | |
6651 } | |
6652 } | |
6653 | |
6654 /* | |
6655 * Extend "l1" with "l2". | |
6656 * If "bef" is NULL append at the end, otherwise insert before this item. | |
6657 * Returns FAIL when out of memory. | |
6658 */ | |
6659 static int | |
6660 list_extend(list_T *l1, list_T *l2, listitem_T *bef) | |
6661 { | |
6662 listitem_T *item; | |
6663 int todo = l2->lv_len; | |
6664 | |
6665 /* We also quit the loop when we have inserted the original item count of | |
6666 * the list, avoid a hang when we extend a list with itself. */ | |
6667 for (item = l2->lv_first; item != NULL && --todo >= 0; item = item->li_next) | |
6668 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) | |
6669 return FAIL; | |
6670 return OK; | |
6671 } | |
6672 | |
6673 /* | |
6674 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". | |
6675 * Return FAIL when out of memory. | |
6676 */ | |
6677 static int | |
6678 list_concat(list_T *l1, list_T *l2, typval_T *tv) | |
6679 { | |
6680 list_T *l; | |
6681 | |
6682 if (l1 == NULL || l2 == NULL) | |
6683 return FAIL; | |
6684 | |
6685 /* make a copy of the first list. */ | |
6686 l = list_copy(l1, FALSE, 0); | |
6687 if (l == NULL) | |
6688 return FAIL; | |
6689 tv->v_type = VAR_LIST; | |
6690 tv->vval.v_list = l; | |
6691 | |
6692 /* append all items from the second list */ | |
6693 return list_extend(l, l2, NULL); | |
6694 } | |
6695 | |
6696 /* | |
6697 * Make a copy of list "orig". Shallow if "deep" is FALSE. | |
6698 * The refcount of the new list is set to 1. | |
6699 * See item_copy() for "copyID". | |
6700 * Returns NULL when out of memory. | |
6701 */ | |
6702 static list_T * | |
6703 list_copy(list_T *orig, int deep, int copyID) | |
6704 { | |
6705 list_T *copy; | |
6706 listitem_T *item; | |
6707 listitem_T *ni; | |
6708 | |
6709 if (orig == NULL) | |
6710 return NULL; | |
6711 | |
6712 copy = list_alloc(); | |
6713 if (copy != NULL) | |
6714 { | |
6715 if (copyID != 0) | |
6716 { | |
6717 /* Do this before adding the items, because one of the items may | |
6718 * refer back to this list. */ | |
6719 orig->lv_copyID = copyID; | |
6720 orig->lv_copylist = copy; | |
6721 } | |
6722 for (item = orig->lv_first; item != NULL && !got_int; | |
6723 item = item->li_next) | |
6724 { | |
6725 ni = listitem_alloc(); | |
6726 if (ni == NULL) | |
6727 break; | |
6728 if (deep) | |
6729 { | |
6730 if (item_copy(&item->li_tv, &ni->li_tv, deep, copyID) == FAIL) | |
6731 { | |
6732 vim_free(ni); | |
6733 break; | |
6734 } | |
6735 } | |
6736 else | |
6737 copy_tv(&item->li_tv, &ni->li_tv); | |
6738 list_append(copy, ni); | |
6739 } | |
6740 ++copy->lv_refcount; | |
6741 if (item != NULL) | |
6742 { | |
6743 list_unref(copy); | |
6744 copy = NULL; | |
6745 } | |
6746 } | |
6747 | |
6748 return copy; | |
6749 } | |
6750 | |
6751 /* | |
6752 * Remove items "item" to "item2" from list "l". | |
6753 * Does not free the listitem or the value! | |
6754 * This used to be called list_remove, but that conflicts with a Sun header | |
6755 * file. | |
6756 */ | |
6757 void | |
6758 vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2) | |
6759 { | |
6760 listitem_T *ip; | |
6761 | |
6762 /* notify watchers */ | |
6763 for (ip = item; ip != NULL; ip = ip->li_next) | |
6764 { | |
6765 --l->lv_len; | |
6766 list_fix_watch(l, ip); | |
6767 if (ip == item2) | |
6768 break; | |
6769 } | |
6770 | |
6771 if (item2->li_next == NULL) | |
6772 l->lv_last = item->li_prev; | |
6773 else | |
6774 item2->li_next->li_prev = item->li_prev; | |
6775 if (item->li_prev == NULL) | |
6776 l->lv_first = item2->li_next; | |
6777 else | |
6778 item->li_prev->li_next = item2->li_next; | |
6779 l->lv_idx_item = NULL; | |
6780 } | |
6781 | |
6782 /* | |
6783 * Return an allocated string with the string representation of a list. | |
6784 * May return NULL. | |
6785 */ | |
6786 static char_u * | |
6787 list2string(typval_T *tv, int copyID, int restore_copyID) | |
6788 { | |
6789 garray_T ga; | |
6790 | |
6791 if (tv->vval.v_list == NULL) | |
6792 return NULL; | |
6793 ga_init2(&ga, (int)sizeof(char), 80); | |
6794 ga_append(&ga, '['); | |
6795 if (list_join(&ga, tv->vval.v_list, (char_u *)", ", | |
6796 FALSE, restore_copyID, copyID) == FAIL) | |
6797 { | |
6798 vim_free(ga.ga_data); | |
6799 return NULL; | |
6800 } | |
6801 ga_append(&ga, ']'); | |
6802 ga_append(&ga, NUL); | |
6803 return (char_u *)ga.ga_data; | |
6804 } | |
6805 | |
6806 typedef struct join_S { | |
6807 char_u *s; | |
6808 char_u *tofree; | |
6809 } join_T; | |
6810 | |
6811 static int | |
6812 list_join_inner( | |
6813 garray_T *gap, /* to store the result in */ | |
6814 list_T *l, | |
6815 char_u *sep, | |
6816 int echo_style, | |
6817 int restore_copyID, | |
6818 int copyID, | |
6819 garray_T *join_gap) /* to keep each list item string */ | |
6820 { | |
6821 int i; | |
6822 join_T *p; | |
6823 int len; | |
6824 int sumlen = 0; | |
6825 int first = TRUE; | |
6826 char_u *tofree; | |
6827 char_u numbuf[NUMBUFLEN]; | |
6828 listitem_T *item; | |
6829 char_u *s; | |
6830 | |
6831 /* Stringify each item in the list. */ | |
6832 for (item = l->lv_first; item != NULL && !got_int; item = item->li_next) | |
6833 { | |
6834 s = echo_string_core(&item->li_tv, &tofree, numbuf, copyID, | |
6835 echo_style, restore_copyID, FALSE); | |
6836 if (s == NULL) | |
6837 return FAIL; | |
6838 | |
6839 len = (int)STRLEN(s); | |
6840 sumlen += len; | |
6841 | |
6842 (void)ga_grow(join_gap, 1); | |
6843 p = ((join_T *)join_gap->ga_data) + (join_gap->ga_len++); | |
6844 if (tofree != NULL || s != numbuf) | |
6845 { | |
6846 p->s = s; | |
6847 p->tofree = tofree; | |
6848 } | |
6849 else | |
6850 { | |
6851 p->s = vim_strnsave(s, len); | |
6852 p->tofree = p->s; | |
6853 } | |
6854 | |
6855 line_breakcheck(); | |
6856 if (did_echo_string_emsg) /* recursion error, bail out */ | |
6857 break; | |
6858 } | |
6859 | |
6860 /* Allocate result buffer with its total size, avoid re-allocation and | |
6861 * multiple copy operations. Add 2 for a tailing ']' and NUL. */ | |
6862 if (join_gap->ga_len >= 2) | |
6863 sumlen += (int)STRLEN(sep) * (join_gap->ga_len - 1); | |
6864 if (ga_grow(gap, sumlen + 2) == FAIL) | |
6865 return FAIL; | |
6866 | |
6867 for (i = 0; i < join_gap->ga_len && !got_int; ++i) | |
6868 { | |
6869 if (first) | |
6870 first = FALSE; | |
6871 else | |
6872 ga_concat(gap, sep); | |
6873 p = ((join_T *)join_gap->ga_data) + i; | |
6874 | |
6875 if (p->s != NULL) | |
6876 ga_concat(gap, p->s); | |
6877 line_breakcheck(); | |
6878 } | |
6879 | |
6880 return OK; | |
6881 } | |
6882 | |
6883 /* | |
6884 * Join list "l" into a string in "*gap", using separator "sep". | |
6885 * When "echo_style" is TRUE use String as echoed, otherwise as inside a List. | |
6886 * Return FAIL or OK. | |
6887 */ | |
6888 static int | |
6889 list_join( | |
6890 garray_T *gap, | |
6891 list_T *l, | |
6892 char_u *sep, | |
6893 int echo_style, | |
6894 int restore_copyID, | |
6895 int copyID) | |
6896 { | |
6897 garray_T join_ga; | |
6898 int retval; | |
6899 join_T *p; | |
6900 int i; | |
6901 | |
6902 if (l->lv_len < 1) | |
6903 return OK; /* nothing to do */ | |
6904 ga_init2(&join_ga, (int)sizeof(join_T), l->lv_len); | |
6905 retval = list_join_inner(gap, l, sep, echo_style, restore_copyID, | |
6906 copyID, &join_ga); | |
6907 | |
6908 /* Dispose each item in join_ga. */ | |
6909 if (join_ga.ga_data != NULL) | |
6910 { | |
6911 p = (join_T *)join_ga.ga_data; | |
6912 for (i = 0; i < join_ga.ga_len; ++i) | |
6913 { | |
6914 vim_free(p->tofree); | |
6915 ++p; | |
6916 } | |
6917 ga_clear(&join_ga); | |
6918 } | |
6919 | |
6920 return retval; | |
6921 } | 6078 } |
6922 | 6079 |
6923 /* | 6080 /* |
6924 * Return the next (unique) copy ID. | 6081 * Return the next (unique) copy ID. |
6925 * Used for serializing nested structures. | 6082 * Used for serializing nested structures. |
7110 * Free lists, dictionaries, channels and jobs that are no longer referenced. | 6267 * Free lists, dictionaries, channels and jobs that are no longer referenced. |
7111 */ | 6268 */ |
7112 static int | 6269 static int |
7113 free_unref_items(int copyID) | 6270 free_unref_items(int copyID) |
7114 { | 6271 { |
7115 list_T *ll, *ll_next; | |
7116 int did_free = FALSE; | 6272 int did_free = FALSE; |
7117 | 6273 |
7118 /* Let all "free" functions know that we are here. This means no | 6274 /* Let all "free" functions know that we are here. This means no |
7119 * dictionaries, lists, channels or jobs are to be freed, because we will | 6275 * dictionaries, lists, channels or jobs are to be freed, because we will |
7120 * do that here. */ | 6276 * do that here. */ |
7126 */ | 6282 */ |
7127 | 6283 |
7128 /* Go through the list of dicts and free items without the copyID. */ | 6284 /* Go through the list of dicts and free items without the copyID. */ |
7129 did_free |= dict_free_nonref(copyID); | 6285 did_free |= dict_free_nonref(copyID); |
7130 | 6286 |
7131 /* | 6287 /* Go through the list of lists and free items without the copyID. */ |
7132 * Go through the list of lists and free items without the copyID. | 6288 did_free |= list_free_nonref(copyID); |
7133 * But don't free a list that has a watcher (used in a for loop), these | |
7134 * are not referenced anywhere. | |
7135 */ | |
7136 for (ll = first_list; ll != NULL; ll = ll->lv_used_next) | |
7137 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) | |
7138 && ll->lv_watch == NULL) | |
7139 { | |
7140 /* Free the List and ordinary items it contains, but don't recurse | |
7141 * into Lists and Dictionaries, they will be in the list of dicts | |
7142 * or list of lists. */ | |
7143 list_free_contents(ll); | |
7144 did_free = TRUE; | |
7145 } | |
7146 | 6289 |
7147 #ifdef FEAT_JOB_CHANNEL | 6290 #ifdef FEAT_JOB_CHANNEL |
7148 /* Go through the list of jobs and free items without the copyID. This | 6291 /* Go through the list of jobs and free items without the copyID. This |
7149 * must happen before doing channels, because jobs refer to channels, but | 6292 * must happen before doing channels, because jobs refer to channels, but |
7150 * the reference from the channel to the job isn't tracked. */ | 6293 * the reference from the channel to the job isn't tracked. */ |
7156 | 6299 |
7157 /* | 6300 /* |
7158 * PASS 2: free the items themselves. | 6301 * PASS 2: free the items themselves. |
7159 */ | 6302 */ |
7160 dict_free_items(copyID); | 6303 dict_free_items(copyID); |
7161 | 6304 list_free_items(copyID); |
7162 for (ll = first_list; ll != NULL; ll = ll_next) | |
7163 { | |
7164 ll_next = ll->lv_used_next; | |
7165 if ((ll->lv_copyID & COPYID_MASK) != (copyID & COPYID_MASK) | |
7166 && ll->lv_watch == NULL) | |
7167 { | |
7168 /* Free the List and ordinary items it contains, but don't recurse | |
7169 * into Lists and Dictionaries, they will be in the list of dicts | |
7170 * or list of lists. */ | |
7171 list_free_list(ll); | |
7172 } | |
7173 } | |
7174 | 6305 |
7175 #ifdef FEAT_JOB_CHANNEL | 6306 #ifdef FEAT_JOB_CHANNEL |
7176 /* Go through the list of jobs and free items without the copyID. This | 6307 /* Go through the list of jobs and free items without the copyID. This |
7177 * must happen before doing channels, because jobs refer to channels, but | 6308 * must happen before doing channels, because jobs refer to channels, but |
7178 * the reference from the channel to the job isn't tracked. */ | 6309 * the reference from the channel to the job isn't tracked. */ |