#define _LARGEFILE64_SOURCE /* required for GLIBC to enable stat64 and friends */ #include #include #include #include #include #include #include #include "mt.h" #include "help.h" #include "mem.h" #include "error.h" #include "term.h" #include "utils.h" #include "selbox.h" #include "globals.h" int edit_stripper_edit_regexp(NEWWIN *win, char **old_re, mybool_t *case_insensitive) { int changed = 0; char *new_re; /* ask new reg exp */ mvwprintw(win -> win, 15, 2, "Edit regular expression: "); new_re = edit_string(win, 16, 2, 58, 128, 0, *old_re, HELP_ENTER_REGEXP, -1, &search_h, case_insensitive); if (new_re) { myfree(*old_re); *old_re = new_re; changed = 1; } return changed; } int edit_stripper_edit_offsets(NEWWIN *win, int *offset_start, int *offset_end) { char *str_start = NULL, *str_end = NULL; char buffer[32] = { 0 }; char linebuf[68 + 1]; int changed = 0; if (*offset_start != -1) snprintf(buffer, sizeof(buffer), "%d", *offset_start); mvwprintw(win -> win, 15, 2, "Enter start offset: "); str_start = edit_string(win, 16, 2, 5, 5, 1, buffer, HELP_STRIPPER_START_OFFSET, -1, NULL, NULL); if (str_start) { if (*offset_end != -1) snprintf(buffer, sizeof(buffer), "%d", *offset_end); else buffer[0] = 0x00; mvwprintw(win -> win, 15, 2, "Enter end offset: "); memset(linebuf, ' ', sizeof(linebuf)); linebuf[sizeof(linebuf) - 1] = 0x00; mvwprintw(win -> win, 16, 1, "%s", linebuf); str_end = edit_string(win, 16, 2, 5, 5, 1, buffer, HELP_STRIPPER_END_OFFSET, -1, NULL, NULL); if (str_end) { *offset_start = atoi(str_start); *offset_end = atoi(str_end); changed = 1; } } myfree(str_start); myfree(str_end); return changed; } int edit_stripper_edit_field(NEWWIN *win, char **del, int *col_nr) { int changed = 0; char *new_del = NULL; char *new_col_nr = NULL; char buffer[32] = { 0 }; char linebuf[58 + 1]; mvwprintw(win -> win, 15, 2, "Enter delimiter: "); new_del = edit_string(win, 16, 2, 58, 128, 0, *del, HELP_STRIPPER_DELIMITER, -1, NULL, NULL); if (new_del) { mvwprintw(win -> win, 15, 2, "Enter column number: "); memset(linebuf, ' ', sizeof(linebuf)); linebuf[sizeof(linebuf) - 1] = 0x00; mvwprintw(win -> win, 16, 1, "%s", linebuf); if (*col_nr != -1) snprintf(buffer, sizeof(buffer), "%d", *col_nr); new_col_nr = edit_string(win, 16, 2, 5, 5, 1, buffer, HELP_STRIPPER_COL_NR, -1, NULL, NULL); } if (new_del != NULL && new_col_nr != NULL) { *del = mystrdup(new_del, __FILE__, __PRETTY_FUNCTION__, __LINE__); *col_nr = atoi(new_col_nr); changed = 1; } myfree(new_col_nr); myfree(new_del); return changed; } int edit_strippers(void) { int changed = 0; NEWWIN *mywin; proginfo *cur; int f_index = 0; int cur_strip = 0; mybool_t case_insensitive = re_case_insensitive; /* select window */ if (nfd > 1) f_index = select_window(HELP_ENTER_STRIPPER_SELECT_WINDOW, "Select window (stripper editing)"); if (f_index == -1) /* user pressed Q/X */ return 0; /* select subwindow */ cur = &pi[f_index]; if (cur -> next) cur = select_subwindow(f_index, HELP_ENTER_STRIPPER_SELECT_SUBWINDOW, "Select subwindow (stripper editing)"); if (!cur) return 0; /* create window */ mywin = create_popup(23, 70); for(;;) { int c, key; int loop; char linebuf[68 + 1]; werase(mywin -> win); draw_border(mywin); win_header(mywin, "Edit strip regular expressions"); mvwprintw(mywin -> win, 2, 2, "%s", cur -> filename); escape_print(mywin, 3, 2, "^a^dd, ^e^dit, ^d^elete, ^q^uit"); /* clear */ memset(linebuf, ' ', sizeof(linebuf) - 1); linebuf[sizeof(linebuf) - 1] = 0x00; for(loop=4; loop<22; loop++) mvwprintw(mywin -> win, loop, 1, linebuf); /* display them lines */ for(loop=0; loop n_strip; loop++) { if (loop == cur_strip) ui_inverse_on(mywin); switch((cur -> pstrip)[loop].type) { case STRIP_KEEP_SUBSTR: case STRIP_TYPE_REGEXP: strncpy(linebuf, (cur -> pstrip)[loop].regex_str, 55); linebuf[55] = 0x00; mvwprintw(mywin -> win, 4 + loop, 1, "RE: %s", linebuf); break; case STRIP_TYPE_RANGE: mvwprintw(mywin -> win, 4 + loop, 1, "Range: %d - %d", (cur -> pstrip)[loop].start, (cur -> pstrip)[loop].end); break; case STRIP_TYPE_COLUMN: mvwprintw(mywin -> win, 4 + loop, 1, "Column: %d (delimiter: '%s')", (cur -> pstrip)[loop].col_nr, (cur -> pstrip)[loop].del); break; } if (loop == cur_strip) ui_inverse_off(mywin); mvwprintw(mywin -> win, 4 + loop, 60, "%d", (cur -> pstrip)[loop].match_count); } mydoupdate(); /* wait for key */ for(;;) { key = wait_for_keypress(HELP_REGEXP_MENU, 2, mywin, 1); c = toupper(key); /* convert return to 'E'dit */ if (key == 13) key = c = 'E'; /* any valid keys? */ if (c == 'Q' || c == abort_key || c == 'X' || c == 'A' || c == 'E' || c == 'D' || key == KEY_DOWN || key == 13 || key == KEY_UP) break; if (key == -1) /* T/O waiting for key? then update counters */ { for(loop=0; loop n_strip; loop++) mvwprintw(mywin -> win, 4 + loop, 60, "%d", (cur -> pstrip)[loop].match_count); mydoupdate(); } else wrong_key(); } /* exit this screen? */ if (c == 'Q' || c == abort_key || c == 'X') break; if (key == KEY_UP) { if (cur_strip > 0) cur_strip--; else wrong_key(); } else if (key == KEY_DOWN || key == 13) { if (cur_strip < (cur -> n_strip -1)) cur_strip++; else wrong_key(); } /* add or edit */ if (c == 'A') { int rc; char *regex_str = NULL; int offset_start = -1, offset_end = -1; char *del = NULL; int col_nr = -1; int c; int cur_changed = 0; /* max. 10 regular expressions */ if (cur -> n_strip == 10) { wrong_key(); continue; } /* ask type */ escape_print(mywin, 15, 2, "reg.^e^xp., ^r^ange, ^c^olumn, ^S^ubstrings"); mydoupdate(); for(;;) { c = toupper(wait_for_keypress(HELP_STRIPPER_TYPE, 0, mywin, 0)); if (c == 'E' || c == 'R' || c == 'C' || c == 'S' || c == abort_key || c == 'Q' || c == 'X') break; wrong_key(); } if (c == abort_key || c == 'Q' || c == 'X') continue; if (c == 'E' || c == 'S') { /* user did not abort edit? */ if (edit_stripper_edit_regexp(mywin, ®ex_str, &case_insensitive)) cur_changed = 1; } else if (c == 'R') { if (edit_stripper_edit_offsets(mywin, &offset_start, &offset_end)) cur_changed = 1; } else if (c == 'C') { if (edit_stripper_edit_field(mywin, &del, &col_nr)) cur_changed = 1; } if (!cur_changed) continue; changed = 1; cur_strip = cur -> n_strip++; cur -> pstrip = (strip_t *)myrealloc(cur -> pstrip, cur -> n_strip * sizeof(strip_t), __FILE__, __PRETTY_FUNCTION__, __LINE__); memset(&(cur -> pstrip)[cur_strip], 0x00, sizeof(strip_t)); /* compile */ if (c == 'E' || c == 'S') { if ((rc = regcomp(&(cur -> pstrip)[cur_strip].regex, regex_str, REG_EXTENDED))) { regexp_error_popup(rc, &(cur -> pre)[cur_strip].regex); cur -> n_strip--; if (cur -> n_strip == cur_strip) cur_strip--; myfree(regex_str); } else { /* compilation went well, remember everything */ (cur -> pstrip)[cur_strip].regex_str = regex_str; (cur -> pstrip)[cur_strip].type = (c == 'E' ? STRIP_TYPE_REGEXP : STRIP_KEEP_SUBSTR); } } else if (c == 'R') { (cur -> pstrip)[cur_strip].type = STRIP_TYPE_RANGE; (cur -> pstrip)[cur_strip].start = offset_start; (cur -> pstrip)[cur_strip].end = offset_end; } else if (c == 'C') { (cur -> pstrip)[cur_strip].type = STRIP_TYPE_COLUMN; (cur -> pstrip)[cur_strip].col_nr = col_nr; (cur -> pstrip)[cur_strip].del = del; } /* reset counter (as it is a different regexp which has not matched anything at all) */ (cur -> pstrip)[cur_strip].match_count = 0; } /* delete entry */ else if (c == 'D') { if (cur -> n_strip > 0) { changed = 1; /* delete entry */ myfree((cur -> pstrip)[cur_strip].regex_str); /* update administration */ if (cur -> n_strip == 1) { myfree(cur -> pstrip); cur -> pstrip = NULL; } else { int n_to_move = (cur -> n_strip - cur_strip) - 1; if (n_to_move > 0) memmove(&(cur -> pstrip)[cur_strip], &(cur -> pstrip)[cur_strip+1], sizeof(strip_t) * n_to_move); } cur -> n_strip--; /* move cursor */ if (cur_strip > 0 && cur_strip == cur -> n_strip) { cur_strip--; } } else wrong_key(); } else if (c == 'E') { if (cur -> n_strip > 0) { if ((cur -> pstrip)[cur_strip].type == STRIP_TYPE_REGEXP || (cur -> pstrip)[cur_strip].type == STRIP_KEEP_SUBSTR) { if (edit_stripper_edit_regexp(mywin, &(cur -> pstrip)[cur_strip].regex_str, &case_insensitive)) changed = 1; } else if ((cur -> pstrip)[cur_strip].type == STRIP_TYPE_RANGE) { if (edit_stripper_edit_offsets(mywin, &(cur -> pstrip)[cur_strip].start, &(cur -> pstrip)[cur_strip].end)) changed = 1; } else if ((cur -> pstrip)[cur_strip].type == STRIP_TYPE_COLUMN) { if (edit_stripper_edit_field(mywin, &(cur -> pstrip)[cur_strip].del, &(cur -> pstrip)[cur_strip].col_nr)) changed = 1; } } else wrong_key(); } } delete_popup(mywin); return changed; } void zero_str(char *what, int start, int end) { memset(&what[start], 0x00, end-start); } char do_strip_re(regex_t *pre, int *match_count, char *in, char *strip_what) { char changed = 0; int search_offset = 0; regmatch_t matches[MAX_N_RE_MATCHES]; do { int new_offset = -1; if (regexec(pre, &in[search_offset], MAX_N_RE_MATCHES, matches, 0) != REG_NOMATCH) { int match_i; for(match_i=0; match_i n_strip == 0) return NULL; len = strlen(in); if (len == 0) return NULL; strip_what = (char *)mymalloc(len, __FILE__, __PRETTY_FUNCTION__, __LINE__); new_string = (char *)mymalloc(len + 1, __FILE__, __PRETTY_FUNCTION__, __LINE__); memset(strip_what, 0x01, len); for(loop=0; loop n_strip; loop++) { if ((cur -> pstrip)[loop].type == STRIP_TYPE_RANGE) { memset(&strip_what[(cur -> pstrip)[loop].start], 0x00, (cur -> pstrip)[loop].end - (cur -> pstrip)[loop].start); changed = 1; } else if ((cur -> pstrip)[loop].type == STRIP_TYPE_REGEXP) { changed |= do_strip_re(&(cur -> pstrip)[loop].regex, &(cur -> pstrip)[loop].match_count, in, strip_what); } else if ((cur -> pstrip)[loop].type == STRIP_TYPE_COLUMN) { changed |= do_strip_column((cur -> pstrip)[loop].del, (cur -> pstrip)[loop].col_nr, in, strip_what); } else if ((cur -> pstrip)[loop].type == STRIP_KEEP_SUBSTR) { changed |= do_keep_re(&(cur -> pstrip)[loop].regex, &(cur -> pstrip)[loop].match_count, in, strip_what); } } if (changed) { for(loop=0; loop