Mercurial > vim
comparison src/eval.c @ 80:d2796c60ca6f v7.0032
updated for version 7.0032
author | vimboss |
---|---|
date | Thu, 06 Jan 2005 23:28:25 +0000 |
parents | 0ef9cebc4f5d |
children | d9030055c432 |
comparison
equal
deleted
inserted
replaced
79:e918d3e340a4 | 80:d2796c60ca6f |
---|---|
318 static void list_unref __ARGS((listvar *l)); | 318 static void list_unref __ARGS((listvar *l)); |
319 static void list_free __ARGS((listvar *l)); | 319 static void list_free __ARGS((listvar *l)); |
320 static listitem *listitem_alloc __ARGS((void)); | 320 static listitem *listitem_alloc __ARGS((void)); |
321 static void listitem_free __ARGS((listitem *item)); | 321 static void listitem_free __ARGS((listitem *item)); |
322 static long list_len __ARGS((listvar *l)); | 322 static long list_len __ARGS((listvar *l)); |
323 static int list_equal __ARGS((listvar *l1, listvar *l2, int ic)); | |
324 static int tv_equal __ARGS((typeval *tv1, typeval *tv2, int ic)); | |
323 static listitem *list_find __ARGS((listvar *l, long n)); | 325 static listitem *list_find __ARGS((listvar *l, long n)); |
326 static listitem *list_find_ext __ARGS((listvar *l, long *ip)); | |
324 static void list_append __ARGS((listvar *l, listitem *item)); | 327 static void list_append __ARGS((listvar *l, listitem *item)); |
325 static int list_append_tv __ARGS((listvar *l, typeval *tv)); | 328 static int list_append_tv __ARGS((listvar *l, typeval *tv)); |
329 static int list_insert_tv __ARGS((listvar *l, typeval *tv, listitem *item)); | |
330 static int list_extend __ARGS((listvar *l1, listvar *l2, listitem *bef)); | |
331 static int list_concat __ARGS((listvar *l1, listvar *l2, typeval *tv)); | |
326 static listvar *list_copy __ARGS((listvar *orig, int deep)); | 332 static listvar *list_copy __ARGS((listvar *orig, int deep)); |
327 static listitem *list_getrem __ARGS((listvar *l, long n)); | 333 static void list_getrem __ARGS((listvar *l, listitem *item, listitem *item2)); |
328 static char_u *list2string __ARGS((typeval *tv)); | 334 static char_u *list2string __ARGS((typeval *tv)); |
329 static char_u *tv2string __ARGS((typeval *tv, char_u **tofree)); | 335 static char_u *tv2string __ARGS((typeval *tv, char_u **tofree, char_u *numbuf)); |
330 static int get_env_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); | 336 static int get_env_tv __ARGS((char_u **arg, typeval *rettv, int evaluate)); |
331 static int find_internal_func __ARGS((char_u *name)); | 337 static int find_internal_func __ARGS((char_u *name)); |
332 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); | 338 static char_u *deref_func_name __ARGS((char_u *name, int *lenp)); |
333 static int get_func_tv __ARGS((char_u *name, int len, typeval *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate)); | 339 static int get_func_tv __ARGS((char_u *name, int len, typeval *rettv, char_u **arg, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate)); |
334 static int call_func __ARGS((char_u *name, int len, typeval *rettv, int argcount, typeval *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate)); | 340 static int call_func __ARGS((char_u *name, int len, typeval *rettv, int argcount, typeval *argvars, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate)); |
346 static void f_bufname __ARGS((typeval *argvars, typeval *rettv)); | 352 static void f_bufname __ARGS((typeval *argvars, typeval *rettv)); |
347 static void f_bufnr __ARGS((typeval *argvars, typeval *rettv)); | 353 static void f_bufnr __ARGS((typeval *argvars, typeval *rettv)); |
348 static void f_bufwinnr __ARGS((typeval *argvars, typeval *rettv)); | 354 static void f_bufwinnr __ARGS((typeval *argvars, typeval *rettv)); |
349 static void f_byte2line __ARGS((typeval *argvars, typeval *rettv)); | 355 static void f_byte2line __ARGS((typeval *argvars, typeval *rettv)); |
350 static void f_byteidx __ARGS((typeval *argvars, typeval *rettv)); | 356 static void f_byteidx __ARGS((typeval *argvars, typeval *rettv)); |
357 static void f_call __ARGS((typeval *argvars, typeval *rettv)); | |
351 static void f_char2nr __ARGS((typeval *argvars, typeval *rettv)); | 358 static void f_char2nr __ARGS((typeval *argvars, typeval *rettv)); |
352 static void f_cindent __ARGS((typeval *argvars, typeval *rettv)); | 359 static void f_cindent __ARGS((typeval *argvars, typeval *rettv)); |
353 static void f_col __ARGS((typeval *argvars, typeval *rettv)); | 360 static void f_col __ARGS((typeval *argvars, typeval *rettv)); |
354 static void f_confirm __ARGS((typeval *argvars, typeval *rettv)); | 361 static void f_confirm __ARGS((typeval *argvars, typeval *rettv)); |
355 static void f_copy __ARGS((typeval *argvars, typeval *rettv)); | 362 static void f_copy __ARGS((typeval *argvars, typeval *rettv)); |
363 static void f_count __ARGS((typeval *argvars, typeval *rettv)); | |
356 static void f_cscope_connection __ARGS((typeval *argvars, typeval *rettv)); | 364 static void f_cscope_connection __ARGS((typeval *argvars, typeval *rettv)); |
357 static void f_cursor __ARGS((typeval *argsvars, typeval *rettv)); | 365 static void f_cursor __ARGS((typeval *argsvars, typeval *rettv)); |
358 static void f_deepcopy __ARGS((typeval *argvars, typeval *rettv)); | 366 static void f_deepcopy __ARGS((typeval *argvars, typeval *rettv)); |
359 static void f_delete __ARGS((typeval *argvars, typeval *rettv)); | 367 static void f_delete __ARGS((typeval *argvars, typeval *rettv)); |
360 static void f_did_filetype __ARGS((typeval *argvars, typeval *rettv)); | 368 static void f_did_filetype __ARGS((typeval *argvars, typeval *rettv)); |
363 static void f_escape __ARGS((typeval *argvars, typeval *rettv)); | 371 static void f_escape __ARGS((typeval *argvars, typeval *rettv)); |
364 static void f_eventhandler __ARGS((typeval *argvars, typeval *rettv)); | 372 static void f_eventhandler __ARGS((typeval *argvars, typeval *rettv)); |
365 static void f_executable __ARGS((typeval *argvars, typeval *rettv)); | 373 static void f_executable __ARGS((typeval *argvars, typeval *rettv)); |
366 static void f_exists __ARGS((typeval *argvars, typeval *rettv)); | 374 static void f_exists __ARGS((typeval *argvars, typeval *rettv)); |
367 static void f_expand __ARGS((typeval *argvars, typeval *rettv)); | 375 static void f_expand __ARGS((typeval *argvars, typeval *rettv)); |
376 static void f_extend __ARGS((typeval *argvars, typeval *rettv)); | |
368 static void f_filereadable __ARGS((typeval *argvars, typeval *rettv)); | 377 static void f_filereadable __ARGS((typeval *argvars, typeval *rettv)); |
369 static void f_filewritable __ARGS((typeval *argvars, typeval *rettv)); | 378 static void f_filewritable __ARGS((typeval *argvars, typeval *rettv)); |
370 static void f_finddir __ARGS((typeval *argvars, typeval *rettv)); | 379 static void f_finddir __ARGS((typeval *argvars, typeval *rettv)); |
371 static void f_findfile __ARGS((typeval *argvars, typeval *rettv)); | 380 static void f_findfile __ARGS((typeval *argvars, typeval *rettv)); |
372 static void f_findfilendir __ARGS((typeval *argvars, typeval *rettv, int dir)); | 381 static void f_findfilendir __ARGS((typeval *argvars, typeval *rettv, int dir)); |
409 static void f_hostname __ARGS((typeval *argvars, typeval *rettv)); | 418 static void f_hostname __ARGS((typeval *argvars, typeval *rettv)); |
410 static void f_iconv __ARGS((typeval *argvars, typeval *rettv)); | 419 static void f_iconv __ARGS((typeval *argvars, typeval *rettv)); |
411 static void f_indent __ARGS((typeval *argvars, typeval *rettv)); | 420 static void f_indent __ARGS((typeval *argvars, typeval *rettv)); |
412 static void f_insert __ARGS((typeval *argvars, typeval *rettv)); | 421 static void f_insert __ARGS((typeval *argvars, typeval *rettv)); |
413 static void f_isdirectory __ARGS((typeval *argvars, typeval *rettv)); | 422 static void f_isdirectory __ARGS((typeval *argvars, typeval *rettv)); |
423 static void f_index __ARGS((typeval *argvars, typeval *rettv)); | |
414 static void f_input __ARGS((typeval *argvars, typeval *rettv)); | 424 static void f_input __ARGS((typeval *argvars, typeval *rettv)); |
415 static void f_inputdialog __ARGS((typeval *argvars, typeval *rettv)); | 425 static void f_inputdialog __ARGS((typeval *argvars, typeval *rettv)); |
416 static void f_inputrestore __ARGS((typeval *argvars, typeval *rettv)); | 426 static void f_inputrestore __ARGS((typeval *argvars, typeval *rettv)); |
417 static void f_inputsave __ARGS((typeval *argvars, typeval *rettv)); | 427 static void f_inputsave __ARGS((typeval *argvars, typeval *rettv)); |
418 static void f_inputsecret __ARGS((typeval *argvars, typeval *rettv)); | 428 static void f_inputsecret __ARGS((typeval *argvars, typeval *rettv)); |
438 static void f_setbufvar __ARGS((typeval *argvars, typeval *rettv)); | 448 static void f_setbufvar __ARGS((typeval *argvars, typeval *rettv)); |
439 static void f_setcmdpos __ARGS((typeval *argvars, typeval *rettv)); | 449 static void f_setcmdpos __ARGS((typeval *argvars, typeval *rettv)); |
440 static void f_setwinvar __ARGS((typeval *argvars, typeval *rettv)); | 450 static void f_setwinvar __ARGS((typeval *argvars, typeval *rettv)); |
441 static void f_remove __ARGS((typeval *argvars, typeval *rettv)); | 451 static void f_remove __ARGS((typeval *argvars, typeval *rettv)); |
442 static void f_rename __ARGS((typeval *argvars, typeval *rettv)); | 452 static void f_rename __ARGS((typeval *argvars, typeval *rettv)); |
453 static void f_repeat __ARGS((typeval *argvars, typeval *rettv)); | |
443 static void f_resolve __ARGS((typeval *argvars, typeval *rettv)); | 454 static void f_resolve __ARGS((typeval *argvars, typeval *rettv)); |
444 static void f_search __ARGS((typeval *argvars, typeval *rettv)); | 455 static void f_search __ARGS((typeval *argvars, typeval *rettv)); |
445 static void f_searchpair __ARGS((typeval *argvars, typeval *rettv)); | 456 static void f_searchpair __ARGS((typeval *argvars, typeval *rettv)); |
446 static int get_search_arg __ARGS((typeval *varp, int *flagsp)); | 457 static int get_search_arg __ARGS((typeval *varp, int *flagsp)); |
447 static void f_remote_expr __ARGS((typeval *argvars, typeval *rettv)); | 458 static void f_remote_expr __ARGS((typeval *argvars, typeval *rettv)); |
448 static void f_remote_foreground __ARGS((typeval *argvars, typeval *rettv)); | 459 static void f_remote_foreground __ARGS((typeval *argvars, typeval *rettv)); |
449 static void f_remote_peek __ARGS((typeval *argvars, typeval *rettv)); | 460 static void f_remote_peek __ARGS((typeval *argvars, typeval *rettv)); |
450 static void f_remote_read __ARGS((typeval *argvars, typeval *rettv)); | 461 static void f_remote_read __ARGS((typeval *argvars, typeval *rettv)); |
451 static void f_remote_send __ARGS((typeval *argvars, typeval *rettv)); | 462 static void f_remote_send __ARGS((typeval *argvars, typeval *rettv)); |
452 static void f_repeat __ARGS((typeval *argvars, typeval *rettv)); | |
453 static void f_server2client __ARGS((typeval *argvars, typeval *rettv)); | 463 static void f_server2client __ARGS((typeval *argvars, typeval *rettv)); |
454 static void f_serverlist __ARGS((typeval *argvars, typeval *rettv)); | 464 static void f_serverlist __ARGS((typeval *argvars, typeval *rettv)); |
455 static void f_setline __ARGS((typeval *argvars, typeval *rettv)); | 465 static void f_setline __ARGS((typeval *argvars, typeval *rettv)); |
456 static void f_setreg __ARGS((typeval *argvars, typeval *rettv)); | 466 static void f_setreg __ARGS((typeval *argvars, typeval *rettv)); |
457 static void f_simplify __ARGS((typeval *argvars, typeval *rettv)); | 467 static void f_simplify __ARGS((typeval *argvars, typeval *rettv)); |
2446 * var1 !~ var2 | 2456 * var1 !~ var2 |
2447 * var1 > var2 | 2457 * var1 > var2 |
2448 * var1 >= var2 | 2458 * var1 >= var2 |
2449 * var1 < var2 | 2459 * var1 < var2 |
2450 * var1 <= var2 | 2460 * var1 <= var2 |
2461 * var1 is var2 | |
2462 * var1 isnot var2 | |
2451 * | 2463 * |
2452 * "arg" must point to the first non-white of the expression. | 2464 * "arg" must point to the first non-white of the expression. |
2453 * "arg" is advanced to the next non-white after the recognized expression. | 2465 * "arg" is advanced to the next non-white after the recognized expression. |
2454 * | 2466 * |
2455 * Return OK or FAIL. | 2467 * Return OK or FAIL. |
2462 { | 2474 { |
2463 typeval var2; | 2475 typeval var2; |
2464 char_u *p; | 2476 char_u *p; |
2465 int i; | 2477 int i; |
2466 exptype_T type = TYPE_UNKNOWN; | 2478 exptype_T type = TYPE_UNKNOWN; |
2479 int type_is = FALSE; /* TRUE for "is" and "isnot" */ | |
2467 int len = 2; | 2480 int len = 2; |
2468 long n1, n2; | 2481 long n1, n2; |
2469 char_u *s1, *s2; | 2482 char_u *s1, *s2; |
2470 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; | 2483 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; |
2471 regmatch_T regmatch; | 2484 regmatch_T regmatch; |
2505 len = 1; | 2518 len = 1; |
2506 } | 2519 } |
2507 else | 2520 else |
2508 type = TYPE_SEQUAL; | 2521 type = TYPE_SEQUAL; |
2509 break; | 2522 break; |
2523 case 'i': if (p[1] == 's') | |
2524 { | |
2525 if (p[2] == 'n' && p[3] == 'o' && p[4] == 't') | |
2526 len = 5; | |
2527 if (!vim_isIDc(p[len])) | |
2528 { | |
2529 type = len == 2 ? TYPE_EQUAL : TYPE_NEQUAL; | |
2530 type_is = TRUE; | |
2531 } | |
2532 } | |
2533 break; | |
2510 } | 2534 } |
2511 | 2535 |
2512 /* | 2536 /* |
2513 * If there is a comparitive operator, use it. | 2537 * If there is a comparitive operator, use it. |
2514 */ | 2538 */ |
2540 return FAIL; | 2564 return FAIL; |
2541 } | 2565 } |
2542 | 2566 |
2543 if (evaluate) | 2567 if (evaluate) |
2544 { | 2568 { |
2569 if (type_is && rettv->v_type != var2.v_type) | |
2570 { | |
2571 /* For "is" a different type always means FALSE, for "notis" | |
2572 * it means TRUE. */ | |
2573 n1 = (type == TYPE_NEQUAL); | |
2574 } | |
2575 else if (rettv->v_type == VAR_LIST || var2.v_type == VAR_LIST) | |
2576 { | |
2577 if (type_is) | |
2578 { | |
2579 n1 = (rettv->v_type == var2.v_type | |
2580 && rettv->vval.v_list == var2.vval.v_list); | |
2581 if (type == TYPE_NEQUAL) | |
2582 n1 = !n1; | |
2583 } | |
2584 else if (rettv->v_type != var2.v_type | |
2585 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) | |
2586 { | |
2587 if (rettv->v_type != var2.v_type) | |
2588 EMSG(_("E999: Can only compare List with List")); | |
2589 else | |
2590 EMSG(_("E999: Invalid operation for Lists")); | |
2591 clear_tv(rettv); | |
2592 clear_tv(&var2); | |
2593 return FAIL; | |
2594 } | |
2595 else | |
2596 { | |
2597 /* Compare two Lists for being equal or unequal. */ | |
2598 n1 = list_equal(rettv->vval.v_list, var2.vval.v_list, ic); | |
2599 if (type == TYPE_NEQUAL) | |
2600 n1 = !n1; | |
2601 } | |
2602 } | |
2603 | |
2604 else if (rettv->v_type == VAR_FUNC || var2.v_type == VAR_FUNC) | |
2605 { | |
2606 if (rettv->v_type != var2.v_type | |
2607 || (type != TYPE_EQUAL && type != TYPE_NEQUAL)) | |
2608 { | |
2609 if (rettv->v_type != var2.v_type) | |
2610 EMSG(_("E999: Can only compare Funcref with Funcref")); | |
2611 else | |
2612 EMSG(_("E999: Invalid operation for Funcrefs")); | |
2613 clear_tv(rettv); | |
2614 clear_tv(&var2); | |
2615 return FAIL; | |
2616 } | |
2617 else | |
2618 { | |
2619 /* Compare two Funcrefs for being equal or unequal. */ | |
2620 if (rettv->vval.v_string == NULL | |
2621 || var2.vval.v_string == NULL) | |
2622 n1 = FALSE; | |
2623 else | |
2624 n1 = STRCMP(rettv->vval.v_string, | |
2625 var2.vval.v_string) == 0; | |
2626 if (type == TYPE_NEQUAL) | |
2627 n1 = !n1; | |
2628 } | |
2629 } | |
2630 | |
2545 /* | 2631 /* |
2546 * If one of the two variables is a number, compare as a number. | 2632 * If one of the two variables is a number, compare as a number. |
2547 * When using "=~" or "!~", always compare as string. | 2633 * When using "=~" or "!~", always compare as string. |
2548 */ | 2634 */ |
2549 if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) | 2635 else if ((rettv->v_type == VAR_NUMBER || var2.v_type == VAR_NUMBER) |
2550 && type != TYPE_MATCH && type != TYPE_NOMATCH) | 2636 && type != TYPE_MATCH && type != TYPE_NOMATCH) |
2551 { | 2637 { |
2552 n1 = get_tv_number(rettv); | 2638 n1 = get_tv_number(rettv); |
2553 n2 = get_tv_number(&var2); | 2639 n2 = get_tv_number(&var2); |
2554 switch (type) | 2640 switch (type) |
2629 char_u **arg; | 2715 char_u **arg; |
2630 typeval *rettv; | 2716 typeval *rettv; |
2631 int evaluate; | 2717 int evaluate; |
2632 { | 2718 { |
2633 typeval var2; | 2719 typeval var2; |
2720 typeval var3; | |
2634 int op; | 2721 int op; |
2635 long n1, n2; | 2722 long n1, n2; |
2636 char_u *s1, *s2; | 2723 char_u *s1, *s2; |
2637 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; | 2724 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; |
2638 char_u *p; | 2725 char_u *p; |
2679 STRCPY(p + op, s2); | 2766 STRCPY(p + op, s2); |
2680 } | 2767 } |
2681 clear_tv(rettv); | 2768 clear_tv(rettv); |
2682 rettv->v_type = VAR_STRING; | 2769 rettv->v_type = VAR_STRING; |
2683 rettv->vval.v_string = p; | 2770 rettv->vval.v_string = p; |
2771 } | |
2772 else if (rettv->v_type == VAR_LIST && var2.v_type == VAR_LIST) | |
2773 { | |
2774 /* concatenate Lists */ | |
2775 if (list_concat(rettv->vval.v_list, var2.vval.v_list, | |
2776 &var3) == FAIL) | |
2777 { | |
2778 clear_tv(rettv); | |
2779 clear_tv(&var2); | |
2780 return FAIL; | |
2781 } | |
2782 clear_tv(rettv); | |
2783 *rettv = var3; | |
2684 } | 2784 } |
2685 else | 2785 else |
2686 { | 2786 { |
2687 n1 = get_tv_number(rettv); | 2787 n1 = get_tv_number(rettv); |
2688 n2 = get_tv_number(&var2); | 2788 n2 = get_tv_number(&var2); |
3587 ++len; | 3687 ++len; |
3588 return len; | 3688 return len; |
3589 } | 3689 } |
3590 | 3690 |
3591 /* | 3691 /* |
3692 * Return TRUE when two lists have exactly the same values. | |
3693 */ | |
3694 static int | |
3695 list_equal(l1, l2, ic) | |
3696 listvar *l1; | |
3697 listvar *l2; | |
3698 int ic; /* ignore case for strings */ | |
3699 { | |
3700 listitem *item1, *item2; | |
3701 | |
3702 for (item1 = l1->lv_first, item2 = l2->lv_first; | |
3703 item1 != NULL && item2 != NULL; | |
3704 item1 = item1->li_next, item2 = item2->li_next) | |
3705 if (!tv_equal(&item1->li_tv, &item2->li_tv, ic)) | |
3706 return FALSE; | |
3707 return item1 == NULL && item2 == NULL; | |
3708 } | |
3709 | |
3710 /* | |
3711 * Return TRUE if "tv1" and "tv2" have the same value. | |
3712 * Compares the items just like "==" would compare them. | |
3713 */ | |
3714 static int | |
3715 tv_equal(tv1, tv2, ic) | |
3716 typeval *tv1; | |
3717 typeval *tv2; | |
3718 int ic; /* ignore case */ | |
3719 { | |
3720 char_u buf1[NUMBUFLEN], buf2[NUMBUFLEN]; | |
3721 | |
3722 if (tv1->v_type == VAR_LIST || tv2->v_type == VAR_LIST) | |
3723 { | |
3724 /* recursive! */ | |
3725 if (tv1->v_type != tv2->v_type | |
3726 || !list_equal(tv1->vval.v_list, tv2->vval.v_list, ic)) | |
3727 return FALSE; | |
3728 } | |
3729 else if (tv1->v_type == VAR_FUNC || tv2->v_type == VAR_FUNC) | |
3730 { | |
3731 if (tv1->v_type != tv2->v_type | |
3732 || tv1->vval.v_string == NULL | |
3733 || tv2->vval.v_string == NULL | |
3734 || STRCMP(tv1->vval.v_string, tv2->vval.v_string) != 0) | |
3735 return FALSE; | |
3736 } | |
3737 else if (tv1->v_type == VAR_NUMBER || tv2->v_type == VAR_NUMBER) | |
3738 { | |
3739 if (get_tv_number(tv1) != get_tv_number(tv2)) | |
3740 return FALSE; | |
3741 } | |
3742 else if (!ic && STRCMP(get_tv_string_buf(tv1, buf1), | |
3743 get_tv_string_buf(tv2, buf2)) != 0) | |
3744 return FALSE; | |
3745 else if (ic && STRICMP(get_tv_string_buf(tv1, buf1), | |
3746 get_tv_string_buf(tv2, buf2)) != 0) | |
3747 return FALSE; | |
3748 return TRUE; | |
3749 } | |
3750 | |
3751 /* | |
3592 * Locate item with index "n" in list "l" and return it. | 3752 * Locate item with index "n" in list "l" and return it. |
3593 * A negative index is counted from the end; -1 is the last item. | 3753 * A negative index is counted from the end; -1 is the last item. |
3594 * Returns NULL when "n" is out of range. | 3754 * Returns NULL when "n" is out of range. |
3595 */ | 3755 */ |
3596 static listitem * | 3756 static listitem * |
3619 return NULL; | 3779 return NULL; |
3620 return item; | 3780 return item; |
3621 } | 3781 } |
3622 | 3782 |
3623 /* | 3783 /* |
3784 * Like list_find(), but also find an item just past the end. | |
3785 * "*ip" is the item to find. | |
3786 * When found "*ip" is set to zero, when not found "*ip" is non-zero. | |
3787 * Returns NULL when item not found or item is just past the end. | |
3788 */ | |
3789 static listitem * | |
3790 list_find_ext(l, ip) | |
3791 listvar *l; | |
3792 long *ip; | |
3793 { | |
3794 long n; | |
3795 listitem *item; | |
3796 | |
3797 if (*ip < 0) | |
3798 { | |
3799 /* Count from the end: -1 is before last item. */ | |
3800 item = l->lv_last; | |
3801 for (n = *ip + 1; n < 0 && item != NULL; ++n) | |
3802 item = item->li_prev; | |
3803 if (item == NULL) | |
3804 n = 1; /* error! */ | |
3805 } | |
3806 else | |
3807 { | |
3808 item = l->lv_first; | |
3809 for (n = *ip; n > 0 && item != NULL; --n) | |
3810 item = item->li_next; | |
3811 } | |
3812 *ip = n; | |
3813 return item; | |
3814 } | |
3815 | |
3816 /* | |
3624 * Append item "item" to the end of list "l". | 3817 * Append item "item" to the end of list "l". |
3625 */ | 3818 */ |
3626 static void | 3819 static void |
3627 list_append(l, item) | 3820 list_append(l, item) |
3628 listvar *l; | 3821 listvar *l; |
3644 item->li_next = NULL; | 3837 item->li_next = NULL; |
3645 } | 3838 } |
3646 | 3839 |
3647 /* | 3840 /* |
3648 * Append typeval "tv" to the end of list "l". | 3841 * Append typeval "tv" to the end of list "l". |
3842 * Return FAIL when out of memory. | |
3649 */ | 3843 */ |
3650 static int | 3844 static int |
3651 list_append_tv(l, tv) | 3845 list_append_tv(l, tv) |
3652 listvar *l; | 3846 listvar *l; |
3653 typeval *tv; | 3847 typeval *tv; |
3657 if (ni == NULL) | 3851 if (ni == NULL) |
3658 return FAIL; | 3852 return FAIL; |
3659 copy_tv(tv, &ni->li_tv); | 3853 copy_tv(tv, &ni->li_tv); |
3660 list_append(l, ni); | 3854 list_append(l, ni); |
3661 return OK; | 3855 return OK; |
3856 } | |
3857 | |
3858 /* | |
3859 * Insert typeval "tv" in list "l" before "item". | |
3860 * If "item" is NULL append at the end. | |
3861 * Return FAIL when out of memory. | |
3862 */ | |
3863 static int | |
3864 list_insert_tv(l, tv, item) | |
3865 listvar *l; | |
3866 typeval *tv; | |
3867 listitem *item; | |
3868 { | |
3869 listitem *ni = listitem_alloc(); | |
3870 | |
3871 if (ni == NULL) | |
3872 return FAIL; | |
3873 copy_tv(tv, &ni->li_tv); | |
3874 if (item == NULL) | |
3875 /* Append new item at end of list. */ | |
3876 list_append(l, ni); | |
3877 else | |
3878 { | |
3879 /* Insert new item before existing item. */ | |
3880 ni->li_prev = item->li_prev; | |
3881 ni->li_next = item; | |
3882 if (item->li_prev == NULL) | |
3883 l->lv_first = ni; | |
3884 else | |
3885 item->li_prev->li_next = ni; | |
3886 item->li_prev = ni; | |
3887 } | |
3888 return OK; | |
3889 } | |
3890 | |
3891 /* | |
3892 * Extend "l1" with "l2". | |
3893 * If "bef" is NULL append at the end, otherwise insert before this item. | |
3894 * Returns FAIL when out of memory. | |
3895 */ | |
3896 static int | |
3897 list_extend(l1, l2, bef) | |
3898 listvar *l1; | |
3899 listvar *l2; | |
3900 listitem *bef; | |
3901 { | |
3902 listitem *item; | |
3903 | |
3904 for (item = l2->lv_first; item != NULL; item = item->li_next) | |
3905 if (list_insert_tv(l1, &item->li_tv, bef) == FAIL) | |
3906 return FAIL; | |
3907 return OK; | |
3908 } | |
3909 | |
3910 /* | |
3911 * Concatenate lists "l1" and "l2" into a new list, stored in "tv". | |
3912 * Return FAIL when out of memory. | |
3913 */ | |
3914 static int | |
3915 list_concat(l1, l2, tv) | |
3916 listvar *l1; | |
3917 listvar *l2; | |
3918 typeval *tv; | |
3919 { | |
3920 listvar *l; | |
3921 | |
3922 /* make a copy of the first list. */ | |
3923 l = list_copy(l1, FALSE); | |
3924 if (l == NULL) | |
3925 return FAIL; | |
3926 tv->v_type = VAR_LIST; | |
3927 tv->vval.v_list = l; | |
3928 | |
3929 /* append all items from the second list */ | |
3930 return list_extend(l, l2, NULL); | |
3662 } | 3931 } |
3663 | 3932 |
3664 /* | 3933 /* |
3665 * Make a copy of list "l". Shallow if "deep" is FALSE. | 3934 * Make a copy of list "l". Shallow if "deep" is FALSE. |
3666 * The refcount of the new list is set to 1. | 3935 * The refcount of the new list is set to 1. |
3714 --recurse; | 3983 --recurse; |
3715 return copy; | 3984 return copy; |
3716 } | 3985 } |
3717 | 3986 |
3718 /* | 3987 /* |
3719 * Remove item with index "n" from list "l" and return it. | 3988 * Remove items "item" to "item2" from list "l". |
3720 * Returns NULL when "n" is out of range. | 3989 */ |
3721 */ | 3990 static void |
3722 static listitem * | 3991 list_getrem(l, item, item2) |
3723 list_getrem(l, n) | |
3724 listvar *l; | 3992 listvar *l; |
3725 long n; | |
3726 { | |
3727 listitem *item; | 3993 listitem *item; |
3728 | 3994 listitem *item2; |
3729 item = list_find(l, n); | 3995 { |
3730 if (item != NULL) | 3996 listitem *ip; |
3731 { | 3997 |
3732 list_fix_watch(l, item); /* notify watchers */ | 3998 /* notify watchers */ |
3733 if (item->li_next == NULL) | 3999 for (ip = item; ip != NULL; ip = ip->li_next) |
3734 l->lv_last = item->li_prev; | 4000 { |
3735 else | 4001 list_fix_watch(l, ip); |
3736 item->li_next->li_prev = item->li_prev; | 4002 if (ip == item2) |
3737 if (item->li_prev == NULL) | 4003 break; |
3738 l->lv_first = item->li_next; | 4004 } |
3739 else | 4005 |
3740 item->li_prev->li_next = item->li_next; | 4006 if (item2->li_next == NULL) |
3741 } | 4007 l->lv_last = item->li_prev; |
3742 return item; | 4008 else |
4009 item2->li_next->li_prev = item->li_prev; | |
4010 if (item->li_prev == NULL) | |
4011 l->lv_first = item2->li_next; | |
4012 else | |
4013 item->li_prev->li_next = item2->li_next; | |
3743 } | 4014 } |
3744 | 4015 |
3745 /* | 4016 /* |
3746 * Return an allocated string with the string representation of a list. | 4017 * Return an allocated string with the string representation of a list. |
3747 * May return NULL. | 4018 * May return NULL. |
3753 garray_T ga; | 4024 garray_T ga; |
3754 listitem *item; | 4025 listitem *item; |
3755 int first = TRUE; | 4026 int first = TRUE; |
3756 char_u *tofree; | 4027 char_u *tofree; |
3757 char_u *s; | 4028 char_u *s; |
4029 char_u numbuf[NUMBUFLEN]; | |
3758 | 4030 |
3759 if (tv->vval.v_list == NULL) | 4031 if (tv->vval.v_list == NULL) |
3760 return NULL; | 4032 return NULL; |
3761 ga_init2(&ga, (int)sizeof(char), 80); | 4033 ga_init2(&ga, (int)sizeof(char), 80); |
3762 ga_append(&ga, '['); | 4034 ga_append(&ga, '['); |
3766 if (first) | 4038 if (first) |
3767 first = FALSE; | 4039 first = FALSE; |
3768 else | 4040 else |
3769 ga_concat(&ga, (char_u *)", "); | 4041 ga_concat(&ga, (char_u *)", "); |
3770 | 4042 |
3771 s = tv2string(&item->li_tv, &tofree); | 4043 s = tv2string(&item->li_tv, &tofree, numbuf); |
3772 if (s != NULL) | 4044 if (s != NULL) |
3773 ga_concat(&ga, s); | 4045 ga_concat(&ga, s); |
3774 vim_free(tofree); | 4046 vim_free(tofree); |
3775 } | 4047 } |
3776 | 4048 |
3780 } | 4052 } |
3781 | 4053 |
3782 /* | 4054 /* |
3783 * Return a string with the string representation of a variable. | 4055 * Return a string with the string representation of a variable. |
3784 * If the memory is allocated "tofree" is set to it, otherwise NULL. | 4056 * If the memory is allocated "tofree" is set to it, otherwise NULL. |
3785 * Can only be used once before the value is used, it may call | 4057 * "numbuf" is used for a number. |
3786 * get_var_string(). | |
3787 * May return NULL; | 4058 * May return NULL; |
3788 */ | 4059 */ |
3789 static char_u * | 4060 static char_u * |
3790 tv2string(tv, tofree) | 4061 tv2string(tv, tofree, numbuf) |
3791 typeval *tv; | 4062 typeval *tv; |
3792 char_u **tofree; | 4063 char_u **tofree; |
4064 char_u *numbuf; | |
3793 { | 4065 { |
3794 switch (tv->v_type) | 4066 switch (tv->v_type) |
3795 { | 4067 { |
3796 case VAR_FUNC: | 4068 case VAR_FUNC: |
3797 *tofree = NULL; | 4069 *tofree = NULL; |
3804 break; | 4076 break; |
3805 default: | 4077 default: |
3806 EMSG2(_(e_intern2), "tv2string()"); | 4078 EMSG2(_(e_intern2), "tv2string()"); |
3807 } | 4079 } |
3808 *tofree = NULL; | 4080 *tofree = NULL; |
3809 return get_tv_string(tv); | 4081 return get_tv_string_buf(tv, numbuf); |
3810 } | 4082 } |
3811 | 4083 |
3812 /* | 4084 /* |
3813 * Get the value of an environment variable. | 4085 * Get the value of an environment variable. |
3814 * "arg" is pointing to the '$'. It is advanced to after the name. | 4086 * "arg" is pointing to the '$'. It is advanced to after the name. |
3886 {"bufname", 1, 1, f_bufname}, | 4158 {"bufname", 1, 1, f_bufname}, |
3887 {"bufnr", 1, 1, f_bufnr}, | 4159 {"bufnr", 1, 1, f_bufnr}, |
3888 {"bufwinnr", 1, 1, f_bufwinnr}, | 4160 {"bufwinnr", 1, 1, f_bufwinnr}, |
3889 {"byte2line", 1, 1, f_byte2line}, | 4161 {"byte2line", 1, 1, f_byte2line}, |
3890 {"byteidx", 2, 2, f_byteidx}, | 4162 {"byteidx", 2, 2, f_byteidx}, |
4163 {"call", 2, 2, f_call}, | |
3891 {"char2nr", 1, 1, f_char2nr}, | 4164 {"char2nr", 1, 1, f_char2nr}, |
3892 {"cindent", 1, 1, f_cindent}, | 4165 {"cindent", 1, 1, f_cindent}, |
3893 {"col", 1, 1, f_col}, | 4166 {"col", 1, 1, f_col}, |
3894 {"confirm", 1, 4, f_confirm}, | 4167 {"confirm", 1, 4, f_confirm}, |
3895 {"copy", 1, 1, f_copy}, | 4168 {"copy", 1, 1, f_copy}, |
4169 {"count", 2, 3, f_count}, | |
3896 {"cscope_connection",0,3, f_cscope_connection}, | 4170 {"cscope_connection",0,3, f_cscope_connection}, |
3897 {"cursor", 2, 2, f_cursor}, | 4171 {"cursor", 2, 2, f_cursor}, |
3898 {"deepcopy", 1, 1, f_deepcopy}, | 4172 {"deepcopy", 1, 1, f_deepcopy}, |
3899 {"delete", 1, 1, f_delete}, | 4173 {"delete", 1, 1, f_delete}, |
3900 {"did_filetype", 0, 0, f_did_filetype}, | 4174 {"did_filetype", 0, 0, f_did_filetype}, |
3903 {"escape", 2, 2, f_escape}, | 4177 {"escape", 2, 2, f_escape}, |
3904 {"eventhandler", 0, 0, f_eventhandler}, | 4178 {"eventhandler", 0, 0, f_eventhandler}, |
3905 {"executable", 1, 1, f_executable}, | 4179 {"executable", 1, 1, f_executable}, |
3906 {"exists", 1, 1, f_exists}, | 4180 {"exists", 1, 1, f_exists}, |
3907 {"expand", 1, 2, f_expand}, | 4181 {"expand", 1, 2, f_expand}, |
4182 {"extend", 2, 3, f_extend}, | |
3908 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ | 4183 {"file_readable", 1, 1, f_filereadable}, /* obsolete */ |
3909 {"filereadable", 1, 1, f_filereadable}, | 4184 {"filereadable", 1, 1, f_filereadable}, |
3910 {"filewritable", 1, 1, f_filewritable}, | 4185 {"filewritable", 1, 1, f_filewritable}, |
3911 {"finddir", 1, 3, f_finddir}, | 4186 {"finddir", 1, 3, f_finddir}, |
3912 {"findfile", 1, 3, f_findfile}, | 4187 {"findfile", 1, 3, f_findfile}, |
3948 {"hlID", 1, 1, f_hlID}, | 4223 {"hlID", 1, 1, f_hlID}, |
3949 {"hlexists", 1, 1, f_hlexists}, | 4224 {"hlexists", 1, 1, f_hlexists}, |
3950 {"hostname", 0, 0, f_hostname}, | 4225 {"hostname", 0, 0, f_hostname}, |
3951 {"iconv", 3, 3, f_iconv}, | 4226 {"iconv", 3, 3, f_iconv}, |
3952 {"indent", 1, 1, f_indent}, | 4227 {"indent", 1, 1, f_indent}, |
4228 {"index", 2, 3, f_index}, | |
3953 {"input", 1, 2, f_input}, | 4229 {"input", 1, 2, f_input}, |
3954 {"inputdialog", 1, 3, f_inputdialog}, | 4230 {"inputdialog", 1, 3, f_inputdialog}, |
3955 {"inputrestore", 0, 0, f_inputrestore}, | 4231 {"inputrestore", 0, 0, f_inputrestore}, |
3956 {"inputsave", 0, 0, f_inputsave}, | 4232 {"inputsave", 0, 0, f_inputsave}, |
3957 {"inputsecret", 1, 2, f_inputsecret}, | 4233 {"inputsecret", 1, 2, f_inputsecret}, |
3977 {"remote_expr", 2, 3, f_remote_expr}, | 4253 {"remote_expr", 2, 3, f_remote_expr}, |
3978 {"remote_foreground", 1, 1, f_remote_foreground}, | 4254 {"remote_foreground", 1, 1, f_remote_foreground}, |
3979 {"remote_peek", 1, 2, f_remote_peek}, | 4255 {"remote_peek", 1, 2, f_remote_peek}, |
3980 {"remote_read", 1, 1, f_remote_read}, | 4256 {"remote_read", 1, 1, f_remote_read}, |
3981 {"remote_send", 2, 3, f_remote_send}, | 4257 {"remote_send", 2, 3, f_remote_send}, |
3982 {"remove", 2, 2, f_remove}, | 4258 {"remove", 2, 3, f_remove}, |
3983 {"rename", 2, 2, f_rename}, | 4259 {"rename", 2, 2, f_rename}, |
3984 {"repeat", 2, 2, f_repeat}, | 4260 {"repeat", 2, 2, f_repeat}, |
3985 {"resolve", 1, 1, f_resolve}, | 4261 {"resolve", 1, 1, f_resolve}, |
3986 {"search", 1, 2, f_search}, | 4262 {"search", 1, 2, f_search}, |
3987 {"searchpair", 3, 5, f_searchpair}, | 4263 {"searchpair", 3, 5, f_searchpair}, |
4400 f_append(argvars, rettv) | 4676 f_append(argvars, rettv) |
4401 typeval *argvars; | 4677 typeval *argvars; |
4402 typeval *rettv; | 4678 typeval *rettv; |
4403 { | 4679 { |
4404 long lnum; | 4680 long lnum; |
4681 listvar *l; | |
4405 | 4682 |
4406 rettv->vval.v_number = 1; /* Default: Failed */ | 4683 rettv->vval.v_number = 1; /* Default: Failed */ |
4407 if (argvars[0].v_type == VAR_LIST) | 4684 if (argvars[0].v_type == VAR_LIST) |
4408 { | 4685 { |
4409 if (argvars[0].vval.v_list != NULL | 4686 l = argvars[0].vval.v_list; |
4410 && list_append_tv(argvars[0].vval.v_list, &argvars[1]) == OK) | 4687 if (l != NULL && list_append_tv(l, &argvars[1]) == OK) |
4688 { | |
4689 ++l->lv_refcount; | |
4411 copy_tv(&argvars[0], rettv); | 4690 copy_tv(&argvars[0], rettv); |
4691 } | |
4412 } | 4692 } |
4413 else | 4693 else |
4414 { | 4694 { |
4415 lnum = get_tv_lnum(argvars); | 4695 lnum = get_tv_lnum(argvars); |
4416 if (lnum >= 0 | 4696 if (lnum >= 0 |
4757 rettv->vval.v_number = t - str; | 5037 rettv->vval.v_number = t - str; |
4758 #else | 5038 #else |
4759 if (idx <= STRLEN(str)) | 5039 if (idx <= STRLEN(str)) |
4760 rettv->vval.v_number = idx; | 5040 rettv->vval.v_number = idx; |
4761 #endif | 5041 #endif |
5042 } | |
5043 | |
5044 /* | |
5045 * "call(func, arglist)" function | |
5046 */ | |
5047 static void | |
5048 f_call(argvars, rettv) | |
5049 typeval *argvars; | |
5050 typeval *rettv; | |
5051 { | |
5052 char_u *func; | |
5053 typeval argv[MAX_FUNC_ARGS]; | |
5054 int argc = 0; | |
5055 listitem *item; | |
5056 int dummy; | |
5057 | |
5058 rettv->vval.v_number = 0; | |
5059 if (argvars[1].v_type != VAR_LIST) | |
5060 { | |
5061 EMSG(_(e_listreq)); | |
5062 return; | |
5063 } | |
5064 if (argvars[1].vval.v_list == NULL) | |
5065 return; | |
5066 | |
5067 if (argvars[0].v_type == VAR_FUNC) | |
5068 func = argvars[0].vval.v_string; | |
5069 else | |
5070 func = get_tv_string(&argvars[0]); | |
5071 | |
5072 for (item = argvars[1].vval.v_list->lv_first; item != NULL; | |
5073 item = item->li_next) | |
5074 { | |
5075 if (argc == MAX_FUNC_ARGS) | |
5076 { | |
5077 EMSG(_("E999: Too many arguments")); | |
5078 break; | |
5079 } | |
5080 /* Make a copy of each argument (is this really needed?) */ | |
5081 copy_tv(&item->li_tv, &argv[argc++]); | |
5082 } | |
5083 | |
5084 if (item == NULL) | |
5085 (void)call_func(func, STRLEN(func), rettv, argc, argv, | |
5086 curwin->w_cursor.lnum, curwin->w_cursor.lnum, &dummy, TRUE); | |
5087 | |
5088 /* Free the arguments. */ | |
5089 while (argc > 0) | |
5090 clear_tv(&argv[--argc]); | |
4762 } | 5091 } |
4763 | 5092 |
4764 /* | 5093 /* |
4765 * "char2nr(string)" function | 5094 * "char2nr(string)" function |
4766 */ | 5095 */ |
4922 else | 5251 else |
4923 copy_tv(&argvars[0], rettv); | 5252 copy_tv(&argvars[0], rettv); |
4924 } | 5253 } |
4925 | 5254 |
4926 /* | 5255 /* |
5256 * "count()" function | |
5257 */ | |
5258 static void | |
5259 f_count(argvars, rettv) | |
5260 typeval *argvars; | |
5261 typeval *rettv; | |
5262 { | |
5263 listitem *li; | |
5264 long n = 0; | |
5265 int ic = FALSE; | |
5266 | |
5267 if (argvars[0].v_type != VAR_LIST) | |
5268 EMSG(_(e_listreq)); | |
5269 else if (argvars[0].vval.v_list != NULL) | |
5270 { | |
5271 if (argvars[2].v_type != VAR_UNKNOWN) | |
5272 ic = get_tv_number(&argvars[2]); | |
5273 | |
5274 for (li = argvars[0].vval.v_list->lv_first; li != NULL; | |
5275 li = li->li_next) | |
5276 if (tv_equal(&li->li_tv, &argvars[1], ic)) | |
5277 ++n; | |
5278 } | |
5279 rettv->vval.v_number = n; | |
5280 } | |
5281 | |
5282 /* | |
4927 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function | 5283 * "cscope_connection([{num} , {dbpath} [, {prepend}]])" function |
4928 * | 5284 * |
4929 * Checks the existence of a cscope connection. | 5285 * Checks the existence of a cscope connection. |
4930 */ | 5286 */ |
4931 /*ARGSUSED*/ | 5287 /*ARGSUSED*/ |
5257 flags |= WILD_KEEP_ALL; | 5613 flags |= WILD_KEEP_ALL; |
5258 ExpandInit(&xpc); | 5614 ExpandInit(&xpc); |
5259 xpc.xp_context = EXPAND_FILES; | 5615 xpc.xp_context = EXPAND_FILES; |
5260 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); | 5616 rettv->vval.v_string = ExpandOne(&xpc, s, NULL, flags, WILD_ALL); |
5261 ExpandCleanup(&xpc); | 5617 ExpandCleanup(&xpc); |
5618 } | |
5619 } | |
5620 | |
5621 /* | |
5622 * "extend(list, list [, idx])" function | |
5623 */ | |
5624 static void | |
5625 f_extend(argvars, rettv) | |
5626 typeval *argvars; | |
5627 typeval *rettv; | |
5628 { | |
5629 long before; | |
5630 long n; | |
5631 listitem *item; | |
5632 listvar *l1, *l2; | |
5633 | |
5634 rettv->vval.v_number = 0; | |
5635 if (argvars[0].v_type != VAR_LIST || argvars[1].v_type != VAR_LIST) | |
5636 { | |
5637 EMSG(_(e_listreq)); | |
5638 return; | |
5639 } | |
5640 l1 = argvars[0].vval.v_list; | |
5641 l2 = argvars[1].vval.v_list; | |
5642 if (l1 != NULL && l2 != NULL) | |
5643 { | |
5644 if (argvars[2].v_type != VAR_UNKNOWN) | |
5645 { | |
5646 n = before = get_tv_number(&argvars[2]); | |
5647 item = list_find_ext(l1, &n); | |
5648 if (n != 0) | |
5649 { | |
5650 EMSGN(_(e_listidx), before); | |
5651 return; | |
5652 } | |
5653 } | |
5654 else | |
5655 item = NULL; | |
5656 list_extend(l1, l2, item); | |
5657 | |
5658 ++l1->lv_refcount; | |
5659 copy_tv(&argvars[0], rettv); | |
5262 } | 5660 } |
5263 } | 5661 } |
5264 | 5662 |
5265 /* | 5663 /* |
5266 * "filereadable()" function | 5664 * "filereadable()" function |
6914 rettv->vval.v_number = get_indent_lnum(lnum); | 7312 rettv->vval.v_number = get_indent_lnum(lnum); |
6915 else | 7313 else |
6916 rettv->vval.v_number = -1; | 7314 rettv->vval.v_number = -1; |
6917 } | 7315 } |
6918 | 7316 |
7317 /* | |
7318 * "index()" function | |
7319 */ | |
7320 static void | |
7321 f_index(argvars, rettv) | |
7322 typeval *argvars; | |
7323 typeval *rettv; | |
7324 { | |
7325 listvar *l; | |
7326 listitem *item; | |
7327 long idx = 0; | |
7328 int ic = FALSE; | |
7329 | |
7330 rettv->vval.v_number = -1; | |
7331 if (argvars[0].v_type != VAR_LIST) | |
7332 { | |
7333 EMSG(_(e_listreq)); | |
7334 return; | |
7335 } | |
7336 l = argvars[0].vval.v_list; | |
7337 if (l != NULL) | |
7338 { | |
7339 if (argvars[2].v_type != VAR_UNKNOWN) | |
7340 ic = get_tv_number(&argvars[2]); | |
7341 | |
7342 for (item = l->lv_first; item != NULL; item = item->li_next, ++idx) | |
7343 if (tv_equal(&item->li_tv, &argvars[1], ic)) | |
7344 { | |
7345 rettv->vval.v_number = idx; | |
7346 break; | |
7347 } | |
7348 } | |
7349 } | |
7350 | |
6919 static int inputsecret_flag = 0; | 7351 static int inputsecret_flag = 0; |
6920 | 7352 |
6921 /* | 7353 /* |
6922 * "input()" function | 7354 * "input()" function |
6923 * Also handles inputsecret() when inputsecret is set. | 7355 * Also handles inputsecret() when inputsecret is set. |
7091 typeval *rettv; | 7523 typeval *rettv; |
7092 { | 7524 { |
7093 long before = 0; | 7525 long before = 0; |
7094 long n; | 7526 long n; |
7095 listitem *item; | 7527 listitem *item; |
7096 listitem *ni; | |
7097 listvar *l; | 7528 listvar *l; |
7098 | 7529 |
7099 if (argvars[0].v_type != VAR_LIST) | 7530 if (argvars[0].v_type != VAR_LIST) |
7100 EMSG(_("E999: First argument of insert() must be a list")); | 7531 EMSG(_("E999: First argument of insert() must be a list")); |
7101 else if ((l = argvars[0].vval.v_list) != NULL) | 7532 else if ((l = argvars[0].vval.v_list) != NULL) |
7102 { | 7533 { |
7103 if (argvars[2].v_type != VAR_UNKNOWN) | 7534 if (argvars[2].v_type != VAR_UNKNOWN) |
7104 before = get_tv_number(&argvars[2]); | 7535 before = get_tv_number(&argvars[2]); |
7105 | 7536 |
7106 if (before < 0) | 7537 n = before; |
7107 { | 7538 item = list_find_ext(l, &n); |
7108 /* Count from the end: -1 is before last item. */ | |
7109 item = l->lv_last; | |
7110 for (n = before + 1; n < 0 && item != NULL; ++n) | |
7111 item = item->li_prev; | |
7112 if (item == NULL) | |
7113 n = 1; /* report an error, don't append */ | |
7114 } | |
7115 else | |
7116 { | |
7117 /* Can't use list_find() here, we allow one past the end. */ | |
7118 item = l->lv_first; | |
7119 for (n = before; n > 0 && item != NULL; --n) | |
7120 item = item->li_next; | |
7121 } | |
7122 if (n > 0) | 7539 if (n > 0) |
7123 EMSGN(_(e_listidx), before); | 7540 EMSGN(_(e_listidx), before); |
7124 else | 7541 else |
7125 { | 7542 { |
7126 ni = listitem_alloc(); | 7543 list_insert_tv(l, &argvars[1], item); |
7127 if (ni != NULL) | 7544 ++l->lv_refcount; |
7128 { | 7545 copy_tv(&argvars[0], rettv); |
7129 copy_tv(&argvars[1], &ni->li_tv); | |
7130 if (item == NULL) | |
7131 /* Append new item at end of list. */ | |
7132 list_append(l, ni); | |
7133 else | |
7134 { | |
7135 /* Insert new item before existing item. */ | |
7136 ni->li_prev = item->li_prev; | |
7137 ni->li_next = item; | |
7138 if (item->li_prev == NULL) | |
7139 l->lv_first = ni; | |
7140 else | |
7141 item->li_prev->li_next = ni; | |
7142 item->li_prev = ni; | |
7143 } | |
7144 copy_tv(&argvars[0], rettv); | |
7145 } | |
7146 } | 7546 } |
7147 } | 7547 } |
7148 } | 7548 } |
7149 | 7549 |
7150 /* | 7550 /* |
7593 rettv->v_type = VAR_STRING; | 7993 rettv->v_type = VAR_STRING; |
7594 rettv->vval.v_string = vim_strsave(buf); | 7994 rettv->vval.v_string = vim_strsave(buf); |
7595 } | 7995 } |
7596 | 7996 |
7597 /* | 7997 /* |
7598 * "remove({list}, {idx})" function | 7998 * "remove({list}, {idx} [, {end}])" function |
7599 */ | 7999 */ |
7600 static void | 8000 static void |
7601 f_remove(argvars, rettv) | 8001 f_remove(argvars, rettv) |
7602 typeval *argvars; | 8002 typeval *argvars; |
7603 typeval *rettv; | 8003 typeval *rettv; |
7604 { | 8004 { |
7605 listvar *l; | 8005 listvar *l; |
7606 listitem *item; | 8006 listitem *item, *item2; |
8007 listitem *li; | |
7607 long idx; | 8008 long idx; |
7608 | 8009 long end; |
8010 | |
8011 rettv->vval.v_number = 0; | |
7609 if (argvars[0].v_type != VAR_LIST) | 8012 if (argvars[0].v_type != VAR_LIST) |
7610 EMSG(_("E999: First argument of remove() must be a list")); | 8013 EMSG(_("E999: First argument of remove() must be a list")); |
7611 else if ((l = argvars[0].vval.v_list) != NULL) | 8014 else if ((l = argvars[0].vval.v_list) != NULL) |
7612 { | 8015 { |
7613 idx = get_tv_number(&argvars[1]); | 8016 idx = get_tv_number(&argvars[1]); |
7614 item = list_getrem(l, idx); | 8017 item = list_find(l, idx); |
7615 if (item == NULL) | 8018 if (item == NULL) |
7616 EMSGN(_(e_listidx), idx); | 8019 EMSGN(_(e_listidx), idx); |
7617 else | 8020 else |
7618 { | 8021 { |
7619 *rettv = item->li_tv; | 8022 if (argvars[2].v_type == VAR_UNKNOWN) |
7620 vim_free(item); | 8023 { |
8024 /* Remove one item, return its value. */ | |
8025 list_getrem(l, item, item); | |
8026 *rettv = item->li_tv; | |
8027 vim_free(item); | |
8028 } | |
8029 else | |
8030 { | |
8031 /* Remove range of items, return list with values. */ | |
8032 end = get_tv_number(&argvars[2]); | |
8033 item2 = list_find(l, end); | |
8034 if (item2 == NULL) | |
8035 EMSGN(_(e_listidx), end); | |
8036 else | |
8037 { | |
8038 for (li = item; li != item2 && li != NULL; li = li->li_next) | |
8039 ; | |
8040 if (li == NULL) /* didn't find "item2" after "item" */ | |
8041 EMSG(_(e_invrange)); | |
8042 else | |
8043 { | |
8044 list_getrem(l, item, item2); | |
8045 l = list_alloc(); | |
8046 if (l != NULL) | |
8047 { | |
8048 rettv->v_type = VAR_LIST; | |
8049 rettv->vval.v_list = l; | |
8050 l->lv_first = item; | |
8051 l->lv_last = item2; | |
8052 l->lv_refcount = 1; | |
8053 item->li_prev = NULL; | |
8054 item2->li_next = NULL; | |
8055 } | |
8056 } | |
8057 } | |
8058 } | |
7621 } | 8059 } |
7622 } | 8060 } |
7623 } | 8061 } |
7624 | 8062 |
7625 /* | 8063 /* |
7635 if (check_restricted() || check_secure()) | 8073 if (check_restricted() || check_secure()) |
7636 rettv->vval.v_number = -1; | 8074 rettv->vval.v_number = -1; |
7637 else | 8075 else |
7638 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), | 8076 rettv->vval.v_number = vim_rename(get_tv_string(&argvars[0]), |
7639 get_tv_string_buf(&argvars[1], buf)); | 8077 get_tv_string_buf(&argvars[1], buf)); |
8078 } | |
8079 | |
8080 /* | |
8081 * "repeat()" function | |
8082 */ | |
8083 /*ARGSUSED*/ | |
8084 static void | |
8085 f_repeat(argvars, rettv) | |
8086 typeval *argvars; | |
8087 typeval *rettv; | |
8088 { | |
8089 char_u *p; | |
8090 int n; | |
8091 int slen; | |
8092 int len; | |
8093 char_u *r; | |
8094 int i; | |
8095 listvar *l; | |
8096 | |
8097 n = get_tv_number(&argvars[1]); | |
8098 if (argvars[0].v_type == VAR_LIST) | |
8099 { | |
8100 l = list_alloc(); | |
8101 if (l != NULL && argvars[0].vval.v_list != NULL) | |
8102 { | |
8103 l->lv_refcount = 1; | |
8104 while (n-- > 0) | |
8105 if (list_extend(l, argvars[0].vval.v_list, NULL) == FAIL) | |
8106 break; | |
8107 } | |
8108 rettv->v_type = VAR_LIST; | |
8109 rettv->vval.v_list = l; | |
8110 } | |
8111 else | |
8112 { | |
8113 p = get_tv_string(&argvars[0]); | |
8114 rettv->v_type = VAR_STRING; | |
8115 rettv->vval.v_string = NULL; | |
8116 | |
8117 slen = (int)STRLEN(p); | |
8118 len = slen * n; | |
8119 if (len <= 0) | |
8120 return; | |
8121 | |
8122 r = alloc(len + 1); | |
8123 if (r != NULL) | |
8124 { | |
8125 for (i = 0; i < n; i++) | |
8126 mch_memmove(r + i * slen, p, (size_t)slen); | |
8127 r[len] = NUL; | |
8128 } | |
8129 | |
8130 rettv->vval.v_string = r; | |
8131 } | |
7640 } | 8132 } |
7641 | 8133 |
7642 /* | 8134 /* |
7643 * "resolve()" function | 8135 * "resolve()" function |
7644 */ | 8136 */ |
8635 vim_free(argvars[1].vval.v_string); | 9127 vim_free(argvars[1].vval.v_string); |
8636 # endif | 9128 # endif |
8637 #endif | 9129 #endif |
8638 } | 9130 } |
8639 | 9131 |
8640 /* | |
8641 * "repeat()" function | |
8642 */ | |
8643 /*ARGSUSED*/ | |
8644 static void | |
8645 f_repeat(argvars, rettv) | |
8646 typeval *argvars; | |
8647 typeval *rettv; | |
8648 { | |
8649 char_u *p; | |
8650 int n; | |
8651 int slen; | |
8652 int len; | |
8653 char_u *r; | |
8654 int i; | |
8655 | |
8656 p = get_tv_string(&argvars[0]); | |
8657 n = get_tv_number(&argvars[1]); | |
8658 | |
8659 rettv->v_type = VAR_STRING; | |
8660 rettv->vval.v_string = NULL; | |
8661 | |
8662 slen = (int)STRLEN(p); | |
8663 len = slen * n; | |
8664 | |
8665 if (len <= 0) | |
8666 return; | |
8667 | |
8668 r = alloc(len + 1); | |
8669 if (r != NULL) | |
8670 { | |
8671 for (i = 0; i < n; i++) | |
8672 mch_memmove(r + i * slen, p, (size_t)slen); | |
8673 r[len] = NUL; | |
8674 } | |
8675 | |
8676 rettv->vval.v_string = r; | |
8677 } | |
8678 | |
8679 #ifdef HAVE_STRFTIME | 9132 #ifdef HAVE_STRFTIME |
8680 /* | 9133 /* |
8681 * "strftime({format}[, {time}])" function | 9134 * "strftime({format}[, {time}])" function |
8682 */ | 9135 */ |
8683 static void | 9136 static void |
8802 f_string(argvars, rettv) | 9255 f_string(argvars, rettv) |
8803 typeval *argvars; | 9256 typeval *argvars; |
8804 typeval *rettv; | 9257 typeval *rettv; |
8805 { | 9258 { |
8806 char_u *tofree; | 9259 char_u *tofree; |
9260 char_u numbuf[NUMBUFLEN]; | |
8807 | 9261 |
8808 rettv->v_type = VAR_STRING; | 9262 rettv->v_type = VAR_STRING; |
8809 rettv->vval.v_string = tv2string(&argvars[0], &tofree); | 9263 rettv->vval.v_string = tv2string(&argvars[0], &tofree, numbuf); |
8810 if (tofree == NULL) | 9264 if (tofree == NULL) |
8811 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); | 9265 rettv->vval.v_string = vim_strsave(rettv->vval.v_string); |
8812 } | 9266 } |
8813 | 9267 |
8814 /* | 9268 /* |
10473 VAR v; | 10927 VAR v; |
10474 char_u *prefix; | 10928 char_u *prefix; |
10475 { | 10929 { |
10476 char_u *tofree; | 10930 char_u *tofree; |
10477 char_u *s; | 10931 char_u *s; |
10478 | 10932 char_u numbuf[NUMBUFLEN]; |
10479 s = tv2string(&v->tv, &tofree); | 10933 |
10934 s = tv2string(&v->tv, &tofree, numbuf); | |
10480 list_one_var_a(prefix, v->v_name, v->tv.v_type, | 10935 list_one_var_a(prefix, v->v_name, v->tv.v_type, |
10481 s == NULL ? (char_u *)"" : s); | 10936 s == NULL ? (char_u *)"" : s); |
10482 vim_free(tofree); | 10937 vim_free(tofree); |
10483 } | 10938 } |
10484 | 10939 |
10697 typeval rettv; | 11152 typeval rettv; |
10698 char_u *tofree; | 11153 char_u *tofree; |
10699 char_u *p; | 11154 char_u *p; |
10700 int needclr = TRUE; | 11155 int needclr = TRUE; |
10701 int atstart = TRUE; | 11156 int atstart = TRUE; |
11157 char_u numbuf[NUMBUFLEN]; | |
10702 | 11158 |
10703 if (eap->skip) | 11159 if (eap->skip) |
10704 ++emsg_skip; | 11160 ++emsg_skip; |
10705 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) | 11161 while (*arg != NUL && *arg != '|' && *arg != '\n' && !got_int) |
10706 { | 11162 { |
10726 if (eap->cmdidx == CMD_echo) | 11182 if (eap->cmdidx == CMD_echo) |
10727 msg_start(); | 11183 msg_start(); |
10728 } | 11184 } |
10729 else if (eap->cmdidx == CMD_echo) | 11185 else if (eap->cmdidx == CMD_echo) |
10730 msg_puts_attr((char_u *)" ", echo_attr); | 11186 msg_puts_attr((char_u *)" ", echo_attr); |
10731 for (p = tv2string(&rettv, &tofree); *p != NUL && !got_int; ++p) | 11187 for (p = tv2string(&rettv, &tofree, numbuf); |
11188 *p != NUL && !got_int; ++p) | |
10732 if (*p == '\n' || *p == '\r' || *p == TAB) | 11189 if (*p == '\n' || *p == '\r' || *p == TAB) |
10733 { | 11190 { |
10734 if (*p != TAB && needclr) | 11191 if (*p != TAB && needclr) |
10735 { | 11192 { |
10736 /* remove any text still there from the command */ | 11193 /* remove any text still there from the command */ |
11936 get_return_cmd(rettv) | 12393 get_return_cmd(rettv) |
11937 void *rettv; | 12394 void *rettv; |
11938 { | 12395 { |
11939 char_u *s; | 12396 char_u *s; |
11940 char_u *tofree = NULL; | 12397 char_u *tofree = NULL; |
12398 char_u numbuf[NUMBUFLEN]; | |
11941 | 12399 |
11942 if (rettv == NULL) | 12400 if (rettv == NULL) |
11943 s = (char_u *)""; | 12401 s = (char_u *)""; |
11944 else | 12402 else |
11945 s = tv2string((typeval *)rettv, &tofree); | 12403 s = tv2string((typeval *)rettv, &tofree, numbuf); |
11946 | 12404 |
11947 STRCPY(IObuff, ":return "); | 12405 STRCPY(IObuff, ":return "); |
11948 STRNCPY(IObuff + 8, s, IOSIZE - 8); | 12406 STRNCPY(IObuff + 8, s, IOSIZE - 8); |
11949 if (STRLEN(s) + 8 >= IOSIZE) | 12407 if (STRLEN(s) + 8 >= IOSIZE) |
11950 STRCPY(IObuff + IOSIZE - 4, "..."); | 12408 STRCPY(IObuff + IOSIZE - 4, "..."); |
12110 garray_T *gap = &variables; /* global variable */ | 12568 garray_T *gap = &variables; /* global variable */ |
12111 VAR this_var; | 12569 VAR this_var; |
12112 int i; | 12570 int i; |
12113 char *s; | 12571 char *s; |
12114 char_u *tofree; | 12572 char_u *tofree; |
12573 char_u numbuf[NUMBUFLEN]; | |
12115 | 12574 |
12116 if (find_viminfo_parameter('!') == NULL) | 12575 if (find_viminfo_parameter('!') == NULL) |
12117 return; | 12576 return; |
12118 | 12577 |
12119 fprintf(fp, _("\n# global variables:\n")); | 12578 fprintf(fp, _("\n# global variables:\n")); |
12128 case VAR_STRING: s = "STR"; break; | 12587 case VAR_STRING: s = "STR"; break; |
12129 case VAR_NUMBER: s = "NUM"; break; | 12588 case VAR_NUMBER: s = "NUM"; break; |
12130 default: continue; | 12589 default: continue; |
12131 } | 12590 } |
12132 fprintf(fp, "!%s\t%s\t", this_var->v_name, s); | 12591 fprintf(fp, "!%s\t%s\t", this_var->v_name, s); |
12133 viminfo_writestring(fp, tv2string(&this_var->tv, &tofree)); | 12592 viminfo_writestring(fp, tv2string(&this_var->tv, &tofree, numbuf)); |
12134 vim_free(tofree); | 12593 vim_free(tofree); |
12135 } | 12594 } |
12136 } | 12595 } |
12137 } | 12596 } |
12138 #endif | 12597 #endif |