comparison src/ops.c @ 6462:86aacd619ac0 v7.4.560

updated for version 7.4.560 Problem: Memory leak using :wviminfo. Issue 296. Solution: Free memory when needed. (idea by Christian Brabandt)
author Bram Moolenaar <bram@vim.org>
date Wed, 17 Dec 2014 21:00:49 +0100
parents 29f5cfca3388
children e1874a4524f8
comparison
equal deleted inserted replaced
6461:ad262c7047d9 6462:86aacd619ac0
5661 int limit; 5661 int limit;
5662 int i; 5662 int i;
5663 int set_prev = FALSE; 5663 int set_prev = FALSE;
5664 char_u *str; 5664 char_u *str;
5665 char_u **array = NULL; 5665 char_u **array = NULL;
5666 int new_type;
5667 colnr_T new_width;
5666 5668
5667 /* We only get here (hopefully) if line[0] == '"' */ 5669 /* We only get here (hopefully) if line[0] == '"' */
5668 str = virp->vir_line + 1; 5670 str = virp->vir_line + 1;
5669 5671
5670 /* If the line starts with "" this is the y_previous register. */ 5672 /* If the line starts with "" this is the y_previous register. */
5693 5695
5694 size = 0; 5696 size = 0;
5695 limit = 100; /* Optimized for registers containing <= 100 lines */ 5697 limit = 100; /* Optimized for registers containing <= 100 lines */
5696 if (do_it) 5698 if (do_it)
5697 { 5699 {
5700 /*
5701 * Build the new register in array[].
5702 * y_array is kept as-is until done.
5703 * The "do_it" flag is reset when something is wrong, in which case
5704 * array[] needs to be freed.
5705 */
5698 if (set_prev) 5706 if (set_prev)
5699 y_previous = y_current; 5707 y_previous = y_current;
5700 vim_free(y_current->y_array); 5708 array = (char_u **)alloc((unsigned)(limit * sizeof(char_u *)));
5701 array = y_current->y_array =
5702 (char_u **)alloc((unsigned)(limit * sizeof(char_u *)));
5703 str = skipwhite(skiptowhite(str)); 5709 str = skipwhite(skiptowhite(str));
5704 if (STRNCMP(str, "CHAR", 4) == 0) 5710 if (STRNCMP(str, "CHAR", 4) == 0)
5705 y_current->y_type = MCHAR; 5711 new_type = MCHAR;
5706 else if (STRNCMP(str, "BLOCK", 5) == 0) 5712 else if (STRNCMP(str, "BLOCK", 5) == 0)
5707 y_current->y_type = MBLOCK; 5713 new_type = MBLOCK;
5708 else 5714 else
5709 y_current->y_type = MLINE; 5715 new_type = MLINE;
5710 /* get the block width; if it's missing we get a zero, which is OK */ 5716 /* get the block width; if it's missing we get a zero, which is OK */
5711 str = skipwhite(skiptowhite(str)); 5717 str = skipwhite(skiptowhite(str));
5712 y_current->y_width = getdigits(&str); 5718 new_width = getdigits(&str);
5713 } 5719 }
5714 5720
5715 while (!(eof = viminfo_readline(virp)) 5721 while (!(eof = viminfo_readline(virp))
5716 && (virp->vir_line[0] == TAB || virp->vir_line[0] == '<')) 5722 && (virp->vir_line[0] == TAB || virp->vir_line[0] == '<'))
5717 { 5723 {
5718 if (do_it) 5724 if (do_it)
5719 { 5725 {
5720 if (size >= limit) 5726 if (size == limit)
5721 { 5727 {
5722 y_current->y_array = (char_u **) 5728 char_u **new_array = (char_u **)
5723 alloc((unsigned)(limit * 2 * sizeof(char_u *))); 5729 alloc((unsigned)(limit * 2 * sizeof(char_u *)));
5730
5731 if (new_array == NULL)
5732 {
5733 do_it = FALSE;
5734 break;
5735 }
5724 for (i = 0; i < limit; i++) 5736 for (i = 0; i < limit; i++)
5725 y_current->y_array[i] = array[i]; 5737 new_array[i] = array[i];
5726 vim_free(array); 5738 vim_free(array);
5739 array = new_array;
5727 limit *= 2; 5740 limit *= 2;
5728 array = y_current->y_array;
5729 } 5741 }
5730 str = viminfo_readstring(virp, 1, TRUE); 5742 str = viminfo_readstring(virp, 1, TRUE);
5731 if (str != NULL) 5743 if (str != NULL)
5732 array[size++] = str; 5744 array[size++] = str;
5733 else 5745 else
5746 /* error, don't store the result */
5734 do_it = FALSE; 5747 do_it = FALSE;
5735 } 5748 }
5736 } 5749 }
5737 if (do_it) 5750 if (do_it)
5738 { 5751 {
5752 /* free y_array[] */
5753 for (i = 0; i < y_current->y_size; i++)
5754 vim_free(y_current->y_array[i]);
5755 vim_free(y_current->y_array);
5756
5757 y_current->y_type = new_type;
5758 y_current->y_width = new_width;
5759 y_current->y_size = size;
5739 if (size == 0) 5760 if (size == 0)
5740 { 5761 {
5741 vim_free(array);
5742 y_current->y_array = NULL; 5762 y_current->y_array = NULL;
5743 } 5763 }
5744 else if (size < limit) 5764 else
5745 { 5765 {
5766 /* Move the lines from array[] to y_array[]. */
5746 y_current->y_array = 5767 y_current->y_array =
5747 (char_u **)alloc((unsigned)(size * sizeof(char_u *))); 5768 (char_u **)alloc((unsigned)(size * sizeof(char_u *)));
5748 for (i = 0; i < size; i++) 5769 for (i = 0; i < size; i++)
5749 y_current->y_array[i] = array[i]; 5770 {
5750 vim_free(array); 5771 if (y_current->y_array == NULL)
5751 } 5772 vim_free(array[i]);
5752 y_current->y_size = size; 5773 else
5753 } 5774 y_current->y_array[i] = array[i];
5775 }
5776 }
5777 }
5778 else
5779 {
5780 /* Free array[] if it was filled. */
5781 for (i = 0; i < size; i++)
5782 vim_free(array[i]);
5783 }
5784 vim_free(array);
5785
5754 return eof; 5786 return eof;
5755 } 5787 }
5756 5788
5757 void 5789 void
5758 write_viminfo_registers(fp) 5790 write_viminfo_registers(fp)