Take a filename and filename length and return the most significant * filename suffix we can find. This ignores suffixes such as "~", * ".bak", ".orig", ".~1~", etc. */
| 1526 | * filename suffix we can find. This ignores suffixes such as "~", |
| 1527 | * ".bak", ".orig", ".~1~", etc. */ |
| 1528 | const char *find_filename_suffix(const char *fn, int fn_len, int *len_ptr) |
| 1529 | { |
| 1530 | const char *suf, *s; |
| 1531 | BOOL had_tilde; |
| 1532 | int s_len; |
| 1533 | |
| 1534 | /* One or more dots at the start aren't a suffix. */ |
| 1535 | while (fn_len && *fn == '.') fn++, fn_len--; |
| 1536 | |
| 1537 | /* Ignore the ~ in a "foo~" filename. */ |
| 1538 | if (fn_len > 1 && fn[fn_len-1] == '~') |
| 1539 | fn_len--, had_tilde = True; |
| 1540 | else |
| 1541 | had_tilde = False; |
| 1542 | |
| 1543 | /* Assume we don't find an suffix. */ |
| 1544 | suf = ""; |
| 1545 | *len_ptr = 0; |
| 1546 | |
| 1547 | /* Find the last significant suffix. */ |
| 1548 | for (s = fn + fn_len; fn_len > 1; ) { |
| 1549 | while (*--s != '.' && s != fn) {} |
| 1550 | if (s == fn) |
| 1551 | break; |
| 1552 | s_len = fn_len - (s - fn); |
| 1553 | fn_len = s - fn; |
| 1554 | if (s_len == 4) { |
| 1555 | if (strcmp(s+1, "bak") == 0 |
| 1556 | || strcmp(s+1, "old") == 0) |
| 1557 | continue; |
| 1558 | } else if (s_len == 5) { |
| 1559 | if (strcmp(s+1, "orig") == 0) |
| 1560 | continue; |
| 1561 | } else if (s_len > 2 && had_tilde && s[1] == '~' && isDigit(s + 2)) |
| 1562 | continue; |
| 1563 | *len_ptr = s_len; |
| 1564 | suf = s; |
| 1565 | if (s_len == 1) |
| 1566 | break; |
| 1567 | /* Determine if the suffix is all digits. */ |
| 1568 | for (s++, s_len--; s_len > 0; s++, s_len--) { |
| 1569 | if (!isDigit(s)) |
| 1570 | return suf; |
| 1571 | } |
| 1572 | /* An all-digit suffix may not be that significant. */ |
| 1573 | s = suf; |
| 1574 | } |
| 1575 | |
| 1576 | return suf; |
| 1577 | } |
| 1578 | |
| 1579 | /* This is an implementation of the Levenshtein distance algorithm. It |
| 1580 | * was implemented to avoid needing a two-dimensional matrix (to save |