Actually use the eina_file memory mapping

Any appended or modified lines need to be stored seperately.
Always check for modified content before using the memory map from the
backing file.
This commit is contained in:
Andy Williams 2014-11-19 22:39:00 +00:00
parent f8896b1f54
commit 822ef10934
10 changed files with 119 additions and 54 deletions

View File

@ -23,6 +23,14 @@ _elm_code_test_win_del(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, voi
elm_exit();
}
static void _append_line(Elm_Code_File *file, const char *line)
{
int length;
length = strlen(line);
elm_code_file_line_append(file, line, length);
}
static Evas_Object *
_elm_code_test_welcome_setup(Evas_Object *parent)
{
@ -32,12 +40,12 @@ _elm_code_test_welcome_setup(Evas_Object *parent)
code = elm_code_create();
elm_code_file_new(code);
widget = elm_code_widget_add(parent, code);
elm_code_file_line_append(code->file, "Hello World, Elm Code!");
_append_line(code->file, "Hello World, Elm Code!");
elm_code_file_line_token_add(code->file, 1, 14, 21, ELM_CODE_TOKEN_TYPE_COMMENT);
elm_code_file_line_append(code->file, "");
elm_code_file_line_append(code->file, "This is a demo of elm_code's capabilities.");
_append_line(code->file, "");
_append_line(code->file, "This is a demo of elm_code's capabilities.");
elm_code_file_line_append(code->file, "*** Currently experimental ***");
_append_line(code->file, "*** Currently experimental ***");
elm_code_file_line_status_set(code->file, 4, ELM_CODE_STATUS_TYPE_ERROR);
evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
@ -65,12 +73,12 @@ _elm_code_test_diff_setup(Evas_Object *parent)
elm_code_file_new(code);
widget = elm_code_widget_add(parent, code);
elm_code_file_line_append(code->file, "Some content to diff");
elm_code_file_line_append(code->file, "");
elm_code_file_line_append(code->file, "more");
elm_code_file_line_append(code->file, "removed");
elm_code_file_line_append(code->file, "will change");
elm_code_file_line_append(code->file, "unchanged");
_append_line(code->file, "Some content to diff");
_append_line(code->file, "");
_append_line(code->file, "more");
_append_line(code->file, "removed");
_append_line(code->file, "will change");
_append_line(code->file, "unchanged");
elm_code_file_line_status_set(code->file, 4, ELM_CODE_STATUS_TYPE_REMOVED);
elm_code_file_line_token_add(code->file, 4, 1, 7, ELM_CODE_TOKEN_TYPE_REMOVED);
@ -87,12 +95,12 @@ _elm_code_test_diff_setup(Evas_Object *parent)
elm_code_file_new(code);
widget = elm_code_widget_add(parent, code);
elm_code_file_line_append(code->file, "Some content to diff");
elm_code_file_line_append(code->file, "added");
elm_code_file_line_append(code->file, "more");
elm_code_file_line_append(code->file, "");
elm_code_file_line_append(code->file, "changed");
elm_code_file_line_append(code->file, "unchanged");
_append_line(code->file, "Some content to diff");
_append_line(code->file, "added");
_append_line(code->file, "more");
_append_line(code->file, "");
_append_line(code->file, "changed");
_append_line(code->file, "unchanged");
elm_code_file_line_status_set(code->file, 2, ELM_CODE_STATUS_TYPE_ADDED);
elm_code_file_line_token_add(code->file, 2, 1, 5, ELM_CODE_TOKEN_TYPE_ADDED);

View File

@ -20,16 +20,25 @@ static Elm_Code_Line *_elm_code_blank_create(int line)
return ecl;
}
static void _elm_code_file_line_append_data(Elm_Code_File *file, const char *content, int length, int row)
static void _elm_code_file_line_append_data(Elm_Code_File *file, const char *content, int length, int row, Eina_Bool mapped)
{
Elm_Code_Line *line;
line = _elm_code_blank_create(row);
if (!line) return;
line->content = malloc(sizeof(char) * (length + 1));
strncpy(line->content, content, length);
line->content[length] = 0;
if (mapped)
{
line->content = content;
line->length = length;
}
else
{
line->modified = malloc(sizeof(char)*(length+1));
strncpy(line->modified, content, length);
line->modified[length] = 0;
line->length = length;
}
file->lines = eina_list_append(file->lines, line);
@ -64,6 +73,7 @@ EAPI Elm_Code_File *elm_code_file_open(Elm_Code *code, const char *path)
ret->file = file;
lastindex = 1;
ret->map = eina_file_map_all(file, EINA_FILE_POPULATE);
it = eina_file_map_lines(file);
EINA_ITERATOR_FOREACH(it, line)
{
@ -78,7 +88,7 @@ EAPI Elm_Code_File *elm_code_file_open(Elm_Code *code, const char *path)
ret->lines = eina_list_append(ret->lines, ecl);
}
_elm_code_file_line_append_data(ret, line->start, line->length, lastindex = line->index);
_elm_code_file_line_append_data(ret, line->start, line->length, lastindex = line->index, EINA_TRUE);
}
eina_iterator_free(it);
@ -96,11 +106,18 @@ EAPI void elm_code_file_free(Elm_Code_File *file)
EINA_LIST_FREE(file->lines, l)
{
if (l->content)
free(l->content);
if (l->modified)
free(l->modified);
free(l);
}
if (file->file)
{
if (file->map)
eina_file_map_free(file->file, file->map);
eina_file_close(file->file);
}
free(file);
}
@ -125,8 +142,9 @@ EAPI void elm_code_file_clear(Elm_Code_File *file)
EINA_LIST_FREE(file->lines, l)
{
if (l->content)
free(l->content);
if (l->modified)
free(l->modified);
free(l);
}
@ -140,12 +158,12 @@ EAPI unsigned int elm_code_file_lines_get(Elm_Code_File *file)
}
EAPI void elm_code_file_line_append(Elm_Code_File *file, const char *line)
EAPI void elm_code_file_line_append(Elm_Code_File *file, const char *line, int length)
{
int row;
row = elm_code_file_lines_get(file);
_elm_code_file_line_append_data(file, line, strlen(line), row+1);
_elm_code_file_line_append_data(file, line, length, row+1, EINA_FALSE);
}
EAPI Elm_Code_Line *elm_code_file_line_get(Elm_Code_File *file, unsigned int number)
@ -153,7 +171,7 @@ EAPI Elm_Code_Line *elm_code_file_line_get(Elm_Code_File *file, unsigned int num
return eina_list_nth(file->lines, number - 1);
}
EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int number)
EAPI const char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int number, int *length)
{
Elm_Code_Line *line;
@ -161,6 +179,11 @@ EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int numb
if (!line)
return NULL;
*length = line->length;
if (line->modified)
return line->modified;
return line->content;
}

View File

@ -24,8 +24,10 @@ typedef struct _Elm_Code_Token
typedef struct _Elm_Code_Line
{
char *content;
const char *content;
int length;
unsigned int number;
char *modified;
Elm_Code_Status_Type status;
Eina_List *tokens;
@ -39,6 +41,7 @@ typedef struct _Elm_Code_File
Eina_List *lines;
Eina_File *file;
void *map;
} Elm_Code_File;
@ -80,11 +83,11 @@ EAPI void elm_code_file_clear(Elm_Code_File *file);
EAPI unsigned int elm_code_file_lines_get(Elm_Code_File *file);
EAPI void elm_code_file_line_append(Elm_Code_File *file, const char *line);
EAPI void elm_code_file_line_append(Elm_Code_File *file, const char *line, int length);
EAPI Elm_Code_Line *elm_code_file_line_get(Elm_Code_File *file, unsigned int line);
EAPI char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int line);
EAPI const char *elm_code_file_line_content_get(Elm_Code_File *file, unsigned int line, int *length);
EAPI void elm_code_file_line_status_set(Elm_Code_File *file, unsigned int line, Elm_Code_Status_Type status);

View File

@ -52,7 +52,7 @@ EAPI void elm_code_widget_fill_line_tokens(Evas_Textgrid_Cell *cells, int count,
int start, length;
start = 1;
length = strlen(line->content);
length = line->length;
EINA_LIST_FOREACH(line->tokens, item, token)
{
@ -77,7 +77,7 @@ static void _elm_code_widget_fill_line(Evas_Object *o, Evas_Textgrid_Cell *cells
if (!_elm_code_widget_resize(o))
return;
length = strlen(line->content);
length = line->length;
evas_object_textgrid_size_get(o, &w, NULL);
cells[0].codepoint = status_icons[line->status];
@ -85,7 +85,10 @@ static void _elm_code_widget_fill_line(Evas_Object *o, Evas_Textgrid_Cell *cells
cells[0].fg = ELM_CODE_TOKEN_TYPE_DEFAULT;
cells[0].bg = line->status;
chr = (char *)line->content;
if (line->modified)
chr = line->modified;
else
chr = (char *)line->content;
for (x = 1; x < (unsigned int) w && x <= length; x++)
{
cells[x].codepoint = *chr;

View File

@ -52,6 +52,18 @@ START_TEST (elm_code_file_load_blank_lines)
}
END_TEST
static void _assert_line_content_eq(const char *content, Elm_Code_Line *line)
{
int length;
int c;
length = strlen(content);
ck_assert_int_eq(length, line->length);
for (c = 0; c < length; c++)
ck_assert_uint_eq(content[c], line->content[c]);
}
START_TEST (elm_code_file_load_content)
{
char *path = "elm_code/tests/testfile.txt";
@ -61,8 +73,8 @@ START_TEST (elm_code_file_load_content)
code = elm_code_create();
file = elm_code_file_open(code, path);
ck_assert_str_eq("line2", elm_code_file_line_content_get(file, 2));
ck_assert_str_eq("another line", elm_code_file_line_content_get(file, 4));
_assert_line_content_eq("line2", elm_code_file_line_get(file, 2));
_assert_line_content_eq("another line", elm_code_file_line_get(file, 4));
elm_code_file_close(file);
elm_code_free(code);
}

View File

@ -13,7 +13,7 @@ START_TEST (elm_code_file_memory_lines)
file = elm_code_file_new(code);
ck_assert_uint_eq(0, elm_code_file_lines_get(file));
elm_code_file_line_append(file, "a line");
elm_code_file_line_append(file, "a line", 6);
ck_assert_uint_eq(1, elm_code_file_lines_get(file));
elm_code_free(code);
@ -29,7 +29,7 @@ START_TEST (elm_code_file_memory_tokens)
code = elm_code_create();
file = elm_code_file_new(code);
elm_code_file_line_append(file, "a line");
elm_code_file_line_append(file, "a line", 6);
elm_code_file_line_token_add(file, 1, 2, 5, ELM_CODE_TOKEN_TYPE_COMMENT);
line = elm_code_file_line_get(file, 1);

View File

@ -29,7 +29,7 @@ START_TEST (elm_code_parse_hook_memory_test)
file = elm_code_file_new(code);
elm_code_parser_add(code, _parser_line_callback, _parser_file_callback);
elm_code_file_line_append(file, "some \"test content\" for parsing");
elm_code_file_line_append(file, "some \"test content\" for parsing", 31);
ck_assert_int_eq(1, line_calls);
ck_assert_int_eq(0, file_calls);

View File

@ -20,7 +20,7 @@ START_TEST (elm_code_widget_token_render_simple_test)
code = elm_code_create();
file = elm_code_file_new(code);
elm_code_file_line_append(file, "some \"test content\", 45");
elm_code_file_line_append(file, "some \"test content\", 45", 23);
line = elm_code_file_line_get(file, 1);
length = strlen(line->content);

View File

@ -211,18 +211,37 @@ _exe_error(void *d EINA_UNUSED, int t EINA_UNUSED, void *event_info)
return ECORE_CALLBACK_RENEW;
}
static void _edi_test_append(const char *content, Elm_Code_Status_Type type)
static void _edi_test_append(const char *content, int length, Elm_Code_Status_Type type)
{
elm_code_file_line_append(_edi_test_code->file, content);
elm_code_file_line_append(_edi_test_code->file, content, length);
elm_code_file_line_status_set(_edi_test_code->file, elm_code_file_lines_get(_edi_test_code->file), type);
}
static Eina_Bool _edi_test_line_contains(const char *start, unsigned int length, const char *needle)
{
unsigned int needlelen, c;
char *ptr;
ptr = (char *) start;
needlelen = strlen(needle);
for (c = 0; c < length - strlen(needle); c++)
{
if (!strncmp(ptr, needle, needlelen))
return EINA_TRUE;
ptr++;
}
return EINA_FALSE;
}
static void _edi_test_line_parse_suite(const char *path)
{
Eina_File *file;
Eina_File_Line *line;
Eina_Iterator *it;
char logfile[PATH_MAX], *tmp;
char logfile[PATH_MAX];
int pathlength;
Elm_Code_Status_Type status;
@ -235,36 +254,33 @@ static void _edi_test_line_parse_suite(const char *path)
EINA_ITERATOR_FOREACH(it, line)
{
status = ELM_CODE_STATUS_TYPE_DEFAULT;
tmp = malloc(line->length + 1);
strncpy(tmp, line->start, line->length);
tmp[line->length] = 0;
if (strstr(tmp, ":P:"))
if (_edi_test_line_contains(line->start, line->length, ":P:"))
status = ELM_CODE_STATUS_TYPE_PASSED;
else if (strstr(tmp, ":F:"))
else if (_edi_test_line_contains(line->start, line->length, ":F:"))
status = ELM_CODE_STATUS_TYPE_FAILED;
_edi_test_append(tmp, status);
free(tmp);
_edi_test_append(line->start, line->length, status);
}
eina_iterator_free(it);
eina_file_close(file);
}
static void _edi_test_line_parse_suite_pass_line(const char *line)
{
_edi_test_line_parse_suite(line);
_edi_test_append("Suite passed", ELM_CODE_STATUS_TYPE_DEFAULT);
_edi_test_append("Suite passed", 13, ELM_CODE_STATUS_TYPE_DEFAULT);
}
static void _edi_test_line_parse_suite_fail_line(const char *line)
{
_edi_test_line_parse_suite(line);
_edi_test_append("Suite failed", ELM_CODE_STATUS_TYPE_DEFAULT);
_edi_test_append("Suite failed", 13, ELM_CODE_STATUS_TYPE_DEFAULT);
}
static void _edi_test_line_parse_summary_line(const char *line)
{
_edi_test_append(line, ELM_CODE_STATUS_TYPE_DEFAULT);
_edi_test_append(line, strlen(line), ELM_CODE_STATUS_TYPE_DEFAULT);
}
static void _edi_test_line_callback(const char *content)

View File

@ -28,7 +28,7 @@ void print_cb(const Eina_Log_Domain *domain,
domain->domain_str, file, fnc, line);
vsnprintf(buffer + printed, buffer_len - printed, fmt, args);
elm_code_file_line_append(_elm_code->file, buffer);
elm_code_file_line_append(_elm_code->file, buffer, strlen(buffer));
if (level <= EINA_LOG_LEVEL_ERR)
{
line_count = elm_code_file_lines_get(_elm_code->file);