home *** CD-ROM | disk | FTP | other *** search
- /* fv is a binary file editor written by Chris Hooper (cdh@mtu.edu)
- * on 6-2-91 and has gone through many revisions since then.
- * Much inspiration was given by Bill Moore, the first real user!
- *
- * Author: CHRISTOPHER D HOOPER
- *
- * fv source Copyright (c) 1992 - 1998 Chris Hooper
- *
- * Modification and redistribution is strictly prohibited.
- * Sale of this software above media cost is prohibited.
- *
- * Except for above two restrictions, this software may be used for
- * any purpose, commercial or private.
- *
- * Disclaimer: This product is fit for no use, foreign or domestic.
- * Use implies knowledge you intend to destroy something.
- */
-
- #include <stdio.h>
- #include <curses.h>
- #include <string.h>
- #include "main.h"
- #if !defined(Amiga) && !defined(OS9) && !defined(FreeBSD)
- # include <malloc.h>
- #endif
- #include "screen.h"
- #include "edit.h"
-
- #ifdef NetBSD
- # include <sys/ttycom.h>
- #endif
-
- #ifdef Dynix
- # include <sys/types.h>
- #endif
-
- #ifdef LINT
- # include "lint.h"
- #endif
-
- char *NONWORD = ",<.>/?;:'`~[{]}=+-\\|!@#$%^&*() \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032";
-
- #define MARKS 64
- extern int generic_search();
-
- STATIC void light_string();
- STATIC int eget_key();
-
- #define KSHISTMAX 256
- static char kshist[KSHISTMAX];
- static int kshistsize = 0;
-
- #define KSFULLHISTMAX 1024
- static char ksfullhist[KSFULLHISTMAX];
- static int ksfullhistsize = 0;
-
- #define KSBUFMAX 1024
- char ksbuf[KSBUFMAX];
- int ksbufsize = 0;
-
-
- int edit_mem_base(addr, base)
- int addr;
- int base;
- {
- uchar *origbuf;
- int ch = ' ';
- int cur = addr;
- int row = 0;
- int col = 0;
- int icur;
- int mrow, mcol;
- int value;
-
- stopping = 0;
-
- #ifdef Amiga
- leaveok(main_window, FALSE);
- #endif
- xmove(status_window, 0, 20);
- xaddstr(status_window, "hex editing..");
- xclrtoeol(status_window);
- xrefresh(status_window);
-
- origbuf = (uchar *) malloc(buf_size);
- if (origbuf == NULL)
- error_exit("edit_mem_base: malloc failed");
-
- memcpy(origbuf, buffer, buf_size);
-
- mcol = 2 * cpline - 1;
- mrow = buf_size / cpline - 1;
-
- col = 2 * (addr % cpline);
- row = addr / cpline;
-
- /* stop on ^M ^J ^D or ^C */
- while ((ch != 13) && (ch != 10) && (ch != 4) && !stopping) {
- cur = row * cpline + col / 2;
- #ifdef Amiga
- xstandout(main_window);
- light_string(cur, 0, 1);
- #endif
- icur = cur ^ swapbytes;
-
- xmove(main_window, icur / cpline, 10 * addis +
- (icur % cpline) * 2 + ((icur % cpline) >> 2) + (col & 1));
- xrefresh(main_window);
- ch = get_key();
- #ifdef Amiga
- light_string(cur, 0, 1);
- #endif
- switch (ch) {
- case 8: /* ^H back */
- case 127:
- case 'h':
- case 2: /* ^B */
- #ifdef KEY_LEFT
- case KEY_LEFT:
- #endif
- if (col)
- col--;
- else if (row) {
- row--;
- col = mcol;
- }
- break;
- case 'j': /* down one row */
- #ifdef KEY_DOWN
- case KEY_DOWN:
- #endif
- if (row < mrow)
- row++;
- break;
- case 'k': /* up one row */
- #ifdef KEY_UP
- case KEY_UP:
- #endif
- if (row > 0)
- row--;
- break;
- case 'l': /* right one column */
- case 6: /* ^F */
- /* case ' ': commented out so paste of xxxx xxxx works */
- #ifdef KEY_RIGHT
- case KEY_RIGHT:
- #endif
- if (col < mcol)
- col++;
- else {
- if (row < mrow) {
- row++;
- col = 0;
- }
- }
- break;
- case '^': /* back to start */
- col = 2 * (addr % cpline);
- row = addr / cpline;
- break;
- #ifndef EMACS_FEEL
- case 24: /* ^X quit */
- #endif
- case 3: /* ^C */
- case 'q':
- case 'Q':
- memcpy(buffer, origbuf, buf_size);
- ch = 4;
- break;
- case '?':
- case 'H':
- #ifdef KEY_HELP
- case KEY_HELP:
- #endif
- help_me(1);
- xtouchwin(main_window);
- xrefresh(main_window);
- break;
- default: /* guess it is hex */
- value = -1;
- if ((ch >= '0') && (ch <= '9'))
- value = ch - '0';
- else if ((ch >= 'a') && (ch <= 'f'))
- value = ch - 'a' + 10;
- else if ((ch >= 'A') && (ch <= 'F')) {
- value = ch - 'A' + 10;
- ch += 'a' - 'A';
- } else
- break;
-
- cur = row * cpline + col / 2;
- if (col & 1) /* odd position */
- buffer[cur ^ SWAPBYTES] =
- (buffer[cur ^ SWAPBYTES] & 0xf0) | value;
- else
- buffer[cur ^ SWAPBYTES] =
- (buffer[cur ^ SWAPBYTES] & 0x0f) | (value << 4);
-
- /* update in character area */
- icur = cur ^ Swapbytes;
- xmove(main_window, icur / cpline,
- 10 * addis + wpline * 9 + (icur % cpline));
- #ifdef CHAR_COLOR
- wattron(main_window, CHAR_COLOR);
- #endif
- xaddch_filt(buffer[cur ^ SWAPBYTES]);
-
- /* update in word area */
- icur = cur ^ swapbytes;
- xmove(main_window, icur / cpline, 10 * addis +
- (icur % cpline) * 2 + ((icur % cpline) >> 2) +
- (col & 1));
- #ifdef WORD_COLOR
- wattron(main_window, WORD_COLOR);
- #endif
- xaddch(main_window, ch);
-
- if (col < mcol)
- col++;
- else if (row < mrow) {
- row++;
- col = 0;
- }
- #ifdef NO_COLOR
- wattrset(main_window, 0);
- #endif
- }
- }
- #ifdef Amiga
- leaveok(main_window, TRUE);
- #endif
- xmove(status_window, 0, 20);
- xclrtoeol(status_window);
- xrefresh(status_window);
- return(0);
- }
-
-
-
- int edit_mem_string(addr)
- int addr;
- {
- uchar *origbuf;
- uchar *prevstr;
- uchar *prevstr2;
- uchar *prevstrtemp;
- int strsize;
- int strpsize;
- int cur;
- int index;
- uchar temp;
- uchar temp2;
- int old_alignment;
- int emode = 1; /* esc mode */
- int amode = 0; /* append mode */
- int rollover = 1;
- int looptime = 1;
- int ch = '\0';
- int ch2;
- int fixed_x_offset;
- int icur;
-
- stopping = 0;
-
- ksfullhistsize = 0;
- old_alignment = alignment;
- cur = addr;
- for (cur = addr; ((cur < buf_size - 1) && buffer[cur ^ SWAPBYTES]); cur++);
- strsize = cur - addr;
- strpsize = strsize + 32;
- origbuf = (uchar *) malloc(strpsize);
- prevstr = (uchar *) malloc(strpsize);
- prevstr2 = (uchar *) malloc(strpsize);
- if ((origbuf == NULL) ||
- (prevstr == NULL) ||
- (prevstr2 == NULL))
- error_exit("edit_mem_string: malloc failed");
- memcpy(origbuf, buffer + addr, strpsize);
- memcpy(prevstr, buffer + addr, strpsize);
- memcpy(prevstr2, buffer + addr, strpsize);
-
-
- xmove(status_window, 0, 20);
- if (mode)
- xaddstr(status_window, "string editing..");
- else
- xaddstr(status_window, "hex editing..");
- xclrtoeol(status_window);
- xrefresh(status_window);
-
- fixed_x_offset = addis * 10 + wpline * 9 * wdis;
-
- cur = addr;
- do { /* ^D - ends editing session */
-
- light_string(addr, 1, strsize);
- light_string(addr + strsize, 0, strpsize - strsize);
-
- icur = cur ^ Swapbytes;
- #ifdef Amiga
- light_string(cur, 2, 1);
- #endif
- xmove(main_window, icur / cpline, fixed_x_offset + icur % cpline);
-
- xrefresh(main_window);
-
- ch = eget_key();
-
- if (emode)
- if (strchr("~aAcCdDiIrRsx", ch)) /* edit cmds */
- if (looptime > 1) {
- sprintf(kshist, "%d%c", looptime, ch);
- kshistsize = strlen(kshist);
- } else {
- kshist[0] = ch;
- kshistsize = 1;
- }
- else if (strchr("?/.0^befG$\010\177hjkl uUtTw\012\015\030q\004\033", ch))
- kshistsize--; /* motion cmd */
-
- switch (ch) { /* FOLLOWING WORK IN BOTH EDIT OR INSERT MODE */
- #ifndef EMACS_FEEL
- case 24: /* ^X abort editing - must precede ^D */
- memcpy(buffer + addr, origbuf, strpsize);
- #endif
- case 4: /* ^D - done editing */
- case 10: /* ^R */
- case 13: /* ^M */
- ch = 4; /* ^D */
- break;
- case ESC: /* 27 return to command mode */
- if (!emode && amode)
- if (cur > addr)
- cur--;
- looptime = 1;
- rollover = 1;
- emode = 1;
- break;
- case 8: /* ^H delete character to left (or crsr left) */
- case 127: /* ^? */
- if (looptime < 1)
- looptime = 1;
- if (emode) {
- if (cur > addr)
- cur--;
- break;
- }
- memcpy(prevstr, buffer + addr, strpsize);
- if (cur > addr) {
- cur--;
- for (index = cur; index <= addr + strsize - looptime;
- index++)
- buffer[index ^ SWAPBYTES] =
- buffer[(index + looptime) ^ SWAPBYTES];
- for (; index <= addr + strsize; index++)
- buffer[index ^ SWAPBYTES] = '\0';
- }
- break;
- default:
- if (emode) /* EDIT MODE COMMAND */
- if (((ch >= '1') && (ch <= '9')) ||
- ((ch == '0') && (rollover == 0))) {
- if (rollover)
- looptime = ch - '0';
- else
- looptime = looptime * 10 + ch - '0';
- rollover = 0;
- } else {
- if (rollover)
- looptime = 1;
- else
- rollover = 1;
-
- switch (ch) {
- #ifdef DEBUG
- case '?':
- printf("___%.*s___", kshistsize, kshist);
- break;
- case '/':
- printf("___%.*s___", ksbufsize, ksbuf);
- break;
- #endif
- case '.':
- while ((looptime--) &&
- (ksbufsize + kshistsize < 1023))
- for (index = kshistsize; index;)
- ksbuf[ksbufsize++] = kshist[--index];
- break;
- case '~':
- while (looptime--) {
- if (buffer[cur ^ SWAPBYTES] & 64)
- buffer[cur ^ SWAPBYTES] ^= 32;
- if (cur + 1 < addr + strpsize)
- cur++;
- }
- break;
- case '0': /* beginning of line */
- cur = addr;
- break;
- case '^': /* beginning of text */
- cur = addr;
- while ((cur == ' ') || (cur == '\t'))
- cur++;
- if (cur > addr + strpsize)
- cur = addr;
- break;
- case 'A': /* append at end - must precede 'a' */
- cur = addr + strsize - 1;
- case 'a': /* append after cursor */
- memcpy(prevstr, buffer + addr, strpsize);
- amode = 1;
- emode = 0;
- if (cur + 1 < addr + strpsize)
- cur++;
- break;
- case 'b': /* back a single word */
- while (looptime--) {
- index = cur - 1;
- for (; index >= addr; index--)
- if (!strchr(NONWORD, buffer[index ^ SWAPBYTES]))
- break;
- for (; index >= addr; index--)
- if (strchr(NONWORD, buffer[index ^ SWAPBYTES]))
- break;
- else
- cur = index;
- }
- break;
- case 'c': /* change (range) - must precede 'd' */
- emode = 0;
- case 'd': /* delete (range) */
- memcpy(prevstr, buffer + addr, strpsize);
- ch2 = eget_key();
-
- if (ch2 == 'w') { /* word */
- while (looptime--) {
- if (strchr(NONWORD, buffer[cur ^ SWAPBYTES]))
- index = cur + 1;
- else
- for (index = cur + 1;
- index < addr + strsize; index++)
- if (strchr(NONWORD, buffer[index ^ SWAPBYTES]))
- break;
- temp = index - cur;
- if ((buffer[index ^ SWAPBYTES] == ' ') &&
- (ch == 'd'))
- temp++;
- for (index = cur; index <= (int)
- (addr + strsize - temp); index++)
- buffer[index ^ SWAPBYTES] = buffer[(index + temp) ^ SWAPBYTES];
- for (; index <= addr + strsize; index++)
- buffer[index ^ SWAPBYTES] = '\0';
- }
- } else if (ch2 == 't') { /* to character */
- ch2 = eget_key();
- while (looptime--)
- for (index = cur + 1;
- index < addr + strsize; index++)
- if (buffer[index ^ SWAPBYTES] == ch2) {
- temp = index - cur;
- for (index = cur; index <= (int)(addr + strsize - temp); index++)
- buffer[index ^ SWAPBYTES] = buffer[(index + temp) ^ SWAPBYTES];
- for (; index <= addr + strsize; index++)
- buffer[index ^ SWAPBYTES] = '\0';
- break;
- }
- } else if (ch2 == 'f') { /* including char. */
- ch2 = eget_key();
- while (looptime--)
- for (index = cur + 1;
- index < addr + strsize; index++)
- if (buffer[index ^ SWAPBYTES] == ch2) {
- temp = index - cur + 1;
- for (index = cur; index <= (addr +
- strsize - temp); index++)
- buffer[index ^ SWAPBYTES] =
- buffer[(index + temp) ^ SWAPBYTES];
- for (; index <= addr + strsize;
- index++)
- buffer[index ^ SWAPBYTES] = '\0';
- break;
- }
- } else if ((ch2 == '0') || /* start of line */
- (ch2 == '^')) {
- if (cur != addr) {
- temp = strsize - cur + addr;
- memcpy(buffer + addr,
- buffer + cur, temp);
- memset(buffer + addr + temp,
- 0, cur - addr);
- cur = addr;
- }
- } else if (ch2 == '$') /* rest of line */
- goto delete_line;
- break;
- case 'C': /* change line - must precede 'D' */
- emode = 0;
- amode = 1;
- case 'D': /* delete line - must follow 'C' */
- delete_line:
- memcpy(prevstr, buffer + addr, strpsize);
- for (index = cur; index <= addr + strsize; index++)
- buffer[index ^ SWAPBYTES] = '\0';
- break;
- case 'e': /* go to end of current word */
- while (looptime--) {
- index = cur + 1;
- for (; index < addr + strpsize; index++)
- if (!strchr(NONWORD, buffer[index ^ SWAPBYTES]))
- break;
- for (; index < addr + strpsize; index++)
- if (strchr(NONWORD, buffer[index ^ SWAPBYTES]))
- break;
- else
- cur = index;
- }
- break;
- case 'f': /* go to specific character */
- ch2 = eget_key();
- while (looptime--)
- for (index = cur + 1;
- index < addr + strsize; index++)
- if (buffer[index ^ SWAPBYTES] == ch2) {
- cur = index;
- break;
- }
- break;
- case 'I': /* insert at start - must precede 'i' */
- cur = addr;
- case 'i': /* insert at cursor position */
- memcpy(prevstr, buffer + addr, strpsize);
- emode = 0;
- break;
- case 'G': /* go to end of string */
- case '$':
- cur = addr + strsize - 1;
- break;
- case 8: /* ^H - go left one character */
- case 127: /* ^? */
- case 'h':
- case 2: /* ^B */
- #ifdef KEY_LEFT
- case KEY_LEFT:
- #endif
- while (looptime--)
- if (cur > addr)
- cur--;
- break;
- case 'j': /* go down one row */
- #ifdef KEY_DOWN
- case KEY_DOWN:
- #endif
- while (looptime--)
- if (cur + cpline< addr + strpsize)
- cur += cpline;
- break;
- case 'k': /* go up one row */
- #ifdef KEY_UP
- case KEY_UP:
- #endif
- while (looptime--)
- if (cur - cpline >= addr)
- cur -= cpline;
- break;
- case 'l': /* go right one character */
- case ' ':
- case 6: /* ^F */
- #ifdef KEY_RIGHT
- case KEY_RIGHT:
- #endif
- while (looptime--)
- if (cur + 1 < addr + strpsize)
- cur++;
- break;
- case 'q': /* terminate edit - no change */
- case 3: /* ^C */
- #ifndef EMACS_FEEL
- case 24: /* ^X */
- #endif
- memcpy(buffer + addr, origbuf, strpsize);
- ch = '\004';
- break;
- case 'r': /* replace character */
- memcpy(prevstr, buffer + addr, strpsize);
- while (looptime--)
- if (cur < addr + strpsize) {
- ch2 = eget_key();
- buffer[cur ^ SWAPBYTES] = ch2;
- light_string(addr, 1, strsize);
- light_string(addr + strsize, 0,
- strpsize - strsize);
- cur++;
- icur = cur ^ Swapbytes;
- xmove(main_window, icur / cpline,
- fixed_x_offset + icur % cpline);
- xrefresh(main_window);
- }
- break;
- case 'R': /* overstrike mode */
- memcpy(prevstr, buffer + addr, strpsize);
- ch2 = eget_key();
- while (ch2 != ESC) {
- if ((ch2 == 8) || (ch2 == 127)) {
- if (cur > addr)
- cur--;
- } else {
- if (cur < addr + strpsize) {
- buffer[cur ^ SWAPBYTES] = ch2;
- } else
- break;
- cur++;
- }
- light_string(addr, 1, strsize);
- light_string(addr + strsize, 0,
- strpsize - strsize);
- icur = cur ^ Swapbytes;
- xmove(main_window, icur / cpline,
- fixed_x_offset + icur % cpline);
- xrefresh(main_window);
-
- ch2 = eget_key();
- }
- break;
- case 's': /* substitute string for character */
- memcpy(prevstr, buffer + addr, strpsize);
- for (index = cur; index <= addr+strsize-looptime; index++)
- buffer[index ^ SWAPBYTES] = buffer[(index + looptime) ^ SWAPBYTES];
- for (; index <= addr + strsize; index++)
- buffer[index ^ SWAPBYTES] = '\0';
- emode = 0;
- break;
- case 't': /* move forward just before character */
- case 'T':
- ch2 = eget_key();
- while (looptime--)
- for (index = cur + 1;
- index < addr + strsize; index++)
- if (buffer[index ^ SWAPBYTES] == ch2) {
- cur = index - 1;
- break;
- }
- break;
- case 'u': /* undo last edit */
- memcpy(prevstr2, buffer + addr, strpsize);
- memcpy(buffer + addr, prevstr, strpsize);
- prevstrtemp = prevstr;
- prevstr = prevstr2;
- prevstr2 = prevstrtemp;
- break;
- case 'U': /* Undo all edits */
- memcpy(prevstr, buffer + addr, strpsize);
- memcpy(buffer + addr, origbuf, strpsize);
- break;
- case 'w': /* move forward to next word */
- while (looptime--)
- for (index = cur + 1; index < addr + strpsize;index++)
- if (strchr(NONWORD, buffer[index ^ SWAPBYTES])) {
- for (index++; index < addr + strpsize;index++)
- if (!strchr(NONWORD, buffer[index ^ SWAPBYTES])) {
- cur = index;
- break;
- }
- break;
- }
- break;
- case 'x': /* delete character */
- memcpy(prevstr, buffer + addr, strpsize);
- for (index = cur; index <= addr+strsize-looptime; index++)
- buffer[index ^ SWAPBYTES] = buffer[(index + looptime) ^ SWAPBYTES];
- for (; index <= addr + strsize; index++)
- buffer[index ^ SWAPBYTES] = '\0';
- break;
- case '?': /* help me */
- #ifdef KEY_HELP
- case KEY_HELP:
- #endif
- help_me(2);
- xtouchwin(main_window);
- xrefresh(main_window);
- break;
- }
- }
- else { /* INSERT MODE (CHARACTER) */
- if (ch == 22) /* ^V - insert verbose next character */
- temp = eget_key();
- else
- temp = ch;
- for (index = cur; index < addr + strsize; index++) {
- temp2 = buffer[index ^ SWAPBYTES];
- buffer[index ^ SWAPBYTES] = temp;
- temp = temp2;
- }
- if ((index == cur) && (index < addr + strpsize)) {
- buffer[index ^ SWAPBYTES] = temp; /* already at end of buffer, add more */
- }
- if (cur + 1 < addr + strpsize)
- cur++;
- }
- }
- } while ((ch != 4) && !stopping); /* ^D or ^C - end editing session */
- light_string(addr, 0, strsize);
-
- alignment = old_alignment;
- xmove(status_window, 0, 20);
- xclrtoeol(status_window);
- xrefresh(status_window);
-
- free(origbuf);
- free(prevstr);
-
- return(0);
- }
-
-
- STATIC void light_string(addr, hi, strsize)
- int addr;
- int hi;
- int strsize;
- {
- int cur;
- int icur;
-
- if (hi > 0)
- xstandout(main_window);
-
- if (chdis) {
- #if defined(CRSR_COLOR) || defined(WORD_COLOR) || defined(CHAR_COLOR)
- if (!noscreen)
- if (hi == 2)
- wattron(main_window, CRSR_COLOR);
- else if (hi)
- wattron(main_window, WORD_COLOR);
- else
- wattron(main_window, CHAR_COLOR);
- #endif
- cur = addr;
- while ((cur < buf_size - 1) && ((cur - addr) < strsize)) {
- icur = cur ^ Swapbytes;
- xmove(main_window, icur / cpline,
- addis * 10 + wpline * 9 * wdis +
- (icur % cpline));
- xaddch_filt(buffer[cur ^ SWAPBYTES]);
- cur++;
- }
- }
-
- if (wdis) {
- #if defined(CRSR_COLOR) || defined(WORD_COLOR) || defined(CHAR_COLOR)
- if (!noscreen)
- if (hi == 2)
- wattron(main_window, CRSR_COLOR);
- else if (hi)
- wattron(main_window, CHAR_COLOR);
- else
- wattron(main_window, WORD_COLOR);
- #endif
- cur = addr;
- while ((cur < buf_size - 1) && ((cur - addr) < strsize)) {
- icur = cur ^ swapbytes;
- xmove(main_window, icur / cpline,
- addis * 10 + ((icur >> 2) % wpline) * 9 +
- (icur & 3) * 2);
- xaddch(main_window, hex[buffer[cur ^ SWAPBYTES] >> 4]);
- xaddch(main_window, hex[buffer[cur ^ SWAPBYTES] & 15]);
- cur++;
- }
- }
-
- if (hi > 0)
- xstandend(main_window);
-
- #ifdef NO_COLOR
- if (!noscreen)
- wattrset(main_window, 0);
- #endif
- }
-
-
- STATIC int eget_key()
- {
- int ch;
-
- if (ksbufsize)
- ch = ksbuf[--ksbufsize];
- else
- ch = get_key();
-
- if (ch != '.')
- ksfullhist[ksfullhistsize++] = ch;
- kshist[kshistsize++] = ch;
-
- return(ch);
- }
-
- int load_ksbuf_from_hist()
- {
- int index;
-
- if (kshistsize == 0)
- return(1);
-
- ksbufsize = 0;
-
- #ifdef NOT
- /* following is not needed because buffer contains exit keystrokes */
- ksbuf[ksbufsize++] = 4; /* ^D */
- ksbuf[ksbufsize++] = 27; /* ESC */
- #endif
-
- for (index = ksfullhistsize; index && (ksfullhistsize < KSBUFMAX - 1); )
- ksbuf[ksbufsize++] = ksfullhist[--index];
-
- return(0);
- }
-