Return list of 5-tuples describing how to turn a into b. Each tuple is of the form (tag, i1, i2, j1, j2). The first tuple has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the tuple preceding it, and likewise for j1 == the previous j2. The tags are characters, with these meanings: '
()
| 374 | // |
| 375 | // 'e' (equal): a[i1:i2] == b[j1:j2] |
| 376 | func (m *SequenceMatcher) GetOpCodes() []OpCode { |
| 377 | if m.opCodes != nil { |
| 378 | return m.opCodes |
| 379 | } |
| 380 | i, j := 0, 0 |
| 381 | matching := m.GetMatchingBlocks() |
| 382 | opCodes := make([]OpCode, 0, len(matching)) |
| 383 | for _, m := range matching { |
| 384 | // invariant: we've pumped out correct diffs to change |
| 385 | // a[:i] into b[:j], and the next matching block is |
| 386 | // a[ai:ai+size] == b[bj:bj+size]. So we need to pump |
| 387 | // out a diff to change a[i:ai] into b[j:bj], pump out |
| 388 | // the matching block, and move (i,j) beyond the match |
| 389 | ai, bj, size := m.A, m.B, m.Size |
| 390 | tag := byte(0) |
| 391 | if i < ai && j < bj { |
| 392 | tag = 'r' |
| 393 | } else if i < ai { |
| 394 | tag = 'd' |
| 395 | } else if j < bj { |
| 396 | tag = 'i' |
| 397 | } |
| 398 | if tag > 0 { |
| 399 | opCodes = append(opCodes, OpCode{tag, i, ai, j, bj}) |
| 400 | } |
| 401 | i, j = ai+size, bj+size |
| 402 | // the list of matching blocks is terminated by a |
| 403 | // sentinel with size 0 |
| 404 | if size > 0 { |
| 405 | opCodes = append(opCodes, OpCode{'e', ai, i, bj, j}) |
| 406 | } |
| 407 | } |
| 408 | m.opCodes = opCodes |
| 409 | return m.opCodes |
| 410 | } |
| 411 | |
| 412 | // Isolate change clusters by eliminating ranges with no changes. |
| 413 | // |