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 "main.h"
- #if !defined(Amiga) && !defined(OS9) && !defined(FreeBSD)
- # include <malloc.h>
- #endif
- #include "screen.h"
- #include "pcurses.h"
-
- #ifdef LINT
- # include "lint.h"
- #endif
-
- char *strdup();
-
- char *help_main = "\
- Main Display Keyboard Mappings (brief) \n\
- ------------------------------------------------------------------- \n\
- 0G() = Start/End/Top/Bottom \n\
- hjkl = Scrolling, HJKL moves buffer view \n\
- {Enter}= Edit string or hex \n\
- {Tab} = Toggle string/hex edit mode \n\
- wq^X = Finished editing \n\
- m' = Set/Go to mark \n\
- twc = Toggle hex/dec,word,character modes \n\
- a+- = Toggle address mode,change columns \n\
- /?nN = Search forward/backward/next \n\
- g = Go to (jump) to hex address \n\
- []{} = Location/Range display address divisor \n\
- AC = Append/Create file from cursor to mark \n\
- udfb = Half Up/Down, Full Forward/Back page \n\
- t<> = Type (hex,dec,flt,dbl) Alignment up/down \n\
- \n\
- \n\
- =================================================================== \n\
- \n\
- \n\
- Main Display Keyboard Mappings (detailed) \n\
- ------------------------------------------------------------------- \n\
- 0-9 Enter number of times to perform command \n\
- a Address display on/off \n\
- A Append from current cursor position until mark to file \n\
- b Back one full display page \n\
- ^B Back one full display page \n\
- c Character display on/off \n\
- C Copy from current cursor position until mark to file \n\
- ^C Exit (do not ask to save) \n\
- d Down one half display page \n\
- ^D Down one half display page \n\
- f Forward one full display page \n\
- F Select new file from list given on command line \n\
- ^F Forward one full display page \n\
- g Go to specific byte position (hex) in file \n\
- G Go to bottom of file \n\
- ^G Show current filename and cursor position in file \n\
- h Cursor left \n\
- H Buffer window left (fix cursor at file position) \n\
- ^H Provide Help screen, ? is Help Screen in other modes \n\
- ^I {tab} Change word search mode (string or hex/dec) \n\
- j Cursor down \n\
- J Buffer window down (fix cursor at file position) \n\
- ^J Edit at word (same as Return, either String or Hex) \n\
- k Cursor up \n\
- K Buffer window up (fix cursor at file position) \n\
- l Cursor right \n\
- L Buffer window right (fix cursor at file position) \n\
- ^L Redraw screen \n\
- m Set mark at current file position (type mark character) \n\
- M Move cursor to middle of screen \n\
- ^M Edit at word (same as Return, either String or Hex) \n\
- n Search for next occurrence in current direction \n\
- N Reverse direction of search and look again \n\
- o Change character that shows for non-ASCII \n\
- O Change character that shows for zero \n\
- q Exit (ask to save if modified) \n\
- Q Exit (do not ask to save) \n\
- r Reread buffer and redisplay \n\
- R Change Read-only mode \n\
- s Change byte swapping mode (off, word, long) \n\
- S Toggle byte swapping cursor motion relative to chars/words \n\
- t Toggle word display type (hex, decimal) \n\
- T Cycle word display type (hex, decimal, float, or double) \n\
- u Up one half display page \n\
- ^U Up one half display page \n\
- w Toggle word display on/off \n\
- W Write current buffer contents to file \n\
- ^W Write current buffer contents to file \n\
- x Exit (ask to save if modified) \n\
- ^X Exit (ask to save if modified) \n\
- z Set current line of display at top \"z<CR>\"; middle \"z.\"; \n\
- bottom \"z-\"; or force bottom to top \"z+\" of display \n\
- 0 Beginning page of file / location zero of file \n\
- / Search forward for String or Hex (depending on '^I' mode) \n\
- ? Search backward for String or Hex (depending on '^I' mode) \n\
- ? is used in other modes to provide help \n\
- ^ Go to beginning of current display row \n\
- $ Go to end of current display row \n\
- + Add more display columns (up to screen size) \n\
- = Add more display columns (up to screen size) \n\
- - Subtract display columns (down to a single word column) \n\
- _ Subtract display columns (down to a single word column) \n\
- ' Go to mark (type mark character) \n\
- ` Go to mark (type mark character) \n\
- ( Go to top / left of screen \n\
- ) Go to bottom / right of screen \n\
- < Increase cursor alignment (1, 2, 4, 8 bytes) \n\
- > Decrease cursor alignment (8, 4, 2, 1 bytes) \n\
- [ Double lower status address display divisor / modulus \n\
- ] Halve lower status address display divisor / modulus \n\
- { Double left address display divisor / modulus ('a' mode) \n\
- } Halve left address display divisor / modulus ('a' mode) \n\
- \" Toggle status range address modify between div and mod \n\
- ~ Toggle left address modify between divisor & modulator \n\
- . Go to string edit mode and repeat last session commands \n\
- : Enter colon mode command \n\
- ";
-
-
- char *help_hex = "\
- Hex Edit Mode \n\
- --------------------------------------------- \n\
- ^B Move cursor left \n\
- ^F Move cursor right \n\
- h Move cursor left \n\
- j Move cursor down \n\
- k Move cursor up \n\
- l Move cursor right \n\
- <CR> Store word in file (same as ^M) \n\
- q Quit editing the string, do not store \n\
- ^X Quit editing the string, do not store \n\
- <Del> Move cursor left \n\
- 0-9 Enter Hex digit 0-9 \n\
- a-f Enter Hex digit a-f \n\
- ^ Jump to start of line \n\
- ? Display this help \n\
- ";
-
-
- char *help_string = "\
- String Edit Mode \n\
- ------------------------------------------------------------- \n\
- ESC Mode: \n\
- a Add after cursor position, enter insert mode \n\
- A Add at end of string, enter insert mode \n\
- b Go to previous word \n\
- c f Delete including character, insert mode \n\
- c t Delete to character, put in insert mode \n\
- c w Delete word, put in insert mode \n\
- c ^ Delete to beginning of string, put in insert mode \n\
- c 0 Delete to beginning of string, put in insert mode \n\
- c $ Delete to end of string, put in insert mode \n\
- C Change to end of string \n\
- d f Delete including character \n\
- d t Delete to character \n\
- d w Delete word \n\
- d ^ Delete to beginning of string \n\
- d 0 Delete to beginning of string \n\
- d $ Delete to end of string \n\
- D Delete to end of string \n\
- e Go to end of this word or next \n\
- f Go to next character typed \n\
- G Go to end of string \n\
- h Cursor left (same as backspace key) \n\
- ^H Cursor left (same as backspace key) \n\
- i Insert at cursor position, enter insert mode \n\
- I Insert at beginning of string, enter insert mode \n\
- j Cursor down \n\
- k Cursor up \n\
- l Cursor right \n\
- q Quit editing the string, do not store \n\
- r Replace single character \n\
- R Replace multiple characters (overstrike) \n\
- s Substitute for single character \n\
- t Go to character before next typed character \n\
- T Go to character before next typed character \n\
- u Undo last change \n\
- U Undo all changes to string \n\
- w Go to next word \n\
- x Erase single character \n\
- 0 Go to beginning of string \n\
- $ Go to end of string \n\
- ~ Switch case of current alphabetic character \n\
- . Repeat last edit command \n\
- ^ Go to beginning of string \n\
- ^M Finished editing (same as return) \n\
- ^X Quit editing the string, do not store \n\
- ? Display this help information \n\
- ESC Enter ESC command mode \n\
- \n\
- Insert Mode only: \n\
- ^H Delete left of cursor (same as backspace key) \n\
- ^V Add next raw character to string \n\
- ";
-
-
- char *help_prompt = "\
- File name prompt editor \n\
- ---------------------------------------- \n\
- a = Add after current cursor position \n\
- A = Add at end of name \n\
- c = Change w=word t=to (character) \n\
- d = Delete w=word t=to (character) \n\
- h = Cursor Left \n\
- i = Insert at current cursor position \n\
- I = Insert at beginning of name \n\
- j = Cursor Right \n\
- k = Cursor Left \n\
- l = Cursor Right \n\
- r = Replace single character \n\
- s = Substitute for single character \n\
- 0 = Go to beginning of name \n\
- ^ = Go to beginning of name \n\
- $ = Go to end of name \n\
- u = Undo last edit \n\
- U = Undo all edits to name \n\
- ^H = Delete left of cursor \n\
- ^U = Erase line \n\
- ^V = Next character is raw \n\
- ESC = Escape (command mode) from insert \n\
- ";
-
-
- char *help_select = "\
- Select file help \n\
- ------------------------------- \n\
- b = Move cursor left \n\
- f = Move cursor right \n\
- h = Move cursor left \n\
- l = Move cursor right \n\
- q = Quit without selecting \n\
- <CR> = Select new file to edit \n\
- $ = Go to last file \n\
- 0 = Go to first file \n\
- ^ = Go to first file \n\
- % = Go to current file \n\
- <Tab> = Go to next file (wraps) \n\
- ? = Display this help \n\
- ^L = Refresh (redraw) screen \n\
- ";
-
- #ifdef COLON_MODE
- char *help_colon = "\
- Colon prompt help \n\
- ------------------------------------------ \n\
- :e = Edit new filename(s) \n\
- :h = This help information \n\
- :n = Go to next file \n\
- :p = Go to previous file \n\
- :q = Quit fv \n\
- :q! = Quit fv without saving \n\
- :r = Go to first file \n\
- :w = Write current buffer \n\
- :wq = Write current buffer and exit \n\
- :x = Exit and write if needed \n\
- \n\
- Press ^H in main editor for keystroke help \n\
- ";
- #endif
-
- char *help_oops = "\
- FV has detected an internal error, # \n\
- \n\
- Please report this to the author, including \n\
- a brief description of what you were attempting \n\
- to do and which mode the editor was in. \n\
- ";
-
- WINDOW *help_window = NULL;
- void help_me_text();
-
-
- void help_me(which)
- int which;
- {
- if (noscreen)
- return;
-
- switch (which) {
- case 0: /* main */
- help_me_text(help_main);
- break;
- case 1: /* hex editor */
- help_me_text(help_hex);
- break;
- case 2: /* string editor */
- help_me_text(help_string);
- break;
- case 3: /* prompt string */
- help_me_text(help_prompt);
- break;
- case 4: /* file selector */
- help_me_text(help_select);
- break;
- #ifdef COLON_MODE
- case 5: /* colon mode */
- help_me_text(help_colon);
- break;
- #endif
- default:
- {
- char *buf;
- buf = strdup(help_oops);
- sprintf(buf + 36, "%d.", which);
- /* get rid of sprintf's '\0' */
- buf[strlen(buf)] = ' ';
- help_me_text(buf);
- free(buf);
- break;
- }
- }
- }
-
- void help_me_text(str)
- char *str;
- {
- int row;
- int col;
- int rows = 0;
- int cols = 0;
- int ccols = 1;
- int scols = 0;
- int srows = 0;
- int index;
- int temp;
- int SCOLS;
- int SLINES;
- int ch;
- char *ptr;
- WINDOW *help_window;
-
- for (ptr = str; *ptr != '\0'; ptr++) {
- ch = *ptr;
- switch (ch) {
- case '\n':
- rows++;
- if (ccols > cols)
- cols = ccols;
- ccols = 0;
- scols = 0;
- break;
- case '\t':
- scols += 8 - ((ccols + scols) & 7);
- break;
- case ' ':
- scols++;
- break;
- default:
- ccols += scols + 1;
- scols = 0;
- }
- }
-
- recalc_screen:
- SCOLS = COLS;
- SLINES = LINES;
- if (rows > SLINES - 6)
- srows = SLINES - 6;
- else
- srows = rows;
-
- if (cols > SCOLS - 6)
- scols = SCOLS - 6;
- else
- scols = cols;
-
- help_window = xnewwin(srows + 2, scols + 2,
- (SLINES - srows - 2) / 2, (SCOLS - scols - 2) / 2);
- #ifdef STAT_COLOR
- wattron(help_window, STAT_COLOR);
- #endif
- box(help_window, '|', '-');
- #ifdef CRSR_COLOR
- wattron(help_window, CRSR_COLOR);
- leaveok(help_window, TRUE);
- #else
- leaveok(help_window, FALSE);
- #endif
-
- col = 0;
- row = 0;
- do {
- /* move to start row in string */
- for (ptr = str, index = 0; index < row; index++) {
- for (; (ch = *ptr) != '\n'; ptr++)
- if (ch == '\0')
- break;
- ptr++;
- }
-
- /* display up to srows rows from here */
- for (index = 0; index < srows; index++) {
- xmove(help_window, index + 1, 1);
- for (temp = 0; (ch = *ptr) != '\n'; ptr++) {
- if ((ch == '\0') || (temp >= col))
- break;
- else if (ch == '\t')
- temp += 8 - (temp & 7);
- else
- temp++;
- if (temp > col)
- break;
- }
- ccols = 0;
- for (; (ch = *ptr) != '\n'; ptr++) {
- if (ch == '\0')
- break;
- if (ch == '\t') {
- temp = 8 - ((ccols + col) & 7);
- while (temp--)
- if (ccols++ < scols)
- xaddch(help_window, ' ');
- } else {
- if (ccols++ < scols)
- xaddch(help_window, ch);
- }
- }
- for (; ccols < scols; ccols++)
- xaddch(help_window, ' ');
- ptr++;
- }
- xmove(help_window, srows + 1, scols + 1);
- xrefresh(help_window);
- ch = get_key();
- if ((COLS != SCOLS) || (LINES != SLINES)) {
- unget_key(ch);
- delwin(help_window);
- touchwin(main_window);
- xrefresh(main_window);
- goto recalc_screen;
- }
-
- switch (ch) {
- #ifndef EMACS_FEEL
- case 2: /* ^B */
- #endif
- case 'b':
- row -= srows;
- if (row < 0)
- row = 0;
- break;
- case 4: /* ^D */
- row += srows / 2;
- if (row > rows - srows)
- row = rows - srows;
- break;
- case ' ':
- if (row == rows - srows)
- ch = 13;
- #ifndef EMACS_FEEL
- case 6: /* ^F */
- #endif
- case 'f':
- row += srows;
- if (row > rows - srows)
- row = rows - srows;
- break;
- case 'h':
- case 'H':
- #ifdef EMACS_FEEL
- case 2: /* ^B */
- #endif
- #ifdef KEY_LEFT
- case KEY_LEFT:
- #endif
- if (col > 0)
- col--;
- break;
- case 'j':
- case 'J':
- case 14: /* ^N */
- #ifdef KEY_DOWN
- case KEY_DOWN:
- #endif
- if (row < rows - srows)
- row++;
- break;
- case 'k':
- case 'K':
- case 16: /* ^P */
- #ifdef KEY_UP
- case KEY_UP:
- #endif
- if (row > 0)
- row--;
- break;
- case 12: /* ^L */
- xclear(stdscr);
- xmove(stdscr, 0, 0);
- xclrtobot(stdscr);
- xtouchwin(main_window);
- xtouchwin(status_window);
- xtouchwin(help_window);
- xrefresh(stdscr);
- xrefresh(main_window);
- xrefresh(status_window);
- xrefresh(help_window);
- break;
- case 'l':
- case 'L':
- #ifdef EMACS_FEEL
- case 6: /* ^F */
- #endif
- #ifdef KEY_RIGHT
- case KEY_RIGHT:
- #endif
- if (col < cols - scols)
- col++;
- break;
- case 'G':
- row = rows - srows;
- if (row < 0)
- row = 0;
- break;
- case 21: /* ^U */
- row -= srows / 2;
- if (row < 0)
- row = 0;
- break;
- case 24: /* ^X */
- case 13: /* ^M */
- case 10: /* ^R */
- case 27: /* ESC */
- case 'q':
- case 'x':
- ch = 13;
- break;
- case '0':
- row = 0;
- break;
- }
- } while (ch != 13); /* ^M */
-
- delwin(help_window);
- }
-