Skip to content

Commit

Permalink
text: move regex related functions to separate file
Browse files Browse the repository at this point in the history
Eventually this should probably be rewritten to use an iternal
regex engine, currently it has unacceptable memory usage, it
copies the whole text.
  • Loading branch information
martanne committed Jul 19, 2015
1 parent 0d6dbfe commit 8129933
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 77 deletions.
1 change: 1 addition & 0 deletions editor.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ typedef struct Win Win;
#include "syntax.h"
#include "ring-buffer.h"
#include "map.h"
#include "text-regex.h"

typedef union {
bool b;
Expand Down
1 change: 1 addition & 0 deletions text-motions.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <stddef.h>
#include "text.h"
#include "text-regex.h"

size_t text_begin(Text*, size_t pos);
size_t text_end(Text*, size_t pos);
Expand Down
71 changes: 71 additions & 0 deletions text-regex.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include <stdlib.h>
#include <regex.h>

#include "text-regex.h"

struct Regex {
const char *string;
regex_t regex;
};

Regex *text_regex_new(void) {
Regex *r = calloc(1, sizeof(Regex));
if (!r)
return NULL;
regcomp(&r->regex, "\0\0", 0); /* this should not match anything */
return r;
}

int text_regex_compile(Regex *regex, const char *string, int cflags) {
regex->string = string;
int r = regcomp(&regex->regex, string, cflags);
if (r)
regcomp(&regex->regex, "\0\0", 0);
return r;
}

void text_regex_free(Regex *r) {
if (!r)
return;
regfree(&r->regex);
free(r);
}

int text_search_range_forward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
char *buf = malloc(len + 1);
if (!buf)
return REG_NOMATCH;
len = text_bytes_get(txt, pos, len, buf);
buf[len] = '\0';
regmatch_t match[nmatch];
int ret = regexec(&r->regex, buf, nmatch, match, eflags);
if (!ret) {
for (size_t i = 0; i < nmatch; i++) {
pmatch[i].start = match[i].rm_so == -1 ? EPOS : pos + match[i].rm_so;
pmatch[i].end = match[i].rm_eo == -1 ? EPOS : pos + match[i].rm_eo;
}
}
free(buf);
return ret;
}

int text_search_range_backward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
char *buf = malloc(len + 1);
if (!buf)
return REG_NOMATCH;
len = text_bytes_get(txt, pos, len, buf);
buf[len] = '\0';
regmatch_t match[nmatch];
char *cur = buf;
int ret = REG_NOMATCH;
while (!regexec(&r->regex, cur, nmatch, match, eflags)) {
ret = 0;
for (size_t i = 0; i < nmatch; i++) {
pmatch[i].start = match[i].rm_so == -1 ? EPOS : pos + (size_t)(cur - buf) + match[i].rm_so;
pmatch[i].end = match[i].rm_eo == -1 ? EPOS : pos + (size_t)(cur - buf) + match[i].rm_eo;
}
cur += match[0].rm_eo;
}
free(buf);
return ret;
}
15 changes: 15 additions & 0 deletions text-regex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef TEXT_REGEX_H
#define TEXT_REGEX_H

#include "text.h"

typedef struct Regex Regex;
typedef Filerange RegexMatch;

Regex *text_regex_new(void);
int text_regex_compile(Regex *r, const char *regex, int cflags);
void text_regex_free(Regex *r);
int text_search_range_forward(Text*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags);
int text_search_range_backward(Text*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags);

#endif
68 changes: 0 additions & 68 deletions text.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <regex.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
Expand All @@ -41,11 +40,6 @@
* results in havoc. */
#define BUFFER_MMAP_SIZE (1 << 23)

struct Regex {
const char *string;
regex_t regex;
};

/* Buffer holding the file content, either readonly mmap(2)-ed from the original
* file or heap allocated to store the modifications.
*/
Expand Down Expand Up @@ -1465,68 +1459,6 @@ size_t text_history_get(Text *txt, size_t index) {
return EPOS;
}

Regex *text_regex_new(void) {
Regex *r = calloc(1, sizeof(Regex));
if (!r)
return NULL;
regcomp(&r->regex, "\0\0", 0); /* this should not match anything */
return r;
}

int text_regex_compile(Regex *regex, const char *string, int cflags) {
regex->string = string;
int r = regcomp(&regex->regex, string, cflags);
if (r)
regcomp(&regex->regex, "\0\0", 0);
return r;
}

void text_regex_free(Regex *r) {
if (!r)
return;
regfree(&r->regex);
free(r);
}

int text_search_range_forward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
char *buf = malloc(len + 1);
if (!buf)
return REG_NOMATCH;
len = text_bytes_get(txt, pos, len, buf);
buf[len] = '\0';
regmatch_t match[nmatch];
int ret = regexec(&r->regex, buf, nmatch, match, eflags);
if (!ret) {
for (size_t i = 0; i < nmatch; i++) {
pmatch[i].start = match[i].rm_so == -1 ? EPOS : pos + match[i].rm_so;
pmatch[i].end = match[i].rm_eo == -1 ? EPOS : pos + match[i].rm_eo;
}
}
free(buf);
return ret;
}

int text_search_range_backward(Text *txt, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags) {
char *buf = malloc(len + 1);
if (!buf)
return REG_NOMATCH;
len = text_bytes_get(txt, pos, len, buf);
buf[len] = '\0';
regmatch_t match[nmatch];
char *cur = buf;
int ret = REG_NOMATCH;
while (!regexec(&r->regex, cur, nmatch, match, eflags)) {
ret = 0;
for (size_t i = 0; i < nmatch; i++) {
pmatch[i].start = match[i].rm_so == -1 ? EPOS : pos + (size_t)(cur - buf) + match[i].rm_so;
pmatch[i].end = match[i].rm_eo == -1 ? EPOS : pos + (size_t)(cur - buf) + match[i].rm_eo;
}
cur += match[0].rm_eo;
}
free(buf);
return ret;
}

bool text_range_valid(Filerange *r) {
return r->start != EPOS && r->end != EPOS && r->start <= r->end;
}
Expand Down
9 changes: 0 additions & 9 deletions text.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,4 @@ ssize_t text_range_write(Text*, Filerange*, int fd);
/* release all ressources associated with this text instance */
void text_free(Text*);

typedef struct Regex Regex;
typedef Filerange RegexMatch;

Regex *text_regex_new(void);
int text_regex_compile(Regex *r, const char *regex, int cflags);
void text_regex_free(Regex *r);
int text_search_range_forward(Text*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags);
int text_search_range_backward(Text*, size_t pos, size_t len, Regex *r, size_t nmatch, RegexMatch pmatch[], int eflags);

#endif

0 comments on commit 8129933

Please sign in to comment.