Mercurial > vim
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) |