Coalesce new lines into base by finding LCS */
| 180 | |
| 181 | /* Coalesce new lines into base by finding LCS */ |
| 182 | static struct lline *coalesce_lines(struct lline *base, int *lenbase, |
| 183 | struct lline *newline, int lennew, |
| 184 | unsigned long parent, long flags) |
| 185 | { |
| 186 | int **lcs; |
| 187 | enum coalesce_direction **directions; |
| 188 | struct lline *baseend, *newend = NULL; |
| 189 | int i, j, origbaselen = *lenbase; |
| 190 | |
| 191 | if (!newline) |
| 192 | return base; |
| 193 | |
| 194 | if (!base) { |
| 195 | *lenbase = lennew; |
| 196 | return newline; |
| 197 | } |
| 198 | |
| 199 | /* |
| 200 | * Coalesce new lines into base by finding the LCS |
| 201 | * - Create the table to run dynamic programming |
| 202 | * - Compute the LCS |
| 203 | * - Then reverse read the direction structure: |
| 204 | * - If we have MATCH, assign parent to base flag, and consume |
| 205 | * both baseend and newend |
| 206 | * - Else if we have BASE, consume baseend |
| 207 | * - Else if we have NEW, insert newend lline into base and |
| 208 | * consume newend |
| 209 | */ |
| 210 | CALLOC_ARRAY(lcs, st_add(origbaselen, 1)); |
| 211 | CALLOC_ARRAY(directions, st_add(origbaselen, 1)); |
| 212 | for (i = 0; i < origbaselen + 1; i++) { |
| 213 | CALLOC_ARRAY(lcs[i], st_add(lennew, 1)); |
| 214 | CALLOC_ARRAY(directions[i], st_add(lennew, 1)); |
| 215 | directions[i][0] = BASE; |
| 216 | } |
| 217 | for (j = 1; j < lennew + 1; j++) |
| 218 | directions[0][j] = NEW; |
| 219 | |
| 220 | for (i = 1, baseend = base; i < origbaselen + 1; i++) { |
| 221 | for (j = 1, newend = newline; j < lennew + 1; j++) { |
| 222 | if (match_string_spaces(baseend->line, baseend->len, |
| 223 | newend->line, newend->len, flags)) { |
| 224 | lcs[i][j] = lcs[i - 1][j - 1] + 1; |
| 225 | directions[i][j] = MATCH; |
| 226 | } else if (lcs[i][j - 1] >= lcs[i - 1][j]) { |
| 227 | lcs[i][j] = lcs[i][j - 1]; |
| 228 | directions[i][j] = NEW; |
| 229 | } else { |
| 230 | lcs[i][j] = lcs[i - 1][j]; |
| 231 | directions[i][j] = BASE; |
| 232 | } |
| 233 | if (newend->next) |
| 234 | newend = newend->next; |
| 235 | } |
| 236 | if (baseend->next) |
| 237 | baseend = baseend->next; |
| 238 | } |
| 239 |
no test coverage detected