* The change from "preimage" and "postimage" has been found to * apply at applied_pos (counts in line numbers) in "img". * Update "img" to remove "preimage" and replace it with "postimage". */
| 2906 | * Update "img" to remove "preimage" and replace it with "postimage". |
| 2907 | */ |
| 2908 | static void update_image(struct apply_state *state, |
| 2909 | struct image *img, |
| 2910 | int applied_pos, |
| 2911 | struct image *preimage, |
| 2912 | struct image *postimage) |
| 2913 | { |
| 2914 | /* |
| 2915 | * remove the copy of preimage at offset in img |
| 2916 | * and replace it with postimage |
| 2917 | */ |
| 2918 | int i, nr; |
| 2919 | size_t remove_count, insert_count, applied_at = 0; |
| 2920 | size_t result_alloc; |
| 2921 | char *result; |
| 2922 | int preimage_limit; |
| 2923 | |
| 2924 | /* |
| 2925 | * If we are removing blank lines at the end of img, |
| 2926 | * the preimage may extend beyond the end. |
| 2927 | * If that is the case, we must be careful only to |
| 2928 | * remove the part of the preimage that falls within |
| 2929 | * the boundaries of img. Initialize preimage_limit |
| 2930 | * to the number of lines in the preimage that falls |
| 2931 | * within the boundaries. |
| 2932 | */ |
| 2933 | preimage_limit = preimage->line_nr; |
| 2934 | if (preimage_limit > img->line_nr - applied_pos) |
| 2935 | preimage_limit = img->line_nr - applied_pos; |
| 2936 | |
| 2937 | for (i = 0; i < applied_pos; i++) |
| 2938 | applied_at += img->line[i].len; |
| 2939 | |
| 2940 | remove_count = 0; |
| 2941 | for (i = 0; i < preimage_limit; i++) |
| 2942 | remove_count += img->line[applied_pos + i].len; |
| 2943 | insert_count = postimage->buf.len; |
| 2944 | |
| 2945 | /* Adjust the contents */ |
| 2946 | result_alloc = st_add3(st_sub(img->buf.len, remove_count), insert_count, 1); |
| 2947 | result = xmalloc(result_alloc); |
| 2948 | memcpy(result, img->buf.buf, applied_at); |
| 2949 | memcpy(result + applied_at, postimage->buf.buf, postimage->buf.len); |
| 2950 | memcpy(result + applied_at + postimage->buf.len, |
| 2951 | img->buf.buf + (applied_at + remove_count), |
| 2952 | img->buf.len - (applied_at + remove_count)); |
| 2953 | strbuf_attach(&img->buf, result, postimage->buf.len + img->buf.len - remove_count, |
| 2954 | result_alloc); |
| 2955 | |
| 2956 | /* Adjust the line table */ |
| 2957 | nr = img->line_nr + postimage->line_nr - preimage_limit; |
| 2958 | if (preimage_limit < postimage->line_nr) |
| 2959 | /* |
| 2960 | * NOTE: this knows that we never call image_remove_first_line() |
| 2961 | * on anything other than pre/post image. |
| 2962 | */ |
| 2963 | REALLOC_ARRAY(img->line, nr); |
| 2964 | if (preimage_limit != postimage->line_nr) |
| 2965 | MOVE_ARRAY(img->line + applied_pos + postimage->line_nr, |
no test coverage detected