/****************************************************************************** * TinTin++ * * Copyright (C) 2004 (See CREDITS file) * * * * This program is protected under the GNU GPL (See COPYING) * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ******************************************************************************/ /****************************************************************************** * (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t * * * * coded by Igor van den Hoven 2004 * ******************************************************************************/ #include "tintin.h" void init_buffer(struct session *ses, int size) { int cnt; push_call("init_buffer(%p,%p)",ses,size); if (ses->scroll_max == size) { pop_call(); return; } if (ses->buffer) { cnt = ses->scroll_row; do { if (++cnt == ses->scroll_max) { cnt = 0; } if (ses->buffer[cnt] == NULL) { break; } str_unhash(ses->buffer[cnt]); } while (cnt != ses->scroll_row); } if (ses->buffer) { free(ses->buffer); } if (size) { ses->buffer = (char **) calloc(size, sizeof(char *)); ses->scroll_max = size; ses->scroll_row = size - 1; ses->scroll_line = - 1; } pop_call(); return; } void add_line_buffer(struct session *ses, char *line, int more_output) { char linebuf[STRING_SIZE]; char *pti, *pto; int lines; int sav_row, sav_col, cur_row, cur_col, top_row, bot_row; push_call("add_line_buffer(%p,%s,%d)",ses,line,more_output); if (ses->buffer == NULL || HAS_BIT(ses->flags, SES_FLAG_SCROLLSTOP)) { pop_call(); return; } sav_row = ses->sav_row; sav_col = ses->sav_col; cur_row = ses->cur_row; cur_col = ses->cur_col; top_row = ses->top_row; bot_row = ses->bot_row; if (more_output == TRUE) { if (strlen(ses->more_output) < BUFFER_SIZE / 2) { strcat(ses->more_output, line); pop_call(); return; } } strcat(ses->more_output, line); pti = pto = ses->more_output; while (*pti != 0) { while (skip_vt102_codes_non_graph(pti)) { interpret_vt102_codes(ses, pti, FALSE); pti += skip_vt102_codes_non_graph(pti); } if (*pti == 0) { break; } if (SCROLL(ses)) { *pto++ = *pti++; } else { pti++; } } *pto = 0; lines = word_wrap(ses, ses->more_output, linebuf, FALSE); ses->more_output[0] = 0; ses->buffer[ses->scroll_row] = str_hash(linebuf, lines); if (more_output == -1) { str_hash_grep(ses->buffer[ses->scroll_row], TRUE); } if (!HAS_BIT(ses->flags, SES_FLAG_LOGLEVEL)) { if (ses->logfile) { logit(ses, linebuf, ses->logfile, TRUE); } } if (gtd->chat) { chat_forward_session(ses, linebuf); } if (ses->logline) { logit(ses, linebuf, ses->logline, TRUE); fclose(ses->logline); ses->logline = NULL; } if (--ses->scroll_row < 0) { ses->scroll_row = ses->scroll_max -1; } if (ses->buffer[ses->scroll_row]) { ses->buffer[ses->scroll_row] = str_unhash(ses->buffer[ses->scroll_row]); } ses->sav_row = sav_row; ses->sav_col = sav_col; ses->cur_row = cur_row; ses->cur_col = cur_col; ses->top_row = top_row; ses->bot_row = bot_row; pop_call(); return; } DO_COMMAND(do_grep) { char left[BUFFER_SIZE], right[BUFFER_SIZE]; int scroll_cnt, grep_cnt, grep_min, grep_max, grep_add, page; grep_cnt = grep_add = scroll_cnt = grep_min = 0; grep_max = ses->bot_row - ses->top_row - 2; get_arg_in_braces(arg, left, FALSE); substitute(ses, left, left, SUB_VAR|SUB_FUN); if (ses->buffer == NULL) { tintin_puts2(ses, "#GREP, NO SCROLL BUFFER AVAILABLE."); } else if (*left == 0) { tintin_puts2(ses, "#GREP WHAT?"); } else { page = get_number(ses, left); if (page) { arg = get_arg_in_braces(arg, left, FALSE); arg = get_arg_in_braces(arg, right, TRUE); if (*right == 0) { tintin_printf2(ses, "#GREP PAGE {%s} FOR WHAT?", left); return ses; } } else { page = 1; arg = get_arg_in_braces(arg, right, TRUE); } if (page > 0) { grep_min = grep_max * page - grep_max; grep_max = grep_max * page; } else { grep_min = grep_max * (page * -1) - grep_max; grep_max = grep_max * (page * -1); } SET_BIT(ses->flags, SES_FLAG_SCROLLSTOP); tintin_header(ses, " GREPPING PAGE %d FOR %s ", page, right); if (page > 0) { scroll_cnt = ses->scroll_row; do { if (scroll_cnt == ses->scroll_max - 1) { scroll_cnt = 0; } else { scroll_cnt++; } if (ses->buffer[scroll_cnt] == NULL) { break; } if (str_hash_grep(ses->buffer[scroll_cnt], FALSE)) { continue; } if (find(ses, ses->buffer[scroll_cnt], right, SUB_NONE)) { grep_add = str_hash_lines(ses->buffer[scroll_cnt]); if (grep_cnt + grep_add > grep_max) { break; } grep_cnt += grep_add; } } while (scroll_cnt != ses->scroll_row); if (grep_cnt <= grep_min) { tintin_puts2(ses, "#NO MATCHES FOUND."); } else do { if (scroll_cnt == 0) { scroll_cnt = ses->scroll_max - 1; } else { scroll_cnt--; } if (ses->buffer[scroll_cnt] == NULL) { break; } if (str_hash_grep(ses->buffer[scroll_cnt], FALSE)) { continue; } if (find(ses, ses->buffer[scroll_cnt], right, SUB_NONE)) { grep_add = str_hash_lines(ses->buffer[scroll_cnt]); if (grep_cnt - grep_add < grep_min) { break; } grep_cnt -= grep_add; tintin_puts2(ses, ses->buffer[scroll_cnt]); } } while (scroll_cnt != ses->scroll_row); } else { if (ses->buffer[0]) { scroll_cnt = ses->scroll_row - 1; } else { scroll_cnt = ses->scroll_max - 1; } do { if (scroll_cnt == -1) { scroll_cnt = 0; } else { scroll_cnt--; } if (ses->buffer[scroll_cnt] == NULL) { break; } if (str_hash_grep(ses->buffer[scroll_cnt], FALSE)) { continue; } if (find(ses, ses->buffer[scroll_cnt], right, SUB_NONE)) { grep_add = str_hash_lines(ses->buffer[scroll_cnt]); if (grep_cnt >= grep_min) { tintin_puts2(ses, ses->buffer[scroll_cnt]); } if (grep_cnt + grep_add >= grep_max) { break; } grep_cnt += grep_add; } } while (scroll_cnt != ses->scroll_row); if (grep_cnt <= grep_min) { tintin_puts2(ses, "#NO MATCHES FOUND."); } } tintin_header(ses, ""); DEL_BIT(ses->flags, SES_FLAG_SCROLLSTOP); } return ses; } int show_buffer(struct session *ses) { char temp[STRING_SIZE]; int scroll_size, scroll_cnt, scroll_tmp, scroll_add, scroll_cut; if (ses != gtd->ses) { return TRUE; } scroll_size = get_scroll_size(ses); scroll_add = 0 - ses->scroll_base; scroll_tmp = 0; scroll_cnt = ses->scroll_line; scroll_cut = 0; /* Find the upper limit of the buffer shown */ while (TRUE) { if (ses->buffer[scroll_cnt] == NULL) { break; } scroll_tmp = str_hash_lines(ses->buffer[scroll_cnt]); if (scroll_add + scroll_tmp > scroll_size) { if (scroll_add == scroll_size) { scroll_cut = 0; } else { scroll_cut = scroll_tmp - (scroll_size - scroll_add); } break; } scroll_add += scroll_tmp; if (scroll_cnt == ses->scroll_max - 1) { scroll_cnt = 0; } else { scroll_cnt++; } } if (ses->buffer[scroll_cnt] == NULL) { erase_screen(ses); } if (IS_SPLIT(ses)) { save_pos(ses); goto_rowcol(ses, ses->bot_row, 1); SET_BIT(ses->flags, SES_FLAG_READMUD); } /* If the top line exists of multiple lines split it in the middle. */ if (ses->buffer[scroll_cnt] && scroll_cut) { if (scroll_add >= 0) { word_wrap_split(ses, ses->buffer[scroll_cnt], temp, scroll_tmp - scroll_cut, scroll_cut); printf("%s\n", temp); } else { word_wrap_split(ses, ses->buffer[scroll_cnt], temp, ses->scroll_base, scroll_size); goto eof; } } /* Print away */ while (TRUE) { if (scroll_cnt == 0) { scroll_cnt = ses->scroll_max - 1; } else { scroll_cnt--; } if (ses->buffer[scroll_cnt] == NULL) { break; } scroll_tmp = word_wrap(ses, ses->buffer[scroll_cnt], temp, FALSE); if (scroll_add - scroll_tmp < 0) { scroll_cut = scroll_add; break; } scroll_add -= scroll_tmp; printf("%s\n", temp); } /* If the bottom line exists of multiple lines split it in the middle */ if (scroll_tmp && ses->buffer[scroll_cnt]) { word_wrap_split(ses, ses->buffer[scroll_cnt], temp, 0, scroll_cut); } eof: if (IS_SPLIT(ses)) { restore_pos(ses); DEL_BIT(ses->flags, SES_FLAG_READMUD); } return TRUE; } DO_COMMAND(do_buffer) { char left[BUFFER_SIZE], right[BUFFER_SIZE]; int cnt; arg = get_arg_in_braces(arg, left, FALSE); arg = get_arg_in_braces(arg, right, TRUE); substitute(ses, right, right, SUB_VAR|SUB_FUN); if (HAS_BIT(gtd->flags, TINTIN_FLAG_RESETBUFFER)) { DEL_BIT(gtd->flags, TINTIN_FLAG_RESETBUFFER); reset_hash_table(); } if (*left == 0) { tintin_header(ses, " BUFFER COMMANDS "); for (cnt = 0 ; *buffer_table[cnt].name != 0 ; cnt++) { tintin_printf2(ses, " [%-13s] %s", buffer_table[cnt].name, buffer_table[cnt].desc); } tintin_header(ses, ""); return ses; } for (cnt = 0 ; *buffer_table[cnt].name ; cnt++) { if (!is_abbrev(left, buffer_table[cnt].name)) { continue; } buffer_table[cnt].fun(ses, right); return ses; } do_buffer(ses, ""); return ses; } DO_BUFFER(buffer_clear) { int cnt; cnt = ses->scroll_row; do { if (++cnt == ses->scroll_max) { cnt = 0; } if (ses->buffer[cnt] == NULL) { break; } ses->buffer[cnt] = str_unhash(ses->buffer[cnt]); } while (cnt != ses->scroll_row); ses->scroll_row = ses->scroll_max - 1; ses->scroll_line = - 1; return; } DO_BUFFER(buffer_up) { int scroll_size, scroll_cnt, buffer_add, buffer_tmp; if (ses->buffer == NULL) { return; } if (ses->scroll_line == -1) { ses->scroll_line = ses->scroll_row + 1; } scroll_size = get_scroll_size(ses); scroll_cnt = ses->scroll_line; buffer_add = 0 - ses->scroll_base; while (TRUE) { if (ses->buffer[scroll_cnt] == NULL) { return; } buffer_tmp = str_hash_lines(ses->buffer[scroll_cnt]); if (scroll_size < buffer_add + buffer_tmp) { ses->scroll_line = scroll_cnt; ses->scroll_base = scroll_size - buffer_add; break; } buffer_add += buffer_tmp; if (scroll_cnt == ses->scroll_max - 1) { scroll_cnt = 0; } else { scroll_cnt++; } } show_buffer(ses); } DO_BUFFER(buffer_down) { int scroll_size, scroll_cnt, buffer_add, buffer_tmp; if (ses->buffer == NULL) { return; } if (ses->scroll_line == -1) { return; } scroll_size = get_scroll_size(ses); scroll_cnt = ses->scroll_line; buffer_add = ses->scroll_base; if (scroll_size <= buffer_add) { ses->scroll_base = buffer_add - scroll_size; show_buffer(ses); return; } if (scroll_cnt == 0) { scroll_cnt = ses->scroll_max - 1; } else { scroll_cnt--; } while (TRUE) { if (ses->buffer[scroll_cnt] == NULL) { buffer_end(ses, ""); return; } buffer_tmp = str_hash_lines(ses->buffer[scroll_cnt]); if (scroll_size <= buffer_add + buffer_tmp) { ses->scroll_line = scroll_cnt; ses->scroll_base = buffer_tmp - (scroll_size - buffer_add); break; } buffer_add += buffer_tmp; if (scroll_cnt == 0) { scroll_cnt = ses->scroll_max - 1; } else { scroll_cnt--; } } show_buffer(ses); } DO_BUFFER(buffer_home) { if (ses->buffer == NULL) { return; } if (ses->buffer[0]) { ses->scroll_line = ses->scroll_row - 1; } else { ses->scroll_line = ses->scroll_max - 1; } ses->scroll_base = str_hash_lines(ses->buffer[ses->scroll_line]); buffer_down(ses, ""); } DO_BUFFER(buffer_end) { if (ses->buffer == NULL) { return; } if (ses->scroll_row == ses->scroll_max - 1) { ses->scroll_line = 0; } else { ses->scroll_line = ses->scroll_row + 1; } ses->scroll_base = 0; show_buffer(ses); ses->scroll_line = -1; ses->scroll_base = 0; } DO_BUFFER(buffer_lock) { if (ses->buffer == NULL) { return; } if (ses->scroll_line == -1) { ses->scroll_line = ses->scroll_row + 1; } else { buffer_end(ses, ""); } } DO_BUFFER(buffer_find) { char left[BUFFER_SIZE], right[BUFFER_SIZE]; int scroll_cnt, grep_cnt, grep_max, page; grep_cnt = grep_max = scroll_cnt = 0; get_arg_in_braces(arg, left, FALSE); if (ses->buffer == NULL) { tintin_puts2(NULL, "#BUFFER, NO SCROLL BUFFER AVAILABLE."); } else if (*left == 0) { tintin_puts2(NULL, "#BUFFER, FIND WHAT?"); } else { page = get_number(ses, left); if (page) { arg = get_arg_in_braces(arg, left, FALSE); arg = get_arg_in_braces(arg, right, TRUE); if (*right == 0) { tintin_printf2(NULL, "#BUFFER, FIND OCCURANCE %d OF WHAT?", page); return; } } else { page = 1; arg = get_arg_in_braces(arg, right, TRUE); } if (page > 0) { scroll_cnt = ses->scroll_row; do { if (scroll_cnt == ses->scroll_max -1) { scroll_cnt = 0; } else { scroll_cnt++; } if (ses->buffer[scroll_cnt] == NULL) { break; } if (str_hash_grep(ses->buffer[scroll_cnt], FALSE)) { continue; } if (find(ses, ses->buffer[scroll_cnt], right, SUB_NONE)) { grep_cnt++; if (grep_cnt == page) { break; } } } while (scroll_cnt != ses->scroll_row); } else { if (ses->buffer[0]) { scroll_cnt = ses->scroll_row - 1; } else { scroll_cnt = ses->scroll_max - 1; } do { if (scroll_cnt == 0) { scroll_cnt = ses->scroll_max -1; } else { scroll_cnt--; } if (ses->buffer[scroll_cnt] == NULL) { break; } if (str_hash_grep(ses->buffer[scroll_cnt], FALSE)) { continue; } if (find(ses, ses->buffer[scroll_cnt], right, SUB_NONE)) { grep_cnt--; if (grep_cnt == page) { break; } } } while (scroll_cnt != ses->scroll_row); } if (ses->buffer[scroll_cnt] == NULL || scroll_cnt == ses->scroll_row) { tintin_puts(NULL, "#BUFFER FIND, NO MATCHES FOUND."); } else { ses->scroll_line = scroll_cnt; show_buffer(ses); } } return; } DO_BUFFER(buffer_get) { char arg1[BUFFER_SIZE], arg2[BUFFER_SIZE], arg3[BUFFER_SIZE]; int min, max, cur, cnt, add; arg = sub_arg_in_braces(ses, arg, arg1, GET_NST, FALSE); arg = get_arg_in_braces(arg, arg2, FALSE); arg = get_arg_in_braces(arg, arg3, FALSE); min = get_number(ses, arg2); max = get_number(ses, arg3); if (*arg1 == 0 || *arg2 == 0) { tintin_printf(ses, "#SYNTAX: #BUFFER GET <VARIABLE> <LOWER BOUND> [UPPER BOUND]"); return; } if (*arg3 == 0) { cur = UMAX(0, (ses->scroll_row + min) % ses->scroll_max); if (ses->buffer[cur] == NULL) { set_nest_node(ses->list[LIST_VARIABLE], arg1, ""); } else { set_nest_node(ses->list[LIST_VARIABLE], arg1, "%s", ses->buffer[cur]); } return; } cnt = 0; add = (min < max) ? 1 : -1; set_nest_node(ses->list[LIST_VARIABLE], arg1, ""); while ((add == 1 && max >= min) || (add == -1 && max <= min)) { sprintf(arg2, "%s[%d]", arg1, ++cnt); cur = (ses->scroll_row + min) % ses->scroll_max; if (ses->buffer[cur] == NULL) { set_nest_node(ses->list[LIST_VARIABLE], arg2, ""); } else { set_nest_node(ses->list[LIST_VARIABLE], arg2, "%s", ses->buffer[cur]); } min = min + add; } return; } DO_BUFFER(buffer_write) { FILE *fp; char left[BUFFER_SIZE], out[STRING_SIZE]; int cnt; arg = get_arg_in_braces(arg, left, FALSE); if (*left == 0) { tintin_printf(ses, "#SYNTAX: #BUFFER WRITE <FILENAME>]"); } else { if ((fp = fopen(left, "w"))) { show_message(ses, LIST_MESSAGE, "#OK: WRITING BUFFER TO '%s'.", left); if (HAS_BIT(ses->flags, SES_FLAG_LOGHTML)) { write_html_header(fp); } cnt = ses->scroll_row; do { if (cnt == 0) { cnt = ses->scroll_max - 1; } else { cnt--; } if (ses->buffer[cnt] == NULL) { continue; } if (HAS_BIT(ses->flags, SES_FLAG_LOGPLAIN)) { strip_vt102_codes(ses->buffer[cnt], out); } else if (HAS_BIT(ses->flags, SES_FLAG_LOGHTML)) { vt102_to_html(ses, ses->buffer[cnt], out); } else { strcpy(out, ses->buffer[cnt]); } strcat(out, "\n"); fputs(out, fp); } while (cnt != ses->scroll_row); fclose(fp); } else { tintin_printf(ses, "#ERROR: #BUFFER WRITE {%s} - FAILED TO OPEN FILE.", left); } } return; }