int ISearch(int arr[],int first,int last,int target){ int s; //보간탐색 //데이터 값과 데이터가 저장된 위치의 인덱스 값이 비례한다고 가정 //정렬된 상태의 배열 s=((double)(target-arr[first])/(arr[last]-arr[first]) * (last-first))+first; if(arr[first]>target || arr[last]<target) return -1; if(arr[s]==target) return s; else if(target<arr[s]) return ISearch(arr,first,s-1,target); else return ISearch(arr,s+1,last,target); }
static void MarkProcess(char **inbufp, size_t *inlenp) { char *inbuf, *pt; int inlen; int cx, cy, x2, y2, j, yend; int newcopylen = 0, od; int in_mark; int rep_cnt; struct acluser *md_user; /* char *extrap = 0, extrabuf[100]; */ markdata = (struct markdata *)flayer->l_data; fore = markdata->md_window; md_user = markdata->md_user; if (inbufp == 0) { MarkAbort(); return; } LGotoPos(flayer, markdata->cx, W2D(markdata->cy)); inbuf = *inbufp; inlen = *inlenp; pt = inbuf; in_mark = 1; while (in_mark && (inlen /* || extrap */ )) { unsigned char ch = (unsigned char)*pt++; inlen--; if (flayer->l_mouseevent.start) { int r = LayProcessMouse(flayer, ch); if (r == -1) LayProcessMouseSwitch(flayer, 0); else { if (r) ch = 0222; else continue; } } od = mark_key_tab[(int)ch]; rep_cnt = markdata->rep_cnt; if (isdigit(od) && !markdata->f_cmd.flag) { if (rep_cnt < 1001 && (od != '0' || rep_cnt != 0)) { markdata->rep_cnt = 10 * rep_cnt + od - '0'; continue; /* * Now what is that 1001 here? Well, we have a screen with * 25 * 80 = 2000 characters. Movement is at most across the full * screen. This we do with word by word movement, as character by * character movement never steps over line boundaries. The most words * we can place on the screen are 1000 single letter words. Thus 1001 * is sufficient. Users with bigger screens never write in single letter * words, as they should be more advanced. jw. * Oh, wrong. We still give even the experienced user a factor of ten. */ } } cx = markdata->cx; cy = markdata->cy; if (markdata->f_cmd.flag) { markdata->f_cmd.flag = 0; markdata->rep_cnt = 0; if (isgraph(od)) { markdata->f_cmd.target = od; rep_cnt = (rep_cnt) ? rep_cnt : 1; nextchar(&cx, &cy, markdata->f_cmd.direction, od, rep_cnt); revto(cx, cy); continue; } } processchar: switch (od) { case 'f': /* fall through */ case 'F': /* fall through */ case 't': /* fall through */ case 'T': /* fall through */ /* * Set f_cmd to do a search on the next key stroke. * If we break, rep_cnt will be reset, so we * continue instead. It might be cleaner to * store the rep_count in f_cmd and * break here so later followon code will be * hit. */ markdata->f_cmd.flag = 1; markdata->f_cmd.direction = od; continue; case ';': case ',': if (!markdata->f_cmd.target) break; if (!rep_cnt) rep_cnt = 1; nextchar(&cx, &cy, od == ';' ? markdata->f_cmd.direction : (markdata->f_cmd.direction ^ 0x20), markdata->f_cmd.target, rep_cnt); revto(cx, cy); break; case 'o': case 'x': if (!markdata->second) break; markdata->cx = markdata->x1; markdata->cy = markdata->y1; markdata->x1 = cx; markdata->y1 = cy; revto(markdata->cx, markdata->cy); break; case '\014': /* CTRL-L Redisplay */ Redisplay(0); LGotoPos(flayer, cx, W2D(cy)); break; case 0202: /* M-C-b */ case '\010': /* CTRL-H Backspace */ case 'h': if (rep_cnt == 0) rep_cnt = 1; revto(cx - rep_cnt, cy); break; case 0216: /* M-C-p */ case '\016': /* CTRL-N */ case 'j': if (rep_cnt == 0) rep_cnt = 1; revto(cx, cy + rep_cnt); break; case '+': if (rep_cnt == 0) rep_cnt = 1; j = cy + rep_cnt; if (j > fore->w_histheight + fore->w_height - 1) j = fore->w_histheight + fore->w_height - 1; revto(linestart(j), j); break; case '-': if (rep_cnt == 0) rep_cnt = 1; cy -= rep_cnt; if (cy < 0) cy = 0; revto(linestart(cy), cy); break; case '^': revto(linestart(cy), cy); break; case '\n': revto(markdata->left_mar, cy + 1); break; case 0220: /* M-C-p */ case '\020': /* CTRL-P */ case 'k': if (rep_cnt == 0) rep_cnt = 1; revto(cx, cy - rep_cnt); break; case 0206: /* M-C-f */ case 'l': if (rep_cnt == 0) rep_cnt = 1; revto(cx + rep_cnt, cy); break; case '\001': /* CTRL-A from tcsh/emacs */ case '0': revto(markdata->left_mar, cy); break; case '\004': /* CTRL-D down half screen */ if (rep_cnt == 0) rep_cnt = (fore->w_height + 1) >> 1; revto_line(cx, cy + rep_cnt, W2D(cy)); break; case '$': revto(lineend(cy), cy); break; case '\022': /* CTRL-R emacs style backwards search */ ISearch(-1); in_mark = 0; break; case '\023': /* CTRL-S emacs style search */ ISearch(1); in_mark = 0; break; case '\025': /* CTRL-U up half screen */ if (rep_cnt == 0) rep_cnt = (fore->w_height + 1) >> 1; revto_line(cx, cy - rep_cnt, W2D(cy)); break; case '\007': /* CTRL-G show cursorpos */ if (markdata->left_mar == 0 && markdata->right_mar == fore->w_width - 1) LMsg(0, "Column %d Line %d(+%d)", cx + 1, W2D(cy) + 1, markdata->hist_offset); else LMsg(0, "Column %d(%d..%d) Line %d(+%d)", cx + 1, markdata->left_mar + 1, markdata->right_mar + 1, W2D(cy) + 1, markdata->hist_offset); break; case '\002': /* CTRL-B back one page */ if (rep_cnt == 0) rep_cnt = 1; rep_cnt *= fore->w_height; revto(cx, cy - rep_cnt); break; case '\006': /* CTRL-F forward one page */ if (rep_cnt == 0) rep_cnt = 1; rep_cnt *= fore->w_height; revto(cx, cy + rep_cnt); break; case '\005': /* CTRL-E scroll up */ if (rep_cnt == 0) rep_cnt = 1; MarkScrollUpDisplay(rep_cnt); if (cy < D2W(0)) revto(cx, D2W(0)); else LGotoPos(flayer, cx, W2D(cy)); break; case '\031': /* CTRL-Y scroll down */ if (rep_cnt == 0) rep_cnt = 1; MarkScrollDownDisplay(rep_cnt); if (cy > D2W(fore->w_height - 1)) revto(cx, D2W(fore->w_height - 1)); else LGotoPos(flayer, cx, W2D(cy)); break; case '@': /* it may be useful to have a key that does nothing */ break; case '%': rep_cnt--; /* rep_cnt is a percentage for the history buffer */ if (rep_cnt < 0) rep_cnt = 0; if (rep_cnt > 100) rep_cnt = 100; revto_line(markdata->left_mar, (rep_cnt * (fore->w_histheight + fore->w_height)) / 100, (fore->w_height - 1) / 2); break; case 0201: case 'g': rep_cnt = 1; /* FALLTHROUGH */ case 0205: case 'G': /* rep_cnt is here the WIN line number */ if (rep_cnt == 0) rep_cnt = fore->w_histheight + fore->w_height; revto_line(markdata->left_mar, --rep_cnt, (fore->w_height - 1) / 2); break; case 'H': revto(markdata->left_mar, D2W(0)); break; case 'M': revto(markdata->left_mar, D2W((fore->w_height - 1) / 2)); break; case 'L': revto(markdata->left_mar, D2W(fore->w_height - 1)); break; case '|': revto(--rep_cnt, cy); break; case 'w': if (rep_cnt == 0) rep_cnt = 1; nextword(&cx, &cy, NW_MUSTMOVE, rep_cnt); revto(cx, cy); break; case 'e': case 'E': if (rep_cnt == 0) rep_cnt = 1; nextword(&cx, &cy, NW_ENDOFWORD | NW_MUSTMOVE | (od == 'E' ? NW_BIG : 0), rep_cnt); revto(cx, cy); break; case 'b': case 'B': if (rep_cnt == 0) rep_cnt = 1; nextword(&cx, &cy, NW_BACK | NW_ENDOFWORD | NW_MUSTMOVE | (od == 'B' ? NW_BIG : 0), rep_cnt); revto(cx, cy); break; case 'a': markdata->append_mode = 1 - markdata->append_mode; LMsg(0, (markdata->append_mode) ? ":set append" : ":set noappend"); break; case 'v': case 'V': /* this sets start column to column 9 for VI :set nu users */ if (markdata->left_mar == 8) rep_cnt = 1; else rep_cnt = 9; /* FALLTHROUGH */ case 'c': case 'C': /* set start column (c) and end column (C) */ if (markdata->second) { rem(markdata->x1, markdata->y1, cx, cy, 1, (char *)0, fore->w_height - 1); /* Hack */ markdata->second = 1; /* rem turns off second */ } rep_cnt--; if (rep_cnt < 0) rep_cnt = cx; if (od != 'C') { markdata->left_mar = rep_cnt; if (markdata->left_mar > markdata->right_mar) markdata->left_mar = markdata->right_mar; } else { markdata->right_mar = rep_cnt; if (markdata->left_mar > markdata->right_mar) markdata->right_mar = markdata->left_mar; } if (markdata->second) { markdata->cx = markdata->x1; markdata->cy = markdata->y1; revto(cx, cy); } if (od == 'v' || od == 'V') LMsg(0, (markdata->left_mar != 8) ? ":set nonu" : ":set nu"); break; case 'J': /* how do you join lines in VI ? */ markdata->nonl = (markdata->nonl + 1) % 4; switch (markdata->nonl) { case 0: if (join_with_cr) LMsg(0, "Multiple lines (CR/LF)"); else LMsg(0, "Multiple lines (LF)"); break; case 1: LMsg(0, "Lines joined"); break; case 2: LMsg(0, "Lines joined with blanks"); break; case 3: LMsg(0, "Lines joined with comma"); break; } break; case '/': Search(1); in_mark = 0; break; case '?': Search(-1); in_mark = 0; break; case 'n': Search(0); break; case 'N': markdata->isdir = -markdata->isdir; Search(0); markdata->isdir = -markdata->isdir; break; case 'y': case 'Y': if (markdata->second == 0) { revto(linestart(cy), cy); markdata->second++; cx = markdata->x1 = markdata->cx; cy = markdata->y1 = markdata->cy; } if (--rep_cnt > 0) revto(cx, cy + rep_cnt); revto(lineend(markdata->cy), markdata->cy); if (od == 'y') break; /* FALLTHROUGH */ case 'W': if (od == 'W') { if (rep_cnt == 0) rep_cnt = 1; if (!markdata->second) { nextword(&cx, &cy, NW_BACK | NW_ENDOFWORD, 1); revto(cx, cy); markdata->second++; cx = markdata->x1 = markdata->cx; cy = markdata->y1 = markdata->cy; } nextword(&cx, &cy, NW_ENDOFWORD, rep_cnt); revto(cx, cy); } cx = markdata->cx; cy = markdata->cy; /* FALLTHROUGH */ case 'A': if (od == 'A') markdata->append_mode = 1; /* FALLTHROUGH */ case '>': if (od == '>') markdata->write_buffer = 1; /* FALLTHROUGH */ case ' ': case '\r': if (!markdata->second) { markdata->second++; markdata->x1 = cx; markdata->y1 = cy; revto(cx, cy); LMsg(0, "First mark set - Column %d Line %d", cx + 1, W2D(cy) + 1); break; } else { int append_mode = markdata->append_mode; int write_buffer = markdata->write_buffer; x2 = cx; y2 = cy; newcopylen = rem(markdata->x1, markdata->y1, x2, y2, 2, (char *)0, 0); /* count */ if (md_user->u_plop.buf && !append_mode) UserFreeCopyBuffer(md_user); yend = fore->w_height - 1; if (fore->w_histheight - markdata->hist_offset < fore->w_height) { markdata->second = 0; yend -= MarkScrollUpDisplay(fore->w_histheight - markdata->hist_offset); } if (newcopylen > 0) { /* the +3 below is for : cr + lf + \0 */ if (md_user->u_plop.buf) md_user->u_plop.buf = realloc(md_user->u_plop.buf, (unsigned)(md_user->u_plop.len + newcopylen + 3)); else { md_user->u_plop.len = 0; md_user->u_plop.buf = malloc((unsigned)(newcopylen + 3)); } if (!md_user->u_plop.buf) { MarkAbort(); in_mark = 0; LMsg(0, "Not enough memory... Sorry."); md_user->u_plop.len = 0; md_user->u_plop.buf = 0; break; } if (append_mode) { switch (markdata->nonl) { /* * this code defines, what glues lines together */ case 0: if (join_with_cr) { md_user->u_plop.buf[md_user->u_plop.len] = '\r'; md_user->u_plop.len++; } md_user->u_plop.buf[md_user->u_plop.len] = '\n'; md_user->u_plop.len++; break; case 1: break; case 2: md_user->u_plop.buf[md_user->u_plop.len] = ' '; md_user->u_plop.len++; break; case 3: md_user->u_plop.buf[md_user->u_plop.len] = ','; md_user->u_plop.len++; break; } } md_user->u_plop.len += rem(markdata->x1, markdata->y1, x2, y2, markdata->hist_offset == fore->w_histheight, md_user->u_plop.buf + md_user->u_plop.len, yend); md_user->u_plop.enc = fore->w_encoding; } if (markdata->hist_offset != fore->w_histheight) { LAY_CALL_UP(LRefreshAll(flayer, 0)); } ExitOverlayPage(); WindowChanged(fore, 'P'); if (append_mode) LMsg(0, "Appended %d characters to buffer", newcopylen); else LMsg(0, "Copied %d characters into buffer", md_user->u_plop.len); if (write_buffer) WriteFile(md_user, (char *)0, DUMP_EXCHANGE); in_mark = 0; break; } case 0222: if (flayer->l_mouseevent.start) { int button = flayer->l_mouseevent.buffer[0]; if (button == 'a') { /* Scroll down */ od = 'j'; } else if (button == '`') { /* Scroll up */ od = 'k'; } else if (button == ' ') { /* Left click */ cx = flayer->l_mouseevent.buffer[1]; cy = D2W(flayer->l_mouseevent.buffer[2]); revto(cx, cy); od = ' '; } else od = 0; LayProcessMouseSwitch(flayer, 0); if (od) goto processchar; } else LayProcessMouseSwitch(flayer, 1); break; default: MarkAbort(); LMsg(0, "Copy mode aborted"); in_mark = 0; break; } if (in_mark) /* markdata may be freed */ markdata->rep_cnt = 0; } if (in_mark) { flayer->l_x = markdata->cx; flayer->l_y = W2D(markdata->cy); } *inbufp = pt; *inlenp = inlen; }