#ifdef HAVE_CONFIG_H # include "config.h" #endif #define BUFFER_SIZE 1024 #include #include #include #include #include #include #include "edi_consolepanel.h" #include "mainview/edi_mainview.h" #include "edi_config.h" #include "edi_private.h" static Evas_Object *_console_box; static const char *_current_dir = NULL; static unsigned int _edi_strlen_current_dir; static int _edi_test_count; static int _edi_test_pass; static int _edi_test_fail; static Elm_Code *_edi_test_code; static void _edi_test_line_callback(const char *content); static const char *_edi_consolepanel_icon_for_line(const char *line) { if (strstr(line, " error:") != NULL) return "error"; if (strstr(line, " warning:") != NULL) return "important"; if (strstr(line, " info:") != NULL || strstr(line, " note:") != NULL) return "info"; return NULL; } static Eina_Bool _startswith_location(const char *line) { regex_t regex; int ret; regcomp(®ex, "^[^/].*:[0-9]*:[0-9]* ", 0); ret = !regexec(®ex, line, 0, NULL, 0); regfree(®ex); return ret; } static void _edi_consolepanel_clicked_cb(void *data, Evas *e EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event_info EINA_UNUSED) { Edi_Path_Options *options; if (strstr(data, edi_project_get()) != data) return; options = edi_path_options_create(data); edi_mainview_open(options); } static void _edi_consolepanel_parse_directory(const char *line) { const char *pos; pos = strstr(line, "Entering directory "); if (pos) { if (_current_dir) eina_stringshare_del(_current_dir); _edi_strlen_current_dir = strlen(pos) - 21; _current_dir = eina_stringshare_add_length(pos + 20, _edi_strlen_current_dir); } } static void _edi_consolepanel_scroll_to_bottom() { Evas_Object *scroller; Evas_Coord x, y, w, h; scroller = elm_object_parent_widget_get(_console_box); evas_object_geometry_get(_console_box, &x, &y, &w, &h); elm_scroller_region_show(scroller, x, h - 10, w, 10); } static void _edi_consolepanel_append_line_type(const char *line, Eina_Bool err) { Evas_Object *txt, *icon, *box; char *buf, *path; const char *pos, *file, *type = NULL, *cursor = NULL; int length; txt = elm_label_add(_console_box); if (err) evas_object_color_set(txt, 255, 63, 63, 255); else evas_object_color_set(txt, 255, 255, 255, 255); if (_startswith_location(line)) { cursor = ELM_CURSOR_HAND1; elm_object_cursor_set(txt, cursor); elm_object_cursor_theme_search_enabled_set(txt, EINA_TRUE); pos = strstr(line, " "); length = strlen(line) - strlen(pos); file = eina_stringshare_add_length(line, length); buf = malloc(sizeof(char) * (strlen(line) + 8)); snprintf(buf, strlen(line) + 8, "%s%s/n", file, pos); elm_object_text_set(txt, buf); length = _edi_strlen_current_dir + strlen(file) + 2; path = malloc(sizeof(char) * length); snprintf(path, length, "%s/%s\n", _current_dir, file); evas_object_event_callback_add(txt, EVAS_CALLBACK_MOUSE_DOWN, _edi_consolepanel_clicked_cb, eina_stringshare_add(path)); free(path); free(buf); } else { _edi_consolepanel_parse_directory(line); elm_object_text_set(txt, line); } evas_object_size_hint_weight_set(txt, EVAS_HINT_EXPAND, 0.0); evas_object_size_hint_align_set(txt, 0.0, EVAS_HINT_FILL); evas_object_show(txt); if (err) type = _edi_consolepanel_icon_for_line(line); icon = elm_icon_add(_console_box); evas_object_size_hint_min_set(icon, 14, 14); evas_object_size_hint_max_set(icon, 14, 14); if (type) { elm_icon_standard_set(icon, type); if (cursor) { elm_object_cursor_set(icon, cursor); elm_object_cursor_theme_search_enabled_set(icon, EINA_TRUE); } } evas_object_show(icon); box = elm_box_add(_console_box); evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL); elm_box_horizontal_set(box, EINA_TRUE); elm_box_pack_end(box, icon); elm_box_pack_end(box, txt); evas_object_show(box); elm_box_pack_end(_console_box, box); _edi_consolepanel_scroll_to_bottom(); _edi_test_line_callback(line); } EAPI void edi_consolepanel_append_line(const char *line) { _edi_consolepanel_append_line_type(line, EINA_FALSE); } EAPI void edi_consolepanel_append_error_line(const char *line) { _edi_consolepanel_append_line_type(line, EINA_TRUE); } EAPI void edi_consolepanel_clear() { elm_box_clear(_console_box); elm_code_file_clear(_edi_test_code->file); _edi_test_count = 0; _edi_test_pass = 0; _edi_test_fail = 0; } static Eina_Bool _exe_data(void *d EINA_UNUSED, int t EINA_UNUSED, void *event_info) { Ecore_Exe_Event_Data *ev; Ecore_Exe_Event_Data_Line *el; ev = event_info; for (el = ev->lines; el && el->line; el++) edi_consolepanel_append_line(el->line); return ECORE_CALLBACK_RENEW; } static Eina_Bool _exe_error(void *d EINA_UNUSED, int t EINA_UNUSED, void *event_info) { Ecore_Exe_Event_Data *ev; Ecore_Exe_Event_Data_Line *el; ev = event_info; for (el = ev->lines; el && el->line; el++) edi_consolepanel_append_error_line(el->line); return ECORE_CALLBACK_RENEW; } 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, 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]; int pathlength; Elm_Code_Status_Type status; pathlength = strlen(path); snprintf(logfile, pathlength + 4 + 1, "%s.log", path); file = eina_file_open(logfile, EINA_FALSE); it = eina_file_map_lines(file); EINA_ITERATOR_FOREACH(it, line) { status = ELM_CODE_STATUS_TYPE_DEFAULT; if (_edi_test_line_contains(line->start, line->length, ":P:")) status = ELM_CODE_STATUS_TYPE_PASSED; else if (_edi_test_line_contains(line->start, line->length, ":F:")) status = ELM_CODE_STATUS_TYPE_FAILED; _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", 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", 13, ELM_CODE_STATUS_TYPE_DEFAULT); } static void _edi_test_line_parse_summary_line(const char *line) { _edi_test_append(line, strlen(line), ELM_CODE_STATUS_TYPE_DEFAULT); } static void _edi_test_line_callback(const char *content) { if (!content) return; if (content[0] == '#') { _edi_test_line_parse_summary_line(content + 2); return; } if (!strncmp(content, "PASS:", 5)) { _edi_test_count++; _edi_test_pass++; _edi_test_line_parse_suite_pass_line(content + 6); } else if (!strncmp(content, "FAIL:", 5)) { _edi_test_count++; _edi_test_fail++; _edi_test_line_parse_suite_fail_line(content + 6); } } EAPI void edi_consolepanel_add(Evas_Object *parent) { Evas_Object *scroll, *vbx; scroll = elm_scroller_add(parent); evas_object_size_hint_weight_set(scroll, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(scroll, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(scroll); vbx = elm_box_add(parent); evas_object_size_hint_weight_set(vbx, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_show(vbx); elm_object_content_set(scroll, vbx); _console_box = vbx; elm_box_pack_end(parent, scroll); ecore_event_handler_add(ECORE_EXE_EVENT_DATA, _exe_data, NULL); ecore_event_handler_add(ECORE_EXE_EVENT_ERROR, _exe_error, NULL); } EAPI void edi_testpanel_add(Evas_Object *parent) { Elm_Code *code; Elm_Code_Widget2 *widget; code = elm_code_create(); _edi_test_code = code; widget = eo_add(ELM_CODE_WIDGET2_CLASS, parent); eo_do(widget, elm_code_widget2_code_set(code); elm_code_widget2_font_size_set(_edi_cfg->font.size)); evas_object_size_hint_weight_set(widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); evas_object_size_hint_align_set(widget, EVAS_HINT_FILL, EVAS_HINT_FILL); evas_object_show(widget); elm_box_pack_end(parent, widget); }