aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/linematch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/linematch.c')
-rw-r--r--src/nvim/linematch.c95
1 files changed, 51 insertions, 44 deletions
diff --git a/src/nvim/linematch.c b/src/nvim/linematch.c
index c34b303193..8943e6e8a6 100644
--- a/src/nvim/linematch.c
+++ b/src/nvim/linematch.c
@@ -5,10 +5,13 @@
#include <stdint.h>
#include <string.h>
+#include "nvim/ascii_defs.h"
#include "nvim/linematch.h"
#include "nvim/macros_defs.h"
#include "nvim/memory.h"
#include "nvim/pos_defs.h"
+#include "nvim/strings.h"
+#include "xdiff/xdiff.h"
#define LN_MAX_BUFS 8
#define LN_DECISION_MAX 255 // pow(2, LN_MAX_BUFS(8)) - 1 = 255
@@ -28,49 +31,49 @@ struct diffcmppath_S {
# include "linematch.c.generated.h"
#endif
-static size_t line_len(const char *s)
+static size_t line_len(const mmfile_t *m)
{
- char *end = strchr(s, '\n');
+ char *s = m->ptr;
+ size_t n = (size_t)m->size;
+ char *end = strnchr(s, &n, '\n');
if (end) {
return (size_t)(end - s);
}
- return strlen(s);
+ return (size_t)m->size;
}
+#define MATCH_CHAR_MAX_LEN 800
+
/// Same as matching_chars but ignore whitespace
///
/// @param s1
/// @param s2
-static int matching_chars_iwhite(const char *s1, const char *s2)
+static int matching_chars_iwhite(const mmfile_t *s1, const mmfile_t *s2)
{
// the newly processed strings that will be compared
- // delete the white space characters, and/or replace all upper case with lower
- char *strsproc[2];
- const char *strsorig[2] = { s1, s2 };
+ // delete the white space characters
+ mmfile_t sp[2];
+ char p[2][MATCH_CHAR_MAX_LEN];
for (int k = 0; k < 2; k++) {
- size_t d = 0;
- size_t i = 0;
- size_t slen = line_len(strsorig[k]);
- strsproc[k] = xmalloc((slen + 1) * sizeof(char));
- while (d + i < slen) {
- char e = strsorig[k][i + d];
+ const mmfile_t *s = k == 0 ? s1 : s2;
+ size_t pi = 0;
+ size_t slen = MIN(MATCH_CHAR_MAX_LEN - 1, line_len(s));
+ for (size_t i = 0; i <= slen; i++) {
+ char e = s->ptr[i];
if (e != ' ' && e != '\t') {
- strsproc[k][i] = e;
- i++;
- } else {
- d++;
+ p[k][pi] = e;
+ pi++;
}
}
- strsproc[k][i] = '\0';
+
+ sp[k] = (mmfile_t){
+ .ptr = p[k],
+ .size = (int)pi,
+ };
}
- int matching = matching_chars(strsproc[0], strsproc[1]);
- xfree(strsproc[0]);
- xfree(strsproc[1]);
- return matching;
+ return matching_chars(&sp[0], &sp[1]);
}
-#define MATCH_CHAR_MAX_LEN 800
-
/// Return matching characters between "s1" and "s2" whilst respecting sequence order.
/// Consider the case of two strings 'AAACCC' and 'CCCAAA', the
/// return value from this function will be 3, either to match
@@ -82,12 +85,14 @@ static int matching_chars_iwhite(const char *s1, const char *s2)
/// matching_chars("abcdefg", "gfedcba") -> 1 // all characters in common,
/// // but only at most 1 in sequence
///
-/// @param s1
-/// @param s2
-static int matching_chars(const char *s1, const char *s2)
+/// @param m1
+/// @param m2
+static int matching_chars(const mmfile_t *m1, const mmfile_t *m2)
{
- size_t s1len = MIN(MATCH_CHAR_MAX_LEN - 1, line_len(s1));
- size_t s2len = MIN(MATCH_CHAR_MAX_LEN - 1, line_len(s2));
+ size_t s1len = MIN(MATCH_CHAR_MAX_LEN - 1, line_len(m1));
+ size_t s2len = MIN(MATCH_CHAR_MAX_LEN - 1, line_len(m2));
+ char *s1 = m1->ptr;
+ char *s2 = m2->ptr;
int matrix[2][MATCH_CHAR_MAX_LEN] = { 0 };
bool icur = 1; // save space by storing only two rows for i axis
for (size_t i = 0; i < s1len; i++) {
@@ -118,13 +123,13 @@ static int matching_chars(const char *s1, const char *s2)
/// @param sp
/// @param fomvals
/// @param n
-static int count_n_matched_chars(const char **sp, const size_t n, bool iwhite)
+static int count_n_matched_chars(mmfile_t **sp, const size_t n, bool iwhite)
{
int matched_chars = 0;
int matched = 0;
for (size_t i = 0; i < n; i++) {
for (size_t j = i + 1; j < n; j++) {
- if (sp[i] != NULL && sp[j] != NULL) {
+ if (sp[i]->ptr != NULL && sp[j]->ptr != NULL) {
matched++;
// TODO(lewis6991): handle whitespace ignoring higher up in the stack
matched_chars += iwhite ? matching_chars_iwhite(sp[i], sp[j])
@@ -142,15 +147,17 @@ static int count_n_matched_chars(const char **sp, const size_t n, bool iwhite)
return matched_chars;
}
-void fastforward_buf_to_lnum(const char **s, linenr_T lnum)
+mmfile_t fastforward_buf_to_lnum(mmfile_t s, linenr_T lnum)
{
for (int i = 0; i < lnum - 1; i++) {
- *s = strchr(*s, '\n');
- if (!*s) {
- return;
+ s.ptr = strnchr(s.ptr, (size_t *)&s.size, '\n');
+ if (!s.ptr) {
+ break;
}
- (*s)++;
+ s.ptr++;
+ s.size--;
}
+ return s;
}
/// try all the different ways to compare these lines and use the one that
@@ -166,25 +173,25 @@ void fastforward_buf_to_lnum(const char **s, linenr_T lnum)
/// @param diff_blk
static void try_possible_paths(const int *df_iters, const size_t *paths, const int npaths,
const int path_idx, int *choice, diffcmppath_T *diffcmppath,
- const int *diff_len, const size_t ndiffs, const char **diff_blk,
+ const int *diff_len, const size_t ndiffs, const mmfile_t **diff_blk,
bool iwhite)
{
if (path_idx == npaths) {
if ((*choice) > 0) {
int from_vals[LN_MAX_BUFS] = { 0 };
const int *to_vals = df_iters;
- const char *current_lines[LN_MAX_BUFS];
+ mmfile_t mm[LN_MAX_BUFS]; // stack memory for current_lines
+ mmfile_t *current_lines[LN_MAX_BUFS];
for (size_t k = 0; k < ndiffs; k++) {
from_vals[k] = df_iters[k];
// get the index at all of the places
if ((*choice) & (1 << k)) {
from_vals[k]--;
- const char *p = diff_blk[k];
- fastforward_buf_to_lnum(&p, df_iters[k]);
- current_lines[k] = p;
+ mm[k] = fastforward_buf_to_lnum(*diff_blk[k], df_iters[k]);
} else {
- current_lines[k] = NULL;
+ mm[k] = (mmfile_t){ 0 };
}
+ current_lines[k] = &mm[k];
}
size_t unwrapped_idx_from = unwrap_indexes(from_vals, diff_len, ndiffs);
size_t unwrapped_idx_to = unwrap_indexes(to_vals, diff_len, ndiffs);
@@ -243,7 +250,7 @@ static size_t unwrap_indexes(const int *values, const int *diff_len, const size_
/// @param ndiffs
/// @param diff_blk
static void populate_tensor(int *df_iters, const size_t ch_dim, diffcmppath_T *diffcmppath,
- const int *diff_len, const size_t ndiffs, const char **diff_blk,
+ const int *diff_len, const size_t ndiffs, const mmfile_t **diff_blk,
bool iwhite)
{
if (ch_dim == ndiffs) {
@@ -326,7 +333,7 @@ static void populate_tensor(int *df_iters, const size_t ch_dim, diffcmppath_T *d
/// @param ndiffs
/// @param [out] [allocated] decisions
/// @return the length of decisions
-size_t linematch_nbuffers(const char **diff_blk, const int *diff_len, const size_t ndiffs,
+size_t linematch_nbuffers(const mmfile_t **diff_blk, const int *diff_len, const size_t ndiffs,
int **decisions, bool iwhite)
{
assert(ndiffs <= LN_MAX_BUFS);