pvr@wang.com (Peter Reilley) (02/28/91)
#! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 7 (of 11)." # Contents: beav.doc1 file.c # Wrapped by pvr@elf on Wed Feb 27 14:16:49 1991 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'beav.doc1' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'beav.doc1'\" else echo shar: Extracting \"'beav.doc1'\" \(27308 characters\) sed "s/^X//" >'beav.doc1' <<'END_OF_FILE' X X X X X X X X X X BEAV X Binary Editor And Viewer X X Manual Copyright 1991 X X By X Peter Reilley X 19 Heritage Cir. X Hudson, N.H. 03051 X pvr@wang.com X X BEAV source and executable can be freely X distributed for non-commercial purposes. X X X BEAV User Manual X X X X X Table of Contents X X1. Introduction X X2. Overview X 2.1 Terms and Definitions X 2.2 The Screen Format X 2.3 Display Modes X 2.4 Commands X 2.5 Buffers X 2.6 Files X 2.7 Key Binding X 2.8 Configuration X X3. Command Description X 3.1 Help X 3.2 Cursor Movement X 3.3 Buffer Management X 3.4 File Management X 3.5 Window Management X 3.6 Inserting and deleting X 3.7 Search and Replace Commands X 3.8 Exiting BEAV X 3.9 Printing X 3.10 Keyboard Macros X 3.11 Key Binding X 3.12 Special Functions X X4. Alphabetical list of commands by name X X5. Alphabetical list of commands by default key binding X X X X X X X X X X X X X X - 2 - X X X X X BEAV User Manual X X X X X1.0 Introduction X X BEAV is an editor that brings the features of a powerful Xfull screen editor to the editing of binary files. It is the Xonly editor that I know of that does that. X X When you need to edit a non-text file you generally have Xtwo choices; a text editor or a file zap type editor. Each Xchoice has significant disadvantages. X X Text editors expect the file to be formatted in a certain Xway. At a minimum they expect that all lines be terminated by Xa carriage return or line feed and be limited in length. XThere is no line length limit with BEAV. Most text editors Xget confused by bytes that are outside of the normal range (20 Xto 7E HEX). In BEAV no special characters such as carriage Xreturn or line feed affect the display aside from producing Xtheir numeric value. BEAV can edit any file no matter the Xformat. X X The other choice is to use a file zap type editor which Xcan edit a binary file without difficulty. These editors are Xoften very limited in their features and capabilities. Most Xfile zap programs can edit a file only in HEX or ASCII. They Xgenerally operate on a sector basis and because of this they Xcannot insert or delete data in the middle of the file. X X All these limits are eliminated in BEAV. You can edit a Xfile in HEX, ASCII, EBCDIC, OCTAL, DECIMAL, and BINARY. You Xcan search or search and replace in any of these modes. Data Xcan be displayed in BYTE, WORD, or DOUBLE WORD formats. While Xdisplaying WORDS or DOUBLE WORDS the data can be displayed in XINTEL's or MOTOROLA's byte swap format. Data of any length Xcan be inserted at any point in the file. The source of this Xdata can be the keyboard, another buffer, of a file. Any data Xthat is being displayed can be sent to a printer in the Xdisplayed format. Files that are bigger than memory can be Xhandled. X X Some users may recognize the similarity to the EMACS text Xeditor that was written by Richard Stallman at MIT. This is Xnot a coincidence. I attempted to keep as much of the user Xinterface and functionality as possible given the very Xdifferent tasks of EMACS and BEAV. X X X X - 3 - X X X X X BEAV User Manual X X X X2. Overview X 2.1 Terms and Definitions X X Throughout this manual certain terms will be used to Xdescribe the operation and structure of BEAV. X X The data that BEAV is editing is held in a buffer that is Xstructured as a byte stream. There are many commands that Xaffect the way that this byte stream is displayed on to the Xscreen. Whatever display mode is chosen the data in the Xbuffer is not effected, only the presentation. X X One such choice is to display the data as bytes, words, Xor double words. That is; 8 bit values, 16 bit values, or 32 Xbit values. Whatever choice is made the value of the selected Xsize will be displayed. These values are referred to as units Xin this manual. Thus the 'delete-forw-unit' command deletes Xthe unit under the cursor. If 32 bit units are being Xdisplayed then 4 bytes will be deleted. X X Many commands in BEAV start by pressing the 'ESCAPE' Xkey. When this manual refers to a command that requires that Xthe 'ESCAPE' key be pressed it will be abbreviated with X'Esc'. Another frequently used key stroke to start commands Xis 'CONTROL X'. This in done by pressing the 'CONTROL' key Xthen pressing the 'X' key at the same time. In this manual Xthis will be abbreviated by 'Ctl-X'. Many commands contain Xother control characters and these will be abbreviates Xsimilarly. Thus the 'insert-unit' command will be listed as X'Ctl-X I'. This will be entered be pressing the CONTROL key Xand while holding it hitting the 'X' key, release the CONTROL Xkey then hit the 'I' key. X X 2.2 The Screen Format X BEAV presents information to the user in a number of Xareas. The first is the window. There will be at least one Xwindow displayed on the screen at all times. The window Xconsists of two areas. The first is the display area. This Xis where the data that is in the buffer is displayed. Most of Xthe time the cursor will be in this area, as this is where most Xediting is done. Each line in the display area will start Xwith a number that indicates the offset into the buffer for Xthis line of data. At the bottom of the display area for each Xwindow is the status line. X X The status line presents the user with a number of Xspecific pieces of information. The first is the program name Xwhich is "BEAV". Next there is a flag indicating the status Xof this particular buffer. Then the buffer name followed by Xthe file name. Next the cursor position in bytes and the Xcharacter position in the unit. The last pieces of Xinformation give the format that the data is being displayed Xin. There can be multiple windows on the screen at the same Xtime but each window will have a status line at the bottom. X X X X - 4 - X X X X X BEAV User Manual X X X X X The very bottom line on the screen is the prompt line. XThis is where you enter data that BEAV requests. If you want Xto edit a new file you would type 'Ctl-X Ctl-V', BEAV would Xrespond with "Visit file:" on the prompt line. The cursor Xwould be positioned after the prompt. You would then enter Xthe name of the file that you wished to edit. X X If you entered the command by mistake, you can abort the Xoperation by typing a 'Ctl-G'. 'Control G' is a universal Xabort command and can be used anywhere. If you want to Xperform a search you will enter the search string on this Xline. When you have entered the information that BEAV has Xrequested hit 'Return' and the cursor will return to it's Xoriginal position in the window display area. The prompt line Xis also where error messages are displayed. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X - 5 - X X X X X BEAV User Manual X X X X 2.3 Display Modes X X The data in the buffer can be displayed in a number of Xformats. First there is the display mode. This can be Xeither; HEXADECIMAL, DECIMAL, OCTAL, BINARY, ASCII, or EBCDIC. X X If ASCII or EBCDIC mode is chosen then each byte in the Xbuffer will be converted to it's ASCII or EBCDIC character and Xdisplayed. Bytes that are outside of the standard character Xset will be displayed as a dot. Each line will be 64 Xcharacters long. The byte value for "carriage return" and X"line feed" will be displayed as a dot as any other Xnon-printable characters. X X Within HEXADECIMAL, DECIMAL, OCTAL, or BINARY format the Xdata can be displayed in 8, 16 or 32 bit values. If 16 or 32 Xbit values are displayed the user can choose to view these Xvalues in either the Intel format or the Motorola format. If XIntel format is chosen then the first byte in each unit is the Xleast significant byte when the value is calculated. Thus in Xhex 32 bit mode a byte string of "32 7A 9F 10" would be Xdisplayed as "109F7A32". If Motorola format is chosen this Xvalue would be displayed as "327A9F10". X X There is another display format choice that affects the X16 or 32 bit formats. This is called shift. The shift can Xbe 0 or 1 for 16 bit modes, or 0, 1, 2, 3 for 32 bit modes. XShift moves the zero point reference for the buffer up by the Xselected value. The default is zero shift. If a buffer is Xdisplaying the following 32 bit hex data; X X "12345678 2F4792AF 673DFEA1 88551199" X Xwith the shift at 0. Changing shift to 1 will produce; X X "3456782F 4792AF67 3DFEA188 55119955" X XThe data has been slid down toward the beginning of the buffer Xby one byte. This has not changed the data in the buffer at Xall, it has only affected the way that the data is presented on Xthe screen. This is useful when looking at WORD or DOUBLE XWORD data that is not aligned on two or four byte boundaries. X X When BEAV is first started or a new window is opened the Xdefault format is HEXADECIMAL BYTES. X X X X X - 6 - X X X X X BEAV User Manual X X X X 2.4 Commands X X Commands are the means that the user controls the Xoperation of BEAV. A command can be given by using one of two Xmethods. The first is to use the key binding. X X A command can have one or more associated key bindings. XIt can also have no key binding. There are a set of default Xkey bindings that BEAV comes configured with. The current set Xof key bindings can be seen by using the 'help' command. The X'help' command is 'Esc ?' or Function Key 1 'F1' on the IBM XPC. The help buffer can be scrolled by using the up and down Xarrow keys. A printed copy may be obtained by going to the Xbottom of the help buffer using the 'move-to-end' command ('Esc X>' or the 'End' key). Then issue the 'print-mark-to-cursor' Xcommand ('Esc P' or 'Ctl-Print') and enter 'PRN' when prompted Xwith "Print to:". This will output the entire help buffer to Xa printer connected to the parallel interface. X X 2.5 Buffers X X Buffers are the in memory storage for all data editing Xand viewing. Each buffer has a name that appears in the mode Xline. Buffers generally have a file name that is associated Xwith them. The file name also appears in the mode line. The Xbuffer name and the file name are independent but the buffer Xname defaults to the file name. X X The buffer name is used to refer to a specific buffer. XThe 'change-buffer' ('Ctl-X B') command will prompt you for a Xbuffer name. After you enter a buffer name that buffer will Xbe displayed in the current window. If there is no such Xbuffer, one will be created and displayed (it will be empty). X X When BEAV is run with a file name as a command line Xparameter, the file is read into a new buffer. The buffer name Xwill be made the same as the file name. The file name is only Xused when the buffer is saved. If the file name is changed Xusing the 'buffer-set-file-name' ('Ctl-X Ctl-F') command then Xwhen the buffer is saved it will be saved to the new file. X X Buffers are dynamically allocated. They grow or shrink Xas the size of the data they contain changes. The buffer size Xcan be frozen using the 'buffer-size-lock' ('Ctl-X Ctl-L') Xcommand. This prevents inserting or deleting data from the Xbuffer but data can be modified. X X Buffers continue to exist even if they are not being Xdisplayed. Buffers are saved in a linked list that can be Xstepped through using the 'change-to-next-buffer' ('Esc +') or X'change-to-prev-buffer' ('Esc -') commands. If the X'change-to-next-buffer' command is given then the next buffer Xin the list is displayed in the current window. X X X X - 7 - X X X X X BEAV User Manual X X X X 2.6 Files X X Files are the means of storing data on disk. Files or Xsegments of files can be loaded into BEAV for editing or Xviewing. The file on the disk has not been changed until BEAV Xdoes a save to that file. When a save to a file is performed Xthe original file contents in saved in a ".BAK" file. X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X - 8 - X X X X X BEAV User Manual X X X X X 2.7 Key Binding X X All commands in BEAV have a command name and a default Xkey binding. The bindings may be changed to suit personal Xpreference by using the 'bind-to-key' ('Esc K') command. The Xcurrent binding of a key sequence can be displayed by using the X'binding-for-key' ('Ctl-X ?') command. X X If there is an environment variable "BEAV=" and it is set Xto a file name, all key bindings that the user sets are saved Xin this file. When BEAV is started again this file is read Xand these bindings are loaded. Thus, any bindings that a user Xcreates becomes permanent. This file is a simple text file Xand can be edited to make changes. X X 2.8 Configuration X X When BEAV is first run it detects whether the system is Xan IBM PC or a clone. If a PC is detected then a set of key Xbindings that use the 10 function keys and the relevant keypad Xkeys are loaded. If the system is not recognized then only Xthe standard bindings are loaded. X X If a PC is detected the screen is managed by making BIOS Xlevel calls that enhance performance. Otherwise, the screen Xis controlled by making ANSI compatible calls to the operating Xsystem. This is much slower but is not sensitive to hardware Xconfiguration. This requires that non-standard systems Xsupport ANSI display controls. The following ANSI escape Xsequences are used; X X Position cursor ESC [ <row> ; <column> H X X Erase to end of line ESC [ 0 K X X Erase to end of page ESC [ 0 J X X Normal video ESC [ 0 m X X Reverse video ESC [ 7 m X X X X X - 9 - X X X X X BEAV User Manual X X X X X3. Command Description X X This section describes all BEAV commands as to their Xfunction and any side effects that they may have. The first Xline of each description of a command will begin with the Xdefault key binding then the command name and follows with the Xkey binding for a PC. X X 3.1 Help X X This command returns information that will aid in the use Xof BEAV. X X Esc ? help F1 X X A new window is opened by splitting the current window Xthen all current key bindings are displayed. This buffer is Xlarger than can be shown at one time and must be scrolled up Xand down to see all entries. All commands that do not alter Xdata can be used to move around and search the help buffer. XTo leave the help buffer you move to the next window using the X'change-window-forw' command ('Ctl-X N'). The help window can Xbe removed from the screen by making the current window the Xonly window with the 'window-single' command ('Ctl-X 1'). X X X X X X X X X X X X X X X X X X X X X - 10 - X X X X X BEAV User Manual X X X X 3.2 Cursor Movement X X There are a number of commands that move the cursor Xaround the current window. If the cursor bumps the top or the Xbottom of the window the position of the window will be Xadjusted so as to keep the cursor within the bounds. When the Xwindow is moved in response to cursor movements it is moved by Xabout one third of the window size. This improves performance Xby reducing the number of window moves. X X Ctl-P move-back-line North (up arrow) X Ctl-N move-forw-line South (down arrow) X X These commands move the cursor up one line or down one Xline. If the cursor is on the top line in the buffer and a X'move-back-line' command is given the cursor will jump to the Xbeginning of the first unit in the buffer. If the cursor is Xon the last line of the buffer and a 'move-forw-line' is given Xthe cursor will move to the last unit in the buffer. X X Ctl-F move-forw-char East (right arrow) X Ctl-B Move-back-char West (left arrow) X X These commands move the cursor forward or backward in the Xcurrent line. If the cursor is at the first character in the Xfirst unit of the line and the 'move-back-char' command is Xgiven then the cursor will wrap to the last character of the Xprevious line. If the cursor is at the last character of the Xlast unit in the current line then it will wrap to the first Xcharacter of the next line. X X Esc F move-forw-unit Ctl-East X Esc B move-back-unit Ctl-West X X These commands are similar to the above set but they move Xthe cursor by units rather than characters. The command X'move-forw-unit' will position the cursor to the first Xcharacter of the next unit. The command 'move-back-unit' will Xmove the cursor to the first character of the previous unit. X X Ctl-V move-forw-page PageUp X Esc V move-back-page PageDown X X These commands move the move the data in the window by Xthe number of lines in the window less one. The cursor will Xstay in the same position relative to the window as the data is Xmoved. X X Esc < move-to-beginning Home X Esc > move-to-end End X X Move the cursor to the beginning or the end of the buffer. X X X X - 11 - X X X X X BEAV User Manual X X X X X Ctl-X G move-to-byte F9 X X Prompt for a byte offset, then go to that position in the Xcurrent buffer. X X Ctl-X Ctl-N move-window-down Ctl-Z X Ctl-X Ctl-P move-window-up Esc Z X X Move the buffer in the window up or down by one line. XThis does not effect the cursor until it hits the top or bottom Xof the window. X X Esc . mark-set F2 X X Set the mark position to the current cursor position. XThe mark position is remembered even for nonactive windows and Xbuffers. X X Ctl-X Ctl-X swap-cursor-and-mark X X The position of the cursor and the position of the mark Xare swapped. X X Esc L window-link X X This command causes all windows that are displaying the Xcontents of the current buffer to have the same cursor Xposition. Thus if one window is scrolled then all other Xwindows that display that buffer are scrolled so as to keep the Xcursor in the window. X X Ctl-X = show-position X X The current position of the cursor and the mark are Xdisplayed. The buffer size, file size and file name are also Xshown. X X X X X X X X X - 12 - X X X X BEAV User Manual X X X X 3.3 Buffer Management X X Buffers store all data that is being edited. The only Xlimit to the number of buffers is the size of available Xmemory. If a file is loaded into a buffer and there is Xinsufficient memory to hold the entire file, then it will be Xloaded until memory is exhausted. The buffer will then be set Xto read only mode. X X Ctl-X Ctl-B buffers-display Ctl-F1 X X A new window is opened and a list of all buffers in BEAV Xis displayed. The list contains the buffer name, the file Xname (if it exists), the buffer size, and a state flag. If Xthe list is too large for the window, you can go to that window Xand scroll the list. X X Ctl-X B change-buffer Ctl-F2 X X This command prompts you for a buffer name. If you Xenter the name of an existing buffer, that buffer will be Xdisplayed in the current window. If the name does not match Xan existing buffer, a new buffer will be created and Xdisplayed. This buffer will be empty and will have no file Xname. X X Esc + change-to-next-buffer Ctl-F4 X Esc - change-to-prev-buffer Ctl-F5 X X The next or the previous buffer in the buffer list is Xdisplayed in the current window. This does not effect buffers Xthat are displayed in other windows. X X Esc G move-to-buffer-split X X Prompt for a buffer name. Then split the current window Xand display that buffer, creating it if necessary. X X Esc Ctl-N buffer-set-name Esc Ctl-N X X The current buffer name is changed to the name that you Xenter. This does not effect the file name. X X Ctl-X Ctl-F buffer-set-file-name Ctl-F7 X X The file name of the current buffer is changed to the Xname that you enter. This does not affect the buffer name. X X X X X - 13 - X X X X BEAV User Manual X X X X Ctl-X K kill-buffer Ctl-F3 X X This command prompts you for a buffer name. This buffer Xis then deleted. If the buffer is currently being displayed Xyou are prompted for conformation. If the buffer has been Xchanged you are again prompted for conformation. X X Ctl-X Ctl-L buffer-size-lock X X The buffer size is prevented from being changed. Data Xcan be edited but only by changing the existing data. If a Xbuffer is copied into a size-locked buffer the operation well Xbe successful but will overwrite existing data. This command Xtoggles between locked and unlocked. X X Esc Y yank-buffer Ctl-F6 X X Data from one buffer is inserted into the current buffer Xat the cursor position. You are prompted for the name of the Xbuffer to copy from. X X Esc O save-mark-to-cursor X X Prompt for a buffer name. Create a new buffer with that Xname and write the data from the mark to the cursor into that Xbuffer. X X X X X X X X X X X X X X X X X X X X - 14 - X X X X BEAV User Manual X X X X 3.4 File Management X X These commands control BEAV's access to files. Files Xare loaded into buffers or are written from buffers. Commands Xthat prompt for a file name also accept range parameters. XRange parameters are always given in the numeric base of the Xcurrent window. Thus if you are displaying data in decimal Xformat then the range parameters must be entered in decimal. X X The size of a file read or write can be limited by Xspecifying a range. The range parameter specifies the offset Xinto the file, not the buffer. Range parameters can be Xspecified in these forms; X X <file name> <start address> X X <file name> <start address> <end address> X X <file name> <start address> +<length> X X The first form causes the read or write to begin from the X<start address> value until the end of the buffer on write or Xthe end of the file on read. X X The second form reads or writes from <start address> Xuntil <end address> non-inclusive. X X The third form reads or writes from <start address> for X<length> bytes. X X Thus, if the command 'file-read' is given and you enter Xat the prompt; main.obj 1000 +100. If the current display Xmode is hex, the file "main.obj" will be read from hex byte Xaddress 1000 to 10FF into the buffer. X X Ctl-X Ctl-R file-read Sh-F2 X X Prompt for a file name and read that file into the Xcurrent buffer. This overwrites the current contents of the Xbuffer. The buffer name is not changed but the buffer file Xname is set to the new file name. X X Ctl-X Ctl-S file-save Sh-F3 X X Write the current buffer out to the file if it has been Xchanged. If the buffer has not been changed then do nothing. X X Ctl-X V file-view X X Prompt for a file name and read file into a new buffer Xand display in current window. Set to read-only mode. X X X X X - 15 - X X X X BEAV User Manual X X X X Ctl-X Ctl-V file-visit Sh-F4 X X Prompt for a file name. If the buffer already exists Xthen display it in the current window. Otherwise, read file Xinto a new buffer and display in current window. If there is Xno such file then create it. X X Esc U file-visit-split X X Same as above but split current window and display new Xbuffer. This displays the new buffer as well as the old Xbuffer. X X Ctl-X Ctl-W file-write Sh-F5 X X Prompt for a file name, then write the current buffer to Xthat file. X X Ctl-X Tab insert-file Sh-F8 X X Prompt for a file name and insert that file into the Xcurrent buffer at the cursor position. X X Ctl-X Return save-all-buffers Sh-F6 X X Write all buffers that have been changed to their Xrespective files. X X X X X X X X X X X X X X X X X X X - 16 - X X X X BEAV User Manual X X X X 3.5 Window Management X X BEAV presents information to the user in one or more Xwindows. Each window is a view into a buffer where the data Xis actually stored. The window controls how this data is Xformatted for display to the user. Data can be displayed as XHEX bytes, OCTAL bytes, ASCII characters, plus many others. XThe display format is associated with the window. Thus if a Xnew buffer is displayed in the current window that new data Xwill be displayed in the current windows format. X X The only limit to the number of windows is the screen Xsize. A window can be no smaller than two lines. This along Xwith the mode line associated with each window limits to eight Xthe number of windows on an IBM PC 25 line screen. X X Any window can view any buffer including having many Xwindows on the same buffer. For example, two windows can Xdisplay the same buffer but present the data in two different Xmodes. One window could display HEX bytes and the other could Xdisplay ASCII characters. X X Ctl-P change-window-back Ctl-PageUp X Ctl-N change-window-forw Ctl-PageDown X X These commands move the cursor to the next or previous Xwindow on the screen, making it the current window. X X Ctl-X Z window-enlarge X Ctl-X Ctl-Z window-shrink X X Enlarge or shrink the current window size by one line. X X Esc ! window-reposition X X Move window position so that the cursor is centered in Xthe window. The cursor position in the buffer does not change. X X Ctl-X 2 window-split X X Split the current window into equal parts. Both haves Xhave the same display mode and view the save buffer. X X Ctl-X 1 window-single X X Expand the current window to fill the entire display, all Xother windows are removed. Make the current window the only Xwindow displayed. This has no effect on the underlying Xbuffers except that they may not be displayed any more. X X X X - 17 - X X END_OF_FILE if test 27308 -ne `wc -c <'beav.doc1'`; then echo shar: \"'beav.doc1'\" unpacked with wrong size! fi # end of 'beav.doc1' fi if test -f 'file.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'file.c'\" else echo shar: Extracting \"'file.c'\" \(21010 characters\) sed "s/^X//" >'file.c' <<'END_OF_FILE' X/* X* File commands. X*/ X#include "def.h" X Xchar load_file (); Xchar readin (); Xvoid makename (); Xbool writeout (); Xbool parse_f_name (); X Xextern char MSG_rd_file[]; Xextern char MSG_trash[]; Xextern char MSG_ins_file[]; Xextern char MSG_not_fnd[]; Xextern char MSG_visit[]; Xextern char MSG_view[]; Xextern char MSG_buf_ex[]; Xextern char MSG_old_buf[]; Xextern char MSG_buf_nam[]; Xextern char MSG_cnt_cr[]; Xextern char MSG_reading[]; Xextern char MSG_read_lx[]; Xextern char MSG_no_mem_rd[]; Xextern char MSG_wr_file[]; Xextern char MSG_no_fn[]; Xextern char MSG_bk_err[]; Xextern char MSG_writing[]; Xextern char MSG_wrot_1[]; Xextern char MSG_wrot_n[]; Xextern char MSG_fil_nam[]; Xextern char MSG_null[]; Xextern char ERR_parse_fn[]; Xextern char ERR_addr_neg[]; Xextern char ERR_f_size[]; X X#include "lintfunc.dec" X Xstatic int ughlyflag = FALSE; X X/* X* Read a file into the current X* buffer. This is really easy; all you do it X* find the name of the file, and call the standard X* "read a file into the current buffer" code. X*/ Xchar fileread () X{ X register char s; X char fname[NFILEN]; X A32 start, end; X X if ((s = ereply (MSG_rd_file, fname, NFILEN, NULL)) != TRUE) X return (s); X if (parse_f_name (fname, &start, &end)) X { X adjustcase (fname); X return (readin (fname, start, end)); X } X return (TRUE); X} X X X/* insert file into current buffer - use readin, and yank X*/ Xchar fileinsert () X{ X register char s; X char bname[NBUFN], X fname[NFILEN]; X A32 start, end; X register char *trash = MSG_trash; X X strcpy (bname, curbp -> b_bname);/* save current buffer */ X if ((s = _usebuffer (trash)) == 0)/* temp buffer */ X return (s); X if ((s = ereply (MSG_ins_file, fname, NFILEN, NULL)) != TRUE) X return (s); X /* if file name and starting and ending addresses are good */ X if (parse_f_name (fname, &start, &end)) X { X adjustcase (fname); X if ((s = readin (fname, start, end)) == 0) X { X writ_echo (MSG_not_fnd); X _usebuffer (bname); X _killbuffer (trash); X return (s); X } X if ((s = _usebuffer (bname)) == 0) X { X _killbuffer (trash); X return (s); X } X if ((s = _yankbuffer (trash)) == 0) X { X _killbuffer (trash); X return (s); X } X writ_echo (okmsg); X } X else X { X _usebuffer (bname); X _killbuffer (trash); X return (FALSE); X } X if ((s = _killbuffer (trash)) == 0) X return (s); X wind_on_dot (curwp); X return (s); X} X X X/* X* Select a file for editing. X* Look around to see if you can find the X* fine in another buffer; if you can find it X* just switch to the buffer. If you cannot find X* the file, create a new buffer, read in the X* text, and switch to the new buffer. X* X* also various hacked versions for auto load, and X* file-vist with auto window split, and readonly (view-file) (jam) X*/ Xchar file_visit (f, n, k) X{ X char fname[NFILEN]; X char s; X A32 start, end; X if ((s = ereply (MSG_visit, fname, NFILEN, NULL)) != TRUE) X return (s); X if (!parse_f_name (fname, &start, &end)) X return (FALSE); X X splitwind (); X return (load_file (fname, start, end)); X} X X X/* like filevisit, only read only X*/ Xchar viewfile () X{ X char fname[NFILEN]; X char s; X A32 start, end; X X if ((s = ereply (MSG_view, fname, NFILEN, NULL)) != TRUE) X return (s); X ughlyflag = TRUE; X if (!parse_f_name (fname, &start, &end)) X return (FALSE); X X s = load_file (fname, start, end); X if (s) X curbp -> b_flag |= BFVIEW; X ughlyflag = FALSE; X return (s); X} X X Xchar filevisit () X{ X char fname[NFILEN]; X char s; X A32 start, end; X X if ((s = ereply (MSG_visit, fname, NFILEN, NULL)) != TRUE) X return (s); X if (!parse_f_name (fname, &start, &end)) X return (FALSE); X X return (load_file (fname, start, end)); X} X X Xchar load_file (fname, start, end) /* jam */ Xchar *fname; XA32 start, end; X{ X register BUFFER * bp; X register WINDOW * wp; X register LINE * lp; X register int i; X char s; X char bname[NBUFN]; X extern int initial_load; /* jam */ X static int append = 0; X X adjustcase (fname); X for (bp = bheadp; bp != NULL; bp = bp -> b_bufp) X { X if (strcmp (bp -> b_fname, fname) == 0) X { X if (ughlyflag == TRUE) X { X writ_echo (MSG_buf_ex); X return (FALSE); X } X if (--curbp -> b_nwnd == 0) X { X curbp -> buf_type = BFILE; X curbp -> b_dotp = curwp -> w_dotp; X curbp -> b_doto = curwp -> w_doto; X curbp -> b_unit_offset = curwp -> w_unit_offset; X curbp -> b_markp = curwp -> w_markp; X curbp -> b_marko = curwp -> w_marko; X } X curbp = bp; X curwp -> w_bufp = bp; X if (bp -> b_nwnd++ == 0) X { X curwp -> w_dotp = bp -> b_dotp; X curwp -> w_doto = bp -> b_doto; X curwp -> w_unit_offset = bp -> b_unit_offset; X curwp -> w_markp = bp -> b_markp; X curwp -> w_marko = bp -> b_marko; X } X else X { X wp = wheadp; X while (wp != NULL) X { X if (wp != curwp && wp -> w_bufp == bp) X { X curwp -> w_dotp = wp -> w_dotp; X curwp -> w_doto = wp -> w_doto; X curwp -> w_unit_offset = wp -> w_unit_offset; X curwp -> w_markp = wp -> w_markp; X curwp -> w_marko = wp -> w_marko; X break; X } X wp = wp -> w_wndp; X } X } X lp = curwp -> w_dotp; X i = curwp -> w_ntrows / 2; X while (i-- && lback (lp) != curbp -> b_linep) X lp = lback (lp); X curwp -> w_linep = lp; X curwp -> w_flag |= WFMODE | WFHARD; X if (kbdmop == NULL) X { X writ_echo (MSG_old_buf); X } X return (TRUE); X } X } X X makename (bname, fname); /* New buffer name. */ X while ((bp = bfind (bname, FALSE)) != NULL) X { X if (initial_load) /* patch old name */ X { X funky_name (bname, append++); X bp = NULL; X break; X } X s = ereply (MSG_buf_nam, bname, NBUFN, NULL); X if (s == ABORT) /* ^G to just quit */ X return (s); X if (strcmp (bp -> b_bname, bname) == 0 || s == FALSE) X { X /* CR to clobber it */ X makename (bname, fname); X break; X } X } X if (bp == NULL && (bp = bfind (bname, TRUE)) == NULL) X { X writ_echo (MSG_cnt_cr); X return (FALSE); X } X if (--curbp -> b_nwnd == 0) X { X /* Undisplay. */ X curbp -> buf_type = BFILE; X curbp -> b_dotp = curwp -> w_dotp; X curbp -> b_doto = curwp -> w_doto; X curbp -> b_unit_offset = curwp -> w_unit_offset; X curbp -> b_markp = curwp -> w_markp; X curbp -> b_marko = curwp -> w_marko; X } X curbp = bp; /* Switch to it. */ X curwp -> w_bufp = bp; X curbp -> b_nwnd++; X return (readin (fname, start, end)); /* Read it in. */ X} X X X/* X* Read the file "fname" into the current buffer. X* Make all of the text in the buffer go away, after checking X* for unsaved changes. This is called by the "read" command, the X* "visit" command, and the mainline (for "beav file"). If the X* BACKUP conditional is set, then this routine also does the read X* end of backup processing. The BFBAK flag, if set in a buffer, X* says that a backup should be taken. It is set when a file is X* read in, but not on a new file (you don't need to make a backup X* copy of nothing). Return a standard status. Print a summary X* (lines read, error message) out as well. X*/ Xchar readin (fname, start, end) Xchar fname[]; XA32 start, end; X{ X register LINE * lp1; X register LINE * lp2; X register char i; X register WINDOW * wp; X register BUFFER * bp; X register char s, m; X long byte_cnt; X char line[NLINE]; X int num_chars, req_chars; X char buf[80], buf1[80]; X A32 temp; X X m = TRUE; X byte_cnt = 0; X bp = curbp; /* Cheap. */ X if ((s = bclear (bp)) != TRUE)/* Might be old. */ X return (s); X#if BACKUP X bp -> b_flag &= ~(BFCHG | BFBAK);/* No change, backup. */ X#else X bp -> b_flag &= ~BFCHG; /* No change. */ X#endif X if ((start == 0L) && (end == MAXPOS)) X strcpy (bp -> b_fname, fname); X else X strcpy (bp -> b_fname, MSG_null); X if ((s = ffropen (fname)) == FIOERR || s == FIOFNF)/* jam */ X goto out; X bp -> b_file_size = file_len (); /* get the file lenth */ X sprintf (buf, MSG_reading, fname);/* jam */ X writ_echo (buf); X temp = ffseek (start); X if (temp != start) X { X sprintf (buf1, ERR_f_size, R_POS_FMT(curwp)); X sprintf (buf, buf1, temp); X writ_echo (buf); X return (FALSE); X } X /* only read the requested number of characters */ X if ((end - start) > NLINE) X req_chars = NLINE; X else X req_chars = (int)(end - start); X X while ((s = ffgetline (line, req_chars, &num_chars)) == FIOSUC) X { X if ((lp1 = lalloc(num_chars)) == NULL) X { X bp -> b_flag |= BFVIEW; /* if no memory set to read only mode */ X m = FALSE; /* flag memory allocation error */ X break; X } X /* this code breaks rules for knowing how lines * are stored and linked X together, oh well */ X lp2 = lback (curbp -> b_linep); X lp2 -> l_fp = lp1; X lp1 -> l_fp = curbp -> b_linep; X lp1 -> l_bp = lp2; X curbp -> b_linep -> l_bp = lp1; X for (i = 0; i < num_chars; ++i) X lputc (lp1, i, line[i]); X lp1 -> l_used = num_chars; /* number of bytes in this line */ X lp1 -> l_file_offset = byte_cnt; /* file offset from begining */ X byte_cnt += (long) num_chars; /* number of bytes read in */ X start += (long) num_chars; X if (end <= start) X break; X /* stop reading after the requested number of characters */ X if (end < start + req_chars) X { X req_chars = end - start; X } X } X ffclose (); /* Ignore errors. */ X if (s == FIOEOF && kbdmop == NULL) X { X /* Don't zap an error. */ X sprintf (buf1, MSG_read_lx, R_POS_FMT(curwp)); X sprintf (buf, buf1, byte_cnt); X writ_echo (buf); X } X if (m == FALSE && kbdmop == NULL) X { X /* Don't zap an error. */ X sprintf (buf1, MSG_no_mem_rd, R_POS_FMT(curwp)); X sprintf (buf, buf1, byte_cnt); X writ_echo (buf); X } X X#if BACKUP X curbp -> b_flag |= BFBAK; /* Need a backup. */ X#endif Xout: X for (wp = wheadp; wp != NULL; wp = wp -> w_wndp) X { X if (wp -> w_bufp == curbp) X { X wp -> w_linep = lforw (curbp -> b_linep); X wp -> w_dotp = lforw (curbp -> b_linep); X wp -> w_doto = 0; X wp -> w_unit_offset = 0; X wp -> w_markp = NULL; X wp -> w_marko = 0; X wp -> w_flag |= WFMODE | WFHARD; X } X } X if (s == FIOERR || s == FIOFNF)/* False if error. */ X return (FALSE); X /* so tell yank-buffer about it */ X if (blistp -> b_nwnd != 0) /* update buffer display */ X listbuffers (); X return (TRUE); X} X X X/* X* Take a file name, and from it X* fabricate a buffer name. This routine knows X* about the syntax of file names on the target system. X* BDC1 left scan delimiter. X* BDC2 optional second left scan delimiter. X* BDC3 optional right scan delimiter. X*/ Xvoid makename (bname, fname) Xchar bname[]; Xchar fname[]; X{ X register char *cp1; X register char *cp2; X X cp1 = &fname[0]; X while (*cp1 != 0) X ++cp1; X#ifdef BDC2 X while (cp1 != &fname[0] && cp1[-1] != BDC1 && cp1[-1] != BDC2) X --cp1; X#else X while (cp1 != &fname[0] && cp1[-1] != BDC1) X --cp1; X#endif X cp2 = &bname[0]; X#ifdef BDC3 X while (cp2 != &bname[NBUFN - 1] && *cp1 != 0 && *cp1 != BDC3) X *cp2++ = *cp1++; X#else X while (cp2 != &bname[NBUFN - 1] && *cp1 != 0) X *cp2++ = *cp1++; X#endif X *cp2 = 0; X} X X X/* X* Ask for a file name, and write the X* contents of the current buffer to that file. X* Update the remembered file name and clear the X* buffer changed flag. This handling of file names X* is different from the earlier versions, and X* is more compatable with Gosling EMACS than X* with ITS EMACS. X*/ Xchar filewrite () X{ X register WINDOW * wp; X register char s; X char fname[NFILEN]; X A32 start, end; X X if ((s = ereply (MSG_wr_file, fname, NFILEN, NULL)) != TRUE) X return (s); X if (!parse_f_name (fname, &start, &end)) X return (FALSE); X X adjustcase (fname); X if ((s = writeout (fname, start, end)) == TRUE) X { X strcpy (curbp -> b_fname, fname); X curbp -> b_flag &= ~BFCHG; X wp = wheadp; /* Update mode lines. */ X while (wp != NULL) X { X if (wp -> w_bufp == curbp) X wp -> w_flag |= WFMODE; X wp = wp -> w_wndp; X } X } X X#if BACKUP X curbp -> b_flag &= ~BFBAK; /* No backup. */ X#endif X return (s); X} X X X/* X* Save the contents of the current buffer back into X* its associated file. Do nothing if there have been no changes X* (is this a bug, or a feature). Error if there is no remembered X* file name. If this is the first write since the read or visit, X* thet a backup copy of the file is made. X*/ Xchar filesave () X{ X register WINDOW * wp; X register char s; X X if ((curbp -> b_flag & BFCHG) == 0)/* Return, no changes. */ X return (TRUE); X if (curbp -> b_fname[0] == 0)/* Must have a name. */ X { X if (!(curbp -> b_flag & BFSAV))/* yanked buffer */ X { X writ_echo (MSG_no_fn); X } X return (FALSE); X } X#if BACKUP X if ((curbp -> b_flag & BFBAK) != 0) X { X s = fbackupfile (curbp -> b_fname); X if (s == ABORT) /* Hard error. */ X return (s); X if (s == FALSE /* Softer error. */ X && (s = eyesno (MSG_bk_err)) != TRUE) X return (s); X } X X#endif X if ((s = writeout (curbp -> b_fname, 0L, MAXPOS)) == TRUE) X { X curbp -> b_flag &= ~BFCHG;/* No change. */ X curbp -> b_flag &= ~BFBAD;/* if it was trashed, forget it now */ X wp = wheadp; /* Update mode lines. */ X while (wp != NULL) X { X if (wp -> w_bufp == curbp) X wp -> w_flag |= WFMODE; X wp = wp -> w_wndp; X } X } X X#if BACKUP X curbp -> b_flag &= ~BFBAK; /* No backup. */ X#endif X return (s); X} X X/* X* This function performs the details of file X* writing. Uses the file management routines in the X* "fileio.c" package. The number of lines written is X* displayed. Sadly, it looks inside a LINE; provide X* a macro for this. Most of the grief is error X* checking of some sort. X*/ Xbool writeout (fn, start, end) Xchar *fn; XA32 start, end; X{ X register int s, num_chars; X register LINE * lp; X register long nbytes; X char buf[80], buf1[80]; X A32 temp; X X if ((s = ffwopen (fn)) != FIOSUC)/* Open writes message. */ X return (FALSE); X temp = ffseek (start); X if (temp != start) X { X sprintf (buf1, ERR_f_size, R_POS_FMT(curwp)); X sprintf (buf, buf1, temp); X writ_echo (buf); X return (FALSE); X } X sprintf (buf, MSG_writing, fn);/* jam */ X writ_echo (buf); X lp = lforw (curbp -> b_linep);/* First line. */ X nbytes = 0; /* Number of bytes. */ X temp = end - start; /* number of bytes to write */ X while (lp != curbp -> b_linep) X { X if (nbytes + (long)llength (lp) > temp) X num_chars = (int)(temp - nbytes); X else X num_chars = llength (lp); X X if ((s = ffputline (&lp -> l_text[0], num_chars)) != FIOSUC) X break; X nbytes += num_chars; X if (temp <= nbytes) X break; X lp = lforw (lp); X } X if (s == FIOSUC) X { X /* No write error. */ X s = ffclose (); X if (s == FIOSUC && kbdmop == NULL) X { X if (nbytes == 1) X { X writ_echo (MSG_wrot_1); X } X else X { X sprintf (buf1, MSG_wrot_n, R_POS_FMT(curwp)); X sprintf (buf, buf1, (long) nbytes); X writ_echo (buf); X } X } X } X else /* Ignore close error */ X ffclose (); /* if a write error. */ X if (s != FIOSUC) /* Some sort of error. */ X return (FALSE); X curbp -> b_file_size = nbytes; /* update file size */ X if (blistp -> b_nwnd != 0) /* update buffer display */ X listbuffers (); X return (TRUE); X} X X/* X* The command allows the user X* to modify the file name associated with X* the current buffer. It is like the "f" command X* in UNIX "ed". The operation is simple; just zap X* the name in the BUFFER structure, and mark the windows X* as needing an update. You can type a blank line at the X* prompt if you wish. X*/ Xchar filename () X{ X register WINDOW * wp; X register char s; X char fname[NFILEN]; X A32 start, end; X X if ((s = ereply (MSG_fil_nam, fname, NFILEN, NULL)) == ABORT) X return (s); X if (!parse_f_name (fname, &start, &end)) X return (FALSE); X X adjustcase (fname); X curbp -> b_flag |= BFCHG; /* jam - on name change, set modify */ X BUF_START(curwp) = start; X l_fix_up (NULL); /* adjust file offsets from first line */ X strcpy (curbp -> b_fname, fname);/* Fix name. */ X wp = wheadp; /* Update mode lines. */ X while (wp != NULL) X { X if (wp -> w_bufp == curbp) X wp -> w_flag |= WFMODE; X wp = wp -> w_wndp; X } X#if BACKUP X curbp -> b_flag &= ~BFBAK; /* No backup. */ X#endif X return (TRUE); X} X X/* X* Get the length parameters that were entered with the file name. X* There can be the file name only. X* There can be a file name and a starting position. X* There can be a name a starting position and an ending position. X* There can be a name a starting position and a length. X* X* input: X* fn pointer to file name string to parse. X* X* output: X* fn pointer to null terminated file name. X* start pointer to the starting point in file (default = 0) X* end pointer to the end point in file (default = -1) X* return FALSE if file name or addresses are bad. X*/ Xbool parse_f_name (fn, start, end) Xchar *fn; XA32 *start, *end; X { X char buf[NFILEN], buf1[80], fmt[10]; X int i_cnt; X A32 temp; X X /* build up format string according to the current screen format */ X sprintf (fmt, "%s %s %s", "%s", R_POS_FMT(curwp), R_POS_FMT(curwp)); X X *start = 0L; X *end = MAXPOS; X sscanf (fn, fmt, buf, start, end); X X if (*end != MAXPOS) X { X for (i_cnt = strlen (fn) - 1; i_cnt >= 0; i_cnt--) X { X if (fn[i_cnt] == '+') X { X *end += *start; X break; X } X } X } X /* start should preceed end */ X if (*start > *end) X { X sprintf (buf1, ERR_parse_fn, R_POS_FMT(curwp), R_POS_FMT(curwp)); X sprintf (buf, buf1, *start, *end); X writ_echo (buf); X return (FALSE); X } X X /* error if addresses are negative */ X if ((*start < 0) || (*end < 0)) X { X writ_echo (ERR_addr_neg); X return (FALSE); X } X X /* deposit null terminated file name */ X strcpy (fn, buf); X return (TRUE); X } END_OF_FILE if test 21010 -ne `wc -c <'file.c'`; then echo shar: \"'file.c'\" unpacked with wrong size! fi chmod +x 'file.c' # end of 'file.c' fi echo shar: End of archive 7 \(of 11\). cp /dev/null ark7isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 11 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0