#ifdef HAVE_CONFIG # include "config.h" #endif #include "Elm_Code.h" #include "elm_code_private.h" EAPI const char * elm_code_line_text_get(Elm_Code_Line *line, unsigned int *length) { if (!line) return NULL; if (length) *length = line->length; if (line->modified) return line->modified; return line->content; } EAPI void elm_code_line_text_set(Elm_Code_Line *line, const char *chars, unsigned int length) { Elm_Code_File *file; char *newtext; if (!line) return; if (line->modified) free(line->modified); newtext = malloc(sizeof(char) * length); strncpy(newtext, chars, length); line->modified = newtext; line->length = length; file = line->file; if (file->parent) { _elm_code_parse_line(file->parent, line); elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_LOAD_DONE, line); } } EAPI int elm_code_text_strnpos(const char *content, unsigned int length, const char *search, int offset) { unsigned int searchlen, c; char *ptr; searchlen = strlen(search); ptr = (char *) content; if (searchlen > length) return ELM_CODE_TEXT_NOT_FOUND; ptr += offset; for (c = offset; c <= length - searchlen; c++) { if (!strncmp(ptr, search, searchlen)) return c; ptr++; } return ELM_CODE_TEXT_NOT_FOUND; } EAPI int elm_code_line_text_strpos(Elm_Code_Line *line, const char *search, int offset) { unsigned int length; const char *content; content = elm_code_line_text_get(line, &length); return elm_code_text_strnpos(content, length, search, offset); } EAPI Eina_Bool elm_code_line_text_contains(Elm_Code_Line *line, const char *search) { return elm_code_line_text_strpos(line, search, 0) != ELM_CODE_TEXT_NOT_FOUND; } EAPI char * elm_code_line_text_substr(Elm_Code_Line *line, unsigned int position, int length) { const char *content; if (!line || length < 1) return strdup(""); if (position + length > line->length) length = line->length - position; content = elm_code_line_text_get(line, NULL); return strndup(content + position, length); } static void _elm_code_line_tokens_move_right(Elm_Code_Line *line, int position, int move) { Eina_List *item; Elm_Code_Token *token; EINA_LIST_FOREACH(line->tokens, item, token) { if (token->end >= position) token->end += move; if (token->start > position) token->start += move; } } static void _elm_code_line_tokens_move_left(Elm_Code_Line *line, int position, int move) { Eina_List *item, *next; Elm_Code_Token *token; EINA_LIST_FOREACH_SAFE(line->tokens, item, next, token) { if (token->end >= position) token->end -= move; if (token->start > position) token->start -= move; if (token->end < token->start) line->tokens = eina_list_remove_list(line->tokens, item); } } EAPI void elm_code_line_text_insert(Elm_Code_Line *line, unsigned int position, const char *string, int length) { Elm_Code_File *file; char *inserted; if (!line) return; inserted = malloc(sizeof(char) * line->length + length); if (position > line->length) position = line->length; _elm_code_line_tokens_move_right(line, position, length); if (line->modified) { strncpy(inserted, line->modified, position); strncpy(inserted + position, string, length); strncpy(inserted + position + length, line->modified + position, line->length - position); free(line->modified); } else { strncpy(inserted, line->content, position); strncpy(inserted + position, string, length); strncpy(inserted + position + length, line->content + position, line->length - position); } line->modified = inserted; line->length += length; file = line->file; elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_LOAD_DONE, line); } EAPI void elm_code_line_text_remove(Elm_Code_Line *line, unsigned int position, int length) { Elm_Code_File *file; char *removed; if (!line) return; removed = malloc(sizeof(char) * line->length - length); if (position > line->length) position = line->length; _elm_code_line_tokens_move_left(line, position, length); if (line->modified) { strncpy(removed, line->modified, position); strncpy(removed + position, line->modified + position + length, line->length - position - length); free(line->modified); } else { strncpy(removed, line->content, position); strncpy(removed + position, line->content + position + length, line->length - position - length); } line->modified = removed; line->length -= length; file = line->file; elm_code_callback_fire(file->parent, &ELM_CODE_EVENT_LINE_LOAD_DONE, line); } /* generic text functions */ EAPI unsigned int elm_code_text_tabwidth_at_position(unsigned int position, unsigned int tabstop) { return tabstop - (position % tabstop); } EAPI int elm_code_text_newlinenpos(const char *text, unsigned int length, short *nllen) { int lfpos, crpos; int check; if (nllen) *nllen = 1; lfpos = elm_code_text_strnpos(text, length, "\n", 0); check = length; if (lfpos != ELM_CODE_TEXT_NOT_FOUND) check = lfpos + 1; crpos = elm_code_text_strnpos(text, check, "\r", 0); if (lfpos == ELM_CODE_TEXT_NOT_FOUND && crpos == ELM_CODE_TEXT_NOT_FOUND) return ELM_CODE_TEXT_NOT_FOUND; if (crpos == ELM_CODE_TEXT_NOT_FOUND) return lfpos; if (lfpos == ELM_CODE_TEXT_NOT_FOUND) return crpos; if (nllen) *nllen = 2; if (lfpos < crpos) return lfpos; return crpos; } EAPI unsigned int elm_code_text_leading_whitespace_length(const char *text, unsigned int length) { unsigned int count = 0; char *ptr = (char *)text; while (count < length) { if (!(*ptr == ' ' || *ptr == '\t')) break; count++; ptr++; } return count; }