comm compress cp crc cron crontab cut \
dd decomp16 DESCRIBE dev2name devsize df dhcpd \
dhrystone diff dirname diskctl du dumpcore \
- ed eject elle elvis env expand factor fbdctl file \
+ ed eject elvis env expand factor fbdctl file \
find finger fingerd fix fold format fortune fsck.mfs \
ftp101 gcore gcov-pull getty grep head hexdump host \
hostaddr id ifconfig ifdef install \
+++ /dev/null
-# Makefile for elle
-
-PROGS= ellec elle
-SRCS.elle= eemain.c eecmds.c eesite.c eevini.c eedisp.c eeterm.c eeerr.c \
- eeques.c eebuff.c eefile.c eefed.c eeedit.c eebit.c eef1.c \
- eef2.c eefd.c eehelp.c eekmac.c eef3.c eesrch.c eequer.c \
- eefill.c eediag.c sbstr.c sbm.c sberr.c
-SRCS.ellec= ellec.c
-CPPFLAGS+= -DIGN_JOB_CONTROl
-MAN.elle=
-MAN.ellec=
-
-.if !empty(CC:Mclang)
-# tons of int functions don't return values
-CFLAGS+= -Wreturn-type
-.endif
-
-defprf.c: deffun.e
- cat deffun.e defprf.e | ellec -Pconf > defprf.c
-
-eefdef.h: deffun.e
- cat deffun.e defprf.e | ellec -Fconf > eefdef.h
-
-eefidx.h: deffun.e
- cat deffun.e defprf.e | ellec -FXconf > eefidx.h
-
-# Don't flush these files if interrupted, dammit!
-.PRECIOUS: ellec deffun.e defprf.e
-
-.include <bsd.prog.mk>
+++ /dev/null
-;;;
-;;; ELLE Master Function Definition file - "deffun.e"
-;;;
-;;; This file serves as input to the ellec program. It defines
-;;; all ELLE functions which may serve as keyboard-bound user commands.
-;;;
-;;; Format: (efun <Index> <Name> <Routine> <Module>)
-;;; Index - an unique index # (used only within ELLE)
-;;; Name - an unique string identifying this function to the user.
-;;; Routine - the C routine implementing the function within ELLE.
-;;; Module - the name of the C source file that the routine is in.
-;;;
-;;; The following definitions are roughly organized by object.
-;;; All functions that emulate EMACS functions are given names identical
-;;; to the EMACS function names. For historical reasons these names
-;;; are not as consistent as they could be (sigh).
-;;; Those which have no exact counterpart in EMACS are identified by comments.
-
-(undefall) ; Ensure all predefined stuff is cleared out.
-
-; Simple Insertion
-(efun 1 "Insert Self" f_insself eef1)
-(efun 2 "Quoted Insert" f_quotins eef1)
-(efun 3 "CRLF" f_crlf eef1)
-
-; Characters
-(efun 4 "Forward Character" f_fchar eef1)
-(efun 5 "Backward Character" f_bchar eef1)
-(efun 6 "Delete Character" f_dchar eef1)
-(efun 7 "Backward Delete Character" f_bdchar eef1)
-(efun 8 "Delete Horizontal Space" f_delspc eef1)
-(efun 9 "Transpose Characters" f_tchars eef1)
-
-; Words
-(efun 10 "Forward Word" f_fword eef1)
-(efun 11 "Backward Word" f_bword eef1)
-(efun 12 "Kill Word" f_kword eef1)
-(efun 13 "Backward Kill Word" f_bkword eef1)
-(efun 14 "Transpose Words" f_twords eef1)
-(efun 15 "Uppercase Word" f_ucword eef1)
-(efun 16 "Lowercase Word" f_lcword eef1)
-(efun 17 "Uppercase Initial" f_uciword eef1)
- ; 18-19 reserved
-
-; Lines
-(efun 20 "Beginning of Line" f_begline eef2)
-(efun 21 "End of Line" f_endline eef2)
-(efun 22 "Next Line" f_nxtline eef2)
-(efun 23 "Previous Line" f_prvline eef2)
-(efun 24 "Down Real Line" f_dnrline eef2)
-(efun 25 "Up Real Line" f_uprline eef2)
-(efun 26 "Open Line" f_oline eef2)
-(efun 27 "Delete Blank Lines" f_delblines eef2)
-(efun 28 "Kill Line" f_kline eef2)
-(efun 29 "Backward Kill Line" f_bkline eef2) ; not EMACS
-(efun 30 "Goto Line" f_goline eef2) ; not EMACS
- ; 31-34 reserved
-
-; Regions
-(efun 35 "Set/Pop Mark" f_setmark eef2)
-(efun 36 "Exchange Point and Mark" f_exchmark eef2)
-(efun 37 "Kill Region" f_kregion eef2)
-(efun 38 "Copy Region" f_copreg eef2)
-(efun 39 "Uppercase Region" f_ucreg eef2)
-(efun 40 "Lowercase Region" f_lcreg eef2)
-(efun 41 "Fill Region" f_fillreg eef2)
- ; 42-44 reserved
-
-; Paragraphs
-(efun 45 "Forward Paragraph" f_fpara eef2)
-(efun 46 "Backward Paragraph" f_bpara eef2)
-(efun 47 "Mark Paragraph" f_mrkpara eef2)
-(efun 48 "Fill Paragraph" f_fillpara eef2)
- ; 49 reserved
-
-; Buffers
-(efun 50 "Select Buffer" f_selbuffer eebuff)
-(efun 51 "Select Existing Buffer" f_selxbuffer eebuff) ; not EMACS
-(efun 52 "Kill Buffer" f_kbuffer eebuff)
-(efun 53 "List Buffers" f_listbufs eebuff)
-(efun 54 "Buffer Not Modified" f_bufnotmod eebuff)
-(efun 55 "EOL CRLF Mode" f_eolmode eebuff) ; ELLE
-(efun 56 "Goto Beginning" f_gobeg eebuff)
-(efun 57 "Goto End" f_goend eebuff)
-(efun 58 "What Page" f_whatpage eebuff)
- ; 59 reserved
-
-; Files
-(efun 60 "Find File" f_ffile eefile)
-(efun 61 "Read File" f_rfile eefile)
-(efun 62 "Visit File" f_vfile eefile)
-(efun 63 "Insert File" f_ifile eefile)
-(efun 64 "Save File" f_sfile eefile)
-(efun 65 "Save All Files" f_savefiles eebuff)
-(efun 66 "Write File" f_wfile eefile)
-(efun 67 "Write Region" f_wreg eefile)
-(efun 68 "Write Last Kill" f_wlastkill eefile) ; not EMACS
- ; 69 reserved
-
-; Windows
-(efun 70 "Two Windows" f_2winds eebuff)
-(efun 71 "One Window" f_1wind eebuff)
-(efun 72 "Other Window" f_othwind eebuff)
-(efun 73 "Grow Window" f_growind eebuff)
-(efun 74 "Shrink Window" f_shrinkwind eebuff) ; not EMACS
-(efun 75 "Delete Window" f_delwind eebuff) ; not EMACS
-(efun 76 "Standout Window" f_sowind eebuff) ; ELLE
-(efun 77 "Two Mode Windows" f_2modewinds eebuff) ; ELLE
-
-; Window Positioning
-(efun 78 "New Window" f_newwin eefd)
-(efun 79 "Next Screen" f_nscreen eefd)
-(efun 80 "Previous Screen" f_pscreen eefd)
-(efun 81 "Other New Screen" f_othnscreen eefd) ; not EMACS
-(efun 82 "Line to Window Border" f_lwindbord eefd) ; not EMACS
-(efun 83 "Scroll Window Up" f_scupwind eefd) ; not EMACS
-(efun 84 "Scroll Window Down" f_scdnwind eefd) ; not EMACS
-(efun 85 "Move to Window Top" f_mvwtop eefd) ; not EMACS
-(efun 86 "Move to Window Bottom" f_mvwbot eefd) ; not EMACS
- ; 87-89 reserved
-
-; Command Input
-(efun 90 "Set Profile" f_setprof eecmds) ; ELLE
-(efun 91 "Prefix Meta" f_pfxmeta eecmds)
-(efun 92 "Prefix Extend" f_pfxext eecmds)
-(efun 93 "Universal Arg" f_uarg eecmds)
-(efun 94 "Negative Argument" f_negarg eecmds)
-(efun 95 "Argument Digit" f_argdig eecmds)
-(efun 96 "VT100 Button Hack" f_vtbuttons eecmds) ; not EMACS
-
-; Help
-(efun 97 "Describe" f_describe eehelp)
- ; 98-99 reserved
-
-; Keyboard Macros
-(efun 100 "Start Kbd Macro" f_skmac eekmac)
-(efun 101 "End Kbd Macro" f_ekmac eekmac)
-(efun 102 "Execute Kbd Macro" f_xkmac eekmac)
-(efun 103 "View Kbd Macro" f_vkmac eekmac)
- ; 104 reserved
-
-; Killing
-(efun 105 "Un-kill" f_unkill eef3)
-(efun 106 "Un-kill Pop" f_unkpop eef3)
-(efun 107 "Append Next Kill" f_appnkill eef3)
- ; 108-109 reserved
-
-; Searching
-(efun 110 "String Search" f_srch eesrch)
-(efun 111 "Reverse String Search" f_rsrch eesrch)
-(efun 112 "Incremental Search" f_isrch eesrch)
-(efun 113 "Reverse Search" f_risrch eesrch)
-
-; Query Replace & friends
-(efun 114 "Replace String" f_repstr eequer)
-(efun 115 "Query Replace" f_querep eequer)
-(efun 116 "Replace in Line" f_repline eequer) ; not EMACS
-
-; Fill Mode
-(efun 117 "Set Fill Column" f_sfcol eefill)
-(efun 118 "Set Fill Prefix" f_sfpref eefill)
-(efun 119 "Auto Fill Mode" f_fillmode eefill)
-(efun 120 "Text Mode" f_textmode eefill) ; IMAGEN
-
-; Indentation
-(efun 121 "Indent According to Mode" f_indatm eef3)
-(efun 122 "Indent New Line" f_indnl eef3)
-(efun 123 "Back to Indentation" f_backind eef3)
-(efun 124 "Indent for Comment" f_indcomm eef3)
-(efun 125 "Indent Relative" f_indrel eef3)
- ; 126-128 reserved
-
-; Miscellaneous
-(efun 129 "Match Bracket" f_matchbrack eef3) ; not EMACS
-
-; Process Control
-(efun 130 "Push to Inferior" f_pshinf eemain)
-(efun 131 "Return to Superior" f_retsup eemain)
-(efun 132 "Write File Exit" f_wfexit eemain) ; not EMACS
- ; 133-139 reserved
-
-; ELLE Debugging
-(efun 140 "Hit Breakpoint" f_bkpt eeerr) ; ELLE
-(efun 141 "Debug Mode" f_debug eediag) ; ELLE
- ; 142-149 reserved
-;---------------------------------------------------------------
-
-; IMAGEN configuration only
-(efun 150 "Execute Unix Command" f_xucmd eemake) ; IMAGEN
-(efun 151 "Execute Make" f_make eemake) ; IMAGEN
-(efun 152 "Find Next Error" f_nxterr eemake) ; IMAGEN
-
-; ICONOGRAPHICS-specific
-(efun 153 "ICO Extend Command" f_icoxcmd eefico) ; ICONOGRAPHICS
-(efun 154 "ICO Typeset Funs" f_icotypfns eefico) ; ICONOGRAPHICS
-(efun 155 "ICO Spec Input Funs" f_icospifns eefico) ; ICONOGRAPHICS
-
-; SUN Mouse functions
-(efun 156 "Stuff Selection" f_stuffsel eesun) ; SUN
-(efun 157 "Select Region" f_selregion eesun) ; SUN
-
+++ /dev/null
-/* This file defines the initial data for ELLE's default user profile.
-** It is automatically generated by ELLEC, and should not be edited.
-*/
-char charmap[] = {
- 35, /* ( 0) ^@ Set/Pop Mark */
- 20, /* ( 1) ^A Beginning of Line */
- 5, /* ( 2) ^B Backward Character */
- 0, /* ( 3) ^C unknown function */
- 6, /* ( 4) ^D Delete Character */
- 21, /* ( 5) ^E End of Line */
- 4, /* ( 6) ^F Forward Character */
- 0, /* ( 7) ^G unknown function */
- 5, /* ( 10) ^H Backward Character */
- 121, /* ( 11) ^I Indent According to Mode */
- 122, /* ( 12) ^J Indent New Line */
- 28, /* ( 13) ^K Kill Line */
- 78, /* ( 14) ^L New Window */
- 3, /* ( 15) ^M CRLF */
- 24, /* ( 16) ^N Down Real Line */
- 26, /* ( 17) ^O Open Line */
- 25, /* ( 20) ^P Up Real Line */
- 2, /* ( 21) ^Q Quoted Insert */
- 113, /* ( 22) ^R Reverse Search */
- 112, /* ( 23) ^S Incremental Search */
- 9, /* ( 24) ^T Transpose Characters */
- 93, /* ( 25) ^U Universal Arg */
- 79, /* ( 26) ^V Next Screen */
- 37, /* ( 27) ^W Kill Region */
- 92, /* ( 30) ^X Prefix Extend */
- 105, /* ( 31) ^Y Un-kill */
- 0, /* ( 32) ^Z unknown function */
- 91, /* ( 33) ^[ Prefix Meta */
- 141, /* ( 34) ^\ Debug Mode */
- 0, /* ( 35) ^] unknown function */
- 140, /* ( 36) ^^ Hit Breakpoint */
- 97, /* ( 37) ^_ Describe */
- 1, /* ( 40) Insert Self */
- 1, /* ( 41) ! Insert Self */
- 1, /* ( 42) " Insert Self */
- 1, /* ( 43) # Insert Self */
- 1, /* ( 44) $ Insert Self */
- 1, /* ( 45) % Insert Self */
- 1, /* ( 46) & Insert Self */
- 1, /* ( 47) ' Insert Self */
- 1, /* ( 50) ( Insert Self */
- 1, /* ( 51) ) Insert Self */
- 1, /* ( 52) * Insert Self */
- 1, /* ( 53) + Insert Self */
- 1, /* ( 54) , Insert Self */
- 1, /* ( 55) - Insert Self */
- 1, /* ( 56) . Insert Self */
- 1, /* ( 57) / Insert Self */
- 1, /* ( 60) 0 Insert Self */
- 1, /* ( 61) 1 Insert Self */
- 1, /* ( 62) 2 Insert Self */
- 1, /* ( 63) 3 Insert Self */
- 1, /* ( 64) 4 Insert Self */
- 1, /* ( 65) 5 Insert Self */
- 1, /* ( 66) 6 Insert Self */
- 1, /* ( 67) 7 Insert Self */
- 1, /* ( 70) 8 Insert Self */
- 1, /* ( 71) 9 Insert Self */
- 1, /* ( 72) : Insert Self */
- 1, /* ( 73) ; Insert Self */
- 1, /* ( 74) < Insert Self */
- 1, /* ( 75) = Insert Self */
- 1, /* ( 76) > Insert Self */
- 1, /* ( 77) ? Insert Self */
- 1, /* (100) @ Insert Self */
- 1, /* (101) A Insert Self */
- 1, /* (102) B Insert Self */
- 1, /* (103) C Insert Self */
- 1, /* (104) D Insert Self */
- 1, /* (105) E Insert Self */
- 1, /* (106) F Insert Self */
- 1, /* (107) G Insert Self */
- 1, /* (110) H Insert Self */
- 1, /* (111) I Insert Self */
- 1, /* (112) J Insert Self */
- 1, /* (113) K Insert Self */
- 1, /* (114) L Insert Self */
- 1, /* (115) M Insert Self */
- 1, /* (116) N Insert Self */
- 1, /* (117) O Insert Self */
- 1, /* (120) P Insert Self */
- 1, /* (121) Q Insert Self */
- 1, /* (122) R Insert Self */
- 1, /* (123) S Insert Self */
- 1, /* (124) T Insert Self */
- 1, /* (125) U Insert Self */
- 1, /* (126) V Insert Self */
- 1, /* (127) W Insert Self */
- 1, /* (130) X Insert Self */
- 1, /* (131) Y Insert Self */
- 1, /* (132) Z Insert Self */
- 1, /* (133) [ Insert Self */
- 1, /* (134) \ Insert Self */
- 1, /* (135) ] Insert Self */
- 1, /* (136) ^ Insert Self */
- 1, /* (137) _ Insert Self */
- 1, /* (140) ` Insert Self */
- 1, /* (141) a Insert Self */
- 1, /* (142) b Insert Self */
- 1, /* (143) c Insert Self */
- 1, /* (144) d Insert Self */
- 1, /* (145) e Insert Self */
- 1, /* (146) f Insert Self */
- 1, /* (147) g Insert Self */
- 1, /* (150) h Insert Self */
- 1, /* (151) i Insert Self */
- 1, /* (152) j Insert Self */
- 1, /* (153) k Insert Self */
- 1, /* (154) l Insert Self */
- 1, /* (155) m Insert Self */
- 1, /* (156) n Insert Self */
- 1, /* (157) o Insert Self */
- 1, /* (160) p Insert Self */
- 1, /* (161) q Insert Self */
- 1, /* (162) r Insert Self */
- 1, /* (163) s Insert Self */
- 1, /* (164) t Insert Self */
- 1, /* (165) u Insert Self */
- 1, /* (166) v Insert Self */
- 1, /* (167) w Insert Self */
- 1, /* (170) x Insert Self */
- 1, /* (171) y Insert Self */
- 1, /* (172) z Insert Self */
- 1, /* (173) { Insert Self */
- 1, /* (174) | Insert Self */
- 1, /* (175) } Insert Self */
- 1, /* (176) ~ Insert Self */
- 7, /* (177) DEL Backward Delete Character */
-};
- char metamap[] = {
- 02 , 86, /* M-^B Move to Window Bottom */
- 014 , 30, /* M-^L Goto Line */
- 016 , 84, /* M-^N Scroll Window Down */
- 020 , 83, /* M-^P Scroll Window Up */
- 022 ,111, /* M-^R Reverse String Search */
- 023 ,110, /* M-^S String Search */
- 024 , 85, /* M-^T Move to Window Top */
- 027 ,107, /* M-^W Append Next Kill */
- 030 , 51, /* M-^X Select Existing Buffer */
- 036 , 74, /* M-^^ Shrink Window */
- 045 ,115, /* M-% Query Replace */
- 055 , 94, /* M-- Negative Argument */
- 060 , 95, /* M-0 Argument Digit */
- 061 , 95, /* M-1 Argument Digit */
- 062 , 95, /* M-2 Argument Digit */
- 063 , 95, /* M-3 Argument Digit */
- 064 , 95, /* M-4 Argument Digit */
- 065 , 95, /* M-5 Argument Digit */
- 066 , 95, /* M-6 Argument Digit */
- 067 , 95, /* M-7 Argument Digit */
- 070 , 95, /* M-8 Argument Digit */
- 071 , 95, /* M-9 Argument Digit */
- 073 ,124, /* M-; Indent for Comment */
- 074 , 56, /* M-< Goto Beginning */
- 076 , 57, /* M-> Goto End */
- 0133, 46, /* M-[ Backward Paragraph */
- 0134, 8, /* M-\ Delete Horizontal Space */
- 0135, 45, /* M-] Forward Paragraph */
- 0102, 11, /* M-B Backward Word */
- 0103, 17, /* M-C Uppercase Initial */
- 0104, 12, /* M-D Kill Word */
- 0106, 10, /* M-F Forward Word */
- 0107, 41, /* M-G Fill Region */
- 0110, 47, /* M-H Mark Paragraph */
- 0111,125, /* M-I Indent Relative */
- 0114, 16, /* M-L Lowercase Word */
- 0115,123, /* M-M Back to Indentation */
- 0116, 22, /* M-N Next Line */
- 0117, 96, /* M-O VT100 Button Hack */
- 0120, 23, /* M-P Previous Line */
- 0121, 48, /* M-Q Fill Paragraph */
- 0124, 14, /* M-T Transpose Words */
- 0125, 15, /* M-U Uppercase Word */
- 0126, 80, /* M-V Previous Screen */
- 0127, 38, /* M-W Copy Region */
- 0131,106, /* M-Y Un-kill Pop */
- 0176, 54, /* M-~ Buffer Not Modified */
- 0177, 13, /* M-DEL Backward Kill Word */
-};
- char extmap[] = {
- 02 , 53, /* X-^B List Buffers */
- 03 ,132, /* X-^C Write File Exit */
- 05 , 67, /* X-^E Write Region */
- 06 , 60, /* X-^F Find File */
- 013 , 68, /* X-^K Write Last Kill */
- 014 , 40, /* X-^L Lowercase Region */
- 015 , 55, /* X-^M EOL CRLF Mode */
- 017 , 27, /* X-^O Delete Blank Lines */
- 020 , 90, /* X-^P Set Profile */
- 022 , 61, /* X-^R Read File */
- 023 , 64, /* X-^S Save File */
- 025 , 39, /* X-^U Uppercase Region */
- 026 , 62, /* X-^V Visit File */
- 027 , 66, /* X-^W Write File */
- 030 , 36, /* X-^X Exchange Point and Mark */
- 032 ,131, /* X-^Z Return to Superior */
- 041 ,130, /* X-! Push to Inferior */
- 044 ,116, /* X-$ Replace in Line */
- 045 ,114, /* X-% Replace String */
- 050 ,100, /* X-( Start Kbd Macro */
- 051 ,101, /* X-) End Kbd Macro */
- 052 ,103, /* X-* View Kbd Macro */
- 056 ,118, /* X-. Set Fill Prefix */
- 060 , 75, /* X-0 Delete Window */
- 061 , 71, /* X-1 One Window */
- 062 , 70, /* X-2 Two Windows */
- 070 , 76, /* X-8 Standout Window */
- 071 , 77, /* X-9 Two Mode Windows */
- 075 , 58, /* X-= What Page */
- 0136, 73, /* X-^ Grow Window */
- 0102, 50, /* X-B Select Buffer */
- 0105,102, /* X-E Execute Kbd Macro */
- 0106,117, /* X-F Set Fill Column */
- 0111, 63, /* X-I Insert File */
- 0113, 52, /* X-K Kill Buffer */
- 0117, 72, /* X-O Other Window */
- 0123, 65, /* X-S Save All Files */
- 0124,119, /* X-T Auto Fill Mode */
- 0177, 29, /* X-DEL Backward Kill Line */
-};
-struct profile def_prof = {
- 1, /* Ver */
- sizeof(charmap), charmap,
- sizeof(metamap)/2, metamap,
- sizeof(extmap)/2, extmap,
- 0, 0
-};
+++ /dev/null
-;;;
-;;; ELLE Default Command Profile - "defprf.e"
-;;;
-;;; This file is input to the ellec program. It defines the default
-;;; command key bindings that ELLE uses, in the absence of an individual
-;;; user profile.
-;;; These defaults attempt to emulate the default EMACS command key
-;;; bindings. Differences, where known, are commented.
-;;;
-;;; "ELLE" means the function is unique to ELLE.
-;;; E/G: (cmd altnam) "thisname";
-;;; "E:" refers to TOPS-20 EMACS, "G:" refers to Gnu Emacs.
-;;; (cmd) This function exists but is bound to "cmd" instead.
-;;; (*) function exists but is not bound to any specific key.
-;;; () function does not exist.
-;;; (=) function exists, with same binding (normally omitted)
-;;; altnam Name by which this function is known.
-;;; "thisname" - name of function bound to this command.
-;;; - means the command is unbound (undefined).
-
-(keyallunbind) ; Flush any predefined bindings
-
-(keybind ^@ "Set/Pop Mark")
-(keybind ^A "Beginning of Line")
-(keybind ^B "Backward Character")
-; ^C not bound. ; E: ()- G: mode-specific-command-prefix
-(keybind ^D "Delete Character")
-(keybind ^E "End of Line")
-(keybind ^F "Forward Character")
-(keybind ^H "Backward Character") ; G: (^B) help-command
-(keybind ^I "Indent According to Mode")
-(keybind ^J "Indent New Line")
-(keybind ^K "Kill Line")
-(keybind ^L "New Window")
-(keybind ^M "CRLF")
-(keybind ^N "Down Real Line")
-(keybind ^O "Open Line")
-(keybind ^P "Up Real Line")
-(keybind ^Q "Quoted Insert")
-(keybind ^R "Reverse Search")
-(keybind ^S "Incremental Search")
-(keybind ^T "Transpose Characters")
-(keybind ^U "Universal Arg")
-(keybind ^V "Next Screen")
-(keybind ^W "Kill Region")
-(keybind ^X "Prefix Extend")
-(keybind ^Y "Un-kill")
-; ^Z not bound ; E: Prefix Control-Meta; G: suspend-emacs
-(keybind ^[ "Prefix Meta")
-(keybind "^\" "Debug Mode") ; ELLE. E: () Prefix Meta; G: () -
-; ^] not bound. ; E+G: Abort Recursive Edit
-(keybind ^^ "Hit Breakpoint") ; ELLE. E: () Prefix Control; G: () -
-(keybind ^_ "Describe") ; E: (M-?) Help; G: (^H-k) undo
-(keybind " " "Insert Self")
-(keybind ! "Insert Self")
-(keybind """" "Insert Self")
-(keybind # "Insert Self")
-(keybind $ "Insert Self")
-(keybind % "Insert Self")
-(keybind & "Insert Self")
-(keybind ' "Insert Self")
-(keybind "(" "Insert Self")
-(keybind ")" "Insert Self")
-(keybind * "Insert Self")
-(keybind + "Insert Self")
-(keybind , "Insert Self")
-(keybind - "Insert Self")
-(keybind . "Insert Self")
-(keybind / "Insert Self")
-(keybind 0 "Insert Self")
-(keybind 1 "Insert Self")
-(keybind 2 "Insert Self")
-(keybind 3 "Insert Self")
-(keybind 4 "Insert Self")
-(keybind 5 "Insert Self")
-(keybind 6 "Insert Self")
-(keybind 7 "Insert Self")
-(keybind 8 "Insert Self")
-(keybind 9 "Insert Self")
-(keybind : "Insert Self")
-(keybind ";" "Insert Self")
-(keybind < "Insert Self")
-(keybind = "Insert Self")
-(keybind > "Insert Self")
-(keybind ? "Insert Self")
-(keybind @ "Insert Self")
-(keybind A "Insert Self")
-(keybind B "Insert Self")
-(keybind C "Insert Self")
-(keybind D "Insert Self")
-(keybind E "Insert Self")
-(keybind F "Insert Self")
-(keybind G "Insert Self")
-(keybind H "Insert Self")
-(keybind I "Insert Self")
-(keybind J "Insert Self")
-(keybind K "Insert Self")
-(keybind L "Insert Self")
-(keybind M "Insert Self")
-(keybind N "Insert Self")
-(keybind O "Insert Self")
-(keybind P "Insert Self")
-(keybind Q "Insert Self")
-(keybind R "Insert Self")
-(keybind S "Insert Self")
-(keybind T "Insert Self")
-(keybind U "Insert Self")
-(keybind V "Insert Self")
-(keybind W "Insert Self")
-(keybind X "Insert Self")
-(keybind Y "Insert Self")
-(keybind Z "Insert Self")
-(keybind [ "Insert Self")
-(keybind "\" "Insert Self")
-(keybind ] "Insert Self")
-(keybind ^ "Insert Self")
-(keybind _ "Insert Self")
-(keybind ` "Insert Self")
-(keybind a "Insert Self")
-(keybind b "Insert Self")
-(keybind c "Insert Self")
-(keybind d "Insert Self")
-(keybind e "Insert Self")
-(keybind f "Insert Self")
-(keybind g "Insert Self")
-(keybind h "Insert Self")
-(keybind i "Insert Self")
-(keybind j "Insert Self")
-(keybind k "Insert Self")
-(keybind l "Insert Self")
-(keybind m "Insert Self")
-(keybind n "Insert Self")
-(keybind o "Insert Self")
-(keybind p "Insert Self")
-(keybind q "Insert Self")
-(keybind r "Insert Self")
-(keybind s "Insert Self")
-(keybind t "Insert Self")
-(keybind u "Insert Self")
-(keybind v "Insert Self")
-(keybind w "Insert Self")
-(keybind x "Insert Self")
-(keybind y "Insert Self")
-(keybind z "Insert Self")
-(keybind { "Insert Self")
-(keybind | "Insert Self")
-(keybind } "Insert Self")
-(keybind ~ "Insert Self")
-(keybind DEL "Backward Delete Character")
-
-; Meta chars
-
-(keybind M-^B "Move to Window Bottom") ; ELLE (ima). E+G:()-
-(keybind M-^L "Goto Line") ; E:(); G:(* goto-line) -
-(keybind M-^N "Scroll Window Down") ; ELLE (ima). E+G:()- forward-list
-(keybind M-^P "Scroll Window Up") ; ELLE (ima). E+G:()- backward-list
-(keybind M-^R "Reverse String Search") ; E:(*); G:(* search-backward) -
-(keybind M-^S "String Search") ; E:(*); G:(* search-forward) isearch-forward-regexp
-(keybind M-^T "Move to Window Top") ; ELLE (ima). E+G:()-
-(keybind M-^W "Append Next Kill")
-(keybind M-^X "Select Existing Buffer") ; ELLE (ima). E+G:()-
-(keybind M-^^ "Shrink Window") ; ELLE (ima). E+G:()-
-(keybind M-% "Query Replace")
-(keybind M-- "Negative Argument")
-(keybind M-0 "Argument Digit")
-(keybind M-1 "Argument Digit")
-(keybind M-2 "Argument Digit")
-(keybind M-3 "Argument Digit")
-(keybind M-4 "Argument Digit")
-(keybind M-5 "Argument Digit")
-(keybind M-6 "Argument Digit")
-(keybind M-7 "Argument Digit")
-(keybind M-8 "Argument Digit")
-(keybind M-9 "Argument Digit")
-(keybind "M-;" "Indent for Comment")
-(keybind M-< "Goto Beginning")
-(keybind M-> "Goto End")
-(keybind M-[ "Backward Paragraph")
-(keybind "M-\" "Delete Horizontal Space")
-(keybind M-] "Forward Paragraph")
-(keybind M-B "Backward Word")
-(keybind M-C "Uppercase Initial")
-(keybind M-D "Kill Word")
-(keybind M-F "Forward Word")
-(keybind M-G "Fill Region")
-(keybind M-H "Mark Paragraph")
-(keybind M-I "Indent Relative") ; E+G: (*) Tab to Tab Stop
-(keybind M-L "Lowercase Word")
-(keybind M-M "Back to Indentation")
-(keybind M-N "Next Line") ; E:(*); G:(* forward-line) -
-(keybind M-O "VT100 button hack") ; ELLE. E+G: () -
-(keybind M-P "Previous Line") ; E:(*); G:() -
-(keybind M-Q "Fill Paragraph")
-(keybind M-T "Transpose Words")
-(keybind M-U "Uppercase Word")
-(keybind M-V "Previous Screen")
-(keybind M-W "Copy Region")
-(keybind M-Y "Un-kill Pop")
-(keybind M-~ "Buffer Not Modified")
-(keybind M-DEL "Backward Kill Word")
-
-; Extended commands
-
-(keybind X-^B "List Buffers")
-(keybind X-^C "Write File Exit") ; ELLE (ima). E:()-; G: (= save-buffers-kill-emacs)
-(keybind X-^E "Write Region") ; E:(*)-; G:(*) eval-last-sexp
-(keybind X-^F "Find File")
-(keybind X-^K "Write Last Kill") ; ELLE (mnx). E+G:()-
-(keybind X-^L "Lowercase Region")
-(keybind X-^M "EOL CRLF Mode") ; ELLE. E+G: ()-
-(keybind X-^O "Delete Blank Lines")
-(keybind X-^P "Set Profile") ; ELLE. E+G: () Mark Page
-(keybind X-^R "Read File")
-(keybind X-^S "Save File")
-(keybind X-^U "Uppercase Region")
-(keybind X-^V "Visit File")
-(keybind X-^W "Write File")
-(keybind X-^X "Exchange Point and Mark")
-(keybind X-^Z "Return to Superior") ; G:() suspend-emacs
-(keybind X-! "Push to Inferior") ; ELLE. E:(*)-; G:()-
-(keybind X-$ "Replace in Line") ; ELLE (mnx). E+G:()-
-(keybind X-% "Replace String") ; E+G: (*) -
-(keybind "X-(" "Start Kbd Macro")
-(keybind "X-)" "End Kbd Macro")
-(keybind X-* "View Kbd Macro") ; E: (*)-; G: ()-
-(keybind X-. "Set Fill Prefix")
-(keybind X-0 "Delete Window") ; E: ()-
-(keybind X-1 "One Window")
-(keybind X-2 "Two Windows")
-(keybind X-8 "Standout Window") ; ELLE. E+G:()-
-(keybind X-9 "Two Mode Windows") ; ELLE. E+G:()-
-(keybind X-= "What Page") ; E+G: (*) What Cursor Position
-(keybind X-^ "Grow Window")
-(keybind X-B "Select Buffer")
-(keybind X-E "Execute Kbd Macro")
-(keybind X-F "Set Fill Column")
-(keybind X-I "Insert File") ; E: (*) Info
-(keybind X-K "Kill Buffer")
-(keybind X-O "Other Window")
-(keybind X-S "Save All Files") ; E:(*)-; G:(= save-some-buffers)
-(keybind X-T "Auto Fill Mode") ; E:(*) Transpose Regions; G:(*)-
-(keybind X-DEL "Backward Kill Line") ; ELLE(ico) E+G:() Backward Kill Sentence
-\f
-; IMAGEN-specific functions, not bound.
-;(keybind "" "Text Mode") ; IMAGEN E:(*); G:(*)
-;(keybind "" "Execute Unix Command") ; IMAGEN E:(); G:(M-! shell-command)
-;(keybind "" "Execute Make") ; IMAGEN E:(* Compile); G:(* compile)
-;(keybind "" "Find Next Error") ; IMAGEN E:(); G:(X-` next-error)
-
-; SUN Mouse functions, for menuitem selection.
-;(menuitem "Stuff Selection") ; SUN
-;(menuitem "Select Region") ; SUN
-
-; Forget completely about these.
-;(keybind "" "ICO Extend Command") ; ICONOGRAPHICS
-;(keybind "" "ICO Typeset Funs") ; ICONOGRAPHICS
-;(keybind "" "ICO Spec Input Funs") ; ICONOGRAPHICS
-
+++ /dev/null
-/* ELLE - Copyright 1985, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/*
- * EEBIT Bit Array functions
- */
-#include "sb.h"
-
-/* Char-bit array functions. All assume that there are at least 8 bits
- * in a byte, and that the number of bytes per word is a power of 2.
- */
-/* CHBBITS represents log 2 of the # of bits stored per chbit-array word.
- * WDBITS already has log2 of the # of bytes per word, and we are
- * assuming each byte has at least 8 bits, so log2(8) = 3.
- */
-#define CHBSIZE (WDSIZE*8) /* # bits per word */
-#define CHBBITS (WDBITS+3) /* log2(CHBSIZE) */
-#define CHBMASK (CHBSIZE-1)
-#define CHBARYSIZ (128/CHBSIZE) /* # words per ASCII array */
-
-/* CHBALLOC(size) - Allocates a char-bit array */
-int *
-chballoc(size)
-int size;
-{ return((int *)calloc((size + CHBSIZE-1)/CHBSIZE, (sizeof(int))));
-}
-
-/* CHBIT(array, char) - Tests bit in char-bit array
- */
-chbit(array,c)
-register int *array, c;
-{ return(array[c >> CHBBITS] & (1 << (c & CHBMASK)));
-}
-/* CHBIS (array, char) - Sets bit in char-bit array
- */
-chbis(array,c)
-register int *array, c;
-{ array[c >> CHBBITS] |= (1 << (c & CHBMASK));
-}
-/* CHBIC (array, char) - Clears bit in char-bit array
- */
-chbic(array,c)
-register int *array, c;
-{ array[c >> CHBBITS] &= ~(1 << (c & CHBMASK));
-}
+++ /dev/null
-/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-
-/* EEBUFF Buffer and Window functions.
- * Each buffer is an independent SB-string described by a
- * buffer structure. All buffer structures are allocated dynamically
- * and chained together starting from buf_head.
- */
-
-#include "elle.h"
-
-#if FX_FILLMODE
-extern int fill_mode;
-#endif
-#if FX_SKMAC
-extern int kdef_mode;
-#endif
-
-struct buffer *make_buf(), *find_buf(), *sel_mbuf(), *sel_nbuf();
-struct window *make_win();
-
-/* EFUN: "Select Buffer" */
-/* Select old buffer or create a new one. Defaults to previously
- * used buffer.
- */
-f_selbuffer()
-{ register char *ans;
- register struct buffer *b;
-
- if((b = last_buf) == cur_buf) /* If default same as current, */
- if(!(b = sel_mbuf(b))) /* try to pick a more useful one. */
- b = sel_nbuf(cur_buf);
-
- ans = ask("Select buffer (%s): ",b->b_name);
- if (ans == 0) /* he aborted */
- return;
- if (*ans != '\0') /* Null string => use last buff */
- { b = find_buf (ans); /* Else find/create one */
- if (b == 0)
- b = make_buf (ans);
- }
- sel_buf(b);
- chkfree(ans);
-}
-
-#if FX_SELXBUFFER
-/* EFUN: "Select Existing Buffer" (not EMACS) - from IMAGEN config */
-
-static int findstr();
-
-f_selxbuffer()
-{ register char *ans;
- register struct buffer *b;
-
- b = last_buf; /* This is default */
- ans = ask("Select existing buffer (%s): ", b->b_name);
- if (ans == 0) /* Aborted */
- return;
- if (*ans != 0)
- { for (b = buf_head; b != 0; b = b->b_next)
- if (findstr(ans, b->b_name))
- break;
- if (b == 0)
- ding("That isn't a substring of any buffer name!");
- }
- chkfree(ans);
- if (b != 0)
- { saytoo(" => ");
- sayntoo(b->b_name);
- sel_buf(b);
- }
-}
-
-static int
-findstr(str, instr) /* Find "str" in string "instr" */
-register char *str, *instr;
-{ register char *sp, *isp;
-
- while (*instr)
- { sp = str;
- isp = instr;
- while (*sp)
- if (*sp++ != *isp++)
- goto next;
- return(1);
-next: ++instr;
- }
- return(0);
-}
-#endif /*FX_SELXBUFFER*/
-
-
-/* EFUN: "Kill Buffer" */
-/* Kill specified buffer - defaults to current buffer.
- * This code assumes a killed buffer will never be on a window list unless it
- * is pointed to by cur_buf or oth_win->w_buf!!!!
- */
-f_kbuffer()
-{ register struct buffer *b, *ob;
- register char *ans;
-
- if((ans = ask("Kill buffer: ")) == 0)
- return;
- if(*ans == 0) b = cur_buf;
- else if(*ans == SP) b = 0;
- else b = find_buf(ans);
-
- chkfree(ans);
- if(!b)
- { ding("No such buffer");
- return;
- }
-#if IMAGEN
- if (b->b_flags & B_PERMANENT)
- { ding("Permanent buffer--cannot kill!");
- return;
- }
- if (b->b_flags & B_MODIFIED)
- { if ((ans == ask("Buffer is modified; are you sure? ")) == 0)
- return;
- if(upcase(*ans) != 'Y')
- { chkfree(ans);
- return;
- }
- chkfree(ans);
- }
-#endif /*IMAGEN*/
- if(b == cur_buf || (oth_win && (oth_win->w_buf == b)))
- { ob = last_buf;
- do
- {
- /* If default same as doomed buffer, try to pick
- * a more useful alternative. */
- if((b == ob) && !(ob = sel_mbuf(b)))
- ob = sel_nbuf(b);
-
- ans = ask("Killing in-use buffer; select which other buffer (%s): ",
- ob->b_name);
- if(ans == 0) return;
- if(*ans)
- { if(*ans == SP) ob = 0;
- else ob = find_buf(ans);
- }
- chkfree(ans);
- if(!ob)
- { ding("No such buffer");
- return;
- }
- } while (b == ob);
-
- /* B is buffer to kill, OB is buffer to replace it with */
- if(oth_win && (oth_win->w_buf == b))
- { f_othwind(); /* Select other one */
- chg_buf(ob); /* Change to new buffer */
- f_othwind();
- }
- if(cur_buf == b)
- chg_buf(ob);
- }
-
- kill_buf(b); /* Die!!!! */
- if(last_buf == b)
- last_buf = cur_buf;
-}
-
-/* EFUN: "List Buffers" */
-/* Display a list of all user buffers. Internal buffers, whose names
- * start with a space, are not shown.
- */
-f_listbufs()
-{
- register struct buffer *b;
- register char *cp;
- register int i;
- struct buffer *tbuf, *savbuf;
- char temp[20];
-
- /* First must set up special buffer... */
- savbuf = cur_buf;
- chg_buf(tbuf = make_buf(" **SHOW**"));
- e_sputz("Buffers in this ELLE:\n\n");
- for(b = buf_head; b; b = b->b_next)
- { cp = b->b_name;
- if(*cp == SP) continue; /* Ignore internal buffs */
- e_sputz((b->b_flags&B_MODIFIED) ? "* " : " ");
- e_sputz(cp); /* Insert buffer name */
- dottoa(temp,ex_blen(b)); /* Get buff-length string */
- if((i = ((FNAMELEN > 14) ? 30 : 20)
- - strlen(cp) - strlen(temp)) > 0)
- e_insn(SP, i);
- e_sputz(" (");
- e_sputz(temp);
- e_sputz(") ");
- if(cp = b->b_fn)
- e_sputz(cp);
-#if IMAGEN
- if (b->b_flags & B_CMODE)
- e_sputz(" (C)");
- else if (b->b_flags & B_TEXTMODE)
- e_sputz(" (Text)");
- else
- e_sputz(" (Fundamental)");
-#endif /*IMAGEN*/
- e_putc(LF);
- }
- mk_showin(tbuf); /* Show this buffer in temp window */
- chg_buf(savbuf); /* Return to real current buffer */
- kill_buf(tbuf);
-}
-\f
-/* EFUN: "Buffer Not Modified" */
-/* Mark the current buffer as not modified.
- */
-f_bufnotmod()
-{
- cur_buf -> b_flags &= ~B_MODIFIED;
- redp(RD_MODE);
-}
-
-#if FX_EOLMODE
-/* EFUN: "EOL CRLF Mode" (not EMACS) */
-/* Toggle the EOL mode of the current buffer.
-** LF EOL Mode means LF alone is an EOL.
-** CRLF EOL Mode means CRLF together is an EOL.
-*/
-f_eolmode()
-{
- cur_buf->b_flags ^= B_EOLCRLF; /* Flip this bit */
- say((cur_buf->b_flags & B_EOLCRLF)
- ? "EOL Mode is CRLF" /* If now on */
- : "EOL Mode is LF"); /* If now off */
-
- redp(RD_WINRES); /* Redo window for this buf */
-}
-#endif /*FX_EOLMODE*/
-\f
-#if FX_GOBEG
-/* EFUN: "Goto Beginning" */
-f_gobeg()
-{ e_gobob();
- ed_setcur();
-}
-#endif /*FX_GOBEG*/
-
-#if FX_GOEND
-/* EFUN: "Goto End" */
-f_goend()
-{ e_goeob();
- ed_setcur();
-}
-#endif /*FX_GOEND*/
-
-#if FX_WHATPAGE
-/* EFUN: "What Page" */
-/* Extra info added as per earlier ICONOGRAPHICS "What Buffer Position"
-** Reports on current position as follows:
-** Dot=<n>, Page <n> Line <n> (line <n> of <m>)
-*/
-f_whatpage()
-{
- register chroff cnt;
- register int c;
- register int page, line;
- int lineatp;
- char tempstr[12], *dottoa ();
-
- saynow("Dot=");
- dottoa(tempstr, cur_dot);
- sayntoo(tempstr);
-
- e_gobob();
- page = line = lineatp = 1;
- for (cnt = cur_dot; --cnt >= 0;)
- if ((c = e_getc()) == LF)
- ++line;
- else if (c == FF)
- { ++page;
- lineatp = line;
- }
-
- saytoo(", Page ");
- dottoa(tempstr, (chroff)page);
- saytoo(tempstr);
- saytoo(" Line ");
- dottoa(tempstr, (chroff)(1 + line - lineatp));
- saytoo(tempstr);
- saytoo(" Col ");
- dottoa(tempstr, (chroff)indtion(cur_dot));
- saytoo(tempstr);
- saytoo(" [line ");
- dottoa(tempstr, (chroff)line);
- saytoo(tempstr);
- sayntoo(" of "); /* Force out while scan rest */
-
- for(e_gocur(); e_gonl() ; ++line) ; /* Count lines until EOF */
- c = e_rgetc(); /* Remember what last char is */
- dottoa(tempstr, (chroff)line);
- saytoo(tempstr);
- if (c != LF) /* Check last char */
- saytoo(" (no EOL at EOF!)");
- sayntoo("]");
- e_gocur(); /* Back to original position */
-}
-#endif /*FX_WHATPAGE*/
-\f
-init_buf () /* init buffer stuff */
-{
- buf_head = 0;
- lines_buf = cur_buf = make_buf(" **LINES**"); /* For sep_win */
- e_insn('-',scr_wid-2); /* Fill with dashes */
- last_buf = cur_buf = make_buf ("Main"); /* Make Main buffer */
- init_win(); /* Now can init windows */
-}
-
-struct buffer *
-make_buf(bname) /* create buffer "bname" if it doesn't exist */
-char *bname;
-{ register struct buffer *b;
- register char *name;
-
- b = find_buf(name = bname);
- if (b) /* if it exists already */
- return(b);
- b = (struct buffer *) memalloc(sizeof (struct buffer));
- b -> b_next = buf_head; /* link it in */
- buf_head = b;
- b->b_name = strdup(name); /* Allocate copy of name string */
- b->b_dot = 0; /* Set dot to beg */
- sb_open(b,(SBSTR *)0); /* Open buffer with null initial sbstring */
- b->b_fn = 0;
- b->b_flags = 0;
- b->b_mode = cur_mode; /* Inherit current mode */
- return(b);
-}
-
-
-struct buffer *
-find_buf(name) /* returns pointer to buffer of that name or 0 */
-char *name;
-{ register struct buffer *b = buf_head;
-
- while (b && strcmp(b->b_name, name))
- b = b -> b_next;
- return(b);
-}
-
-sel_buf(b) /* select buffer, saving last */
-struct buffer *b;
-{
- if(b != cur_buf) last_buf = cur_buf;
- chg_buf(b);
-}
-
-chg_buf (newbuf) /* change current buffer to newbuf */
-struct buffer *newbuf;
-{ register struct buffer *obuf, *nbuf;
-
- if ((nbuf = newbuf) == (obuf = cur_buf))
- return; /* Do nothing if same buffers */
- obuf->b_dot = cur_dot;
- cur_buf = nbuf;
- cur_mode = nbuf->b_mode;
- e_gosetcur(nbuf->b_dot); /* Set cur_dot and go there */
- cur_win->w_buf = nbuf;
- cur_win->w_dot = cur_dot;
-#if IMAGEN
- cur_win->w_redp = RD_WINRES|RD_REDO;
-#else
- cur_win->w_redp = RD_WINRES; /* Reset flags - do complete update */
-#endif /*-IMAGEN*/
- unlk_buf(obuf); /* Unlock previous buffer if can */
- mark_p = 0; /* this is lazy */
- redp(RD_MODE|RD_WINRES);
-}
-
-/* See if specified buffer belongs to any active window, and
- * if not then get it into an idle, unlocked state; this helps the
- * edit package compact and swap stuff out while it's not being used.
- * Assumes proper state of dot has been stored into b_dot.
- */
-unlk_buf(bufp)
-struct buffer *bufp;
-{ register struct buffer *b;
- register struct window *w;
-
- b = bufp;
- for(w = win_head; w; w = w->w_next)
- if(b == w->w_buf)
- return; /* Buffer is actively being shown */
- sb_rewind((SBBUF *)b); /* Return to idle state */
-}
-
-/* SEL_NBUF(buf) - Select next user buffer. Ignores internal buffers.
- * Arg of 0 starts at beg of buffer list. Always returns
- * a buffer pointer - returns argument (which may be 0)
- * if found no other user buffers.
- *
- * SEL_MBUF(buf) - Select next modified buffer.
- * Returns buffer ptr to "next" modified buffer, if any.
- * Arg of 0 starts at beg of buffer list and scans all of them.
- * Returns 0 if no other modified buffers exist (unlike SEL_NBUF!)
- * Ignores internal buffers, whose names start with a space.
- */
-/* struct buffer *buf_mptr; */
-#if 0
-struct buffer *
-sel_mbuf(buf)
-struct buffer *buf;
-{ register struct buffer *b;
- register int sweep;
-
- sweep = 0; /* Make 2 sweeps only */
- if(b = buf) b = b->b_next;
- do {
- if(b == 0) /* Initialize if needed */
- b = buf_head;
- for(; b; b = b->b_next)
- if((b->b_flags & B_MODIFIED) && (*b->b_name != SP))
- return((b == buf) ? 0 : b);
- } while(sweep++ != 0);
- return(0);
-}
-#endif /*COMMENT*/
-
-struct buffer *
-sel_mbuf(buf)
-register struct buffer *buf;
-{ register struct buffer *b, *b2;
- b = b2 = sel_nbuf(buf);
- do { if(b == buf) break;
- if(b->b_flags & B_MODIFIED)
- return(b);
- } while((b = sel_nbuf(b)) != b2);
-
- return(0);
-}
-
-struct buffer *
-sel_nbuf(buf)
-register struct buffer *buf;
-{ register struct buffer *b;
-
- b = buf;
- do {
- if(!b || !(b = b->b_next))
- b = buf_head;
- if(*b->b_name != SP)
- break;
- } while (b != buf);
- return(b);
-}
-
-
-kill_buf(buf)
-struct buffer *buf;
-{ register struct buffer *b, *b1, *bt;
-
- b = buf;
- b1 = 0;
- for(bt = buf_head; bt && bt != b; bt = bt -> b_next)
- b1 = bt;
- if(bt == 0)
- { ring_bell();
- errbarf("No such buffer"); /* Internal error */
- return;
- }
- if (b1 == 0)
- buf_head = b->b_next;
- else
- b1->b_next = b->b_next;
- sbs_del(sb_close((SBBUF *)b)); /* Close buffer & delete sbstring */
- sb_fdcls(-1); /* Make sweep for unused FD's */
- if(b->b_fn)
- chkfree(b->b_fn); /* Flush filename if one */
- chkfree(b->b_name); /* Flush name */
- chkfree((char *)b); /* Flush buffer */
-}
-\f
-/* ZAP_BUFFER - Delete all of the buffer, but if it's been modified,
- * ask first. Returns 0 if user aborts.
- */
-zap_buffer()
-{
-#if IMAGEN
- extern struct buffer *exec_buf; /* in e_make.c */
-
- if(cur_buf != exec_buf && cur_buf -> b_flags & B_MODIFIED)
-#else
- if(cur_buf -> b_flags & B_MODIFIED)
-#endif /*-IMAGEN*/
- if(ask_kbuf(cur_buf) <= 0)
- return(0); /* Aborted */
- ed_reset(); /* This takes care of redisplay too */
- mark_p = 0;
-#if IMAGEN
- cur_buf->b_flags &= ~B_BACKEDUP; /* Clear backed-up flag */
-#endif
- return(1);
-}
-
-
-\f
-/* ASK_KBUF - Ask user "are you sure?" before killing a buffer.
- * Returns +1 if user says "yes" - OK to kill.
- * 0 if user aborts (^G)
- * -1 if user says "no".
- */
-ask_kbuf(buf)
-struct buffer *buf;
-{ register struct buffer *b;
- register char *s;
- register int ans;
-
- b = buf;
- s = ask("Buffer %s contains changes - forget them? ", b->b_name);
- if(s == 0) return(0);
- ans = (upcase(*s) == 'Y') ? 1 : -1;
- chkfree(s);
- return(ans);
-}
-\f
-/* Window stuff */
-
-/* Like EMACS, ELLE only provides at most two user windows.
- * The current user window is pointed to by user_win;
- * the "other" one is oth_win. If oth_win == 0, there is only one user
- * window.
- */
-
-#if FX_2MODEWINDS
-int sepmode_p = 0; /* Set true if separator window is a 2nd mode win */
-#endif
-
-/* EFUN: "Two Windows" */
-/* Divide the current window in half, put the current buffer in the
- * other window, and go to the new window.
- */
-f_2winds()
-{ register int h, t;
- register struct window *w;
-
- if (oth_win)
- {
-#if !(IMAGEN)
- ding("Already 2 windows");
-#endif /*-IMAGEN*/
- return;
- }
- w = cur_win;
- d_fixcur(); /* Stabilize current window */
- h = (w->w_ht) / 2;
- t = w->w_pos + h; /* Pos of dividing window */
- sep_win = make_win(t, 1, lines_buf);
- /* assume using dashes to separate */
- oth_win = make_win(t + 1, w->w_ht - (h + 1), cur_buf);
- /* Other window has balance */
-#if FX_SOWIND
- oth_win->w_flags |= cur_win->w_flags&W_STANDOUT;
- sep_win->w_flags |= mode_win->w_flags&W_STANDOUT;
-#endif
-#if FX_2MODEWINDS
- chk2modws(); /* Update 2-mode-wind status */
-#endif
- w->w_ht = h; /* Decrease current window to half */
-
- /* Minimize redisplay by moving each window's dot into
- * a currently displayed area */
- if(cur_dot < (oth_win->w_topldot = scr[t+1]->sl_boff))
- oth_win->w_dot = oth_win->w_topldot; /* Adj bottom win */
- else /* Adjust top window */
- { oth_win->w_dot = cur_dot; /* Bottom keeps dot */
- cur_dot = scr[t-1]->sl_boff; /* but top needs new one. */
- }
- f_othwind(); /* switch to other window */
- redp(RD_WINDS); /* Update all windows */
-}
-
-
-/* EFUN: "One Window" */
-/* Revert to using only one window; use the current buffer (unlike
- * EMACS which always selects the top window's buffer)
- * Ensures that current window's vars are correctly set for
- * new dimensions (w_pos, w_ht, plus w_topldot to minimize redisplay),
- * then kills unneeded windows.
- */
-f_1wind()
-{ register struct window *w;
-
- if (oth_win == 0)
- {
-#if (!IMAGEN)
- ding("Only 1 window");
-#endif /*-IMAGEN*/
- return;
- }
- w = cur_win;
- if(w->w_pos) /* If not top window */
- { d_fixcur(); /* Ensure screen-line data correct */
- e_go(w->w_topldot); /* Beginning from top of window, */
- d_fgoloff(-w->w_pos); /* Move back enough lines */
- w->w_topldot = e_dot(); /* To set new start of window */
- e_gocur(); /* Then move back to orig place */
- w->w_pos = 0;
- }
- w->w_ht += oth_win -> w_ht + 1;
- kill_win (oth_win);
- kill_win (sep_win);
- oth_win = sep_win = 0;
-#if FX_2MODEWINDS
- chk2modws(); /* Update notion of whether have 2 mode winds */
-#endif
- redp(RD_FIXWIN|RD_WINDS|RD_MODE); /* New topldot for this window,
- * and check all remaining windows */
-}
-
-/* EFUN: "Other Window" */
-/* Move to the "other" user window.
- */
-f_othwind ()
-{ if (oth_win == 0)
- {
-#if !(IMAGEN)
- ding("Only 1 window");
-#endif /*-IMAGEN*/
- return;
- }
- chg_win(oth_win);
- oth_win = user_win;
- user_win = cur_win;
- redp(RD_MODE);
-}
-
-/* EFUN: "Grow Window" */
-/* Grow the current window - while in two window mode,
- * increase the size of the current window by the arg
- * and decrease the other accordingly
- */
-f_growind()
-{ register struct window *cw, *ow;
- register int e;
-
- if ((ow = oth_win) == 0)
- {
-#if !(IMAGEN)
- ding("Only 1 window");
-#endif /*-IMAGEN*/
- return;
- }
- e = exp;
- if((cw = cur_win)->w_pos != 0) /* If current window is on bottom */
- { cw = ow; /* Then fake code to think it's top */
- ow = cur_win;
- e = -e;
- }
- if( cw->w_ht + e < 1
- || ow->w_ht + e < 1)
- { ding("Too much");
- return;
- }
- cw -> w_ht += e;
- ow -> w_pos += e;
- ow -> w_ht -= e;
- sep_win -> w_pos += e;
- redp(RD_WINDS | RD_MODE); /* Update all windows */
-}
-
-#if FX_SHRINKWIND
-/* EFUN: "Shrink Window" (not EMACS) - from IMAGEN config */
-f_shrinkwind()
-{
- if (! oth_win)
- return;
- f_othwind();
- f_growind();
- f_othwind();
-}
-#endif /*FX_SHRINKWIND*/
-
-#if FX_DELWIND
-/* EFUN: "Delete Window" (not EMACS) - from IMAGEN config */
-f_delwind()
-{
- if(!oth_win)
- return;
- f_othwind();
- f_1wind();
-}
-#endif /*FX_DELWIND*/
-
-#if FX_SOWIND
-/* EFUN: "Standout Window" (not EMACS) */
-/* Toggles the display standout mode for the current window.
-** With argument of 4, toggles the standout mode for the non-buffer
-** parts of the screen, such as the ELLE mode line.
-** (This corresponds to FS INVMOD$ in EMACS)
-** With argument of 0, turns standout mode off for all windows.
-*/
-/* It suffices to set the window flag bit and force a RD_WINRES for that
- * window; the redisplay code will do the rest.
-*/
-static void tgso_wind();
-
-f_sowind()
-{
- register struct window *w;
- switch(exp)
- { default: /* Toggle current window */
- tgso_wind(cur_win);
- break;
- case 4: /* Toggle mode & separator windows */
- tgso_wind(mode_win);
- tgso_wind(sep_win); /* This may not exist */
- break;
- case 0: /* Turn off standout for all winds */
- for(w = win_head; w; w = w->w_next)
- if(w->w_flags&W_STANDOUT)
- tgso_wind(w);
- }
-#if FX_2MODEWINDS
- chk2modws(); /* Update notion of whether have 2 mode winds */
-#endif
-}
-
-static void
-tgso_wind(w) /* Toggle standout mode for given window */
-register struct window *w;
-{
- if (w == 0) return; /* For case of no sep_win */
- if (w->w_flags & W_STANDOUT)
- w->w_flags &= ~W_STANDOUT;
- else w->w_flags |= W_STANDOUT;
- w->w_redp |= RD_WINRES; /* Re-do this particular window */
- redp(RD_CHKALL); /* Check all windows for changes */
-}
-#endif /*FX_SOWIND*/
-
-
-#if FX_2MODEWINDS
-/* EFUN: "Two Mode Windows" (not EMACS) */
-/* With arg, sets ev_2modws to that value (0, 1, or 2).
-** No arg, toggles current setting between 0 and 2.
-*/
-
-f_2modewinds()
-{
- ev_2modws = exp_p ? exp : (ev_2modws ? 0 : 2);
- chk2modws();
-}
-
-/* CHK2MODWS - Called after anything changes which might affect
-** whether 2 mode windows are in effect or not. Fixes up
-** sep_win to either be or not be a mode window.
-*/
-chk2modws()
-{ register struct window *w;
- static struct buffer *sep_buf = 0;
-
- if(!(w = sep_win))
- { sepmode_p = 0; /* Don't have 2 windows at all */
- return;
- }
- sepmode_p = (ev_2modws == 1)
- ? (mode_win->w_flags&W_STANDOUT)
- : ev_2modws;
-
- if(sepmode_p) /* Turn 2-mode-winds on? */
- {
- if(!sep_buf)
- sep_buf = make_buf(" **SEPMODE**");
- w->w_buf = sep_buf;
- w->w_flags |= W_MODE;
- }
- else /* Turn 2-mode-winds off */
- { w->w_buf = lines_buf;
- w->w_flags &= ~W_MODE;
- redp(RD_CHKALL); /* No longer a mode win, so must */
- /* check all to ensure it's updated */
- }
- w->w_redp |= RD_WINRES;
- redp(RD_MODE);
-}
-#endif /*FX_2MODEWINDS*/
-\f
-init_win ()
-{
- win_head = 0;
- oth_win = 0;
- user_win = make_win(0, scr_ht - (ECHOLINES+1), cur_buf); /* Main */
- mode_win = make_win(scr_ht - (ECHOLINES+1), 1, make_buf(" **MODE**"));
- ask_win = make_win(scr_ht - ECHOLINES, 1, make_buf(" **ASK**"));
-#if FX_SOWIND
- if(ev_modwso)
- mode_win->w_flags |= W_STANDOUT;
-#endif
-
- cur_win = user_win;
-}
-
-chg_win(newwin) /* change current window to newwin */
-struct window *newwin;
-{
- cur_win->w_dot = cur_dot; /* Save window's current dot */
- cur_win->w_redp |= rd_type&RDS_WINFLGS; /* and its redisplay flags */
- cur_win = newwin; /* OK, switch to new current window */
- cur_buf = newwin->w_buf; /* Set new buffer from win */
- e_gosetcur(newwin->w_dot); /* Set new cur_dot from win too */
- /* Note done this way to canonicalize the location
- ** (may be past new EOB) and ensure SB buffer
- ** internals agree with cur_dot.
- */
- rd_type &= ~RDS_WINFLGS; /* Remove old per-window flags */
- redp(RD_WINRES|RD_MODE); /* Maybe caller shd handle? */
- /* Note WINRES must be set in case we are pointing
- * to a buffer that was modified while we were in
- * the other window!
- */
-}
-
-
-struct window *
-make_win (pos, ht, buf)
-int pos, ht;
-struct buffer *buf;
-{ register struct window *w;
- register struct buffer *b;
-
- b = buf;
- w = (struct window *) memalloc(sizeof (struct window));
- w->w_flags = 0;
- w->w_pos = pos;
- w->w_ht = ht;
- w->w_buf = b;
- w->w_dot = b->b_dot; /* Set dot from buffer value */
- w->w_topldot = 0; /* Set top of window to beg of buffer */
- w->w_pct = 200; /* Assume "ALL" */
- w->w_bmod = 0;
- w->w_emod = 0;
- w->w_oldz = 0;
- w->w_redp = RD_WINRES; /* Window will need complete update */
- w->w_next = win_head; /* Done, now link it in */
- win_head = w;
- return (w);
-}
-
-kill_win (win)
-struct window *win;
-{ register struct window *w, *w1, *kw;
-
- kw = win;
- w1 = 0;
- for (w = win_head; w && w != kw; w = w -> w_next)
- w1 = w;
- if (w == 0)
- { ring_bell();
- errbarf("No such window"); /* Internal error */
- return;
- }
- if (w1 == 0)
- win_head = w -> w_next;
- else
- w1 -> w_next = w -> w_next;
- kw->w_buf->b_dot = (kw == cur_win) ? cur_dot : kw->w_dot;
- chkfree (kw);
-#if IMAGEN /* Not needed? */
- redp (RD_WINRES|RD_WINDS|RD_REDO);
-#endif /*IMAGEN*/
-}
-\f
-/*
- * "Show-window" routines, used to set up, step through, and close a
- * temporary "show" window.
- * MK_SHOWIN(bufp)
- * UP_SHOWIN()
- * KL_SHOWIN()
- */
-
-/* MK_SHOWIN(bufp) - Temporarily display a buffer
- */
-mk_showin(b)
-struct buffer *b;
-{ register struct window *w;
- register int i;
- int moreflg, intflg; /* Interrupt flag */
- struct window *savwin;
-
- /* First must set up special window... */
- savwin = cur_win;
- chg_win(w = make_win(0, scr_ht-(ECHOLINES+3), b));
- redo:
- d_fixcur(); /* Fix up screen image of current window */
-
- /* Find how many lines actually used, and reduce size to that */
- i = w->w_ht;
- while(--i >= 0)
- {
- if(scr[i]->sl_boff != w->w_oldz) break;
- }
- if(++i <= 0)
- goto skipit; /* Punt the whole thing */
- if(!(moreflg = (i >= w->w_ht)))
- w->w_ht = i; /* Reduce size of window */
-
- intflg = upd_wind(w); /* Update the window! */
- if(!intflg) /* Unless input waiting, add prompt. */
- {
- yellat( moreflg ?
- "--MORE-- (type Space for more, or type any command to flush)" :
- "------------------------------------------------ (Hit space to continue)--",
- w->w_ht);
-
- }
- tbufls(); /* Ensure all output forced out */
- i = cmd_read(); /* then wait for user to input a char */
- if(i == SP)
- { if(moreflg)
- { yellat("", w->w_ht);
- d_screen(1);
- w->w_redp |= RD_WINRES;
- goto redo;
- }
- }
-#if !(IMAGEN) /* IMAGEN - always ignore what was typed */
- else unrchf = i;
-#endif /*-IMAGEN*/
-skipit: chg_win(savwin);
- kill_win(w);
- redp(RD_WINDS); /* Update all remaining windows */
-}
-\f
-/* Mode Line generation */
-
-struct window *
-make_mode(bw)
-register struct window *bw; /* Base window we are reporting status of */
-{
- register struct buffer *b; /* Buffer of this window */
- struct window *mw, *savew; /* Save current window */
- struct buffer *saveb; /* and current buffer (in case different) */
- char temp[20];
-
- saveb = cur_buf; /* Save values prior to context switch */
- savew = cur_win;
- b = bw->w_buf; /* Get buffer for that window */
-
-#if FX_2MODEWINDS
- if((mw = sep_win) && (mw->w_flags&W_MODE) &&
- (bw->w_pos == 0)) /* Base window is top window? */
- { /* Use sep_win as mode wind */
- }
- else
-#endif
- mw = mode_win; /* Default is normal mode window */
- chg_win(mw); /* Go to mode line window */
- e_gobob(); /* go to beginning */
- e_reset(); /* Flush buffer */
-#if IMAGEN
- e_sputz(" ");
- e_sputz(b->b_name);
- if (b -> b_flags & B_MODIFIED)
- e_sputz("*");
- e_sputz(" (");
- if (b->b_flags & B_QUERYREP)
- e_sputz("[Query Replace] ");
- if (b->b_flags & B_CMODE)
- e_sputz("C");
- else if (b->b_flags & B_TEXTMODE)
- e_sputz("Text");
- else
- e_sputz("Fundamental");
- e_sputz(") ");
- if (b->b_fn)
- e_sputz(b->b_fn);
- e_sputz(" ");
-#else
- e_sputz(ev_verstr); /* Editor name/version */
- e_sputz(" (");
- e_sputz(cur_mode->mjm_name); /* insert major mode name */
-#if FX_FILLMODE
- if(fill_mode) e_sputz(" Fill");
-#endif /*FX_FILLMODE*/
-#if FX_SKMAC
- if(kdef_mode) e_sputz(" MacroDef");
-#endif /*FX_SKMAC*/
- e_sputz(") ");
- e_sputz(b->b_name); /* buffer name */
- e_sputz(": ");
- if (b->b_fn)
- e_sputz(b->b_fn); /* file name */
- if (b->b_flags & B_MODIFIED)
- e_sputz(" *");
- else e_sputz(" ");
-#endif /*-IMAGEN*/
- if(bw->w_pct < 200) /* Not ALL? */
- { e_sputz(" --");
- switch(bw->w_pct)
- { case -1:
- e_sputz("TOP");
- break;
- case 150:
- e_sputz("BOT");
- break;
- default:
- dottoa(&temp[0],(chroff)bw->w_pct);
- e_sputz(&temp[0]);
- e_putc('%');
- }
- e_sputz("--");
- }
-#if FX_SOWIND
- if(mw->w_flags&W_STANDOUT)
- e_insn(SP, (int)(scr_wd0 - e_blen())); /* Stuff out with spaces */
-#endif
-
- redp(RD_WINRES);
- chg_win(savew); /* Restore context */
- chg_buf(saveb);
- return(mw); /* Return mode window */
-}
-
-
-buf_mod()
-{ register struct buffer *b;
-
- b = cur_buf;
- if((b->b_flags & B_MODIFIED) == 0)
- { b->b_flags |= B_MODIFIED;
- redp(RD_MODE);
- }
-}
-
-/* BUF_TMOD - called when text modified in buffer, to set all
- * the appropriate indicators so that redisplay works right.
- * Changed text is everything from CUR_DOT to the given offset
- * from same. If stuff was deleted, offset should be 0.
- * BUF_TMAT - similar but argument is location of other end of range,
- * when caller knows that and wants life easy.
- */
-
-buf_tmat(dot)
-chroff dot;
-{ buf_tmod(dot - cur_dot); /* Convert to offset */
-}
-buf_tmod(offset)
-chroff offset;
-{ register struct window *w;
- chroff a, b, tmp;
-
- w = cur_win;
- a = cur_dot;
- b = a + offset;
- if(a > b) /* Get into right order */
- { tmp = a;
- a = b;
- b = tmp;
- }
- b = e_blen() - b; /* Make upper bound relative to EOB */
- if(w->w_bmod < 0) /* Have range vars been set yet? */
- { w->w_bmod = a; /* Nope, so can just set 'em now. */
- w->w_emod = b;
- }
- else
- { if(a < w->w_bmod)
- w->w_bmod = a;
- if(b < w->w_emod)
- w->w_emod = b;
- }
- buf_mod(); /* Maybe later just insert here? */
- redp(RD_TMOD);
-}
+++ /dev/null
-/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-
-/* EECMDS Command table lookup and profile code
- */
-
-#include "elle.h"
-#include "eeproto.h"
-
-/* Function table, see the included file for explanation. */
-
- /* First must pre-declare function addrs */
-#if 0
-#define EFUN(rtn,rtnstr,name) int rtn();
-#define EFUNHOLE
-#include "eefdef.h"
-#endif
-
- /* Now re-insert to define function table */
-typedef int (*eefunc)();
-eefunc funtab[] =
-{
-#undef EFUN /* Avoid redefinition error message */
-#undef EFUNHOLE
-#define EFUN(rtn,rtnstr,name) (eefunc) rtn,
-#define EFUNHOLE 0,
-#include "eefdef.h"
-};
-int funmax = sizeof(funtab)/sizeof(funtab[0]); /* 1st illegal function # */
-
-/* Insert default command char map tables and profile structure */
-
-#include "defprf.c"
-\f
-/* EFUN: "Prefix Meta" */
-/* Meta-prefix command.
- * For now, very simple. Perhaps later try to hair up with
- * time-out "M-" prompt?
- */
-f_pfxmeta()
-{ return(cmd_xct(cmd_read()|CB_META));
-}
-
-/* EFUN: "Prefix Extend" */
-/* Extended-prefix command.
- * Likewise trivial; perhaps later hair up with timeout "^X-" prompt?
- */
-f_pfxext()
-{ return(cmd_xct(cmd_read()|CB_EXT));
-}
-
-/* EFUN: "Universal Arg" */
-/* This routine is also called by "Argument Digit" with a special arg
- * of -1 in order to share code. Since that invocation always sets unrchf,
- * it should always complete at least one digit read loop.
- * Note that exp and exp_p are set to 1 and 0 at the top-level command
- * loop.
- */
-f_uarg(ch)
-int ch;
-{ register int c, oc, i;
-
- /* Set distinguishing exp_p value depending on whether invoked
- * by CTRL-U or another function (Argument Digit, Negative Argument)
- */
- exp_p = (ch < 0) ? 1 : 4;
- i = 0; /* Read numerical arg if any follows */
- for(;;)
- { oc = cmd_read(); /* Get next input char */
- c = oc & 0177;
- if(c == '-' && !i)
- { exp_p = -1;
- exp = 1; /* Set in case no digits follow */
- }
- else if('0' <= c && c <= '9') /* If it's a digit too, */
- { i = (i * 10) + c - '0'; /* add digit in. */
- if(exp_p >= 0) exp_p = 1;
- exp = i;
- }
- else break;
- }
- exp *= exp_p; /* Multiply arg appropriately */
- unrchf = oc; /* Not a digit, re-read it next. */
-
- this_cmd = ARGCMD;
-}
-
-/* EFUN: "Negative Argument" */
-f_negarg(ch)
-int ch;
-{ f_uarg(-1); /* Invoke code from Universal Arg */
- exp = -exp;
-}
-
-/* EFUN: "Argument Digit" */
-f_argdig(ch)
-int ch;
-{ unrchf = ch; /* Re-read the digit */
- f_uarg(-1); /* Invoke code from Universal Arg */
-}
-
-/* EFUN: "Set Profile" */
-/* Asks for a profile file and sets profile from it.
- */
-f_setprof()
-{ hack_file("Set Profile: ", set_profile);
-}
-
-#if FX_VTBUTTONS
-/* EFUN: "VT100 Button Hack" */
-/* This must be bound to Meta-O if anything, because the VT100 sends
- * an ESC O prefix when the function buttons are used.
- */
-f_vtbuttons () /* vt100 function buttons */
-{
- switch(cmd_read())
- { case ('A'):
- return (f_uprline ());
- case ('B'):
- return (f_dnrline ());
- case ('C'):
- return (f_fword ());
- case ('D'):
- return (f_bword ());
- case ('Q'): /* PF1 */
- return (f_kregion());
- default:
- ring_bell ();
- break;
- }
-}
-#endif /*FX_VTBUTTONS*/
-\f
-/* CMD_WAIT() - Return TRUE if any command input waiting.
-*/
-cmd_wait()
-{ return(unrchf >= 0
-#if FX_SKMAC
- || km_inwait() /* Check for kbdmac input waiting */
-#endif /*FX_SKMAC*/
- || tinwait());
-}
-
-/* CMD_READ() - Read a command (single char) from user, and return it.
-*/
-cmd_read()
-{ register int c;
-
- if((c = unrchf) >= 0) /* Re-reading last char? */
- { unrchf = -1;
- return(c);
- }
-#if FX_SKMAC /* Hacking keyboard macros? */
- return(km_getc()); /* Yes. This calls tgetc if no kbd macro */
-#else
- return(tgetc());
-#endif /*-FX_SKMAC*/
-}
-
-/* CMD_XCT(ch) - Command Execution dispatch routine.
-** Takes char and executes the function (efun) bound to that command key.
-*/
-cmd_xct(ch)
-int ch;
-{ register int (*funct) ();
- register int c;
- int (*(cmd_fun())) ();
-
- if(funct = cmd_fun(c = ch)) /* Get function to run */
- return((*funct) (c&0177)); /* Invoke with char arg */
- ring_bell(); /* Undefined command char, error. */
-}
-
-/* CMD_FUN(ch) - Return function for char, 0 if none
-*/
-int (*cmd_fun(c))()
-int c;
-{
- return(funtab[cmd_idx(c)]);
-}
-
-/* CMD_IDX(ch) - Given command char, return function index for it
-*/
-cmd_idx(c)
-register int c;
-{ register char *cp;
- register int i;
-
- if(c&CB_EXT)
- { cp = def_prof.extvec;
- i = def_prof.extvcnt;
- goto inlup;
- }
- if(c&CB_META)
- { cp = def_prof.metavec;
- i = def_prof.metavcnt;
- inlup: c = upcase(c);
- do { if(*cp++ != c) cp++;
- else
- { i = *cp&0377;
- break;
- }
- } while(--i); /* If counts out, will return 0! */
- }
- else i = def_prof.chrvec[c&0177]&0377;
- if(i >= funmax)
- return(0);
- return(i);
-}
-\f
-/* Profile hacking */
-
-#if TOPS20
-#include <sys/file.h> /* for O_BINARY */
-#endif
-
-void set_profile(filename)
-char *filename;
-{ char pfile[200];
- register int pfd, len;
- chroff sbx_fdlen();
- register char *profptr;
- struct stored_profile st_prof;
-
- if(filename) strcpy(pfile,filename);
- else /* Check for user's profile */
- {
- strcat(strcat(strcpy(pfile,homedir),"/"),ev_profile);
- }
- if((pfd = open(pfile,
-#if TOPS20
- O_BINARY
-#else
- 0
-#endif
- )) < 0)
- { if(filename)
- { ding("Cannot open file");
- }
- return;
- }
- if((len = (int)sbx_fdlen(pfd)) < sizeof(struct stored_profile))
- goto badfil;
- profptr = memalloc((SBMO)len);
- if(read(pfd,profptr,len) != len)
- goto badfmt;
-
- /* Have read profile into memory, now set up ptrs etc */
- bcopy((SBMA)profptr,(SBMA)&st_prof,sizeof(struct stored_profile));
- def_prof.version = prof_upack(st_prof.version);
- if(def_prof.version != 1)
- goto badfmt;
- def_prof.chrvcnt = prof_upack(st_prof.chrvcnt);
- def_prof.chrvec = profptr + prof_upack(st_prof.chrvec);
- def_prof.metavcnt = prof_upack(st_prof.metavcnt);
- def_prof.metavec = profptr + prof_upack(st_prof.metavec);
- def_prof.extvcnt = prof_upack(st_prof.extvcnt);
- def_prof.extvec = profptr + prof_upack(st_prof.extvec);
-#if SUN
- def_prof.menuvcnt = prof_upack(st_prof.menuvcnt);
- def_prof.menuvec = profptr + prof_upack(st_prof.menuvec);
-#endif /*SUN*/
- goto done;
-
-badfmt: chkfree(profptr);
-badfil: ding("Bad profile format");
-done: close(pfd);
-}
-\f
-#if SUN
-/* SUN Menu profile hacking.
- * This is here, instead of e_sun.c, because
- * the profile format is still evolving and for the time being I want to
- * keep all profile-hacking code in one place. --KLH
- */
-#include "suntool/tool_hs.h"
-#include "suntool/menu.h"
-
-#define MENUMAX 16
-
-/* Defined in eesun.c */
-extern struct menu *menuptr;
-extern struct menu menu;
-
-char *funamtab[] = {
-#undef EFUN
-#undef EFUNHOLE
-#define EFUN(rtn,rtnstr,name) name,
-#define EFUNHOLE 0,
-#include "eefdef.h"
-};
-
-init_menu() /* initialize the menu for elle from user profile */
-{
- register struct menuitem *mi;
- register int n, i, fni;
-
- if((n = def_prof.menuvcnt) <= 0)
- return;
- if(n > MENUMAX) n = MENUMAX;
- mi = menu.m_items = (struct menuitem *) calloc(n, sizeof *mi);
-
- menu.m_itemcount = 0;
- for(i = 0; i < n; i++)
- { fni = def_prof.menuvec[i]&0377;
- if(fni >= funmax) continue;
- if(funtab[fni] && funamtab[fni])
- { mi->mi_data = (caddr_t) funtab[fni];
- mi->mi_imagedata = (caddr_t) strdup(funamtab[fni]);
- mi->mi_imagetype = MENU_IMAGESTRING;
- mi++;
- menu.m_itemcount++;
- }
- }
- if(menu.m_itemcount)
- menuptr = &menu;
-}
-#endif /*SUN*/
+++ /dev/null
-/* ELLE - Copyright 1982, 1985, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/* EEDIAG - Error diagnostics and testing routines
- */
-
-#include "elle.h"
-
-#if FX_DEBUG
-
-/* EFUN: "Debug Mode" */
-/* With no arg, toggles self-checking on and off.
- * With arg of 4 (^U), enters special debug/diagnostics mode.
- */
-
-f_debug(ch)
-int ch;
-{ extern int (*vfy_vec)(); /* In E_MAIN.C */
- char *vfy_data();
-
- if(ch < 0) /* Internal call? */
- { dbg_diag();
- return;
- }
- if(exp == 4)
- { askerr();
- return;
- }
- if(vfy_vec) vfy_vec = 0; /* Toggle current value */
- else vfy_vec = (int (*)())vfy_data;
- say(vfy_vec ? "Self-checking on" : "Self-checking off");
-}
-\f
-char *
-vfy_data(flag) /* Flag = 0 for quiet check */
-int flag;
-{
- register char *res, *mess;
-
- if(res = sbe_mvfy()) mess = "Mem mgt";
- else if(res = sbe_sbvfy(cur_buf)) mess = "SBBUF";
- else if(res = sbe_svfy()) mess = "SD list";
- else return(0); /* Success */
-
- if(flag)
- { int ostate = clean_exit();
- printf("\n%s error: %s !!!\n",mess,res);
- askerr();
- if(ostate > 0) set_tty();
- }
- return(res); /* Error seen */
-}
-\f
-extern char *asklin();
-extern int sbx_nfl,sbm_nfl;
-
-char diaghelp[] = "\
-Q - Quit diag mode\n\
-! - Goto subshell\n\
-V - Verify Mem & SD lists\n\
-MF - Mem Freelist\n\
-M - Mem list\n\
-B - Current buffer SB\n\
-DF - SD Freelist\n\
-D - SDs in use\n\
-DL - SD Logical lists\n\
-DP - SD Physical lists\n\
-C n - Compact; 0-7=sbx_comp(n), 8=SM freelist, 9=SD freelist.\n\
-W - Window printout\n\
-X n - Xercise randomly (GC every n)\n\
-Z n - like X but with notes\n";
-
-dbg_diag()
-{ register char *cp;
- register int c;
- char linbuf[100];
- char *sbe_mfl();
- char *sbe_sfl();
- char *sbe_sbs();
- char *sbe_sdlist();
-
- for(;;)
- { printf("D>");
- asklin(cp = linbuf); /* Read a line of input */
- switch(upcase(*cp++))
- {
- case '?':
- writez(1,diaghelp); /* Too long for printf */
- continue;
- case '!':
- f_pshinf(); /* Invoke inferior subshell */
- clean_exit(); /* Restore normal modes */
- continue;
- case 'Q': /* Quit */
- return;
-
- case 'B': /* Print current SBBUF */
- sbe_sbs(cur_buf,1);
- continue;
-
- case 'C': /* C n - Compact */
- c = atoi(&linbuf[1]);
- if(c == 8)
- sbm_ngc(); /* GC the SM nodes */
-#if 0 /* This doesn't work, dangerous to invoke. */
- else if(c == 9)
- sbm_xngc(&sbx_nfl,sizeof(struct sdblk),
- SM_DNODS);
-#endif
- else
- sbx_comp(512,c);
- continue;
-
- case 'D': /* Print all SD blocks in mem order */
- switch(upcase(*cp))
- {
- case 0: /* D - all SDs in mem order */
- sbe_sds();
- continue;
- case 'F': /* DF - SD freelist */
- sbe_sfl(1);
- continue;
- case 'L': /* DL - SD logical list */
- sbe_sdlist(1,0);
- continue;
- case 'P': /* DP - SD physical list */
- sbe_sdlist(1,1);
- continue;
- }
- break; /* failure */
-
- case 'M':
- switch(upcase(*cp))
- {
- case 0: /* M - all mem alloc info */
- sbe_mem();
- continue;
- case 'F': /* MF - mem freelist */
- sbe_mfl(1);
- continue;
- }
- break; /* failure */
-
- case 'V': /* Verify */
- if(cp = vfy_data(0))
- printf(" Failed: %s\n",cp);
- else printf(" OK\n");
- continue;
- case 'W': /* Print out current window */
- db_prwind(cur_win);
- continue;
- case 'X': /* Xercise */
- c = atoi(&linbuf[1]);
- vfy_exer(0, c ? c : 100);
- continue;
- case 'Z': /* Zercise */
- c = atoi(&linbuf[1]);
- vfy_exer(1, c ? c : 100);
- continue;
-
- } /* End of switch */
-
- printf("?? Type ? for help\n");
- } /* Loop forever */
-}
-\f
-
-/* VFY_EXER - a "random" editor exerciser. It creates a buffer,
- * fills it with some patterned stuff, and then edits it
- * pseudo-randomly in ways which retain the basic pattern.
- * Frequent GC's and self-checks are done, and execution
- * halted either when an error is seen or when typein is detected.
- */
-char *xer_strs [] = {
- "throne", "too", "sky", "fore", "fingers", "sex", "stone",
- "010", "nazgul", "base"
-};
-
-
-vfy_exer(pf, gcfrq)
-int pf; /* Nonzero to print notes as we go */
-int gcfrq; /* Frequency of GC invocation (# passes per GC) */
-{ register int i, k, c;
- long npass;
- char *res, linbuf[100];
- chroff lbeg, lend;
- struct buffer *bfp, *make_buf();
-
- /* Clean out kill buffer first */
- for(i = 0; i < KILL_LEN; ++i)
- kill_push((SBSTR *)0);
-
- bfp = make_buf("**EXORCISE**");
- chg_buf(bfp);
- i = 2000;
- e_gobol();
- do {
- ed_sins("Line ");
- ed_sins(xer_strs[i%10]);
- e_putc(LF);
- } while(--i);
- if(pf) printf("Bufflen: %ld\n", e_blen());
-
- /* Buffer now has stuff in it, start hacking. */
- npass = 0;
- srand(1); /* Start random seed */
- for(;;)
- { if(tinwait() && (*asklin(linbuf)))
- { printf("Typein stop.\n");
- break;
- }
- ++npass;
- printf(" Pass %ld",npass);
- if(npass%gcfrq == 0) /* Time to do a GC? */
- {
- i = rand(); /* Level between 0-4 */
- i = (i < 0 ? -i : i) % 5;
- printf(" - GC lev %d\n", i);
- sbx_comp(512,i);
- goto xerchk;
- }
-
- k = (i = rand())%1024;
- if (i&020000) k = -k;
- e_igoff(k); /* Move randomly */
- e_gobol(); /* Get stuff to flush */
- lbeg = e_dot();
- k = (i = rand())%64;
- if(i&010000) k = -k;
- e_igoff(k);
- lend = e_nldot();
- if(pf) printf(" Kill %ld/ %d;", lbeg, k);
- ed_kill(lbeg, lend);
- if(res = vfy_data(0))
- { printf("XERR after kill: %s\n",res);
- break;
- }
- k = (i = rand())%2048;
- if(i&04000) k = -k;
- e_igoff(k);
- e_gobol();
- e_setcur();
- if(pf) printf(" Yank %ld;", e_dot());
- f_unkill(); /* Yank back */
- if(res = vfy_data(0))
- { printf("XERR after yank: %s\n",res);
- break;
- }
- last_cmd = YANKCMD;
- for(i = rand()%4; i >= 0; --i)
- { if(pf) printf(" Pop;");
- f_unkpop(); /* Do meta-Y */
- if(res = vfy_data(0))
- { printf("XERR after pop: %s\n",res);
- goto out;
- }
- }
- if(rand()&07) /* Slowly add stuff */
- { if(pf) printf(" Add");
- ed_sins("Line ");
- ed_sins(xer_strs[rand()%10]);
- e_putc(LF);
- if(res = vfy_data(0))
- { printf("XERR after ins: %s\n",res);
- break;
- }
- }
- printf("\n");
-
- /* Okay, done with this pass edits, run through the
- * file to ensure pattern is still there
- */
- xerchk: e_gobob();
- while((c = e_getc()) != EOF)
- if(c == LF && (c = e_getc()) != EOF)
- { if( c != 'L'
- || e_getc() != 'i'
- || e_getc() != 'n'
- || e_getc() != 'e'
- || e_getc() != ' ')
- { printf("XERR in pattern!\n");
- goto out;
- }
- }
- }
- /* User typein or error, stop. */
-out: e_setcur();
- redp(RD_SCREEN);
- printf("Loop count = %ld\n",npass);
-}
-\f
-/* DB_PRWIND(win) - Print out stuff about given window
- */
-db_prwind(w)
-register struct window *w;
-{ register struct scr_line *s;
- register int i;
- char tstr[MAXLINE+MAXCHAR];
- char *db_scflgs();
-
- printf("cur_dot/ %ld cur_buf/ %o cur_win/ %o\n",
- cur_dot, cur_buf, cur_win);
-
- printf("Window %o:\n", w);
- printf(" next/ %o\n", w->w_next);
- printf(" buf / %o\n", w->w_buf);
- printf(" redp/ %o\n", w->w_redp);
-
- printf(" topldot/ %ld\n", w->w_topldot);
- printf(" dot / %ld\n", w->w_dot);
- printf(" bmod/ %ld\n", w->w_bmod);
- printf(" emod/ %ld\n", w->w_emod);
- printf(" oldz/ %ld\n", w->w_oldz);
-
- printf(" pos / %d\n", w->w_pos);
- printf(" ht / %d\n", w->w_ht);
- printf("\
-# Flags Boff Len ! Cols Line\n");
- for(i = w->w_pos; i < w->w_pos + w->w_ht; ++i)
- { s = scr[i];
- printf("%2d %-5.5s %6ld %3d %1d %4d ",
- i, db_scflgs(s->sl_flg), s->sl_boff, s->sl_len,
- s->sl_cont, s->sl_col);
- strncpy(tstr, s->sl_line, MAXLINE);
- tstr[s->sl_col] = 0;
- printf("%-40.40s\n", tstr);
- if(s->sl_flg&SL_MOD)
- { printf("%26d ", s->sl_ncol);
- strncpy(tstr, s->sl_nlin, MAXLINE);
- tstr[s->sl_ncol] = 0;
- printf("%-40.40s\n", tstr);
- }
- }
-}
-
-char *
-db_scflgs(flags)
-int flags;
-{ static char retstr[10];
- register char *cp;
-
- cp = retstr;
- if(flags&SL_MOD) *cp++ = 'M';
- if(flags&SL_EOL) *cp++ = 'E';
- *cp = 0;
- return(retstr);
-}
-
-#endif /*FX_DEBUG*/
+++ /dev/null
-/* ELLE - Copyright 1982, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/* EEDISP Redisplay and screen image routines
- */
-
-#if 0
-
-Note that there are several different types of "efficiency" criteria
-involved with respect to display updating:
- (1) Terminal speed: minimize # characters output.
- (2) Program speed: minimize CPU time used.
- (3) Program size: minimize code and memory usage.
- (4) Program modularity: minimize "hooks" between edit/display rtns.
-The current algorithms necessarily represent a compromise among all of
-these objectives.
-
- The cursor is always located at CUR_DOT in the buffer CUR_BUF
-of the current window CUR_WIN. This may not be true during function
-execution, but is always true at the top-level loop of command
-execution and redisplay. In order to minimize update overhead, there
-are various flags or variables that the edit functions can use to
-communicate with "redisplay" and tell it how extensive the updates
-really need to be.
-
- The entire known screen is always represented by a linked list
-of "windows"; updating the entire screen consists of separately
-updating every window on the list. Windows can only be defined
-horizontally (as a range of lines), and must not overlap. Each window
-has a buffer associated with it; the redisplay routines are responsible
-for displaying the contents of this buffer.
-
- The lowest level data structure for the screen consists of an
-array of SCR_LINE structures, one for each possible physical screen
-line. Each line structure has some flags, and pointers to three different
-representations of what should be on the line:
- (1) SL_BOFF, SL_LEN - Defines the range of the buffer data which
- this screen line should represent.
- If the flag SL_EOL is set, this range ends with (and includes)
- an EOL character.
- (2) SL_LINE, SL_COL - Always keeps a copy of the current physical
- screen line image. Each byte is a character which occupies
- only one column position on the screen.
- If the flag SL_CSO is set, the line is in standout mode.
- (3) SL_NLIN, SL_NCOL - The desired "new" screen line image.
- This is only valid if the SL_MOD flag is set for the line,
- indicating that these variables are set and point to the
- new image of what the screen line should be.
- If the flag SL_NSO is set, the new line should be in standout
- mode.
-
- Lastly there is a variable SL_CONT, which is needed for
-continuation of too-long logical lines over several physical lines. If
-SL_CONT is:
- 0 = logical line fits entirely on the screen.
- Either SL_EOL is set, or this line is ended by EOF
- (end of the buffer).
- 1 = logical line is too long, but the last buffer char fits
- entirely on this physical line. SL_EOL is never set.
- >1 = logical line is too long, and the last buffer char
- "overruns" the end of the physical image; that is, part of
- its representation is at the end of this line, but the
- rest of it is at the start of the next line. This can
- only happen with "big" characters like TAB, ^A, ~^A, etc.
- that need more than one column of representation.
- There are SL_CONT-1 chars of overrun stored at the
- end of SL_LINE (SL_NLIN if SL_MOD is set).
- SL_EOL is never set.
-
-Note that if a line contains any overrun, and the next line is also
-part of the same window, the next line''s screen image will start with
-the SL_CONT-1 chars of overrun, rather than with the representation of
-that line''s first buffer char.
-
- The "EOL" character on Unix systems is normally the new-line
-character '\n' (ASCII LF). However, on other systems EOL may be
-indicated by a two-character CR-LF sequence, with either CR or LF alone
-considered to be "stray". For this reason, the buffer flag B_EOLCRLF
-exists to control handling and display of EOLs. If the flag is off,
-the EOL mode is LF, and there are no problems of splitting up characters.
-If the flag is on, however, the EOL mode is CRLF and the following rules
-hold:
- EOL is the sequence CR-LF only.
- LF without preceding CR is a "stray" LF, displayed as ^J.
- CR without following LF is a "stray" CR, displayed as ^M.
- Stray LFs and CRs do not terminate a logical line.
- "End of Line" as a position is the dot just before the CR of a CR-LF.
- "Beg of Line" as a position is the dot just after the LF of a CR-LF.
- If the current dot is between a CR and LF, it is positioned at
- the beginning of the physical screen line.
-
-
-SL_LINE and SL_COL are always accurate at every stage of processing.
-The other variables are accurate only after fix_wind has been called
-to "fix up" the line structures within a window. If either
-RD_WINRES or RD_TMOD is set, none of these "other variables" should
-be depended on. Any functions which are screen-relative (d_ type)
-must be sure that fix_wind is called if necessary, and must give
-preference to the "new" representation in SL_NLINE and SL_NCOL if
-SL_MOD is set.
-
-The flag RD_UPDWIN will be set by fix_wind if any lines have been
-modified. Because fix_wind does not perform any actual display update,
-it is possible for functions to continue operating on the buffer and
-screen image without requiring that changes be displayed until there is
-nothing else left to do. The routine upd_wind performs the actual
-terminal I/O necessary to update all the screen lines which have SL_MOD
-set. Although the process of updating each line is currently
-non-interruptible, it is possible for upd_wind to interrupt itself
-between line updates if it detects that user input has happened, and it will
-return with the window only partially updated. The screen image state
-will be completely consistent, however, and the RD_UPDWIN flag will
-remain set.
-
-Communication between the editing functions and the redisplay routines
-is limited as much as possible to the flags in the global RD_TYPE.
-Each window has its own copy of these flags in W_REDP, so that if
-windows are changed, the update hints for that window will be
-preserved. The flags that can be set are listed below. Those marked
-with "*" are global in nature; all others apply only within a single
-window (normally the current window).
-
-* RD_SCREEN - Total refresh. Clears entire screen and redisplays all
- windows.
-* RD_MODE - Mode line has changed, update it.
-* RD_CHKALL - Check ALL windows for any redisplay flags, and perform
- any updates necessary. Otherwise only the current (or specified)
- window flags are checked.
-* RD_WINDS - Updates all windows. Like RD_WINRES applied to all windows.
- RD_WINRES - Update window (assume completely changed).
- RD_TMOD - Text changed in this window. The range of changes is
- specified by W_BMOD and W_EMOD in combination with W_OLDZ.
- Redisplay checking will limit itself to this range.
- These vars are set by buf_tmod in the main command loop, and
- reset by fix_wind when the window is fixed up.
- RD_MOVE - Cursor has moved within current window; may have moved outside
- the window. W_DOT or CUR_DOT specifies where it should be.
- RD_ILIN - Hint: Line insert done. Currently no function sets this.
- RD_DLIN - Hint: Line delete done. Currently no function sets this.
-
-Internal flags:
- RD_UPDWIN - Window needs updating. Used by fix_wind and upd_wind only.
- Set when window has been "fixed up" and at least one screen
- line was modified.
- RD_FIXWIN - Supposed to mean window needs fixing (via call to fix_wind).
- Not really used.
-
-Not implemented, may never be, but comments retained:
- RD_WINCLR - Clear window (not entire screen)
- RD_NEWWIN - Window has moved. (not needed? Random stuff here)
- a. to follow cursor; redisplay selects a new TOPLDOT.
- b. randomly; new TOPLDOT furnished, use unless cursor out (then a).
- c. find new TOPLDOT as directed (move up/down N screen lines)
- For now, assume that (c) doesn''t apply (ie C-V uses (b) and sets
- TOPLDOT itself). So fix_wind selects new one only if cursor
- won''t fit. topldot takes precedence over sl_boff.
-
-#endif /*COMMENT*/
-\f
-/* Declarations and stuff */
-
-#include "elle.h"
-
-static int sctr();
-\f
-int trm_mode; /* 0 = TTY in normal, non-edit mode.
- * 1 = TTY in edit mode.
- * -1 = TTY detached (hung up).
- * This flag is only used by the 3 routines below,
- * plus hup_exit.
- */
-
-/* REDP_INIT() - Called once-only at startup to initialize redisplay
- * and terminal
- */
-redp_init ()
-{
- trm_mode = 0; /* Ensure flag says not in edit mode */
- ts_init(); /* Get sys term info, set up stuff */
- if (trm_ospeed == 0) /* Default speed to 9600 if unknown */
- trm_ospeed = 13;
- t_init(); /* Identify term type, set term-dep stuff */
- set_scr(); /* Set up software screen image */
- set_tty(); /* Enter editing mode! */
- redp(RD_SCREEN|RD_MODE); /* Force full re-display, new mode line */
-}
-
-/* SET_TTY() - Set up terminal modes for editing */
-
-void set_tty()
-{ if(trm_mode) return; /* Ignore if detached or in edit mode */
- trm_mode++;
- ts_enter(); /* Set up system's ideas about terminal */
- t_enter(); /* Set terminal up for editing */
-}
-
-/* CLEAN_EXIT() - Restore original terminal modes.
- * Returns previous state.
- */
-clean_exit ()
-{ register int prevstate = trm_mode;
-
- if(prevstate > 0) /* Ignore unless in editing mode */
- { trm_mode = 0;
- t_curpos(scr_ht-1, 0); /* Go to screen bottom */
- t_exit(); /* Clean up the terminal */
- tbufls(); /* Force out all buffered output */
- ts_exit(); /* Restore system's old term state */
-#if ! IMAGEN
- writez(1,"\n"); /* Get fresh line using OS output */
-#endif /*-IMAGEN*/
- }
- return prevstate;
-}
-
-/* SET_SCR() - Allocate screen image, set up screenline pointer table */
-
-set_scr()
-{ register struct scr_line **scrp, *stp;
- register scrsiz;
- char *sbuf;
-
- scr_wd0 = scr_wid - 1;
- scrsiz = scr_ht*(scr_wid+MAXCHAR);
- if( scr_ht > MAXHT || scr_wid > MAXLINE)
- { clean_exit();
- printf("ELLE: %dx%d screen too big\n",scr_ht,scr_wid);
- exit(1);
- }
- if((stp = (struct scr_line *) calloc(scr_ht*sizeof(struct scr_line)
- + scrsiz*2,1)) == 0)
- { clean_exit();
- printf("ELLE: not enough memory\n");
- exit(1);
- }
- sbuf = (char *)stp + scr_ht*sizeof(struct scr_line);
- for(scrp = &scr[0]; scrp < &scr[scr_ht]; sbuf += scr_wid+MAXCHAR)
- { stp->sl_line = sbuf;
- stp->sl_nlin = sbuf + scrsiz;
- *scrp++ = stp++;
- }
-}
-\f
-/* REDISPLAY()
- * Main function of redisplay routines. Called every time ELLE
- * forces update of the terminal screen. "rd_type" contains hints
- * as to what has changed or needs updating, to avoid wasting time
- * on things which don't need attention.
- */
-void redisplay ()
-{ register struct window *w;
- register i;
- struct window *make_mode();
-
- w = cur_win;
- w->w_redp |= rd_type&RDS_WINFLGS; /* Set cur_win's flags */
- rd_type &= ~RDS_WINFLGS; /* Leave only globals */
-
- if (rd_type & RD_SCREEN) /* Clear and refresh? */
- {
- t_clear (); /* Clear the screen */
- for(i = scr_ht; --i >= 0;) /* Clear screen image */
- scr[i]->sl_col = 0;
- if(w != ask_win) /* If not in ask-window */
- { chg_win(ask_win);
- e_reset(); /* Then flush its contents */
- chg_win(w);
- }
- redp(RD_WINDS); /* Update all windows */
- rd_type &= ~RD_SCREEN; /* If redisplay is interrupted, */
- /* don't do it all over again */
- }
- if (rd_type & RD_WINDS) /* Update all windows? */
- { redp(RD_CHKALL);
- for (w = win_head; w; w = w -> w_next) /* For each win */
- w->w_redp |= RD_WINRES;
- rd_type &= ~RD_WINDS;
- }
- if (rd_type & RD_CHKALL) /* Check all windows for changes? */
- { for (w = win_head; w; w = w->w_next) /* For each win */
- if(!(w->w_flags&W_MODE)) /* skip mode wins */
- if(w->w_redp && upd_wind(w))
- return; /* May be interrupted */
-
- }
-
- /* See if ask-window needs updating (to avoid RD_CHKALL in SAY) */
- if((w = ask_win)->w_redp && upd_wind(w))
- return; /* May be interrupted */
-
- /* Check current window for changes */
- if((w = cur_win)->w_redp && upd_wind(w))
- return; /* May be interrupted */
-
- /* Now update mode line(s) if necessary */
- if(rd_type&RD_MODE)
- {
- fupd_wind(w = make_mode(user_win));
-#if FX_2MODEWINDS
- if (sep_win /* If 2 windows */
- && (sep_win->w_flags&W_MODE) /* and 2 mode windows */
- && (sep_win->w_redp || mode_win->w_redp)) /* Check */
- fupd_wind(make_mode(oth_win)); /* Must update both */
-#endif
- }
-
- /* Finally, leave cursor in right place. */
- if(upd_curs(cur_dot)==0) /* If something screwed up, */
- errbarf("Cursor out of window"); /* Complain, */
- /* and leave cursor at bot */
- rd_type = 0;
- tbufls(); /* Force out all terminal output */
-}
-
-fupd_wind(w) /* Force window update */
-register struct window *w;
-{
- w->w_redp |= RD_WINRES;
- if(fix_wind(w))
- upd_wind(w);
-}
-\f
-/*
- * UPD_CURS
- * Move screen cursor to position of specified dot within current window.
- * Returns 0 if dot was not within window (and cursor was not moved),
- * otherwise returns 1 for success.
- */
-upd_curs(adot)
-chroff adot;
-{ register struct scr_line *s;
- register int y, x;
- chroff savdot;
-
- if((y = d_line(adot)) < 0)
- return(0); /* Fail, not within window */
- s = scr[y]; /* Now have line that dot is on */
-
- /* Get proper offset for any continuation chars from prev line */
- if(y > cur_win->w_pos)
- { if((x = scr[y-1]->sl_cont) > 0)
- x--;
- }
- else x = 0;
-
- savdot = e_dot();
- e_go(s->sl_boff);
- if((x = d_ncols((int)(adot - s->sl_boff),x)) < 0)
- { /* If lost, assume it's because we are just after a char
- ** which has its representation continued onto next line.
- ** Move cursor to end of that continuation.
- ** d_line should have ensured that this is safe, but
- ** we double-check just to make sure.
- */
- if((x = s->sl_cont) > 0) /* Set X to end of cont */
- --x;
- /* and on next line down */
- if(++y >= (cur_win->w_pos + cur_win->w_ht))
- { e_go(savdot); /* Failed, below window */
- return(0);
- }
- }
- e_go(savdot);
- t_move(y, x); /* Move cursor cleverly */
- return(1); /* Return success! */
-}
-
-/* Return line # for given dot, -1 if out of current window */
-d_line(cdot)
-chroff cdot;
-{ register struct scr_line *s;
- register struct window *w;
- register int i;
- chroff savdot;
- int bot;
-
- w = cur_win;
- i = w->w_pos;
- bot = i + w->w_ht;
- for(; i < bot; i++)
- { s = scr[i];
- if(cdot <= s->sl_boff)
- goto gotl;
- }
- /* End of window, repeat test specially for last line */
- savdot = s->sl_boff + (chroff)s->sl_len;
- if(cdot > savdot) /* If past last char of last line */
- return(-1); /* then clearly outside */
- --i; /* Make i match s (bottom line) */
- if(savdot != cdot) /* If not exactly at end */
- return(i); /* Then we're inside for sure */
- goto linbet;
-
-gotl: if(s->sl_boff != cdot) /* Are we on line boundary? */
- { if(i <= w->w_pos) /* No, off top of window? */
- return(-1); /* Above top, out for sure */
- return(--i);
- }
-
- /* Here, dot is exactly on line boundary, have to decide which
- * line it really belongs to.
- * Get S = pointer to line which cursor is at the end of.
- */
- if(i <= w->w_pos) /* Quick chk of trivial case, empty buffer */
- return(i);
- s = scr[--i];
-linbet:
- if((s->sl_flg&SL_EOL) /* If line has LF */
- || (s->sl_cont > 1)) /* or a continued char */
- if(++i >= bot) /* Then cursor is on next line */
- return(-1);
- return(i);
-}
-\f
-/* D_NCOLS - auxiliary for UPD_CURS. (also called by indtion() in EEFD)
-** We are positioned at a place in the current buffer corresponding to
-** the beginning of the screen line, and given:
-** lcnt - # of chars in buffer to move forward over
-** ccol - current column position
-** Returns the new column position. There are some special cases:
-** Hits EOF: returns normally (new column position)
-** Hits EOL: returns -1
-** Position is past end of screen: returns -1
-** The buffer position has changed, but this is irrelevant as upd_curs
-** restores it just after the call.
-*/
-d_ncols(lcnt, ccol)
-int lcnt;
-int ccol;
-{ register int col, i;
- register SBBUF *sb;
- int c;
- char tmp[MAXCHAR*2]; /* MAXCHAR is enough, but *2 just in case */
-
- col = ccol;
- sb = (SBBUF *) cur_buf;
- if((i = lcnt) > 0)
- do { if((c = sb_getc(sb)) == EOF)
- break;
- /* Check to see if we've run into an EOL */
-#if FX_EOLMODE
- if(c == CR)
- { if(eolcrlf(sb))
- { if((c = sb_getc(sb)) == LF) /* EOL? */
- /* Real EOL. Fail unless point
- ** is between CR and LF, in which case
- ** we return 0 (left margin).
- */
- return (i==1 ? 0 : -1);
- /* Stray CR, back up & fall thru */
- if(c != EOF)
- sb_backc(sb);
- c = CR;
- }
- } else if (c == LF)
- { if(!eolcrlf(sb)) /* Real EOL? */
- return -1; /* Yes, fail */
- /* If EOL mode is CRLF then hitting a LF
- ** can only happen for stray LFs (the
- ** previous check for CR takes care of
- ** CRLFs, and we never start scanning
- ** from the middle of a CRLF.
- ** Drop thru to show stray LF.
- */
- }
-#else
- if(c == LF)
- return(-1);
-#endif /*-FX_EOLMODE*/
- col += sctr(c, tmp, col);
- } while(--i);
- if(col > scr_wd0)
- return(-1);
- return(col);
-}
-
-/* D_LUPD - called from command level to completely redisplay a
- * specific line on the screen.
- */
-d_lupd(w, idx)
-struct window *w; /* Window this line belongs to, if known */
-int idx;
-{ t_curpos(idx, 0);
- t_docleol(); /* Zap physical screen line */
- scr[idx]->sl_col = 0; /* Reflect it on phys screen image */
- if(w) /* Mark window for updating */
- w->w_redp |= RD_WINRES;
- else redp(RD_WINDS); /* No window given, assume global */
- redp(RD_MOVE); /* Cursor has moved */
-}
-
-/* Clear a window completely the "quickest possible way" */
-clear_wind(w)
-register struct window *w;
-{
- register int i = w->w_pos; /* Top line of window */
- register int bot = i + w->w_ht; /* Bottom line (plus 1) of window */
-
- for ( ; i < bot; ++i)
- d_lupd(w, i); /* Zap that line */
-}
-\f
-/* FIX_WIND - Sets up window screen image. Does not generate any
- * terminal output, but completely specifies what the new screen
- * image should look like.
- * Only the following 4 flags (lumped together in RDS_DOFIX)
- * provoke fix_wind to do something:
- * RD_MOVE - cursor has moved, must make sure still within
- * window, and select new one if not.
- * RD_TMOD - Text has been changed somewhere.
- * RD_FIXWIN - Something requested that fix_wind fix things.
- * Normally this is set when a new w_topldot is set.
- * RD_WINRES - Window needs to be completely regenerated.
- * Results:
- * Verifies that the current dot for the window (w_dot) exists.
- * If it is past the end of buffer, it is reset to EOB, and if this is
- * the current window, also updates cur_dot. Otherwise, w_dot is never
- * adjusted; it is fix_wind's responsibility to make sure that the window
- * displays w_dot.
- * Verifies that current w_topldot setting will result in cursor
- * (specified by w_dot) appearing within window. If not, resets w_topldot
- * to an appropriate value (1/3 of way down from top, unless
- * moving up in which case 1/3 of way up from bottom).
- * Makes sure that sl_boff, sl_len, sl_flg, and sl_cont
- * are set properly for all lines in window. SL_MOD is set
- * for any lines requiring screen updates; these lines
- * also have sl_nlin and sl_ncol properly set.
- * Note that sl_line and sl_col are NOT updated or changed, because
- * the physical screen has not been altered!
- *
- * Returns 0 if no physical screen updates are needed (other than
- * cursor moving and mode line updating).
- * Returns 1 if screen updates are needed; RD_UPDWIN is set in w_redp,
- * indicating that UPD_WIND should be called.
- */
-
-fix_wind (win)
-struct window *win;
-{
- register struct window *w;
- register int i;
- register struct scr_line *s;
- chroff cdot, bdelta, updot, sdot, newz;
- chroff savdot;
- struct buffer *savbuf;
- int bot, nlmod, savi, contf, ocontf, randomflg;
- int newpct;
-
- if(!(w = win))
- return(0);
- if(!(w->w_redp&RDS_DOFIX)) /* Anything we need to do? */
- return(0); /* Nope, just ignore */
-
- /* Find current dot for this window, and set up other stuff */
- cdot = (w == cur_win) ? cur_dot : w->w_dot;
- bot = w->w_pos + w->w_ht;
- savbuf = cur_buf;
- cur_buf = w->w_buf;
- savdot = e_dot();
- nlmod = 0; /* No screen image changes so far */
-
- /* Dot (ie cursor) is before current top? If so, must move
- * backwards to find a new topldot. Note also that buffer may have
- * changed so that either cdot or topldot points past EOF.
- */
- if(w->w_topldot > cdot)
- { /* Yes, must search backwards scrht/3 screen lines */
- /* from cdot in order to find topldot. */
- /* Don't bother updating scr stuff beforehand since we'll
- * have to revise everything anyway and can do it on the fly.
- */
- i = (ev_mvpct * w->w_ht) / 100;
- goto skipdn;
-
- finddn: i = ((100 - ev_mvpct) * w->w_ht) / 100;
- skipdn: if(i <= 0) i = 1; /* Ensure # is reasonable */
- else if(i >= w->w_ht) i = w->w_ht-1;
- e_go(cdot); /* Start here (may normalize to EOF)*/
- d_backup(i ? i : 1); /* Try to back up cleverly */
- w->w_topldot = e_dot();
- randomflg = 0; /* We have some idea where we are */
- fixall: /* Entry point for later recheck, with randomflg==1 */
- newz = e_blen();
- if(newz < cdot) /* Part of buf may have gone away */
- { /* So normalize dot to EOF */
- w->w_dot = cdot = newz;
- if(w == cur_win) /* Special check for fixing */
- cur_dot = newz; /* up cur_dot too! */
- goto finddn; /* and get a new top-of-window loc */
- }
- retry: i = w->w_pos;
- contf = 0;
- s = 0;
- for(; i < bot; i++)
- { nlmod++;
- fix_line(scr[i], s); /* s = 0 the first time */
- s = scr[i];
-#if FX_SOWIND
- if(w->w_flags & W_STANDOUT)
- s->sl_flg |= SL_NSO;
- else s->sl_flg &= ~SL_NSO;
-#endif
- }
- if(inwinp(w,cdot)) /* Ensure in window */
- goto mdone;
- if(randomflg) /* If jumped randomly, */
- { i = (ev_nwpct * w->w_ht) / 100;
- goto skipdn; /* Try to select new window */
- }
-
- /* We tried to back up and went too far. */
- if(cdot < w->w_topldot) /* Verify place is ahead */
- { errbarf("fix_wind failed"); /* Didn't back up?? */
- goto finddn;
- }
- /* Move down one line and try again */
- if(w->w_ht > 1)
- w->w_topldot = scr[w->w_pos+1]->sl_boff;
- else
- { s = scr[w->w_pos];
- w->w_topldot = s->sl_boff + s->sl_len;
- }
- e_go(w->w_topldot);
- goto retry;
- }
-
- /* At some future point, could separate out processing for
- * RD_WINRES and RD_FIXWIN. Latter flag implies only w_topldot
- * has changed (new window selected). Former implies whole
- * buffer has been munged, and everything is completely redone.
- */
- if(w->w_redp&(RD_WINRES|RD_FIXWIN)) /* If re-figuring whole window */
- { e_go(w->w_topldot); /* Start here, and */
- randomflg = 1; /* set up flag saying random jump */
- goto fixall; /* and go crunch all lines. */
- }
- if((w->w_redp&RD_TMOD)==0) /* If claims no text mods, */
- { if(inwinp(w,cdot)==0) /* Just verify cursor loc. */
- goto finddn; /* Sigh.... */
- newz = w->w_oldz; /* Win, set up for exit. */
- goto done;
- }
- /* Here only when RD_TMOD is set, indicating changes are
- * between range variables.
- */
- /* Find upper bound of any mods. This is a little gross in the
- * speed dept and some faster way should perhaps be devised.
- * In particular the main loop should incrementally keep track of
- * buffer size, and should set a flag RD_TEXT if anything has
- * actually been changed. Edit routines should have lots of
- * flags available to tell main loop more precisely what they did,
- * so main loop can take care of updating b/emod and stuff.
- */
- if((newz = e_blen()) == 0)
- goto finddn; /* Ensure blank window is cleared */
- bdelta = newz - w->w_oldz;
- if((updot = newz) > w->w_emod)
- updot -= w->w_emod;
- if(bdelta == 0 && (updot == w->w_bmod))
- goto inwinq;
-
- /* Could also check for updot < w_topldot (changes above win)
- * or sl_boff+sl_len < w_bmod (changes below win) but those
- * cases are probably pretty rare.
- */
- /* First find line where changes start */
- for(i = w->w_pos; i < bot; i++)
- { s = scr[i];
- if(w->w_bmod <= s->sl_boff) /* Changes prior to this? */
- break;
- }
- if(i >= bot) /* Test last line specially */
- { if(w->w_bmod > (s->sl_boff + (chroff)s->sl_len))
- goto inwinq; /* Outside window */
- /* Last line changed, hack it */
- }
- if(i > w->w_pos /* If we have a prev line */
- && (s->sl_len == 0 /* and we're at EOF, */
- || w->w_bmod != s->sl_boff /* or not at start of line */
- || scr[i-1]->sl_cont)) /* or prev line is continuation */
- s = scr[--i]; /* then it's prev line we want */
-
- /* I has index for screen line changes begin on; S has ptr.
- * This piece of code handles case where buffer has been modified
- * starting at BMOD, and BDELTA chars have been inserted/deleted;
- * range of changes ends at UPDOT.
- */
- savi = i;
- while(++i < bot)
- scr[i]->sl_boff += bdelta;
- i = savi;
-
- /* Now start with 1st changed line and start figuring new line
- * lengths. Stop when hit end, or past updot and boff is correct
- * for start of line.
- */
- /* can improve this by jumping out when past emod, and testing for
- * an EOL - then know stuff has to match someplace, so look for that.
- * could then simply update lengths or something?
- */
- if(i > w->w_pos) /* Find # cols already there from prev line*/
- contf = scr[i-1]->sl_cont;
- else contf = 0;
- ocontf = 1; /* Fake it so always update 1st line*/
- e_go(sdot = s->sl_boff);
- for(; i < bot; i++)
- { s = scr[i];
- if(updot <= sdot /* If past changed stuff */
- && sdot == s->sl_boff /* and locs are lined up */
- && contf == 0 /* and previous line clean */
- && ocontf == 0) /* (both old and new images) */
- break; /* Then done. */
- nlmod++;
- ocontf = s->sl_cont; /* Save old-image contf value */
- fix_line(s, (i > w->w_pos) ? scr[i-1] : 0);
-#if FX_SOWIND
- if(w->w_flags & W_STANDOUT)
- s->sl_flg |= SL_NSO;
- else s->sl_flg &= ~SL_NSO;
-#endif
- sdot = e_dot();
- contf = s->sl_cont; /* Get new-image contf value */
- }
- if(inwinp(w,cdot)) /* OK, screen fixed, see if cursor inside */
- goto mdone;
- goto finddn;
-
- /* Test if still in window and dispatch appropriately */
-inwinq: if(inwinp(w,cdot))
- goto done;
- else goto finddn;
-
- /* Come here when done, after mods made to window.
- * Calculate new %-of-buffer position for window's view, and
- * see if it's changed from current %.
- */
-mdone: if(w != cur_win) goto done; /* If not current window, ignore */
- s = scr[bot-1];
- if((s->sl_boff + (chroff)s->sl_len) >= newz)
- if(w->w_topldot) newpct = 150; /* BOT */
- else newpct = 200; /* ALL */
- else if(w->w_topldot == 0)
- newpct = -1; /* TOP */
- else /* NOTE: This won't work if topldot is huge */
- newpct = (w->w_topldot*100)/newz; /* nn% */
- if(newpct != w->w_pct) /* OK, now compare with old % */
- { w->w_pct = newpct; /* Different, must set and */
- redp(RD_MODE); /* invoke redisplay of mode line! */
- }
-
-done: w->w_bmod = -1; /* To indicate vars not set */
- w->w_oldz = newz;
- w->w_redp &= ~RDS_DOFIX; /* Clear flags that invoked us */
- if(nlmod)
- w->w_redp |= RD_UPDWIN; /* Say stuff to be updated */
- e_go(savdot);
- cur_buf = savbuf;
- return(nlmod);
-}
-
-/* INWINP - Returns true if given dot is inside given window.
- */
-inwinp(win,cdot)
-struct window *win;
-chroff cdot;
-{ register struct scr_line *s;
- register struct window *w;
- chroff sdot;
-
- w = win;
- if(cdot < w->w_topldot)
- return(0);
- s = scr[(w->w_pos + w->w_ht) - 1];
- sdot = s->sl_boff + (chroff)s->sl_len;
- if(cdot < sdot)
- return(1); /* Yup, inside window. */
- if(cdot > sdot)
- return(0);
-
- /* Dot is exactly at end of window, must check further. */
- if(s->sl_len /* If line exists, */
- && ((s->sl_flg&SL_EOL) /* and ends in LF, */
- || s->sl_cont > 1)) /* or sl_cont > 1, lose. */
- return(0);
- return(1); /* Else inside, win. */
-}
-\f
-/*
- * UPD_WIND
- * If argument 0, assumes cur_win and DOESN'T interrupt if input
- * detected.
- */
-
-upd_wind(win)
-struct window *win;
-{ register int i, n;
- register struct scr_line *s;
- struct window *w;
- int top, bot, dspf, num, noicost, nodcost, iline, dline;
-#if FX_SOWIND
- int oldso;
-#endif
-#if IMAGEN
- int origdspf;
- char redpmsg[128];
-#endif /*IMAGEN*/
-
- if((w=win)==0)
- w = cur_win;
- dspf = w->w_redp; /* Get update flags for window */
-#if IMAGEN
- origdspf = dspf;
-#endif /*IMAGEN*/
- if(w == cur_win) /* If updating current window, */
- dspf |= rd_type; /* merge in global flags */
- if((dspf &= RDS_WINFLGS) == 0) /* Well, it might happen sometimes */
- goto zdone;
- w->w_redp = dspf;
- if(dspf&(RD_WINRES|RD_TMOD|RD_MOVE|RD_FIXWIN))
- { fix_wind(w); /* May set some flags, so */
- dspf = w->w_redp; /* get them back... */
- }
- if((dspf&RD_UPDWIN)==0) /* Must ask for update! */
- goto zdone;
-#if IMAGEN
- if (dbg_redp)
- { sprintf(redpmsg,
- "buffer: %14s, rd_type: %06o, w_redp: %06o, dspf: %06o",
- w->w_buf->b_name, rd_type, origdspf, dspf);
- barf2(redpmsg);
- }
-#endif /*IMAGEN*/
-
- /* Assume screen structure set up by FIX_WIND, just go
- * effect change for every line modified.
- */
-#if FX_SOWIND
- oldso = t_dostandout((w->w_flags&W_STANDOUT)? 1:0);
-#endif
- top = w->w_pos;
- bot = top + w->w_ht;
- for(i = top; i < bot; ++i)
- if((s = scr[i])->sl_flg&SL_MOD)
- { if(win && tinwait()) /* If OK, stop if any chars typed */
- { tbufls();
- w->w_redp = dspf;
-#if FX_SOWIND
- t_dostandout(oldso);
-#endif
- return(1); /* Return immediately, say int'd */
- }
- if(slineq(s,s)) /* Compare old with new */
- goto ldone; /* Lines equal, no update needed */
-
-#if IMAGEN
- /* If hint says redo entirely */
- if (dspf & RD_REDO)
- { s->sl_flg |= SL_REDO; /* Do "fast update" */
- goto nodel; /* Just go update line */
- }
-#endif /*IMAGEN*/
- if((trm_flags&TF_IDLIN)==0)
- goto nodel; /* Just go update line */
-
-
- /* Check for I/D line. If no hints exist, check for both
- * insert and delete.
- */
- if((dspf&(RD_ILIN|RD_DLIN))==0)
- dspf |= RD_ILIN|RD_DLIN;
- noicost = 0;
- nodcost = 0;
-
- /* Check for insert line. See if the current old screen
- * line is duplicated among any of the new lines which
- * follow it. If a match is found, keep looking and add
- * up the number of characters in the matching lines.
- */
- if(dspf&RD_ILIN)
- {
- /* See if this old screen line is needed elsewhere */
- if(s->sl_col == 0) /* Ignore if blank */
- goto noins;
-
- for(n = i+1; n < bot; n++)
- { if((scr[n]->sl_flg&SL_MOD)==0)
- break;
- if(slineq(s, scr[n])) /* Old, new */
- { if(!noicost) iline = n; /* 1st time */
- noicost += s->sl_col;
- s++;
- }
- else if(noicost) break;
- }
- if(!noicost) /* If no match, forget it */
- goto noins; /* S will not have changed. */
- s = scr[i]; /* Restore S */
- n = iline; /* Have matches, get index
- * of first matching line */
-
- /* Heuristic to decide whether to perform
- * insert-line operation. Kind of stupid, but
- * good enough for now.
- */
- num = (n-i)*(tvc_ldn+tvc_lin) + (tvc_li + tvc_ld);
- if((n-i) >= (scr_ht-(ECHOLINES+3))
- /* Don't move lines all the
- * way down full screen! */
- || num >= noicost) /* Compare cost with estimated
- * cost of not doing insert.*/
- goto noins;
-
- /* Insert lines! */
- dspf &= ~RD_ILIN;
- inslin(i, n - i, w);
- for(; i < n; i++) /* Update intervening lines */
- upd_line (i);
- goto ldone;
- }
-noins:
-
- /* Check for delete line. See if the new screen line
- * is duplicated among any of the old lines already on
- * the screen. If a match is found, keep looking and add
- * up the number of characters in the matching lines.
- */
- if(dspf&RD_DLIN)
- {
- /* See if the new line already exists elsewhere */
- if(s->sl_ncol == 0) /* Ignore blank lines */
- goto nodel;
- for (n = i + 1; n < bot; n++)
- { if((scr[n]->sl_flg&SL_MOD)==0)
- break;
- if(slineq(scr[n],s)) /* Old, new */
- { if(!nodcost) dline = n; /* 1st time */
- nodcost += s->sl_ncol;
- s++;
- }
- else if(nodcost) break;
- }
- if(!nodcost) /* If no match, forget it */
- goto nodel; /* S will not have changed. */
- s = scr[i]; /* Restore S */
- n = dline; /* Index of 1st match */
-
- /* Heuristic to decide whether to perform
- * delete-line operation. Same hack as for
- * insert-line.
- */
- num = (n-i)*(tvc_ldn+tvc_lin) + (tvc_li + tvc_ld);
- if((n-i) >= (scr_ht-(ECHOLINES+3))
- || num >= nodcost)
- goto nodel;
-
- /* Delete lines! */
- dspf &= ~RD_DLIN;
- dellin(i, n - i, w);
- goto ldone;
- }
-nodel:
- /* All failed, so just update line */
- upd_line(i);
-ldone: s->sl_flg &= ~SL_MOD; /* Clear mod flag */
- }
-done:
-#if FX_SOWIND
- t_dostandout(oldso); /* Back to previous mode */
-#endif
-zdone: w->w_redp = 0;
- return(0); /* Say completed */
-}
-\f
-
-/*
- * SLINEQ - Compare old, new screen image lines. If new line doesn't
- * have the modified flag set, use its old image.
- * If the standout mode differs, always fails.
- */
-
-slineq(olds, news)
-struct scr_line *olds;
-struct scr_line *news;
-{ register char *cpo, *cpn;
- register int cnt;
-
- cpo = (char *)news;
- if(((struct scr_line *)cpo)->sl_flg&SL_MOD)
- { cnt = ((struct scr_line *)cpo)->sl_ncol;
- cpn = ((struct scr_line *)cpo)->sl_nlin;
-#if FX_SOWIND /* Mode of old must match mode of new */
- if(((olds->sl_flg & SL_CSO)==0) !=
- ((((struct scr_line *)cpo)->sl_flg & SL_NSO)==0))
- return 0;
-#endif
- }
- else
- { cnt = ((struct scr_line *)cpo)->sl_col;
- cpn = ((struct scr_line *)cpo)->sl_line;
-#if FX_SOWIND /* Modes of current lines must match */
- if((olds->sl_flg & SL_CSO) !=
- (((struct scr_line *)cpo)->sl_flg & SL_CSO))
- return 0;
-#endif
- }
-
- /* Crufty match stuff */
- if(cnt != olds->sl_col)
- return(0);
- if(cnt)
- { cpo = olds->sl_line;
- do { if(*cpo++ != *cpn++)
- return(0);
- } while(--cnt);
- }
- return(1);
-}
-\f
-/* UPD_LINE(lineno) - Effects the update of a physical screen line,
- * assuming that the screen line structure for that line has been
- * properly set up by fix_wind. It cannot be interrupted by typein.
- * Does a lot of work to check out optimization for char I/D.
- * Someday it could also check out the possibility of doing a CLEOL at
- * some point to reduce the number of spaces that need to be output.
- */
-
-upd_line(y)
-int y;
-{ register i;
- register char *sci, *cp;
- struct scr_line *s;
-
- int xpos; /* actual screen position */
- int c, c2, p2, cmpcost, delcost;
- int savc, ocol, ncol;
- char *savcp, *savsci;
-#if FX_SOWIND
- int oldso, newso;
- int writall = 0;
-#endif
-
- s = scr[y];
- savsci = sci = s->sl_line; /* What is currently on the screen */
-#if IMAGEN
- if (s->sl_flg & SL_REDO)
- { /* Check for line-redo flag */
- s->sl_flg &= ~SL_REDO; /* Clear it: we are handling it */
- writall = 1; /* Re-do this line completely */
- t_move(y, 0);
- t_docleol();
- s->sl_col = 0;
- }
-#endif /*IMAGEN*/
-
-#if FX_SOWIND
- /* See whether modes of the lines are the same or not. */
- newso = (s->sl_flg & SL_NSO)!=0; /* Get new mode (true if SO)*/
- if(((s->sl_flg & SL_CSO)!=0) != newso)
- { t_move(y, 0); /* Not same, must zap existing line */
- t_docleol();
- s->sl_col = 0;
- writall = newso; /* Output all if SO is new mode */
- }
- oldso = t_dostandout(newso); /* Get in right mode */
-#endif
-
- ocol = s->sl_col;
- savcp = cp = s->sl_nlin;
- ncol = s->sl_ncol;
-
- /* Find leading equalness */
- i = ocol;
- if(i > ncol) i = ncol; /* Use minimum count */
- if(i)
- { do { if(*cp++ != *sci++)
- { --cp;
- break;
- }
- } while(--i);
- i = cp - savcp;
- sci = savsci; /* Restore ptr to beg of cur line */
- }
-
- /* From here on, "i" is now the x-coordinate (column addr)
- * of the first position that doesn't match. "cp" points to
- * the first nonmatching char in the new line image.
- */
-#if COHERENT /* Has direct video interface capability */
- if(trm_flags&TF_DIRVID)
- { if(ncol < ocol)
- { /* Flesh out new line to completely replace old */
- fillsp(&s->sl_nlin[ncol], ocol-ncol);
- ncol = ocol;
- }
- /* Spit out changed stuff. t_direct will handle the
- * case where i == ncol (ie no changes needed).
- */
- t_direct(y,i,cp,ncol-i);
- goto done;
- }
-#endif /*COHERENT*/
-
- if(i == ncol) /* Matched up to end of new line? */
- goto idone; /* Yes, can skip big loop! */
-
-#if FX_SOWIND
- if(writall) /* If simply writing everything...*/
- { t_move(y, 0);
- tputn(cp, ncol); /* Output them all */
- curs_col = ncol; /* Update cursor position */
- goto idone; /* then wrap up! */
- }
-#endif
-
- /* Now must fill out remainder of old line with blanks. */
- if(ocol < scr_wid)
- {
-#if FX_SOWIND
- if(newso) fillset(&sci[ocol], scr_wid-ocol, 0);
- else
-#endif
- fillsp(&sci[ocol],scr_wid-ocol); /* Fill out */
- }
-
- /****** Main update loop. ******/
- for (; i < ncol; i++)
- { c = *cp++; /* Note *CP will point to next */
- if(c == sci[i])
- continue;
- if(i >= ocol) /* Past EOL of old line? */
- {
-putin: sci[i] = c;
- if(y != curs_lin || i != curs_col)
- t_move(y, i);
- tput(c);
- curs_col++;
- continue;
- }
-
- if((trm_flags&TF_IDCHR)==0) /* Replace */
- goto putin;
-
- /* Do checking to see whether char I/D operations should
- * be invoked. This code is quite CPU intensive and
- * can cause noticeable pauses if run on a slow CPU with
- * a fast (9600) terminal line. The optimization tradeoff
- * seems worthwhile most of the time, however.
- */
- cmpcost = 0; /* Default is don't compare */
- if(ncol == ocol) /* If line lengths same, must chk */
- {
-/* if(ncol >= scr_wid) */ /* If line overrun, compare */
- cmpcost++;
- }
-#if 0
-If ncol == ocol, have problem with tabs:
- If don''t use I/D char, but tabs exist, lots of wasteful update.
- If DO use I/D char, and no tabs exist, potential for mistakenly
- using I/D when didn''t have to. Not too bad, though?
- If DO use I/D char, then mild screw when inserting/deleting
- just before a tab, since could have just overwritten,
- but I/D insists on jerking things around.
- Insert test:
- If old char was space, replace? Problem: will cause cursor
- jump if really should have shifted a long run of spaces.
- But that is probably okay.
- Delete test:
- If new char is space, replace? again, will cause cursor jump
- with long run of spaces.
-#endif /*COMMENT*/
-
- if(ncol < ocol || cmpcost) /* Try delete-char */
- {
- /* Search old for match of c and nextc */
-dodel: savc = c;
- if(i >= ncol-1)
- goto putin;
- c2 = *cp;
- if(c == SP && ncol == ocol)
- goto tryins;
- p2 = i;
- for(;;)
- { if(c == sci[i] && c2 == sci[i+1])
- break;
- if(++i < ocol)
- continue;
- i = p2;
- if(cmpcost) {cmpcost = 0; goto tryins;}
- goto putin;
- }
- /* Find # chars that match (i.e. will be saved) */
- for(c=1; (i+c < ncol) && (sci[i+c] == cp[c-1]); c++);
- delcost = tvc_cd + tvc_cdn*(i - p2);
- if(delcost >= c)
- { c = savc;
- i = p2;
- if(cmpcost) { cmpcost = 0; goto tryins;}
- goto putin; /* Punt */
- }
- if(cmpcost)
- { c = savc; i = p2;
- goto tryins;
- }
- t_move(y, p2);
- c = i - p2; /* Find # chars to flush */
- strncpy(&sci[p2],&sci[i], ocol-i);
- ocol -= c;
- fillsp(&sci[ocol], c);
- i = p2; /* Restore i */
- t_delchr(c); /* Flush this many cols */
- continue;
- }
-
- /* Try ins-char */
- /* Search new for match of i and i+1 */
- /* Note this cannot be used while in standout mode, since
- ** the new spaces created will probably be in the wrong mode.
- */
-tryins:
-#if FX_SOWIND
- if(newso) goto putin;
-#endif
- if(i+1 >= ocol)
- goto putin;
-
- savc = c;
- savcp = cp;
- c2 = sci[i+1];
- if(sci[i] == SP && ncol == ocol)
- goto putin;
- xpos = i; /* save current col */
- i++;
- for(;;)
- { if(i >= ncol) goto puntx;
- c = *cp++;
-inlp2: if(c != sci[xpos])
- { if(i > scr_wid) goto puntx;
- i++;
- continue;
- }
- if(i >= ncol) goto puntx;
- c = *cp++;
- if(c != c2)
- { i++; /* Allow for previous c */
- goto inlp2; /* which is always 1 */
- }
- break;
- }
- if(i >= scr_wid) goto puntx;
-
- /* Find how many chars match (i.e. will be saved) */
- for(c = 2; xpos+c < ncol && sci[xpos+c] == *cp++; c++);
- if((p2 = tvc_ci + tvc_cin*(i - xpos)) >= c)
- goto puntx; /* Not worth it... */
- if(cmpcost && p2 >= delcost)
- goto puntx; /* Do delchr instead */
-
- /* We've decided to insert some chars! */
- i -= xpos; /* Get # char positions to insert */
- cp = savcp; /* Get ptr to newline string */
- --cp; /* Point at 1st char to insert */
- /* Make room in scr array */
- inspc(&sci[xpos],
- &sci[(ocol+i >= scr_wid) ? scr_wid-i : ocol], i);
- ocol += i; /* Update size of old line */
- strncpy(&sci[xpos], cp, i); /* Copy all inserted chars */
-
- t_move(y, xpos); /* Now ensure in right place */
- t_inschr(i, cp); /* and insert string onto screen! */
-
- cp += i; /* Update source ptr */
- cp++; /* Point to next char */
- i += xpos;
- continue; /* Now continue loop! */
-
- puntx: i = xpos;
- c = savc;
- cp = savcp;
- if(cmpcost) { cmpcost = 0; goto dodel;}
- goto putin;
- }
-
- /* All done putting up new stuff. Now see if any remaining old
- ** stuff needs to be cleared from end of line.
- */
-idone: if(i < ocol) /* if still have text to right, */
- { t_move(y,i); /* move there */
- t_docleol(); /* and clear old stuff. */
- }
-
-done: s->sl_line = s->sl_nlin; /* Replace old image by new */
- s->sl_col = s->sl_ncol;
- s->sl_nlin = sci;
- s->sl_flg &= ~SL_MOD;
-#if FX_SOWIND /* Copy standout mode to current */
- if(newso) s->sl_flg |= SL_CSO;
- else s->sl_flg &= ~SL_CSO;
-#endif
-}
-
-#if FX_SOWIND
-void fillset(str,cnt,c)
-char *str;
-int cnt;
-int c;
-{ register int n;
- register char *cp;
- if((n = cnt) <= 0) return;
- cp = str;
- do{ *cp++ = c;
- } while(--n);
-}
-#endif
-
-void fillsp(str,cnt)
-char *str;
-int cnt;
-{ register int n;
- register char *cp;
- if((n = cnt) <= 0) return;
- cp = str;
- do{ *cp++ = SP;
- } while(--n);
-}
-
-void inspc(cp0, cpl, cnt)
-char *cp0, *cpl;
-int cnt;
-{ register char *cp, *cp2;
- register n;
- if((n = cnt) <= 0) return;
- cp = cpl; /* ptr to last+1 char in string */
- cp2 = cp+n; /* ptr to loc+1 to move to */
- n = cp - cp0; /* # chars to move */
- do *--cp2 = *--cp;
- while(--n);
- n = cnt; /* Now fill gap with spaces */
- do *cp++ = SP;
- while(--n);
-}
-\f
-/* FIX_LINE - Fixes up new screen image for a single line. Does not
- * do any actual terminal I/O, and does not change the old screen
- * image. Assumes that previous line (if any is furnished) has
- * already been properly set up.
- */
-
-int sctreol = 0; /* Ugly crock for talking to sctrin() */
- /* 0 = no EOL seen, 1 = EOL seen, -1 = EOF seen */
-void fix_line(slp, olds)
-struct scr_line *slp;
-struct scr_line *olds;
-{ register struct scr_line *s;
- register int col, scrw;
- char *cp;
-
- col = 0;
- scrw = scr_wid;
- cp = slp->sl_nlin;
- if((s = olds) && (col = s->sl_cont))
- { if(--col)
- strncpy(cp, (s->sl_flg&SL_MOD) ?
- &s->sl_nlin[scrw]
- : &s->sl_line[scrw], col);
- cp += col;
- }
- scrw--; /* Note now using scr_wd0 !! */
- s = slp;
- s->sl_boff = e_dot();
- col = sctrin(cp, scrw, col);
- if (col < scrw || sctreol) /* Does line need continuation mark? */
- s->sl_cont = 0; /* No, say no cont chars */
- else {
- /* Yes, find # cols of overflow. If not 0, must be > 0 */
- /* and char is a biggie. Make room for continuation chars */
- if(col -= scrw)
- inspc(&s->sl_nlin[scrw],&s->sl_nlin[scrw+col], 1);
- s->sl_cont = col+1; /* # cont chars, plus 1 */
- s->sl_nlin[scrw] = CI_CLINE; /* Display "contin" mark */
- col = scrw+1;
- }
-
- s->sl_ncol = col;
- s->sl_len = e_dot() - s->sl_boff;
- s->sl_flg |= (SL_MOD|SL_EOL); /* Say new, and assume line has EOL */
- if(sctreol <= 0) /* unless it doesn't really */
- s->sl_flg &= ~SL_EOL; /* in which case turn off flag */
- return;
-}
-
-/* SCTRIN - auxiliary for FIX_LINE.
- * lim - # cols chars are allowed to use
- * ccol - current column (0 = bol)
- * Returns when see EOL or EOF, or
- * when all columns have been filled up. Retval-ccol = # overflow.
- * Note that any overflow is indivisible (i.e. a char with a
- * multi-col representation is responsible for the overflow).
- * So, overflow = 0 means next char would be in 1st non-ex column
- * and overflow > 0 means last char read has extra columns, but
- * it did start within bounds.
- */
-sctrin(to, lim, ccol)
-char *to;
-int lim;
-int ccol;
-{ register SBBUF *sb;
- register col, cnt;
-
- sb = (SBBUF *) cur_buf;
- col = ccol;
- sctreol = 0; /* No EOL or EOF seen */
- do
- { cnt = sb_getc(sb);
- if(cnt == EOF)
- { --sctreol; /* Say EOF seen! */
- return(col);
- }
-#if FX_EOLMODE
- if(cnt == CR) /* Possible EOL? */
- { if(eolcrlf(sb))
- { if((cnt = sb_getc(sb)) == LF) /* Real EOL? */
- { sctreol++;
- return col; /* Yes, return */
- }
- /* Stray CR, back up & fall thru */
- if(cnt != EOF)
- sb_backc(sb);
- cnt = CR; /* Show stray CR */
- }
- } else if (cnt == LF)
- { if(!eolcrlf(sb)) /* Real EOL? */
- { sctreol++;
- return col; /* Yes, return */
- }
- /* If EOL mode is CRLF then hitting a LF
- ** can only happen for stray LFs (the
- ** previous check for CR takes care of
- ** CRLFs, and we never start scanning
- ** from the middle of a CRLF.
- ** Drop thru to show stray LF.
- */
- }
-#else
- if(cnt == LF)
- { sctreol++; /* Say EOL seen */
- return col;
- }
-#endif /*_FX_EOLMODE*/
- cnt = sctr(cnt, to, col);
- to += cnt;
- col += cnt;
- } while(col < lim);
-
- /* If we're stopping because last char put us precisely at the
- ** end of the line, make a further check to see whether an EOL
- ** is next. If so, we can include that in the line since it
- ** doesn't need any more columns for representation!
- */
- if (col == lim) /* If stopping exactly at edge of screen */
- switch (sb_getc(sb)) /* Check out next char */
- { case EOF:
- --sctreol; /* Yes, note EOF seen */
- break; /* and can return immed */
-#if FX_EOLMODE
- case CR: /* Possible EOL? */
- if(eolcrlf(sb))
- { if((cnt = sb_getc(sb)) == LF) /* Real EOL? */
- { sctreol++; /* Yes, set flag */
- break; /* and return */
- }
- /* Stray CR, back up & fall thru */
- if(cnt != EOF) /* Back up char that */
- sb_backc(sb); /* came after the CR */
- sb_rgetc(sb); /* Then back over CR */
- break;
- }
- sb_backc(sb);
- break;
- case LF:
- if(!eolcrlf(sb)) /* Real EOL? */
- { sctreol++; /* Yes, set flag */
- break; /* and return */
- }
- /* If EOL mode is CRLF then hitting a LF
- ** can only happen for stray LFs (the
- ** previous check for CR takes care of
- ** CRLFs, and we never start scanning
- ** from the middle of a CRLF.
- ** Drop thru into default to back up over LF.
- */
-#else
- case LF:
- sctreol++; /* Say EOL seen */
- break; /* and return */
-#endif /*-FX_EOLMODE*/
- default:
- sb_backc(sb); /* Back up over random char */
- break;
- }
- return(col);
-}
-\f
-/* SCTR - Screen Char TRanslation routine.
-** This routine is completely responsible for the way a buffer char is
-** displayed on the screen. Given a char and the current column position,
-** it stores the representation using the given pointer and returns
-** the number of chars (columns) used by the representation.
-** Normal printing chars (plus space) are simply themselves.
-** TAB is a variable number of spaces depending on the column pos.
-** (we use standard tabstops of 8)
-** All control chars are uparrow followed by a printing char.
-** e.g. ctrl-A = ^A
-** This includes ESC which is ^[.
-** DEL is shown as ^?.
-** Chars with the 8th bit set have the prefix CI_META (currently ~) and
-** the rest of the representation is as above (except for TAB).
-** Chars with the 9th bit set have the prefix CI_TOP (currently |) and
-** the rest of the representation is as above (except for TAB).
-** This only exists for systems with 9-bit chars such as TOPS-20.
-*/
-
-static int
-sctr(ch, to, ccol)
-int ch; /* Buffer char to translate */
-char *to; /* Place to deposit translation in */
-int ccol; /* Current column position */
-{ register char *cp;
- register c, n;
-
- c = ch;
- if(037 < c && c < 0177) /* Most common case */
- { *to = c;
- return(1);
- }
- cp = to;
- if(c == TAB) /* Next most common case */
- { n = 010 - (ccol&07); /* Tab stops are every 8 cols */
- ccol = n; /* Save value */
- do *cp++ = SP;
- while (--n);
- return(ccol);
- }
- ccol = 1; /* Re-use var */
-#if TOPS20
- if(c&0400) /* 9th bit set? */
- { *cp++ = CI_TOP;
- ccol++;
- }
-#endif /*TOPS20*/
- if(c&0200)
- { *cp++ = CI_META;
- ccol++;
- }
- if((c &= 0177) <= 037 || c == 0177)
- { *cp++ = CI_CNTRL;
- c ^= 0100; /* Transform cntrl char */
- ccol++;
- }
- *cp = c;
- return(ccol);
-}
-\f
-/* INSLIN(line, N, wind) - Insert lines
- * DELLIN(line, N, wind) - Delete lines
- * Both routines insert/delete N lines at "line" in window "wind"
- * and update the screen image accordingly.
- */
-
-inslin (line, n, win)
-int line; /* line number to insert BEFORE */
-int n; /* number of lines to insert */
-struct window *win; /* window we are in */
-{ register int i;
- register int bot;
- register char **savp;
- char *savscr[MAXHT];
-
- bot = win -> w_ht + win -> w_pos;
- t_curpos (line, 0);
- t_inslin (n, bot); /* do the insertion on the screen */
- savp = &savscr[0];
- for (i = 1; i <= n; i++) /* free lines that fall off-screen */
- *savp++ = scr[bot - i]->sl_line;
-
- for (i = bot - 1; i >= line + n; i--) /* move down lines */
- { scr[i]->sl_line = scr[i - n]->sl_line; /* below the insertion */
- scr[i]->sl_col = scr[i - n]->sl_col;
- }
- savp = &savscr[0];
- for (i = line + n - 1; i >= line; i--)
- /* blank lines where inserted */
- { scr[i]->sl_line = *savp++;
- scr[i]->sl_col = 0;
- }
- for(i = line; i < bot; ++i)
- scr[i]->sl_flg |= SL_MOD;
-}
-
-dellin (line, n, win)
-int line; /* first line to be deleted */
-int n; /* number of lines to be deleted */
-struct window *win; /* window we are in */
-{ register int i;
- register int bot;
- register char **savp;
- char *savscr[MAXHT];
-
- bot = win -> w_ht + win -> w_pos;
-
- t_curpos (line, 0);
- t_dellin (n, bot); /* do the deletion on the screen */
- savp = &savscr[0];
- for (i = line; i < line + n; i++) /* free the deleted lines */
- *savp++ = scr[i]->sl_line;
- for (i = line; i < bot - n; i++) /* move lines up to fill */
- { scr[i]->sl_line = scr[i + n]->sl_line; /* deleted spaces */
- scr[i]->sl_col = scr[i + n]->sl_col;
- }
-
- savp = &savscr[0];
- for (i = bot - n; i < bot; i++) /* blank lines at bottom */
- { scr[i]->sl_line = *savp++;
- scr[i]->sl_col = 0;
- }
- for(i = line; i < bot; ++i)
- scr[i]->sl_flg |= SL_MOD;
-}
-\f
-/* T_ Terminal functions - these are similar to the terminal-dependent
- * routines in EETERM (which they call) but rely on some knowledge of
- * the screen image in order to do their job cleverly.
- */
-
-#if FX_SOWIND
-
-/* T_DOSTANDOUT(on) - Turn standout mode on or off, cleverly.
-** Returns previous state.
-*/
-static int curso = 0; /* Current state (initially off) */
-int
-t_dostandout(on)
-int on;
-{
- int oldso;
-
- if ((oldso = curso) != on) /* If desired state doesn't match, */
- { t_standout(on); /* invoke new state. */
- curso = on;
- }
- return oldso;
-}
-#endif
-
-
-void t_move(y,x)
-register int y,x;
-{ register int d;
-
- if(y != curs_lin) /* No vertical smarts yet */
- { t_curpos(y, x);
- return;
- }
- if((d = (x - curs_col)) >= 0) /* Find diff in column position */
- { if(d == 0) return; /* If none, nothing to do! */
-
- /* Moving right. If distance is less than abs-move cost,
- * do clever right-move by copying screen image */
- if(d < tvc_pos)
-#if FX_SOWIND /* Ensure not in standout mode */
- if((scr[y]->sl_flg&(SL_CSO|SL_NSO))==0)
-#endif
- {
- tputn(&scr[y]->sl_line[curs_col], d);
- curs_col = x;
- return;
- }
- }
- /* Moving to left, try to do clever left-move by backspacing
- * instead of using abs move.
- */
- else if((d = -d)*tvc_bs < tvc_pos)
- { do { t_backspace();
- } while(--d);
- return;
- }
- /* No luck with cleverness, just move. */
- t_curpos(y, x);
-}
-
-t_docleol()
-{ register struct scr_line *s;
- register int cnt, ocol;
-
- if(trm_flags&TF_CLEOL) t_cleol(); /* Winning */
- else /* Losing */
- { s = scr[curs_lin];
- if((cnt = s->sl_col - curs_col) > 0)
- {
-#if FX_SOWIND
- int oldso = t_dostandout(0);
-#endif
- ocol = curs_col;
- do { tput(SP); curs_col++;
- } while(--cnt);
-#if FX_SOWIND
- t_dostandout(oldso);
-#endif
- t_move(curs_lin, ocol);
- }
- }
-}
-
+++ /dev/null
-/* ELLE - Copyright 1982, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/* EEEDIT - E-type routines */
-
-#include "elle.h"
-
-/* E_ - Operate on cur_buf. Do not change value of cur_dot unless
- * unavoidable side effect (also e_setcur).
- * EX_ - Like E_ but take SB ptr value. Never touch cur_dot.
- * ED_ - Like E_, operate on cur_buf, update cur_dot and display stuff.
- * D_ - Perform necessary display update for given operations.
- *
- * Note that "dot" refers to the current read/write pointer for a sbbuffer.
- * The name comes from EMACS/TECO where "." represents this value.
- */
-
-#define CURSBB (SBBUF *)cur_buf /* Shorthand for current SB buffer */
-
-e_reset() /* Reset current buffer */
-{ ex_reset(CURSBB);
- cur_dot = 0;
-}
-
-/* Basic functions - apply SB routines to current buffer.
- * There is some optimization here which knows that certain SB functions
- * are macros.
- */
-e_rgetc() /* Read/move 1 char backward */
-{ return(sb_rgetc((CURSBB)));
-}
-e_rdelc() /* Delete 1 char backward */
-{ return(sb_rdelc((CURSBB)));
-}
-e_delc() /* Delete 1 char forward */
-{ return(sb_deln(CURSBB,(chroff)1));
-}
-e_getc() /* Read/move 1 char forward */
-{ register SBBUF *sb;
- sb = CURSBB; /* Macro: use reg */
- return(sb_getc(sb));
-}
-e_backc() /* Move 1 char backward */
-{ register SBBUF *sb;
- sb = CURSBB; /* Macro: use reg */
- sb_backc(sb); /* No value returned */
-}
-e_putc(c) /* Insert/write 1 char forward */
-char c;
-{ register SBBUF *sb;
- sb = CURSBB; /* Macro: use reg */
- return(sb_putc(sb, c));
-}
-e_peekc() /* Read 1 char forward (no move) */
-{ register SBBUF *sb;
- sb = CURSBB; /* Macro: use reg */
- return(sb_peekc(sb));
-}
-e_ovwc(ch) /* Overwrite 1 char forward */
-char ch;
-{
- sb_setovw(CURSBB); /* Turn on overwrite mode */
- e_putc(ch);
- sb_clrovw(CURSBB); /* Turn off overwrite mode */
-}
-
-SBSTR *
-e_copyn(off) /* Copy N chars forward/backward, return SD to sbstring */
-chroff off;
-{ return(sb_cpyn(CURSBB,off));
-}
-e_deln(off) /* Delete N chars forward/backward */
-chroff off;
-{ return(sb_deln(CURSBB, off));
-}
-
-/* E_SETCUR() - set cur_dot to current position (dot). This is the only
- * E_ routine that mungs cur_dot except for e_reset.
- */
-e_setcur()
-{ cur_dot = e_dot();
-}
-e_gosetcur(dot) /* Go to specified dot and set cur_dot as well */
-chroff dot;
-{ sb_seek(CURSBB,dot,0);
- e_setcur(); /* Not cur_dot = dot since want canonicalization */
-}
-
-/* E_GO(dot) - Move to specified location. */
-/* These "GO" routines all move to the location specified, returning
- * 0 if successful and -1 on error. "cur_dot" is never changed,
- * with the exception of e_gosetcur.
- * Note that other "GO" routines (eg E_GONL) will return 1 if successful
- * and 0 if stopped by EOF.
- */
-
-e_gocur() { return(e_go(cur_dot)); } /* Move to cur_dot */
-e_gobob() { return(e_go((chroff) 0)); } /* Move to Beg Of Buffer */
-e_goeob() { return(sb_seek(CURSBB,(chroff)0,2)); } /* Move to End Of Buffer */
-e_go(dot) /* Move to specified location. */
-chroff dot;
-{ return(sb_seek(CURSBB,dot,0));
-}
-e_igoff(ioff) /* Move (int) N chars forward/backward */
-int ioff;
-{ return(sb_seek(CURSBB,(chroff)ioff,1));
-}
-
-e_goff(off) /* Move (full) N chars forward/backward */
-chroff off;
-{ return(sb_seek(CURSBB,off,1));
-}
-
-int ex_gonl(), ex_gopl(), ex_gobol(), ex_goeol();
-
-e_gobol() { return(ex_gobol(CURSBB)); } /* Move to beg of this line */
-e_goeol() { return(ex_goeol(CURSBB)); } /* Move to end of this line */
-e_gonl() { return(ex_gonl(CURSBB)); } /* Move to beg of next line */
-e_gopl() { return(ex_gopl(CURSBB)); } /* Move to beg of prev line */
-
-
-/* E_DOT() - Return current value of dot. */
-chroff e_dot() { return(sb_tell(CURSBB)); } /* Current pos */
-chroff e_nldot() { return(e_alldot(CURSBB,ex_gonl)); } /* Beg of next line */
-chroff e_pldot() { return(e_alldot(CURSBB,ex_gopl)); } /* Beg of prev line */
-chroff e_boldot(){ return(e_alldot(CURSBB,ex_gobol));} /* Beg of this line */
-chroff e_eoldot(){ return(e_alldot(CURSBB,ex_goeol));} /* End of this line */
-
-chroff
-e_alldot(sbp,rtn) /* Auxiliary for above stuff */
-SBBUF *sbp;
-int (*rtn)();
-{ return(ex_alldot(sbp,rtn,e_dot()));
-}
-
-/* E_BLEN - Return length of current buffer */
-chroff
-e_blen() { return(ex_blen(CURSBB)); }
-\f
-/* EX_ routines - similar to E_ but take a buffer/sbbuf argument
- * instead of assuming current buffer.
- */
-
-/* EX_RESET - Reset a given buffer */
-ex_reset(b)
-struct buffer *b;
-{ sbs_del(sb_close((SBBUF *)b));
- sb_open((SBBUF *)b,(SBSTR *)0);
-}
-
-ex_go(sbp,loc) /* Move to given dot in specified sbbuf */
-chroff loc;
-SBBUF *sbp;
-{ return(sb_seek(sbp,loc,0));
-}
-
-chroff
-ex_dot(sbp) /* Return current position in specified sbbuf */
-SBBUF *sbp;
-{
- return(sb_tell(sbp));
-}
-
-
-chroff
-ex_boldot(sbp,dot) /* Return dot for BOL of specified sbbuf */
-SBBUF *sbp;
-chroff dot;
-{ return(ex_alldot(sbp,ex_gobol,dot));
-}
-
-chroff
-ex_alldot(sbp,rtn,dot) /* Auxiliary for some e_ stuff */
-SBBUF *sbp;
-int (*rtn)();
-chroff dot;
-{ register SBBUF *sb;
- chroff savloc, retloc;
-
- savloc = sb_tell(sb = sbp);
- sb_seek(sb,dot,0);
- (*rtn)(sb);
- retloc = sb_tell(sb);
- sb_seek(sb,savloc,0);
- return(retloc);
-}
-
-/* GO (forward) to Next Line of specified sbbuf - returns 0 if stopped at EOF
- * before an EOL is seen. */
-ex_gonl(sbp)
-SBBUF *sbp;
-{ register SBBUF *sb;
- register int c;
- sb = sbp;
-#if FX_EOLMODE
- if(eolcrlf(sb))
- while((c = sb_getc(sb)) != EOF)
- { if(c == LF) /* Possible EOL? */
- { sb_backc(sb); /* See if prev char was CR */
- if((c = sb_rgetc(sb)) != EOF)
- sb_getc(sb);
- sb_getc(sb); /* Must restore position */
- if(c == CR) /* Now test for CR */
- return(1); /* Won, CR-LF! */
- }
- }
- else
-#endif
- while((c = sb_getc(sb)) != EOF)
- if(c == LF)
- return(1);
- return(0);
-}
-
-/* GO (forward) to End Of Line of specified sbbuf - returns 0 if stopped at
- * EOF before an EOL is seen. */
-ex_goeol(sbp)
-SBBUF *sbp;
-{ register SBBUF *sb;
- register int c;
- sb = sbp;
-#if FX_EOLMODE
- if(eolcrlf(sb))
- while((c = sb_getc(sb)) != EOF)
- { if(c == LF) /* Possible EOL? */
- { sb_backc(sb); /* See if prev char was CR */
- if((c = sb_rgetc(sb)) == CR)
- return(1); /* Won, CR-LF! */
- if(c != EOF) /* No, must restore position */
- sb_getc(sb); /* Skip over */
- sb_getc(sb); /* Skip over LF */
- }
- }
- else
-#endif
- while((c = sb_getc(sb)) != EOF)
- if(c == LF)
- { sb_backc(sb);
- return(1);
- }
- return(0);
-}
-
-/* GO (backward) to Beg Of Line of specified sbbuf - returns 0 if stopped
- * at EOF
- */
-ex_gobol(sbp)
-SBBUF *sbp;
-{ register SBBUF *sb;
- register int c;
- sb = sbp;
-#if FX_EOLMODE
- if(eolcrlf(sb))
- while((c = sb_rgetc(sb)) != EOF)
- { if(c == LF) /* Possible EOL? */
- { if((c = sb_rgetc(sb)) == CR)
- { sb_getc(sb); /* Won, CR-LF! */
- sb_getc(sb); /* Move back */
- return(1);
- }
- if(c != EOF) /* No, must restore position */
- sb_getc(sb); /* Undo the rgetc */
- }
- }
- else
-#endif
- while((c = sb_rgetc(sb)) != EOF)
- if(c == LF)
- { sb_getc(sb);
- return(1);
- }
- return(0);
-}
-
-/* GO (backward) to Previous Line of specified sbbuf - returns 0 if stopped
- * at EOF before an EOL is seen (i.e. if already on 1st line of buffer)
- */
-ex_gopl(sbp)
-SBBUF *sbp;
-{ register SBBUF *sb;
- register int c;
- sb = sbp;
-#if FX_EOLMODE
- if(eolcrlf(sb))
- while((c = sb_rgetc(sb)) != EOF)
- { if(c == LF) /* Possible EOL? */
- { if((c = sb_rgetc(sb)) == CR)
- { ex_gobol(sb);
- return(1); /* Won! */
- }
- if(c != EOF) /* No, must restore position */
- sb_getc(sb); /* Undo the rgetc */
- }
- }
- else
-#endif
- while((c = sb_rgetc(sb)) != EOF)
- if(c == LF)
- { ex_gobol(sb);
- return(1); /* Won! */
- }
- return(0);
-}
-
-
-chroff
-ex_blen(sbp) /* Return length of specified sbbuf */
-SBBUF *sbp;
-{
- return(sb_tell(sbp)+sb_ztell(sbp));
-}
-\f
-/* Miscellaneous stuff */
-
-/* E_GOFWSP() - Forward over whitespace */
-e_gofwsp()
-{ register int c;
- while((c = e_getc()) == SP || c == TAB);
- if(c != EOF) e_backc();
-}
-
-/* E_GOBWSP() - Backward over whitespace */
-e_gobwsp()
-{ register int c;
- while((c = e_rgetc()) == SP || c == TAB);
- if(c != EOF) e_getc();
-}
-
-
-/* E_GOLINE(n) - Goes N lines forward (or backward).
-** If N == 0, goes to beginning of current line.
-** Returns 0 if hit EOF.
-*/
-e_goline(i)
-register int i;
-{
- if(i > 0)
- { do { if(!e_gonl()) return(0); }
- while(--i);
- }
- else if(i < 0)
- { i = -i;
- do { if(!e_gopl()) return(0); }
- while(--i);
- }
- else e_gobol(); /* arg of 0 */
- return 1;
-}
-
-/* E_LBLANKP() - Returns true if all characters in rest of line are blank.
- * Moves to beginning of next line as side effect, unless fails.
- */
-e_lblankp()
-{ register int c;
- for(;;) switch(e_getc())
- {
- case SP:
- case TAB:
- continue;
- case LF: /* Normally drop thru to return 1 as for EOF */
-#if FX_EOLMODE
- if(eolcrlf(cur_buf))
- { e_rgetc();
- if((c = e_rgetc()) != EOF) /* Get prev char */
- e_getc();
- e_getc();
- if(c != CR) /* Now examine */
- continue; /* Not CR-LF, go on */
- } /* Else drop thru to return win */
-#endif
- case EOF:
- return(1);
- default:
- return(0);
- }
- /* Never drops out */
-}
-\f
-
-e_insn(ch, cnt)
-int ch;
-int cnt;
-{ register int i;
- if((i = cnt) > 0)
- do { e_putc(ch);
- } while(--i);
-}
-
-e_sputz(acp)
-char *acp;
-{ register SBBUF *sb;
- register char *cp;
- register int c;
- if(cp = acp)
- { sb = CURSBB;
- while(c = *cp++)
- sb_putc(sb,c);
- }
-}
-
-/* BOLEQ - Returns TRUE if 2 dots are on the same line
- * (i.e. have the same Beg-Of-Line)
- */
-boleq(dot1,dot2)
-chroff dot1,dot2;
-{ return( (ex_boldot(CURSBB,dot1) == ex_boldot(CURSBB,dot2)));
-}
-
-
-char *
-dottoa(str,val)
-char *str;
-chroff val;
-{ register char *s;
-
- s = str;
- if(val < 0)
- { *s++ = '-';
- val = -val;
- }
- if(val >= 10)
- s = dottoa(s, val/10);
- *s++ = '0' + (int)(val%10);
- *s = 0;
- return(s);
-}
-
-\f
-/* Paragraph utilities */
-
-#if FX_FPARA || FX_BPARA || FX_MRKPARA || FX_FILLPARA
-
-#if FX_SFPREF
-extern char *fill_prefix; /* Defined in eefill.c for now */
-extern int fill_plen; /* Ditto */
-#endif /*FX_SFPREF*/
-
-#if ICONOGRAPHICS
-int para_mode = PARABLOCK; /* eexcmd.c only other file that refs this */
-#endif /*ICONOGRAPHICS*/
-
-
-/* Go to beginning of paragraph */
-e_gobpa()
-{ register int c;
- chroff savdot;
-
- savdot = e_dot();
- e_bwsp();
- while((c = e_rgetc()) != EOF)
- if(c == LF) /* Went past line? */
- { e_getc(); /* Back up and check */
-#if FX_SFPREF
- if(fill_plen)
- if(tstfillp(fill_plen))
- { e_igoff(-(fill_plen+1));
- continue;
- }
- else break;
-#endif /*FX_SFPREF*/
-#if ICONOGRAPHICS
- c = e_peekc ();
-
- if (para_mode == PARABLOCK)
- if (c == LF)
- break;
-
- if (para_mode == PARALINE)
- if (c_wsp (c))
- break;
-#else
- if(c_pwsp(e_peekc())) /* Check 1st chr for wsp */
- break; /* If wsp, done */
-#endif /*ICONOGRAPHICS*/
- e_rgetc(); /* Nope, continue */
- }
- if((c = e_peekc()) == '.' || c == '-')
- { e_gonl();
- if(e_dot() >= savdot)
- e_gopl();
- }
-}
-
-/* Go to end of paragraph */
-e_goepa()
-{ register int c;
-
- e_gobol(); /* First go to beg of cur line */
- e_fwsp();
- while((c = e_getc()) != EOF)
- if (c == LF)
- {
-#if FX_SFPREF
- if(fill_plen) /* If Fill Prefix is defined */
- if(tstfillp(fill_plen)) /* then must start with it */
- continue;
- else break; /* or else we're done */
-#endif /*FX_SFPREF*/
-#if ICONOGRAPHICS
- if (para_mode == PARABLOCK)
- if (e_peekc () == LF)
- break;
-
- if (para_mode == PARALINE)
- if (c_wsp (e_peekc ()))
- break;
-#else
- if(c_pwsp(e_peekc()))
- break;
-#endif /*-ICONOGRAPHICS*/
- }
-}
-
-exp_do(rpos, rneg)
-int (*rpos)(), (*rneg)();
-{ register int e;
- register int (*rtn)();
-
- if((e = exp) == 0)
- return;
- rtn = rpos;
- if(e < 0)
- { rtn = rneg;
- e = -e;
- }
- do { (*rtn)();
- } while(--e);
-}
-
-
-e_fwsp()
-{ register int c;
- while(c_wsp(c = e_getc()));
- if(c != EOF) e_backc();
-}
-e_bwsp()
-{ register int c;
- while(c_wsp(c = e_rgetc()));
- if(c != EOF) e_getc();
-}
-
-
-c_wsp(ch)
-int ch;
-{ register int c;
- c = ch;
- if(c == SP || c == TAB || c == LF || c == FF)
- return(1);
- return(0);
-}
-c_pwsp(ch)
-int ch;
-{ register int c;
- c = ch;
- if(c == '.' || c == '-')
- return(1);
- return(c_wsp(c));
-}
-
-#endif /* FX_FPARA || FX_BPARA || FX_MRKPARA || FX_FILLPARA */
-\f
-/* Word function auxiliaries */
-
-/* Returns true if this character is a delimiter. */
-delimp(c)
-int c;
-{ static int delim_tab[] =
- {
- 0177777, 0177777, /* All controls */
- 0177777, 0176000, /* All punct but 0-9 */
- 0000001, 0074000, /* All punct but A-Z and _ */
- 0000001, 0174000 /* All punct but a-z */
- };
- return (delim_tab[c >> 4] & (1 << (c & 017)));
-}
-
-e_wding(adot,n)
-register chroff *adot;
-int n;
-{ chroff savdot;
- savdot = e_dot();
- e_gowd(n);
- *adot = e_dot();
- e_go(savdot);
- if(*adot == savdot)
- { ring_bell();
- return(0);
- }
- return(1);
-}
-chroff
-e_wdot(dot,n)
-chroff dot;
-int n;
-{ chroff savdot, retdot;
- savdot = e_dot();
- e_go(dot);
- e_gowd(n);
- retdot = e_dot();
- e_go(savdot);
- return(retdot);
-}
-e_gowd(n)
-int n;
-{ register int (*gch)(), c, cnt;
- int e_getc(), e_rgetc();
- chroff ret_dot;
-
- if((cnt = n) == 0)
- return;
- if(cnt > 0)
- gch = e_getc; /* Forward routine */
- else
- { gch = e_rgetc; /* Backward routine */
- cnt = -cnt;
- }
- do
- { ret_dot = e_dot(); /* Remember dot for last word found */
- while((c = (*gch)()) != EOF && delimp(c));
- if(c == EOF)
- { e_go(ret_dot); /* Use last word found */
- break;
- }
- while((c = (*gch)()) != EOF && !delimp(c));
- if(c == EOF)
- break;
- if(n < 0) e_getc(); else e_backc();
- } while(--cnt);
-}
-\f
-/* Searching */
-
-e_search(mstr,mlen,backwards)
-char *mstr;
-int mlen;
-int backwards;
-{ register SBBUF *sb;
- register char *cp;
- register int c;
- char *savcp;
- int cnt, scnt;
-#if IMAGEN
- register int c1;
- register int caseless = (cur_buf->b_flags & B_TEXTMODE);
-#endif /*IMAGEN*/
-
- sb = (SBBUF *) cur_buf;
- if (!backwards)
- { /* Search forwards */
- sfwd: cp = mstr;
- while((c = sb_getc(sb)) != EOF)
- {
-#if IMAGEN
- if((!caseless && c != *cp) ||
- (caseless && upcase(c) != upcase(*cp))) continue;
-#else
- if(c != *cp) continue;
-#endif /*-IMAGEN*/
- cp++;
- cnt = mlen;
- while(--cnt > 0)
- {
-#if IMAGEN
- c1 = *cp++;
- c = e_getc();
- if ((!caseless && c1 != c) ||
- (caseless && upcase(c1) != upcase(c)))
-#else
- if(*cp++ != (c = e_getc()))
-#endif /*-IMAGEN*/
- { if(c == EOF) return(0);
- sb_seek(sb,(chroff)(cnt-mlen),1);
- goto sfwd;
- }
- }
- return(1);
- }
- }
- else
- { /* Search backwards */
- scnt = mlen - 1;
- savcp = mstr + scnt; /* Point to end of string */
-
- sbck: cp = savcp;
- while((c = sb_rgetc(sb)) != EOF)
- {
-#if IMAGEN
- if((!caseless && c != *cp) ||
- (caseless && upcase(c) != upcase(*cp))) continue;
-#else
- if(c != *cp) continue;
-#endif /*-IMAGEN*/
- cp--;
- if((cnt = scnt) == 0) return(1);
- do
- {
-#if IMAGEN
- c1 = *cp--;
- c = e_rgetc();
- if ((!caseless && c1 != c) ||
- (caseless && upcase(c1) != upcase(c)))
-#else
- if(*cp-- != (c = e_rgetc()))
-#endif /*-IMAGEN*/
- { if(c == EOF) return(0);
- sb_seek(sb,(chroff)(mlen-cnt),1);
- goto sbck;
- }
- }
- while(--cnt);
- return(1);
- }
- }
- return(0); /* Failed */
-}
+++ /dev/null
-/* ELLE - Copyright 1982, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/* EEERR - Error handling & testing routines
- */
-
-#include "elle.h"
-
-#if V6
-#include "eesigs.h"
-#else
-#include <signal.h>
-#endif
-
-/* EFUN: "Hit Breakpoint" */
-f_bkpt()
-{ clean_exit();
- bpt();
- set_tty();
-}
-bpt() {} /* Put a DDT/ADB breakpoint here */
-\f
-#if !(STRERROR) /* If strerror() not supported, we provide it. */
-extern int sys_nerr; /* Max index into sys_errlist */
-extern char *sys_errlist[];
-
-char *
-strerror(num)
-int num;
-{
- static char badbuf[30];
- if (num > 0 && num <= sys_nerr)
- return (sys_errlist[num]);
- sprintf(badbuf, "unknown error %d", num);
- return badbuf;
-}
-#endif /* -STRERROR */
-\f
-
-errsbm(type,adr,str,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)
-register int type; /* Type, flags */
-int (*adr)(); /* Addr called from */
-char *str; /* Printf string */
-{ register struct buffer *b;
- int oldttystate;
-
- oldttystate = clean_exit(); /* Ensure not in editing mode */
- if(type == SBFERR) /* File overwrite error? A0 is FD */
- { printf("WARNING - FILE CORRUPTED!\nBuffers affected:\n");
- for(b = buf_head; b; b = b->b_next)
- { if(sb_fdinp((SBBUF *)b, a0))
- printf((b->b_fn ? " %s: %s\n" : " %s\n"),
- b->b_name, b->b_fn);
- }
- if (oldttystate > 0) set_tty();
- return(1); /* Try to continue normally */
- }
- printf("%sERR: %o ", (type ? "SBX" : "SBM"), adr);
- printf(str,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12);
- askerr();
-}
-
-/*
- * Bite_bag -- Try to save our rear ends after a catastrophe.
- * This routine is mainly called from "interrupt"
- * level when a memory fault or bus error occurs.
- * We try to save the buffer to the file "ELLE.crash"
- * in the current working directory. If it loses, well
- * then you have really lost. Note: this routine does
- * not reset the appropriate signal handler, so it is
- * never re-entered. If a fault repeats once in this
- * code, then the world dies.
- */
-
-bite_bag(fault) /* We come here on any memory error */
-int fault;
-{
- int ostate;
- /* Some systems, such as BSD4.x and SUN, do not reset caught signals
- * to SIG_DFL.
- * This is a win, but isn't what vanilla UNIX code expects.
- * Since it doesn't hurt to do it explicitly, we always turn it off
- * explicitly...
- */
- signal(fault, SIG_DFL); /* Reinstate default handling */
-
- ostate = clean_exit(); /* Fix up the terminal modes first! */
- printf("ELLE stopped by fatal interrupt (%d)!\n\
-Type S or W to try saving your work.\n",fault);
- askerr();
- if(ostate > 0) set_tty();
- signal(fault, bite_bag); /* If continued, re-enable signal */
-}
-
-/* HUP_EXIT - Called by a SIGHUP hangup signal.
- * Tries to save all modified buffers before exiting.
- * Note that the TTY is not touched at all, although the terminal mode
- * flag is set just in case further error handling routines are invoked.
- */
-hup_exit()
-{ extern int trm_mode; /* See e_disp.c */
-
- trm_mode = -1; /* Say TTY is now detached */
- saveworld((struct buffer *)0, 0); /* Save world, w/o feedback */
- exit(1);
-}
-\f
-errint() /* Routine provided for ADB jumps */
-{ askerr();
-}
-char askh1[] = "\
-A - Abort process\n\
-B - Breakpoint (must have \"bpt:b\" set in ADB)\n\
-C - Continue\n\
-D - Diagnostic command mode\n";
-char askh2[] = "\
-S - Try to save current buffer\n\
-W - Try to save world (all modified buffers)\n";
-
-int bsaving = 0; /* Set while in middle of saving buffer(s) */
-
-askerr()
-{ register struct buffer *b;
- char linbuf[100];
- char *asklin();
- extern int (*funtab[])(); /* In E_CMDS.C */
- int ostate;
-
- ostate = clean_exit(); /* Clean up TTY if not already done */
-reask:
- printf("(A,B,C,D,S,W,?)");
- switch(upcase(*asklin(linbuf)))
- {
- case '?':
- writez(1,askh1); /* Too long for &$@! printf */
- writez(1,askh2); /* Too long for &$@! V6 C */
- break; /* optimizer (/lib/c2) */
- case 'A':
- abort();
- break;
- case 'B':
- bpt();
- break;
- case 'Q':
- case 'C':
- goto done;
- case 'D':
- if(funtab[FN_DEBUG])
- (*funtab[FN_DEBUG])(-1);
- else printf("Sorry, no diagnostics\n");
- break;
- case 'S': /* Try to save current buffer only */
- b = cur_buf;
- goto savb;
- case 'W': /* Try to save all modified buffers */
- b = 0;
- savb: if(bsaving++)
- { printf("Already saving -- continued");
- goto done;
- }
- saveworld(b, 1); /* Save, with feedback */
- bsaving = 0;
- break;
- }
- goto reask;
-done:
- if(ostate > 0)
- set_tty();
-}
-
-char *
-asklin(acp)
-char *acp;
-{ register char *cp;
- register int c;
- cp = acp;
- while((c = tgetc()) != LF)
- *cp++ = c;
- *cp++ = 0;
- return(acp);
-}
+++ /dev/null
-/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/*
- * EEF1 Various functions
- * Char move/ins/del
- * Case change
- * Char/word transpose
- */
-
-#include "elle.h"
-
-/* EFUN: "Insert Self" */
-f_insself (c)
-int c;
-{
-#if IMAGEN
- fim_insself(c);
-#else
-#if FX_FILLMODE
- extern int fill_mode;
-
- if(fill_mode) fx_insfill(c);
- else
-#endif /*FX_FILLMODE*/
- ed_insn(c, exp); /* Normal stuff */
-#endif /*-IMAGEN*/
-}
-
-/* EFUN: "Quoted Insert"
-** Inserts next char directly, <exp> number of times.
-** Does not check anything about the char and does not do anything
-** depending on the mode. In particular, CR is not turned into EOL.
-*/
-f_quotins()
-{
- ed_insn(cmd_read(), exp); /* Insert next char directly */
-}
-
-#if FX_CRLF
-/* EFUN: "CRLF" */
-f_crlf()
-{
-#if IMAGEN
- fim_crlf();
-#else
- register int i;
-
- if(e_goeol() == cur_dot /* If at end of current line */
- && exp == 1 /* and inserting only 1 new line */
- && e_lblankp() && e_lblankp()) /* and next 2 lines blank */
- { e_gocur(); /* Then just re-use next line. */
- e_gonl(); /* Go to its start */
- e_setcur(); /* and establish cur_dot there. */
- ed_delete(e_dot(), e_eoldot()); /* Ensure any blanks flushed */
- }
- else
- { e_gocur(); /* Otherwise back to original place */
- if((i = exp) > 0) /* and simply insert newlines */
- do ed_crins();
- while(--i);
- }
-#endif /*-IMAGEN*/
-}
-#endif /*FX_CRLF*/
-\f
-/* EFUN: "Forward Character" */
-f_fchar()
-{ ed_igoff(exp);
-}
-
-/* EFUN: "Backward Character" */
-f_bchar()
-{ ed_igoff(-exp);
-}
-
-/* EFUN: "Delete Character" */
-f_dchar ()
-{
-#if IMAGEN
- fim_dchar();
-#else
- ef_deln(exp);
-#endif /*-IMAGEN*/
-}
-
-/* EFUN: "Backward Delete Character" */
-f_bdchar ()
-{
-#if IMAGEN
- fim_bdchar();
-#else
- ef_deln(-exp);
-#endif /*-IMAGEN*/
-}
-
-/* Delete forward or backward N characters.
- * If arg, kills instead of deleting.
- */
-ef_deln(x)
-int x;
-{
- e_igoff(x);
- if(exp_p) ed_kill(cur_dot, e_dot());
- else ed_delete(cur_dot, e_dot());
-}
-\f
-#if FX_DELSPC
-/* EFUN: "Delete Horizontal Space" */
-/* Delete spaces/tabs around point.
- */
-f_delspc()
-{ chroff dot1;
-
- e_gobwsp(); /* Move backward over whitespace */
- dot1 = e_dot(); /* Save point */
- e_gofwsp(); /* Move forward over whitespace */
- ed_delete(dot1,e_dot()); /* Delete twixt start and here */
-}
-#endif /*FX_DELSPC*/
-\f
-#if FX_TCHARS
-/* EFUN: "Transpose Characters"
- * Transpose chars before and after cursor. Doesn't hack args yet.
- * EMACS: With positive arg, exchs chars before & after cursor, moves right,
- * and repeats the specified # of times, dragging the char to the
- * left of the cursor right.
- * With negative arg, transposes 2 chars to left of cursor, moves
- * between them, and repeats the specified # of times, exactly undoing
- * the positive arg form. With zero arg, transposes chars at point
- * and mark.
- * HOWEVER: at the end of a line, with no arg, the preceding 2 chars
- * are transposed.
- */
-f_tchars()
-{ register int c, c2;
-#if IMAGEN
- c = e_rgetc(); /* Gosmacs style: twiddle prev 2 */
- if (c == EOF)
- return(e_gocur()); /* Do nothing at beginning of bfr */
-#else
-
- if((c = e_getc()) == EOF /* If at EOF */
- || e_rgetc() == LF) /* or at end of line, */
- c = e_rgetc(); /* use preceding 2 chars */
-#endif /*-IMAGEN*/
-
- if((c2 = e_rgetc()) == EOF) /* At beginning of buffer? */
- return(e_gocur()); /* Yes, do nothing */
- e_ovwc(c);
- e_ovwc(c2);
- e_setcur();
- buf_tmod((chroff)-2); /* Munged these 2 chars */
-}
-#endif /*FX_TCHARS*/
-\f
-#if FX_FWORD
-/* EFUN: "Forward Word" */
-f_fword()
-{ chroff retdot;
- if(e_wding(&retdot, exp))
- ed_go(retdot);
-}
-#endif
-
-#if FX_BWORD
-/* EFUN: "Backward Word" */
-f_bword()
-{ exp = -exp;
- f_fword();
-}
-#endif
-
-#if FX_KWORD
-/* EFUN: "Kill Word" */
-f_kword()
-{ chroff retdot;
-
- if(e_wding(&retdot,exp))
- { ed_kill(cur_dot,retdot);
- this_cmd = KILLCMD;
- }
-}
-#endif
-
-#if FX_BKWORD
-/* EFUN: "Backward Kill Word" */
-f_bkword()
-{ exp = -exp;
- f_kword();
-}
-#endif
-\f
-#if FX_TWORDS
-/* EFUN: "Transpose Words" */
-/* Transpose word. Urk!
- */
-f_twords()
-{ register SBSTR *sd1, *sd2;
- register SBBUF *sb;
- chroff begwd1, endwd1, begwd2, endwd2;
-
- endwd2 = e_wdot(cur_dot, 1); /* Go to end of 2nd word */
- begwd2 = e_wdot(endwd2, -1); /* Go to beg of 2nd word */
- if(begwd2 >= endwd2) /* If no 2nd word, punt. */
- return;
- begwd1 = e_wdot(begwd2, -1); /* Go to beg of 1st word */
- endwd1 = e_wdot(begwd1, 1); /* Go to end of 1st word */
- if(begwd1 >= endwd1) /* If no 1st word, punt. */
- return;
- if(endwd1 > begwd2) /* Avoid possible overlap */
- return;
-
- e_go(begwd2);
- sb = (SBBUF *)cur_buf;
- sd2 = sb_killn(sb, endwd2 - begwd2); /* Excise wd 2 first */
- e_go(begwd1);
- sd1 = sb_killn(sb, endwd1 - begwd1); /* Excise wd 1 */
- sb_sins(sb, sd2); /* Replace with wd 2 */
- e_goff(begwd2 - endwd1); /* Move past between stuff */
- sb_sins(sb, sd1); /* Insert wd 1 */
- e_setcur();
- buf_tmat(begwd1); /* Modified this range */
-}
-#endif /*FX_TWORDS*/
-\f
-/* Case hacking functions and support */
-
-#if FX_UCWORD
-/* EFUN: "Uppercase Word" */
-f_ucword()
-{ case_word(0);
-}
-#endif /*FX_UCWORD*/
-
-#if FX_LCWORD
-/* EFUN: "Lowercase Word" */
-f_lcword()
-{ case_word(1);
-}
-#endif /*FX_LCWORD*/
-
-#if FX_UCIWORD
-/* EFUN: "Uppercase Initial" */
-f_uciword()
-{ case_word(2);
-}
-#endif /*FX_UCIWORD*/
-
-#if FX_UCWORD||FX_LCWORD||FX_UCIWORD
-case_word (downp)
-{ chroff retdot;
-#if IMAGEN
- chroff startdot;
-
- /* Normalize our position to beginning of "current" word,
- * where "current" is defined to be the current word we are in,
- * or else the previous word if we are not in any word.
- * All this silly nonsense just to perpetuate Gosmacs's
- * wrong behaviour!
- */
- startdot = cur_dot; /* Save current position */
- e_getc(); /* If at beg of word, ensure we get inside it */
- e_gowd(-1); /* Go to start of this or prev word */
- e_setcur(); /* Set cur_dot */
-#endif /*IMAGEN*/
-
- if(e_wding(&retdot, exp))
- { ed_case(cur_dot,retdot,downp);
- e_gosetcur(retdot);
- }
-#if IMAGEN
- e_gosetcur(startdot);
-#endif /*IMAGEN*/
-}
-#endif /* any case_word caller */
+++ /dev/null
-/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/*
- * EEF2 Various functions
- */
-
-#include "elle.h"
-
-/* Line Handling functions */
-
-/* EFUN: "Beginning of Line" */
-f_begline()
-{ e_gobol();
- ed_setcur();
-}
-
-/* EFUN: "End of Line" */
-f_endline()
-{ e_goeol();
- ed_setcur();
-}
-
-/* EFUN: "Next Line" */
-/* Goes to beginning of next line */
-f_nxtline()
-{ return(down_bline(exp));
-}
-
-/* EFUN: "Previous Line" */
-/* Goes to beginning of previous line */
-f_prvline()
-{ return(down_bline(-exp));
-}
-
-/* EFUN: "Down Real Line" */
-f_dnrline ()
-{ down_line(exp);
-}
-
-/* EFUN: "Up Real Line" */
-f_uprline ()
-{ down_line(-exp);
-}
-
-#if FX_OLINE
-/* EFUN: "Open Line" */
-f_oline()
-{ register int i;
- chroff savdot;
-
- savdot = cur_dot;
- if((i = exp) > 0)
- do { ed_crins(); }
- while(--i);
- e_gosetcur(savdot);
-}
-#endif /*FX_OLINE*/
-
-#if FX_DELBLINES
-/* EFUN: "Delete Blank Lines" */
-/* Delete blank lines around point.
- */
-f_delblines()
-{ register int c;
- chroff dot1, dot2, oldcur;
-
- oldcur = cur_dot;
- do { e_gobwsp(); }
- while ((c = e_rgetc()) == LF);
- if (c != EOF)
- e_gonl();
- dot1 = e_dot();
- if(dot1 > oldcur) return;
- do { e_gofwsp(); }
- while ((c = e_getc()) == LF);
- if(c != EOF)
- e_gobol();
- dot2 = e_dot();
- if(dot2 < oldcur) return;
- ed_delete(dot1,dot2);
-}
-#endif /*FX_DELBLINES*/
-
-#if FX_KLINE
-/* EFUN: "Kill Line" */
-f_kline()
-{
- if(exp_p)
- e_goline(exp); /* Move that many lines */
- /* (if 0, goes to BOL) */
- else /* No arg, handle specially */
- { if(e_lblankp()) /* Is rest of line blank? */
- ; /* Yes, now at next line! */
- else e_goeol(); /* No, go to EOL rather than NL */
- }
- ed_kill(cur_dot,e_dot());
- e_setcur();
- this_cmd = KILLCMD;
-}
-#endif /*FX_KLINE*/
-
-#if FX_BKLINE
-/* EFUN: "Backward Kill Line" (not EMACS) */
-/* Originally an Iconographics function.
-*/
-f_bkline()
-{
- if(exp_p) exp = -exp; /* If arg, invert it */
- else
- { exp = 0; /* No arg, furnish 0 */
- exp_p = 1;
- }
- f_kline(); /* Invoke "Kill Line" */
-}
-#endif /*FX_BKLINE*/
-
-#if FX_GOLINE
-/* EFUN: "Goto Line" (not EMACS) (GNU goto-line) */
-f_goline()
-{
- e_gobob();
- down_bline(exp-1); /* already at line 1 */
-}
-#endif /*FX_GOLINE*/
-\f
-down_bline(arg)
-int arg;
-{
- if(arg)
- e_goline(arg);
- ed_setcur();
-}
-
-#if FX_DNRLINE || FX_UPRLINE
-down_line (x)
-int x;
-{ register int i, res;
-
- res = x ? e_goline(x) : 1; /* Move that many lines */
- goal = 0;
- if(res == 0) /* Hit buffer limits (EOF)? */
- { if(x > 0) /* Moving downwards? */
- {
-#if !(IMAGEN) /* If IMAGEN, do not extend!! */
- if(x == 1) ed_crins(); /* Yeah, maybe extend */
- else
-#endif
- goal = indtion(cur_dot);
- goto done;
- }
- }
-
- if(last_cmd == LINECMD /* If previous cmd also a line move */
- && pgoal != -1) /* and we have a previous goal col */
- goal = pgoal; /* then make it the current goal */
- else goal = indtion(cur_dot); /* Else invent goal from current pos */
-
- i = inindex(e_dot(), goal); /* See # chars needed to reach goal */
- if(i == -1) /* If off edge of line, */
- e_goeol(); /* just move to end of this line */
- else e_igoff(i); /* else move to goal. */
-
-done: pgoal = goal;
- this_cmd = LINECMD;
- ed_setcur();
-}
-#endif /*FX_DNRLINE || FX_UPRLINE*/
-
-
-\f
-/* Region Handling functions */
-
-/* EFUN: "Set/Pop Mark" */
-f_setmark()
-{
- mark_dot = e_dot();
- mark_p = 1;
- if(ev_markshow) /* If have one, show indicator */
- saytoo(ev_markshow); /* that mark was set. */
-}
-
-/* EFUN: "Exchange Point and Mark" */
-f_exchmark()
-{ chroff tmpdot;
-
- if(chkmark())
- { tmpdot = mark_dot;
- mark_dot = cur_dot;
- ed_go(tmpdot); /* Set cur_dot and go there */
- }
-}
-
-/* EFUN: "Kill Region" */
-f_kregion()
-{
- if(chkmark())
- { ed_kill(cur_dot,mark_dot); /* Will adj cur_dot, mark_dot */
- e_gocur();
- this_cmd = KILLCMD;
- }
-}
-
-/* EFUN: "Copy Region" */
-f_copreg()
-{
- if(chkmark())
- { e_gocur();
- kill_push(e_copyn(mark_dot - cur_dot));
- e_gocur();
- }
-}
-
-
-/* EFUN: "Uppercase Region" */
-f_ucreg()
-{ ef_creg(0);
-}
-
-/* EFUN: "Lowercase Region" */
-f_lcreg()
-{ ef_creg(1);
-}
-
-ef_creg(downp)
-int downp;
-{
- if(chkmark())
- ed_case(cur_dot,mark_dot,downp);
-}
-
-#if FX_FILLREG
-/* EFUN: "Fill Region" */
-f_fillreg()
-{ if(chkmark())
- ed_fill(mark_dot,cur_dot,0);
-}
-#endif /*FX_FILLREG*/
-
-/* CHKMARK() - minor utility for region-hacking functions.
- * Returns TRUE if mark exists.
- * Otherwise complains to user and returns 0.
- */
-chkmark()
-{ if(mark_p == 0)
- ding("No mark!");
- return(mark_p);
-}
-\f
-/* Paragraph functions */
-
-#if FX_FPARA
-/* EFUN: "Forward Paragraph" */
-f_fpara()
-{ int e_gobpa(), e_goepa();
-
- exp_do(e_goepa, e_gobpa);
- ed_setcur();
-}
-#endif /*FX_FPARA*/
-
-#if FX_BPARA
-/* EFUN: "Backward Paragraph" */
-/* Go to beginning of paragraph.
- * Skip all whitespace until text seen, then stop at beginning of
- * 1st line starting with whitespace.
- */
-f_bpara()
-{ int e_gobpa(), e_goepa();
-
- exp_do(e_gobpa, e_goepa);
- ed_setcur();
-}
-#endif /*FX_BPARA*/
-
-#if FX_MRKPARA
-/* EFUN: "Mark Paragraph" */
-f_mrkpara()
-{
- f_fpara(); /* Go to end of paragraph */
- f_setmark(); /* Put mark there */
- f_bpara(); /* Then back to start of paragraph */
-}
-#endif /*FX_MRKPARA*/
-
-#if FX_FILLPARA
-/* EFUN: "Fill Paragraph" */
-f_fillpara()
-{
- chroff savloc, endloc;
-
- savloc = cur_dot;
-#if ICONOGRAPHICS
- e_getc(); /* DON'T go to next para if at end */
- e_gobpa(); /* of this one!! */
-#endif /*ICONOGRAPHICS*/
- e_goepa(); /* Go to end of parag */
- if(e_rgetc() != LF) /* If last char EOL, back over it. */
- e_getc();
- endloc = e_dot(); /* Remember where end is */
- e_gobpa(); /* Go to beg of parag */
-#if ICONOGRAPHICS
- kill_push(e_copyn(endloc - e_dot ()));
- /* put old version on kill ring */
-#endif /*ICONOGRAPHICS*/
- e_fwsp(); /* Move over initial whitespace */
- ed_fill(e_dot(), endloc, 0); /* Fill this region, return to dot */
-}
-#endif /*FX_FILLPARA*/
+++ /dev/null
-/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/*
- * EEF3 Various Functions (Yanking, Indentation, miscellaneous)
- */
-
-#include "elle.h"
-
-#if FX_APPNKILL
-/* EFUN: "Append Next Kill" */
-f_appnkill()
-{ this_cmd = KILLCMD; /* Fake out next call to ed_kill */
-}
-#endif /*FX_APPNKILL*/
-
-#if FX_UNKILL
-/* EFUN: "Un-kill" */
-f_unkill()
-{ register SBSTR *sd;
-
- if((sd = kill_ring[kill_ptr]) == 0)
- { ring_bell();
- return;
- }
- mark_dot = cur_dot; /* Set mark at old location */
- mark_p = 1; /* Mark's been set */
- sb_sins((SBBUF *)cur_buf,sbs_cpy(sd)); /* Insert copy of stuff */
- cur_dot = e_dot(); /* We're now after the new stuff */
- buf_tmat(mark_dot); /* Say modified from here to cur_dot*/
- this_cmd = YANKCMD;
-}
-#endif /*FX_UNKILL*/
-
-#if FX_UNKPOP
-/* EFUN: "Un-kill Pop" */
-f_unkpop()
-{ register SBSTR *sd;
- register int i;
-
- if (last_cmd != YANKCMD)
- { ring_bell ();
- return;
- }
- ed_delete(cur_dot,mark_dot);
- if(cur_dot > mark_dot)
- cur_dot = mark_dot;
- i = KILL_LEN;
- do {
- if(--kill_ptr < 0)
- kill_ptr = KILL_LEN-1;
- if(sd = kill_ring[kill_ptr])
- break;
- } while(--i);
-
- /* kill_ptr now pointing to right place; effect the yank. */
- e_gocur(); /* Make sure point at right place too! */
- return(f_unkill());
-}
-#endif /*FX_UNKPOP*/
-\f
-/* Indentation routines - still not polished */
-
-#if FX_INDATM
-/* EFUN: "Indent According to Mode" */
-/* In Fundamental mode, just inserts a tab.
-*/
-f_indatm()
-{ f_insself(TAB); /* This takes care of mode checking */
-}
-#endif /*FX_INDATM*/
-
-#if FX_INDNL
-/* EFUN: "Indent New Line" */
-f_indnl() /* execute CR followed by tab */
-{
-#if IMAGEN
- /* Not dispatch-based, but rather hard-wired to do Gosmacs thing */
- ed_crins();
- f_indund();
-#else
- cmd_xct(CR);
- cmd_xct(TAB);
-#endif /*-IMAGEN*/
-}
-#endif /*FX_INDNL*/
-
-
-#if FX_BACKIND
-/* EFUN: "Back to Indentation"
-** Moves to end of current line's indentation.
-*/
-f_backind()
-{ e_gobol(); /* First move to beg of line */
- e_gofwsp(); /* Then forward over whitespace */
- ed_setcur();
-}
-#endif /*FX_BACKIND*/
-
-
-#if FX_INDCOMM
-
-static char *comm_beg = "/* ";
-static char *comm_end = " */";
-
-/* EFUN: "Indent for Comment" */
-f_indcomm()
-{
- f_endline();
- if(indtion(cur_dot) < ev_ccolumn)
- ed_indto(ev_ccolumn);
- else ed_sins(" ");
- ed_sins (comm_beg);
- ed_sins (comm_end);
- e_igoff(-strlen (comm_end)); /* back over end string */
- e_setcur();
-}
-#endif /*FX_INDCOMM*/
-
-#if FX_INDREL
-/* EFUN: "Indent Relative" */
-/* This used to mistakenly be called Indent Under.
-** Still not fully implemented.
-** If at beginning of line, looks back at previous indented line,
-** and indents this line that much. If there is no preceding indented
-** line or not at beginning of line, insert a tab.
-*/
-f_indrel()
-{ register int c;
- register n;
-#if IMAGEN
- chroff savdot;
-#endif /*IMAGEN*/
-#if ICONOGRAPHICS
- chroff savdot;
- int curind, newind, morebuf;
-#endif /*ICONOGRAPHICS*/
-
- if((c = e_rgetc()) == EOF)
-#if IMAGEN
- return(f_insself(TAB)); /* Do mode-based tabbing */
-#else
- return(ed_insert(TAB));
-#endif /*-IMAGEN*/
-
- if(c == LF)
- { e_gobol();
- e_gofwsp();
- n = d_curind();
- e_gonl(); /* Return to orig pos */
- if(n)
- { ed_indto(n);
-#if IMAGEN
- savdot = e_dot();
- e_gofwsp();
- ed_delete(savdot, e_dot());
-#endif /*IMAGEN*/
- return;
- }
- }
-#if ICONOGRAPHICS
- else
- { e_igoff (1);
- curind = indtion (savdot = e_dot ());
- /* get current dot and indentation */
- while (1) /* find a prev line that extends rightward */
- { morebuf = e_gopl ();
- e_goeol ();
- if ((newind = d_curind()) > curind) break;
- if (morebuf == 0) /* hit beginning of buffer */
- { e_go (savdot);
- f_delspc();
- return (1);
- }
- }
-
- e_gobol ();
- e_igoff (inindex (e_dot (), curind));
- if (d_curind() > curind)
- e_rgetc (); /* pushed ahead by tab */
-
- while (c_wsp (e_getc ()) == 0) ;
- e_backc ();
- e_fwsp ();
- newind = d_curind();
- e_go (savdot);
- f_delspc();
- ed_indto (newind);
- }
-#else
- else e_getc();
-#if IMAGEN
- f_insself(TAB); /* Do mode-based tabbing */
-#else
- ed_insert(TAB);
-#endif /*-IMAGEN*/
-#endif /*-ICONOGRAPHICS*/
-}
-#endif /*FX_INDREL*/
-
-\f
-/* Paren matching stuff. Note that this stuff will be very painful unless
-** tinwait() works properly.
-*/
-#if 0
-/* EFUN: "Self-Insert and Match" (intended to be bound to brackets) */
-/* (KLH: Evidently this was never finished)
-*/
-insertmatch(c)
-register int c;
-{
-
-}
-#endif
-
-/* Should change this to Matching Paren */
-#if FX_MATCHBRACK
-/* EFUN: "Match Bracket" (not EMACS) - from IMAGEN config
- * Show the matching bracket for the character right before dot
- */
-f_matchbrack()
-{
- chroff savdot;
- register int i, mc, secs;
-
- if (exp_p)
- secs = exp;
- else
- secs = 1;
- savdot = cur_dot; /* Save our location */
- mc = e_rgetc(); /* Pick up character before dot */
- if (mc != ')' && mc != ']' && mc != '}')
- { e_getc(); /* Nothing, try at dot instead */
- e_getc();
- mc = e_rgetc();
- if (mc != ')' && mc != ']' && mc != '}')
- { ding("What bracket?");
- e_go(savdot);
- return;
- }
- }
- if (! matchonelevel(mc))
- ring_bell();
- else
- { ed_setcur();
- if (d_line(cur_dot) < 0)
- secs = 10; /* Wait longer if off-screen */
- redisplay(); /* Wish it were simple upd_wind() */
- for (i = 1; i <= secs; ++i)
- { if (tinwait())
- break;
- sleep(1);
- }
- }
- e_gosetcur(savdot); /* Back to origin */
- redp(RD_MOVE); /* Cursor has moved */
-}
-
-
-/* Try to match 'mc', return true iff found it */
-matchonelevel(mc)
-register int mc;
-{
- register int c;
-
- while ((c = e_rgetc()) != EOF)
- { if (c == /*[*/ ']' || c == /*(*/ ')' || c == /*{*/ '}')
- { if (! matchonelevel(c))
- break;
- }
- else if (c == '(' /*)*/)
- return(mc == /*(*/ ')');
- else if (c == '[' /*]*/)
- return(mc == /*[*/ ']');
- else if (c == '{' /*}*/)
- return(mc == /*{*/ '}');
- }
- return(0);
-}
-#endif /*FX_MATCHBRACK*/
+++ /dev/null
-/* ELLE - Copyright 1982, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-
-/* EEFD Display control functions
- */
-
-#include "elle.h"
-
-static void moveborder(int);
-
-
-#if FX_NEWWIN
-/* EFUN: "New Window" */
-/* Clear current window and set as requested.
- * ^L - clear current window and redisplay it (default top)
- * <arg>^L - select new window so that current line is
- * the <arg>'th from top of window (0 = top line)
- * ^U^L - clear current line and redisplay.
- */
-f_newwin()
-{ register int i, n;
- register struct window *w;
-
- d_fixcur(); /* Ensure screen vars correct */
- w = cur_win;
- if (exp_p)
- { if((n = exp) == 4 && exp_p == 4 /* CTRL-U? */
- && (i = d_line(cur_dot)) >= 0) /* On valid line? */
- { d_lupd(w, i); /* Update it */
- return;
- }
- }
- else /* No argument given */
- { redp(RD_SCREEN); /* Clear whole screen (later just window? */
-#if IMAGEN
- return;
-#else
- n = (ev_nwpct*w->w_ht)/100; /* Set new window using % */
-#endif /*-IMAGEN*/
- }
- if (n < 0) n = 0; /* Ensure # is reasonable */
- else if (n >= w->w_ht)
- n = w->w_ht - 1;
- d_fgoloff(-n); /* Go up given # of lines */
- w->w_topldot = e_dot(); /* Set new top-line dot */
- e_gocur(); /* Move back to cur_dot */
- redp(RD_FIXWIN); /* Say to re-hack window */
-}
-#endif /*FX_NEWWIN*/
-
-#if FX_NSCREEN
-/* EFUN: "Next Screen" */
-f_nscreen()
-{ d_screen( exp);
-}
-#endif /*FX_NSCREEN*/
-
-#if FX_PSCREEN
-/* EFUN: "Previous Screen" */
-f_pscreen()
-{ d_screen(-exp);
-}
-#endif /*FX_PSCREEN*/
-
-#if FX_OTHNSCREEN
-/* EFUN: "Other New Screen" (not EMACS) - from IMAGEN config */
-f_othnscreen()
-{
- if (! oth_win)
- return;
- f_othwind();
- if (exp_p) /* With arg, back up */
- d_screen(-1);
- else
- d_screen(1);
- f_othwind();
- redp(RD_WINDS); /* Look at all windows */
-}
-#endif /*FX_OTHNSCREEN*/
-
-
-#if FX_LWINDBORD
-/* EFUN: "Line to Window Border" (not EMACS) - from IMAGEN config */
-f_lwindbord()
-{
- if (exp_p)
- /* With arg, means "to bottom" */
- exp = cur_win->w_ht - 1;
- else
- /* Else, to top */
- exp = 0;
-
- /* Just a "front end" for ^L */
- exp_p = 1;
- f_newwin();
-}
-#endif /*FX_LWINDBORD*/
-
-#if FX_SCUPWIND
-/* EFUN: "Scroll Window Up" (not EMACS) - from IMAGEN config */
-f_scupwind()
-{
- scroll_win(exp);
-}
-#endif /*FX_SCUPWIND*/
-
-#if FX_SCDNWIND
-/* EFUN: "Scroll Window Down" (not EMACS) - from IMAGEN config */
-f_scdnwind()
-{
- scroll_win(-exp);
-}
-#endif /*FX_SCDNWIND*/
-
-
-#if FX_MVWTOP
-/* EFUN: "Move to Window Top" (not EMACS) - from IMAGEN config */
-f_mvwtop()
-{
- moveborder(1);
-}
-#endif /*FX_MVWTOP*/
-
-#if FX_MVWBOT
-/* EFUN: "Move to Window Bottom" (not EMACS) - from IMAGEN config */
-f_mvwbot()
-{
- moveborder(0);
-}
-#endif /*FX_MVWBOT*/
-
-
-\f
-#if FX_NSCREEN || FX_PSCREEN || FX_OTHNSCREEN
-/* Move to new loc by N screenfuls.
- * If moving downward, keep bottom 2 lines of current screen on top of next.
- * If moving up, keep top 2 lines of current screen on bottom of next.
- */
-d_screen(rep)
-int rep;
-{
- register int i;
- register struct window *w;
- chroff newdot;
-
- w = cur_win;
- if((i = w->w_ht - 2) <= 0) /* Just-in-case check */
- i = 1;
- if((i *= rep) == 0)
- return;
- d_fixcur(); /* Ensure window fixed up */
- e_go(w->w_topldot); /* Start at top of screen */
- d_fgoloff(i);
-
- /* Find where we are now, and make that the new top of window. */
- if((newdot = e_dot()) != e_blen()) /* If not at EOF, */
- w->w_topldot = newdot; /* set new top of window! */
- else w->w_topldot = 0; /* Else let fix_wind select top. */
-
- e_setcur(); /* Ensure cur_dot set to real loc */
-#if IMAGEN
- redp(RD_WINRES|RD_REDO); /* HINT: just repaint screen */
-#else
- redp(RD_FIXWIN|RD_MOVE);
-#endif /*-IMAGEN*/
-}
-#endif /*FX_NSCREEN || FX_PSCREEN || FX_OTHNSCREEN*/
-\f
-#if FX_SCUPWIND || FX_SCDNWIND /* If want scroll-window function */
-scroll_win(n)
-register int n;
-{ register struct window *w = cur_win;
- chroff savdot;
-
- if (n == 0) return;
- d_fixcur(); /* Ensure screen vars for win all set up */
- e_go(w->w_topldot); /* Go to top of current window */
- d_fgoloff(n); /* Move given # of display lines */
- w->w_topldot = e_dot(); /* Set new top of window */
- redp(RD_FIXWIN); /* Say new window needs fixing up */
-
- /* Now adjust position of current dot so it is still within window */
- if (n > 0)
- { /* Moving screen text "up" (win down) */
- if (cur_dot < w->w_topldot) /* See if scrolled off top */
- e_setcur(); /* yes, make dot be win top */
- }
- else { /* Moving screen text "down" (win up) */
- savdot = cur_dot; /* Save since must temporarily */
- e_setcur(); /* set current dot within window, */
- d_fixcur(); /* so screen can be fixed up. */
- if (inwinp(w, savdot)) /* Now see if old dot in new win */
- cur_dot = savdot; /* Yes, just restore it! */
- else /* No, make it beg of bottom line. */
- cur_dot = scr[w->w_pos + w->w_ht - 1]->sl_boff;
- }
- e_gocur(); /* Make current pos be cur_dot */
-}
-#endif /* FX_SC%%WIND */
-
-#if FX_MVWTOP || FX_MVWBOT /* Guts for above two functions */
-static void
-moveborder(top)
-int top;
-{
- d_fixcur(); /* Ensure current win screen image fixed up */
- e_gosetcur(top ? cur_win->w_topldot
- : scr[cur_win->w_pos + cur_win->w_ht - 1]->sl_boff);
-
- redp(RD_MOVE); /* Should only be cursor adjustment */
-}
-#endif /*FX_MVW%%%*/
-\f
-/* Given a line and a position in that line, return the xpos.
- * NOTE CAREFULLY that when line extends over several screen lines,
- * the value returned is the screen X position even though it
- * may be some lines down from the start of the logical line!
- * Also note this won't work very well if tabs exist on the extra
- * lines. This rtn should not be used for cursor positioning.
- * Also note: d_ncols() will never return -1 meaning EOL because the
- * setup guarantees there is no EOL within the range checked.
- */
-d_curind() /* Find current indentation */
-{ indtion(e_dot());
-}
-indtion(lin)
-chroff lin;
-{ register int i, col;
- chroff savdot;
- chroff nchars;
-
- savdot = e_dot(); /* Save current position */
- e_go(lin); /* Go to line caller wants */
- e_gobol(); /* Go to its beginning */
- col = 0; /* Start at left margin */
- if((nchars = lin - e_dot()) > 0)
- do {
- if(nchars < (i = scr_wd0))
- i = nchars;
- if((col = d_ncols(i, col)) < 0) /* Hit edge of screen? */
- col = 0; /* Reset to left margin */
- } while((nchars -= i) > 0);
- e_go(savdot); /* Restore current position */
- return(col);
-}
-
-/* ININDEX - How many positions in lin must we go to get to xpos?
- * Returns -1 if can't be done. Assumes "lin" is at beginning of a line!
- */
-
-inindex (lin, xpos)
-chroff lin;
-int xpos;
-{ register int col, x;
- chroff savdot;
- char tmp[MAXLINE+MAXCHAR];
- extern int sctreol; /* From EEDISP */
-
- if((x = xpos) <= 0) return(0);
- if(x >= MAXLINE) return(-1); /* ?!? */
- col = 0;
- savdot = e_dot();
- e_go(lin); /* Assumes this is start of line */
- col = sctrin(tmp, x, 0); /* Translate from sb_getc input */
- if((col - x) >= 0) /* Exact count-out or past it? */
- { x = e_dot() - lin; /* Yup, win. */
- if (sctreol > 0) /* Did we hit (and include) EOL? */
-#if FX_EOLMODE /* If so, back up over the EOL. */
- x -= eolcrlf(cur_buf) ? 2 : 1;
-#else
- --x;
-#endif
- }
- else x = -1; /* Nope, EOL or EOF hit too soon. */
- e_go(savdot);
- return(x);
-}
-\f
-/*
- * D_ ROUTINES - display-relative functions. Similar to E_, but
- * a "line" is defined as one line of the screen rather than
- * as a logical text line. Also, for efficiency reasons
- * arguments are given saying how many lines to hack.
- */
-
-d_gopl() { return(d_goloff(-1)); }
-d_gonl() { return(d_goloff( 1)); }
-
-/* D_GOLOFF(i) - Go to beginning of a display line
- * D_FGOLOFF(i) - ditto, but assumes screen image of window already fixed up.
- * i - # of lines offset. Negative moves up, positive down.
- * Zero arg goes to beginning of current display line.
- * Side effects: screen image of window is fixed up at
- * start of routine, but is NOT updated by the move to new location.
- */
-d_goloff(cnt)
-int cnt;
-{ d_fixcur();
- d_fgoloff(cnt); /* Now can invoke fixed-up fast version */
-}
-d_fgoloff(cnt)
-register int cnt;
-{ register int y;
- struct scr_line l;
- char line[MAXLINE+MAXCHAR];
- int top, bot;
-
- /* Find current position in window, since can save time
- * by using stuff already in fixed-up screen image.
- */
- if((y = d_line(e_dot())) < 0) /* Get current Y position */
- {
- errbarf("Dot out of window");
- y = 0;
- }
- top = cur_win->w_pos; /* 1st line of window */
- bot = top + cur_win->w_ht; /* 1st line not in window */
- l.sl_boff = scr[y]->sl_boff;
- l.sl_nlin = &line[0];
- l.sl_cont = 0;
-
- if(cnt > 0) goto down;
-
- /* Go upwards. This is hairy because we want to be clever about
- * huge logical lines -- avoid going all the way back to BOL.
- */
- if((y+cnt) >= top) /* Fits? */
- goto onscr; /* Hurray, hack it! */
- cnt += y - top; /* Sigh, find # lines to skip */
- y = top;
- l.sl_boff = scr[y]->sl_boff;
- e_go(l.sl_boff);
-
- /* Okay, here's the hairy part. Must go backwards from top
- * line; if no EOL within scr_wid*cnt chars, then simply assume one is
- * seen.
- */
- cnt = -cnt;
- d_backup(cnt);
- return; /* Really should re-adjust stuff, but... */
-
- /* Go downwards. Not too bad... */
-down:
- if((y+cnt) <= bot) /* Fits? */
- goto onscr; /* Hurray, hack it! */
- cnt -= bot - y; /* Sigh, find # lines can skip */
- y = bot - 1;
- l.sl_boff = scr[y]->sl_boff + scr[y]->sl_len;
- if(y > top
- && (l.sl_cont = scr[y-1]->sl_cont))
- l.sl_line = scr[y-1]->sl_line;
- e_go(l.sl_boff);
-
- do {
- fix_line(&l,&l);
- } while(--cnt > 0 && l.sl_len);
- return;
-
-onscr: if((y += cnt) >= bot)
- { --y;
- e_go(scr[y]->sl_boff + scr[y]->sl_len);
- }
- else e_go(scr[y]->sl_boff);
-}
-
-/* D_FIXCUR() - Ensure current window is fixed up, with
- * current location (not necessarily cur_dot)!
- * Ensure cur_dot reflects real loc so that fix_wind will work,
- * and always call fix_wind to ensure that screen image vars
- * are set properly. Note any active redisplay flags must be carried
- * on into window redisplay flags, so fix_wind will notice them.
- */
-d_fixcur()
-{ register struct window *w;
- chroff savedot;
-
- w = cur_win;
- savedot = cur_dot;
- e_setcur();
- w->w_redp |= rd_type&RDS_WINFLGS;
- fix_wind(w); /* Always ensure window is set up! */
- redp(w->w_redp); /* Add back new flags */
- rd_type &= ~RDS_DOFIX; /* and flush fix-invoking ones */
- cur_dot = savedot; /* Restore cur_dot, no longer hacked. */
-}
-\f
-d_backup(nlin) /* Try to back up by nlin screen lines */
-int nlin;
-{ register int cnt, n, c;
- int eolstop;
-
- if((cnt = nlin+1) <= 0) return;
- c = 0;
- do
- { n = scr_wid;
- eolstop = 0; /* Not yet stopped at EOL */
- do { if((c = e_rgetc()) == EOF)
- return;
- if(c == LF)
- {
-#if FX_EOLMODE
- if(eolcrlf(cur_buf))
- { if((c = e_rgetc()) == CR)
- { eolstop++;
- break;
- }
- if(c != EOF)
- e_getc();
- }
- else
-#endif
- { eolstop++;
- break;
- }
- }
- } while(--n);
- } while(--cnt);
- if(eolstop)
- {
-#if FX_EOLMODE
- if(eolcrlf(cur_buf)) e_getc(); /* Skip back over CR */
-#endif
- e_getc(); /* Skip back over LF */
- }
-
- /* At this point, dot is guaranteed to be less than goal,
- * which is the important thing for fix_wind, which can handle
- * things okay if dot is off bottom of window.
- */
- return(1); /* Say always test result */
-}
+++ /dev/null
-/* .H Function Definition file, generated by ELLEC */
-/* 0 */ EFUNHOLE /* Always undefined */
-/* 1 */ EFUN( f_insself , "f_insself" , "Insert Self")
-/* 2 */ EFUN( f_quotins , "f_quotins" , "Quoted Insert")
-/* 3 */ EFUN( f_crlf , "f_crlf" , "CRLF")
-/* 4 */ EFUN( f_fchar , "f_fchar" , "Forward Character")
-/* 5 */ EFUN( f_bchar , "f_bchar" , "Backward Character")
-/* 6 */ EFUN( f_dchar , "f_dchar" , "Delete Character")
-/* 7 */ EFUN( f_bdchar , "f_bdchar" , "Backward Delete Character")
-/* 8 */ EFUN( f_delspc , "f_delspc" , "Delete Horizontal Space")
-/* 9 */ EFUN( f_tchars , "f_tchars" , "Transpose Characters")
-/* 10 */ EFUN( f_fword , "f_fword" , "Forward Word")
-/* 11 */ EFUN( f_bword , "f_bword" , "Backward Word")
-/* 12 */ EFUN( f_kword , "f_kword" , "Kill Word")
-/* 13 */ EFUN( f_bkword , "f_bkword" , "Backward Kill Word")
-/* 14 */ EFUN( f_twords , "f_twords" , "Transpose Words")
-/* 15 */ EFUN( f_ucword , "f_ucword" , "Uppercase Word")
-/* 16 */ EFUN( f_lcword , "f_lcword" , "Lowercase Word")
-/* 17 */ EFUN( f_uciword , "f_uciword" , "Uppercase Initial")
-/* 18 */ EFUNHOLE
-/* 19 */ EFUNHOLE
-/* 20 */ EFUN( f_begline , "f_begline" , "Beginning of Line")
-/* 21 */ EFUN( f_endline , "f_endline" , "End of Line")
-/* 22 */ EFUN( f_nxtline , "f_nxtline" , "Next Line")
-/* 23 */ EFUN( f_prvline , "f_prvline" , "Previous Line")
-/* 24 */ EFUN( f_dnrline , "f_dnrline" , "Down Real Line")
-/* 25 */ EFUN( f_uprline , "f_uprline" , "Up Real Line")
-/* 26 */ EFUN( f_oline , "f_oline" , "Open Line")
-/* 27 */ EFUN( f_delblines , "f_delblines" , "Delete Blank Lines")
-/* 28 */ EFUN( f_kline , "f_kline" , "Kill Line")
-/* 29 */ EFUN( f_bkline , "f_bkline" , "Backward Kill Line")
-/* 30 */ EFUN( f_goline , "f_goline" , "Goto Line")
-/* 31 */ EFUNHOLE
-/* 32 */ EFUNHOLE
-/* 33 */ EFUNHOLE
-/* 34 */ EFUNHOLE
-/* 35 */ EFUN( f_setmark , "f_setmark" , "Set/Pop Mark")
-/* 36 */ EFUN( f_exchmark , "f_exchmark" , "Exchange Point and Mark")
-/* 37 */ EFUN( f_kregion , "f_kregion" , "Kill Region")
-/* 38 */ EFUN( f_copreg , "f_copreg" , "Copy Region")
-/* 39 */ EFUN( f_ucreg , "f_ucreg" , "Uppercase Region")
-/* 40 */ EFUN( f_lcreg , "f_lcreg" , "Lowercase Region")
-/* 41 */ EFUN( f_fillreg , "f_fillreg" , "Fill Region")
-/* 42 */ EFUNHOLE
-/* 43 */ EFUNHOLE
-/* 44 */ EFUNHOLE
-/* 45 */ EFUN( f_fpara , "f_fpara" , "Forward Paragraph")
-/* 46 */ EFUN( f_bpara , "f_bpara" , "Backward Paragraph")
-/* 47 */ EFUN( f_mrkpara , "f_mrkpara" , "Mark Paragraph")
-/* 48 */ EFUN( f_fillpara , "f_fillpara" , "Fill Paragraph")
-/* 49 */ EFUNHOLE
-/* 50 */ EFUN( f_selbuffer , "f_selbuffer" , "Select Buffer")
-/* 51 */ EFUN( f_selxbuffer, "f_selxbuffer", "Select Existing Buffer")
-/* 52 */ EFUN( f_kbuffer , "f_kbuffer" , "Kill Buffer")
-/* 53 */ EFUN( f_listbufs , "f_listbufs" , "List Buffers")
-/* 54 */ EFUN( f_bufnotmod , "f_bufnotmod" , "Buffer Not Modified")
-/* 55 */ EFUN( f_eolmode , "f_eolmode" , "EOL CRLF Mode")
-/* 56 */ EFUN( f_gobeg , "f_gobeg" , "Goto Beginning")
-/* 57 */ EFUN( f_goend , "f_goend" , "Goto End")
-/* 58 */ EFUN( f_whatpage , "f_whatpage" , "What Page")
-/* 59 */ EFUNHOLE
-/* 60 */ EFUN( f_ffile , "f_ffile" , "Find File")
-/* 61 */ EFUN( f_rfile , "f_rfile" , "Read File")
-/* 62 */ EFUN( f_vfile , "f_vfile" , "Visit File")
-/* 63 */ EFUN( f_ifile , "f_ifile" , "Insert File")
-/* 64 */ EFUN( f_sfile , "f_sfile" , "Save File")
-/* 65 */ EFUN( f_savefiles , "f_savefiles" , "Save All Files")
-/* 66 */ EFUN( f_wfile , "f_wfile" , "Write File")
-/* 67 */ EFUN( f_wreg , "f_wreg" , "Write Region")
-/* 68 */ EFUN( f_wlastkill , "f_wlastkill" , "Write Last Kill")
-/* 69 */ EFUNHOLE
-/* 70 */ EFUN( f_2winds , "f_2winds" , "Two Windows")
-/* 71 */ EFUN( f_1wind , "f_1wind" , "One Window")
-/* 72 */ EFUN( f_othwind , "f_othwind" , "Other Window")
-/* 73 */ EFUN( f_growind , "f_growind" , "Grow Window")
-/* 74 */ EFUN( f_shrinkwind, "f_shrinkwind", "Shrink Window")
-/* 75 */ EFUN( f_delwind , "f_delwind" , "Delete Window")
-/* 76 */ EFUN( f_sowind , "f_sowind" , "Standout Window")
-/* 77 */ EFUN( f_2modewinds, "f_2modewinds", "Two Mode Windows")
-/* 78 */ EFUN( f_newwin , "f_newwin" , "New Window")
-/* 79 */ EFUN( f_nscreen , "f_nscreen" , "Next Screen")
-/* 80 */ EFUN( f_pscreen , "f_pscreen" , "Previous Screen")
-/* 81 */ EFUNHOLE
-/* 82 */ EFUNHOLE
-/* 83 */ EFUN( f_scupwind , "f_scupwind" , "Scroll Window Up")
-/* 84 */ EFUN( f_scdnwind , "f_scdnwind" , "Scroll Window Down")
-/* 85 */ EFUN( f_mvwtop , "f_mvwtop" , "Move to Window Top")
-/* 86 */ EFUN( f_mvwbot , "f_mvwbot" , "Move to Window Bottom")
-/* 87 */ EFUNHOLE
-/* 88 */ EFUNHOLE
-/* 89 */ EFUNHOLE
-/* 90 */ EFUN( f_setprof , "f_setprof" , "Set Profile")
-/* 91 */ EFUN( f_pfxmeta , "f_pfxmeta" , "Prefix Meta")
-/* 92 */ EFUN( f_pfxext , "f_pfxext" , "Prefix Extend")
-/* 93 */ EFUN( f_uarg , "f_uarg" , "Universal Arg")
-/* 94 */ EFUN( f_negarg , "f_negarg" , "Negative Argument")
-/* 95 */ EFUN( f_argdig , "f_argdig" , "Argument Digit")
-/* 96 */ EFUN( f_vtbuttons , "f_vtbuttons" , "VT100 Button Hack")
-/* 97 */ EFUN( f_describe , "f_describe" , "Describe")
-/* 98 */ EFUNHOLE
-/* 99 */ EFUNHOLE
-/* 100 */ EFUN( f_skmac , "f_skmac" , "Start Kbd Macro")
-/* 101 */ EFUN( f_ekmac , "f_ekmac" , "End Kbd Macro")
-/* 102 */ EFUN( f_xkmac , "f_xkmac" , "Execute Kbd Macro")
-/* 103 */ EFUN( f_vkmac , "f_vkmac" , "View Kbd Macro")
-/* 104 */ EFUNHOLE
-/* 105 */ EFUN( f_unkill , "f_unkill" , "Un-kill")
-/* 106 */ EFUN( f_unkpop , "f_unkpop" , "Un-kill Pop")
-/* 107 */ EFUN( f_appnkill , "f_appnkill" , "Append Next Kill")
-/* 108 */ EFUNHOLE
-/* 109 */ EFUNHOLE
-/* 110 */ EFUN( f_srch , "f_srch" , "String Search")
-/* 111 */ EFUN( f_rsrch , "f_rsrch" , "Reverse String Search")
-/* 112 */ EFUN( f_isrch , "f_isrch" , "Incremental Search")
-/* 113 */ EFUN( f_risrch , "f_risrch" , "Reverse Search")
-/* 114 */ EFUN( f_repstr , "f_repstr" , "Replace String")
-/* 115 */ EFUN( f_querep , "f_querep" , "Query Replace")
-/* 116 */ EFUN( f_repline , "f_repline" , "Replace in Line")
-/* 117 */ EFUN( f_sfcol , "f_sfcol" , "Set Fill Column")
-/* 118 */ EFUN( f_sfpref , "f_sfpref" , "Set Fill Prefix")
-/* 119 */ EFUN( f_fillmode , "f_fillmode" , "Auto Fill Mode")
-/* 120 */ EFUNHOLE
-/* 121 */ EFUN( f_indatm , "f_indatm" , "Indent According to Mode")
-/* 122 */ EFUN( f_indnl , "f_indnl" , "Indent New Line")
-/* 123 */ EFUN( f_backind , "f_backind" , "Back to Indentation")
-/* 124 */ EFUN( f_indcomm , "f_indcomm" , "Indent for Comment")
-/* 125 */ EFUN( f_indrel , "f_indrel" , "Indent Relative")
-/* 126 */ EFUNHOLE
-/* 127 */ EFUNHOLE
-/* 128 */ EFUNHOLE
-/* 129 */ EFUNHOLE
-/* 130 */ EFUN( f_pshinf , "f_pshinf" , "Push to Inferior")
-/* 131 */ EFUN( f_retsup , "f_retsup" , "Return to Superior")
-/* 132 */ EFUN( f_wfexit , "f_wfexit" , "Write File Exit")
-/* 133 */ EFUNHOLE
-/* 134 */ EFUNHOLE
-/* 135 */ EFUNHOLE
-/* 136 */ EFUNHOLE
-/* 137 */ EFUNHOLE
-/* 138 */ EFUNHOLE
-/* 139 */ EFUNHOLE
-/* 140 */ EFUN( f_bkpt , "f_bkpt" , "Hit Breakpoint")
-/* 141 */ EFUN( f_debug , "f_debug" , "Debug Mode")
-/* 142 */ EFUNHOLE
-/* 143 */ EFUNHOLE
-/* 144 */ EFUNHOLE
-/* 145 */ EFUNHOLE
-/* 146 */ EFUNHOLE
-/* 147 */ EFUNHOLE
-/* 148 */ EFUNHOLE
-/* 149 */ EFUNHOLE
-/* 150 */ EFUNHOLE
-/* 151 */ EFUNHOLE
-/* 152 */ EFUNHOLE
-/* 153 */ EFUNHOLE
-/* 154 */ EFUNHOLE
-/* 155 */ EFUNHOLE
-/* 156 */ EFUNHOLE
-/* 157 */ EFUNHOLE
+++ /dev/null
-/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/* EEFED - ED-type functions
- */
-#include "elle.h"
-
-/*
- * ED_INSERT -- Insert character given as argument.
- */
-
-ed_insert(c)
-int c;
-{ register SBBUF *sb;
-
- sb = (SBBUF *) cur_buf; /* For a little speed */
- sb_putc(sb,c); /* Insert the char */
- cur_dot++; /* Advance dot */
- buf_tmod((chroff)-1); /* Mark buffer modified, for redisplay etc. */
- /* Perhaps later use specialized routine? */
-}
-
-ed_insn(ch, cnt)
-int ch, cnt;
-{ register int i;
- if((i = cnt) > 0)
- do { ed_insert(ch);
- } while(--i);
-}
-
-ed_crins()
-{
-#if FX_EOLMODE
- if (eolcrlf(cur_buf)) /* If EOL is made of CR-LF */
- ed_insert(CR); /* then first insert CR, then drop down to */
-#endif
- ed_insert(LF); /* Insert LF */
-}
-
-
-ed_sins (s) /* insert this string */
-register char *s;
-{ register c;
- while (c = *s++)
- ed_insert (c);
-}
-
-ed_nsins (s, i) /* Insert string of N chars */
-register char *s;
-register int i;
-{ if(i > 0)
- do { ed_insert(*s++); } while(--i);
-}
-
-/* ED_INDTO(col) - Indent to specified column.
-** Finds current cursor position, and inserts tabs and spaces
-** so cursor ends up at column goal. Does nothing if already at or past
-** specified column.
-*/
-
-ed_indto(goal)
-register int goal;
-{ register int ng;
-
- ng = goal & ~07; /* Get distance to tab stop */
- ed_insn(TAB, ((ng - (d_curind() & ~07)) >> 3));
- ed_insn(SP, goal-ng);
-}
-\f
-/* Oddball routine - Set cur_dot to actual I/O location and
- * tell display that cursor probably moved. This is not really a
- * function of itself; it provides support for real functions.
- */
-ed_setcur()
-{ e_setcur(); /* Set cur_dot */
- redp(RD_MOVE); /* Alert redisplay to check cursor loc */
-}
-
-/* Go to given dot */
-ed_go (dot)
-chroff dot;
-{ e_go(dot);
- ed_setcur();
-}
-
-/* Go to given offset from current location */
-ed_goff(off)
-chroff off;
-{ e_goff(off);
- ed_setcur();
-}
-
-/* Go to given INTEGER offset from current location */
-ed_igoff(ioff)
-int ioff;
-{ e_igoff(ioff);
- ed_setcur();
-}
-
-/* Reset (delete all of) Buffer
- * Should buffer be marked modified or not? Currently isn't.
- */
-ed_reset()
-{ if(e_blen() == 0)
- return; /* Already empty */
- e_reset();
- cur_dot = 0;
- cur_win->w_topldot = 0; /* Is this necessary? */
-#if IMAGEN
- redp(RD_WINRES|RD_REDO);
-#else
- redp(RD_WINRES); /* This window needs complete update */
-#endif /*-IMAGEN*/
-
-/* buf_mod(); */ /* Mark modified ?? */
-/* mark_p = 0; */ /* Say no mark set ?? */
-}
-
-ed_deln(off)
-chroff off;
-{ chroff dot;
- dot = e_dot();
- e_goff(off);
- ed_delete(e_dot(), dot);
-}
-
-/* ED_DELETE(dot1,dot2) - Delete all characters between the two
- * positions indicated by dot1 and dot2. Their order does not
- * matter; cur_dot and mark_dot are updated as necessary.
- */
-ed_delete(dot1,dot2)
-chroff dot1,dot2;
-{ chroff tmpdot, savdot;
-
- if(dot1 > dot2)
- { tmpdot = dot1;
- dot1 = dot2;
- dot2 = tmpdot;
- }
- e_go(dot1);
- tmpdot = dot2-dot1;
- sb_deln((SBBUF *)cur_buf,tmpdot);
-
- savdot = cur_dot; /* Save cur_dot value */
- cur_dot = dot1; /* so can set up for */
- buf_tmod((chroff)0); /* call to update disp-change vars */
- cur_dot = savdot;
-
- if(cur_dot >= dot2)
- cur_dot -= tmpdot;
- else if(cur_dot > dot1)
- cur_dot = dot1;
- if(mark_dot >= dot2)
- mark_dot -= tmpdot;
- else if(mark_dot > dot1)
- mark_dot = dot1;
- e_gocur();
-}
-
-/* ED_KILL(dot1,dot2) - Kill (save and delete) text between two places in
- * the buffer.
- * We assume we are deleting from dot1 to dot2, thus if dot1 > dot2
- * then backwards deletion is implied, and the saved text is prefixed
- * (instead of appended) to any previously killed text.
- */
-ed_kill(dot1,dot2)
-chroff dot1,dot2;
-{ register SBSTR *sd, *sdo;
- SBSTR *e_copyn();
-
- e_go(dot1);
- sd = e_copyn(dot2-dot1);
- if(sd == 0) return;
- if(last_cmd == KILLCMD && (sdo = kill_ring[kill_ptr]))
- { if(dot1 > dot2) /* Prefix new killed stuff onto old stuff */
- { sbs_app(sd,sdo);
- kill_ring[kill_ptr] = sd;
- }
- else /* Append new stuff to old stuff */
- sbs_app(sdo,sd);
- }
- else kill_push(sd);
- ed_delete(dot1,dot2);
-}
-
-kill_push(sdp)
-SBSTR *sdp;
-{ register SBSTR *sd;
-
- if(++kill_ptr >= KILL_LEN) kill_ptr = 0;
- if(sd = kill_ring[kill_ptr])
- sbs_del(sd);
- kill_ring[kill_ptr] = sdp;
-}
-\f
-
-#define isupper(c) (('A' <= c) && (c <= 'Z'))
-#define islower(c) (('a' <= c) && (c <= 'z'))
-#define toupper(c) (c + ('A' - 'a'))
-#define tolower(c) (c + ('a' - 'A'))
-
-#if FX_UCWORD||FX_LCWORD||FX_UCIWORD||FX_UCREG||FX_LCREG
-
-/* ED_CASE(dot1,dot2,downp) - Change the case within a region.
- * downp = 0 for uppercase, 1 for lowercase, 2 for capitalize.
- */
-ed_case(dot1, dot2, downp)
-chroff dot1, dot2;
-int downp;
-{ chroff dcnt;
- register int c, a, z;
- int modflg;
-
- modflg = 0;
- if((dcnt = dot2 - dot1) < 0)
- { dcnt = dot1;
- dot1 = dot2;
- dot2 = dcnt;
- dcnt -= dot1;
- }
- e_go(dot1);
-
- if(downp==2)
- { a = 0; /* 0 looking for wd, 1 in word */
- while(--dcnt >= 0)
- { if(delimp(c = e_getc())) /* Char in wd? */
- { a = 0; /* No */
- continue;
- }
- if(a) /* If already inside word */
- { if(isupper(c))
- c = tolower(c);
- else continue;
- }
- else /* If encountered start of word */
- { a = 1;
- if(islower(c))
- c = toupper(c);
- else continue;
- }
- e_backc();
- e_ovwc(c);
- modflg++;
- }
- goto casdon;
- }
- if(downp==0)
- { a = 'a'; /* Convert to lower case */
- z = 'z';
- downp = -040;
- }
- else
- { a = 'A'; /* Convert to upper case */
- z = 'Z';
- downp = 040;
- }
- while(--dcnt >= 0)
- { if(a <= (c = e_getc()) && c <= z)
- { e_backc();
- e_ovwc(c+downp);
- modflg++;
- }
- }
-
-casdon: dot2 = cur_dot; /* Save dot */
- e_setcur(); /* Set up for modification range chk*/
- if(modflg)
- buf_tmat(dot1); /* Stuff munged from there to here */
- ed_go(dot2);
-}
-#endif /* any ed_case caller */
-
-
-/* UPCASE(c) - Return upper-case version of character */
-upcase(ch)
-int ch;
-{ register int c;
- c = ch&0177;
- return(islower(c) ? toupper(c) : c);
-}
-
+++ /dev/null
-/* .H Function Index Definition file, generated by ELLEC */
-/* FN_ defines Function Numbers (indices) for all known functions */
-/* FX_ defines Function eXistence in this ELLE configuration */
-#define FN_INSSELF 1 /* Insert Self */
-#define FX_INSSELF 1
-#define FN_QUOTINS 2 /* Quoted Insert */
-#define FX_QUOTINS 2
-#define FN_CRLF 3 /* CRLF */
-#define FX_CRLF 3
-#define FN_FCHAR 4 /* Forward Character */
-#define FX_FCHAR 4
-#define FN_BCHAR 5 /* Backward Character */
-#define FX_BCHAR 5
-#define FN_DCHAR 6 /* Delete Character */
-#define FX_DCHAR 6
-#define FN_BDCHAR 7 /* Backward Delete Character */
-#define FX_BDCHAR 7
-#define FN_DELSPC 8 /* Delete Horizontal Space */
-#define FX_DELSPC 8
-#define FN_TCHARS 9 /* Transpose Characters */
-#define FX_TCHARS 9
-#define FN_FWORD 10 /* Forward Word */
-#define FX_FWORD 10
-#define FN_BWORD 11 /* Backward Word */
-#define FX_BWORD 11
-#define FN_KWORD 12 /* Kill Word */
-#define FX_KWORD 12
-#define FN_BKWORD 13 /* Backward Kill Word */
-#define FX_BKWORD 13
-#define FN_TWORDS 14 /* Transpose Words */
-#define FX_TWORDS 14
-#define FN_UCWORD 15 /* Uppercase Word */
-#define FX_UCWORD 15
-#define FN_LCWORD 16 /* Lowercase Word */
-#define FX_LCWORD 16
-#define FN_UCIWORD 17 /* Uppercase Initial */
-#define FX_UCIWORD 17
-#define FN_BEGLINE 20 /* Beginning of Line */
-#define FX_BEGLINE 20
-#define FN_ENDLINE 21 /* End of Line */
-#define FX_ENDLINE 21
-#define FN_NXTLINE 22 /* Next Line */
-#define FX_NXTLINE 22
-#define FN_PRVLINE 23 /* Previous Line */
-#define FX_PRVLINE 23
-#define FN_DNRLINE 24 /* Down Real Line */
-#define FX_DNRLINE 24
-#define FN_UPRLINE 25 /* Up Real Line */
-#define FX_UPRLINE 25
-#define FN_OLINE 26 /* Open Line */
-#define FX_OLINE 26
-#define FN_DELBLINES 27 /* Delete Blank Lines */
-#define FX_DELBLINES 27
-#define FN_KLINE 28 /* Kill Line */
-#define FX_KLINE 28
-#define FN_BKLINE 29 /* Backward Kill Line */
-#define FX_BKLINE 29
-#define FN_GOLINE 30 /* Goto Line */
-#define FX_GOLINE 30
-#define FN_SETMARK 35 /* Set/Pop Mark */
-#define FX_SETMARK 35
-#define FN_EXCHMARK 36 /* Exchange Point and Mark */
-#define FX_EXCHMARK 36
-#define FN_KREGION 37 /* Kill Region */
-#define FX_KREGION 37
-#define FN_COPREG 38 /* Copy Region */
-#define FX_COPREG 38
-#define FN_UCREG 39 /* Uppercase Region */
-#define FX_UCREG 39
-#define FN_LCREG 40 /* Lowercase Region */
-#define FX_LCREG 40
-#define FN_FILLREG 41 /* Fill Region */
-#define FX_FILLREG 41
-#define FN_FPARA 45 /* Forward Paragraph */
-#define FX_FPARA 45
-#define FN_BPARA 46 /* Backward Paragraph */
-#define FX_BPARA 46
-#define FN_MRKPARA 47 /* Mark Paragraph */
-#define FX_MRKPARA 47
-#define FN_FILLPARA 48 /* Fill Paragraph */
-#define FX_FILLPARA 48
-#define FN_SELBUFFER 50 /* Select Buffer */
-#define FX_SELBUFFER 50
-#define FN_SELXBUFFER 51 /* Select Existing Buffer */
-#define FX_SELXBUFFER 51
-#define FN_KBUFFER 52 /* Kill Buffer */
-#define FX_KBUFFER 52
-#define FN_LISTBUFS 53 /* List Buffers */
-#define FX_LISTBUFS 53
-#define FN_BUFNOTMOD 54 /* Buffer Not Modified */
-#define FX_BUFNOTMOD 54
-#define FN_EOLMODE 55 /* EOL CRLF Mode */
-#define FX_EOLMODE 55
-#define FN_GOBEG 56 /* Goto Beginning */
-#define FX_GOBEG 56
-#define FN_GOEND 57 /* Goto End */
-#define FX_GOEND 57
-#define FN_WHATPAGE 58 /* What Page */
-#define FX_WHATPAGE 58
-#define FN_FFILE 60 /* Find File */
-#define FX_FFILE 60
-#define FN_RFILE 61 /* Read File */
-#define FX_RFILE 61
-#define FN_VFILE 62 /* Visit File */
-#define FX_VFILE 62
-#define FN_IFILE 63 /* Insert File */
-#define FX_IFILE 63
-#define FN_SFILE 64 /* Save File */
-#define FX_SFILE 64
-#define FN_SAVEFILES 65 /* Save All Files */
-#define FX_SAVEFILES 65
-#define FN_WFILE 66 /* Write File */
-#define FX_WFILE 66
-#define FN_WREG 67 /* Write Region */
-#define FX_WREG 67
-#define FN_WLASTKILL 68 /* Write Last Kill */
-#define FX_WLASTKILL 68
-#define FN_2WINDS 70 /* Two Windows */
-#define FX_2WINDS 70
-#define FN_1WIND 71 /* One Window */
-#define FX_1WIND 71
-#define FN_OTHWIND 72 /* Other Window */
-#define FX_OTHWIND 72
-#define FN_GROWIND 73 /* Grow Window */
-#define FX_GROWIND 73
-#define FN_SHRINKWIND 74 /* Shrink Window */
-#define FX_SHRINKWIND 74
-#define FN_DELWIND 75 /* Delete Window */
-#define FX_DELWIND 75
-#define FN_SOWIND 76 /* Standout Window */
-#define FX_SOWIND 76
-#define FN_2MODEWINDS 77 /* Two Mode Windows */
-#define FX_2MODEWINDS 77
-#define FN_NEWWIN 78 /* New Window */
-#define FX_NEWWIN 78
-#define FN_NSCREEN 79 /* Next Screen */
-#define FX_NSCREEN 79
-#define FN_PSCREEN 80 /* Previous Screen */
-#define FX_PSCREEN 80
-#define FN_OTHNSCREEN 81 /* Other New Screen */
-#define FX_OTHNSCREEN 0
-#define FN_LWINDBORD 82 /* Line to Window Border */
-#define FX_LWINDBORD 0
-#define FN_SCUPWIND 83 /* Scroll Window Up */
-#define FX_SCUPWIND 83
-#define FN_SCDNWIND 84 /* Scroll Window Down */
-#define FX_SCDNWIND 84
-#define FN_MVWTOP 85 /* Move to Window Top */
-#define FX_MVWTOP 85
-#define FN_MVWBOT 86 /* Move to Window Bottom */
-#define FX_MVWBOT 86
-#define FN_SETPROF 90 /* Set Profile */
-#define FX_SETPROF 90
-#define FN_PFXMETA 91 /* Prefix Meta */
-#define FX_PFXMETA 91
-#define FN_PFXEXT 92 /* Prefix Extend */
-#define FX_PFXEXT 92
-#define FN_UARG 93 /* Universal Arg */
-#define FX_UARG 93
-#define FN_NEGARG 94 /* Negative Argument */
-#define FX_NEGARG 94
-#define FN_ARGDIG 95 /* Argument Digit */
-#define FX_ARGDIG 95
-#define FN_VTBUTTONS 96 /* VT100 Button Hack */
-#define FX_VTBUTTONS 96
-#define FN_DESCRIBE 97 /* Describe */
-#define FX_DESCRIBE 97
-#define FN_SKMAC 100 /* Start Kbd Macro */
-#define FX_SKMAC 100
-#define FN_EKMAC 101 /* End Kbd Macro */
-#define FX_EKMAC 101
-#define FN_XKMAC 102 /* Execute Kbd Macro */
-#define FX_XKMAC 102
-#define FN_VKMAC 103 /* View Kbd Macro */
-#define FX_VKMAC 103
-#define FN_UNKILL 105 /* Un-kill */
-#define FX_UNKILL 105
-#define FN_UNKPOP 106 /* Un-kill Pop */
-#define FX_UNKPOP 106
-#define FN_APPNKILL 107 /* Append Next Kill */
-#define FX_APPNKILL 107
-#define FN_SRCH 110 /* String Search */
-#define FX_SRCH 110
-#define FN_RSRCH 111 /* Reverse String Search */
-#define FX_RSRCH 111
-#define FN_ISRCH 112 /* Incremental Search */
-#define FX_ISRCH 112
-#define FN_RISRCH 113 /* Reverse Search */
-#define FX_RISRCH 113
-#define FN_REPSTR 114 /* Replace String */
-#define FX_REPSTR 114
-#define FN_QUEREP 115 /* Query Replace */
-#define FX_QUEREP 115
-#define FN_REPLINE 116 /* Replace in Line */
-#define FX_REPLINE 116
-#define FN_SFCOL 117 /* Set Fill Column */
-#define FX_SFCOL 117
-#define FN_SFPREF 118 /* Set Fill Prefix */
-#define FX_SFPREF 118
-#define FN_FILLMODE 119 /* Auto Fill Mode */
-#define FX_FILLMODE 119
-#define FN_TEXTMODE 120 /* Text Mode */
-#define FX_TEXTMODE 0
-#define FN_INDATM 121 /* Indent According to Mode */
-#define FX_INDATM 121
-#define FN_INDNL 122 /* Indent New Line */
-#define FX_INDNL 122
-#define FN_BACKIND 123 /* Back to Indentation */
-#define FX_BACKIND 123
-#define FN_INDCOMM 124 /* Indent for Comment */
-#define FX_INDCOMM 124
-#define FN_INDREL 125 /* Indent Relative */
-#define FX_INDREL 125
-#define FN_MATCHBRACK 129 /* Match Bracket */
-#define FX_MATCHBRACK 0
-#define FN_PSHINF 130 /* Push to Inferior */
-#define FX_PSHINF 130
-#define FN_RETSUP 131 /* Return to Superior */
-#define FX_RETSUP 131
-#define FN_WFEXIT 132 /* Write File Exit */
-#define FX_WFEXIT 132
-#define FN_BKPT 140 /* Hit Breakpoint */
-#define FX_BKPT 140
-#define FN_DEBUG 141 /* Debug Mode */
-#define FX_DEBUG 141
-#define FN_XUCMD 150 /* Execute Unix Command */
-#define FX_XUCMD 0
-#define FN_MAKE 151 /* Execute Make */
-#define FX_MAKE 0
-#define FN_NXTERR 152 /* Find Next Error */
-#define FX_NXTERR 0
-#define FN_ICOXCMD 153 /* ICO Extend Command */
-#define FX_ICOXCMD 0
-#define FN_ICOTYPFNS 154 /* ICO Typeset Funs */
-#define FX_ICOTYPFNS 0
-#define FN_ICOSPIFNS 155 /* ICO Spec Input Funs */
-#define FX_ICOSPIFNS 0
-#define FN_STUFFSEL 156 /* Stuff Selection */
-#define FX_STUFFSEL 0
-#define FN_SELREGION 157 /* Select Region */
-#define FX_SELREGION 0
+++ /dev/null
-/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/*
- * EEFILE File reading/writing functions
- */
-
-#include "elle.h"
-#include <stdio.h> /* Use "standard" I/O package for writing */
-#ifndef BUFSIZ
-#define BUFSIZ BUFSIZE /* Some places use wrong name in stdio.h */
-#endif /*-BUFSIZ*/
-#if V6
- struct stat {
- int st_dev;
- int st_ino;
- char *st_mode;
- char st_nlink;
- char st_uid;
- char st_gid;
- char st_size0;
- char st_size;
- int st_addr[8];
- long st_atime;
- long st_mtime;
- };
-#define ENOENT (2) /* Syscall error - no such file or dir */
-#else
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#endif /*-V6*/
-
-#if TOPS20
-#include <sys/file.h> /* Get open mode bits */
-#endif
-
-extern char *strerror(); /* Return error string for errno */
-extern struct buffer *make_buf(), *find_buf();
-
-char *fncons(), *last_fname();
-
-int hoardfd = -1; /* Retain a FD here to ensure we can always write */
-
-/* Flags for iwritfile() */
-#define WF_SMASK 07 /* Source Mask */
-#define WF_SBUFF 0 /* source: Buffer */
-#define WF_SREG 1 /* source: Region */
-#define WF_SKILL 2 /* source: Last Kill */
-#define WF_ASK 010 /* Ask for filename to write to */
-static int iwritfile();
-\f
-/* EFUN: "Find File" */
-/* Ask user for a filename and do a find_file for it.
- * If buffer exists for that filename, select that buffer.
- * Else create a buffer for it, and read in the file if it exists.
- */
-f_ffile()
-{ int find_file();
-#if IMAGEN
- hack_file("Visit file: ", find_file);
-#else
- hack_file("Find file: ", find_file);
-#endif /*-IMAGEN*/
-}
-
-/* EFUN: "Read File" */
-/* User read_file function, asks user for a filename and reads it
- */
-f_rfile() { u_r_file("Read file: "); }
-
-/* EFUN: "Visit File" */
-/* Same as Read File, with different prompt.
- */
-f_vfile() { u_r_file("Visit file: "); }
-
-
-u_r_file(prompt)
-char *prompt;
-{ register char *f_name;
- register struct buffer *b;
-
- if((f_name = ask (prompt))==0) /* prompt user for filename */
- return; /* user punted... */
- b = cur_buf;
- if(*f_name == '\0')
- { if (b -> b_fn == 0)
- ding("No default file name.");
- else read_file(b -> b_fn);
- }
- else read_file(f_name);
- chkfree(f_name);
-}
-
-/* EFUN: "Insert File" */
-/* Asks for a filename and inserts the file at current location.
- * Point is left at beginning, and the mark at the end.
- */
-f_ifile()
-{ int ins_file();
- hack_file("Insert file: ", ins_file);
-}
-\f
-/* EFUN: "Save File" */
-/* Save current buffer to its default file name
- */
-f_sfile()
-{ if(cur_buf->b_flags&B_MODIFIED)
- return(iwritfile(WF_SBUFF)); /* Write buffer, don't ask */
- else
- { saynow("(No changes need to be written)");
- return(1);
- }
-}
-
-#if FX_SAVEFILES || FX_WFEXIT
-/* EFUN: "Save All Files" */
-/* F_SAVEFILES - Offer to save all modified files.
- * With argument, doesn't ask.
- * Returns 0 if user aborts or if an error happened.
- */
-f_savefiles()
-{ register struct buffer *b, *savb;
- register int res = 1;
- char *ans;
-
- savb = cur_buf;
- for (b = buf_head; res && b; b = b->b_next)
- if ((b->b_flags & B_MODIFIED) && b->b_fn)
- { if(exp_p) /* If arg, */
- { chg_buf(b); /* just save, don't ask */
- res = f_sfile();
- continue; /* Check next buffer */
- }
- /* Ask user whether to save */
- ans = ask("Buffer %s contains changes - write out? ",
- b->b_name);
- if(ans == 0)
- { res = 0; /* User aborted */
- break;
- }
- if (upcase(*ans) == 'Y')
- { chg_buf(b);
- res = f_sfile(); /* Save File */
- }
- chkfree(ans);
- }
- chg_buf(savb);
- return(res);
-}
-#endif /*FX_SAVEFILES||FX_WFEXIT*/
-\f
-/* EFUN: "Write File" */
-/* Write out the buffer to an output file.
- */
-f_wfile()
-{ return iwritfile(WF_ASK|WF_SBUFF);
-}
-
-/* EFUN: "Write Region" */
-/* Write region out to a file
- */
-f_wreg()
-{ return iwritfile(WF_ASK|WF_SREG); /* Ask, write region */
-}
-
-#if FX_WLASTKILL
-/* EFUN: "Write Last Kill" (not EMACS) */
-/* Write current kill buffer out to a file.
-** This is mainly for MINIX.
-*/
-extern int kill_ptr; /* From EEF3 */
-extern SBSTR *kill_ring[];
-
-f_wlastkill()
-{ return iwritfile(WF_ASK|WF_SKILL);
-}
-#endif
-\f
-
-/* HACK_FILE - intermediate subroutine
- */
-hack_file(prompt, rtn)
-char *prompt;
-int (*rtn)();
-{ register char *f_name;
-
- if((f_name = ask(prompt)) == 0)
- return;
- if (*f_name != '\0') /* Check for null answer */
- (*rtn)(f_name);
- chkfree(f_name);
-}
-
-/* FIND_FILE(f_name)
- * If there is a buffer whose fn == f_name, select that buffer.
- * Else create one with name of the last section of f_name and
- * read the file into that buffer.
- */
-find_file(f_name)
-register char *f_name;
-{ register struct buffer *b;
- register char *ans;
- char *lastn;
- int fd;
-
-#if IMAGEN
- char real_name[128]; /* File name w/ expanded ~ and $ */
- expand_file(real_name, f_name);
- f_name = real_name;
-#endif /*IMAGEN*/
-
- for (b = buf_head; b; b = b -> b_next)
- if(b->b_fn && (strcmp (b -> b_fn, f_name) == 0))
- break;
- if (b) /* if we found one */
- { sel_buf(b); /* go there */
- return; /* and we are done */
- }
- if((fd = open(f_name,0)) < 0) /* See if file exists */
- { if(errno != ENOENT) /* No, check reason */
- { ferr_ropn(); /* Strange error, complain */
- return; /* and do nothing else. */
- }
- }
- else close(fd); /* Found! Close FD, since the */
- /* read_file rtn will re-open. */
-
- lastn = last_fname(f_name); /* Find buffer name */
- b = find_buf(lastn); /* Is there a buffer of that name? */
- if (b && (ex_blen(b) || b->b_fn))
- { ans = ask("Buffer %s contains %s, which buffer shall I use? ",
- b -> b_name, b->b_fn ? b->b_fn : "something");
- if(ans == 0) return; /* Aborted */
- if (*ans != '\0') /* if null answer, use b */
- b = make_buf(ans); /* else use ans */
- chkfree(ans);
- }
- else
- b = make_buf(lastn);
- sel_buf(b);
- if(fd < 0) /* If file doesn't exist, */
- { set_fn(f_name); /* just say "new" and set filename */
- return; /* and return right away. */
- }
- if (read_file(f_name)==0) /* File exists, read it in! */
- { if(b->b_fn) /* Failed... if filename, */
- { chkfree(b->b_fn); /* flush the filename. */
- b->b_fn = 0;
- }
- }
-}
-
-/* READ_FILE(f_name)
- * Reads file into current buffer, flushing any
- * previous contents (if buffer modified, will ask about saving)
- * Returns 0 if failed.
- */
-read_file(f_name)
-char *f_name;
-{
-#if IMAGEN
- struct stat s;
- char real_name[128]; /* File name w/ expanded ~ and $ */
-#endif /*IMAGEN*/
-
- if(!zap_buffer()) /* Flush the whole buffer */
- return; /* Unless user aborts */
-#if IMAGEN
- expand_file(real_name, f_name);
- f_name = real_name; /* Hack, hack! */
-#endif /*IMAGEN*/
- set_fn(f_name);
- if (ins_file(f_name)==0)
- return 0;
- f_bufnotmod(); /* Say not modified now */
-#if IMAGEN
- stat(f_name, &s); /* Get file stat */
- cur_buf->b_mtime = s.st_mtime; /* and pick out last-modified time */
-#endif /*IMAGEN*/
- return 1;
-}
-
-/* INS_FILE(f_name)
- * Inserts file named f_name into current buffer at current point
- * Point is not moved; mark is set to end of inserted stuff.
- * Returns 0 if failed, 1 if won.
- */
-ins_file (f_name)
-char *f_name;
-{ register int ifd;
- register SBSTR *sd;
- chroff insdot; /* To check for range of mods */
-
-#if IMAGEN
- char real_name[128]; /* File name w/ expanded ~ and $ */
- expand_file(real_name, f_name);
- f_name = real_name;
-#endif /*IMAGEN*/
-#if !(TOPS20)
- if((ifd = open(f_name,0)) < 0)
-#else
- if((ifd = open(f_name,O_RDONLY|O_UNCONVERTED)) < 0)
-#endif /*TOPS20*/
- { ferr_ropn(); /* Can't open, complain */
- return 0; /* no redisplay */
- }
- errno = 0;
- if((sd = sb_fduse(ifd)) == 0)
- { if (ifd >= SB_NFILES)
- dingtoo(" Cannot read - too many internal files");
- else if (errno)
- ferr_ropn();
- else errbarf("SB rtn cannot read file?");
- close(ifd);
- return 0;
- }
- sb_sins(cur_buf,sd);
- insdot = e_dot();
- f_setmark(); /* Set mark at current ptr */
- if(cur_dot != insdot) /* If pointer was advanced, */
- buf_tmat(insdot); /* then stuff was inserted */
- e_gocur();
- return 1;
-}
-
-ferr_ropn() { ferr(" Cannot read"); }
-ferr_wopn() { ferr(" Cannot write"); }
-ferr(str)
-char *str;
-{ saytoo(str);
- saytoo(" - ");
- dingtoo(strerror(errno));
-}
-\f
-
-/* IWRITFILE - auxiliary for writing files.
-** Returns 1 if write successful, 0 if not.
-*/
-static int
-iwritfile(flags)
-int flags;
-{ register struct buffer *b;
- register char *o_name; /* output file name */
- int styp = flags & WF_SMASK; /* Source type, one of WF_Sxxx */
- char *prompt;
-#ifdef STDWRITE
- register FILE *o_file; /* output file pointer */
- char obuf[BUFSIZ];
- chroff dotcnt;
-#endif /*STDWRITE*/
- int ofd; /* output file FD */
- SBSTR *sd;
- char fname[FNAMSIZ]; /* To avoid chkfree hassle */
- char newname[FNAMSIZ]; /* for robustness */
- char oldname[FNAMSIZ]; /* ditto */
- int res;
- struct stat statb;
- int statres;
-#if IMAGEN
- struct stat s;
- char real_name[128]; /* File name w/ expanded ~ and $ */
-#endif /*IMAGEN*/
- res = 1; /* Let's keep track of success */
-
- /* Check for existence of source, and set prompt string */
- switch(styp)
- {
- case WF_SBUFF:
- prompt = "Write File: ";
- break;
- case WF_SREG:
- if(!mark_p)
- { dingtoo(" No Mark!");
- return(0);
- }
- prompt = "Write Region: ";
- break;
-#if FX_WLASTKILL
- case WF_SKILL:
- if(!kill_ring[kill_ptr])
- { dingtoo("No killed stuff");
- return(0);
- }
- prompt = "Write Last Kill: ";
- break;
-#endif
- default: /* Internal error */
- errbarf("bad iwritfile arg");
- return 0;
- }
-
- if (flags&WF_ASK)
- { if((o_name = ask(prompt))==0)
- return(0); /* User punted. */
- strcpy(&fname[0], o_name); /* Copy filename onto stack */
- chkfree(o_name);
- }
- o_name = &fname[0];
- b = cur_buf;
- if (!(flags&WF_ASK) || (*o_name == '\0'))
- { if (b->b_fn == 0)
- { ding("No default file name.");
- return(0);
- }
- strcpy(o_name, b->b_fn);
- }
-
-#if IMAGEN
- expand_file(real_name, o_name);
- o_name = real_name; /* Hack, hack */
-#endif /*IMAGEN*/
-
- statres = stat(o_name,&statb); /* Get old file's info (if any) */
-
-#if IMAGEN
- /* Now, make sure someone hasn't written the file behind our backs */
- if ((styp==WF_SBUFF) && !(flags&WF_ASK)
- && b->b_fn && stat(b->b_fn, &s) >= 0)
- if (s.st_mtime != b->b_mtime)
- { char *ans;
- ans = ask("Since you last read \"%s\", someone has changed it.\nDo you want to write it anyway (NOT RECOMMENDED!)? ",
- b->b_fn);
- if (ans == 0 || upcase(*ans) != 'Y')
- {
- ding("I suggest you either read it again, or\nwrite it to a temporary file, and merge the two versions manually.");
- if (ans) chkfree(ans);
- return(0);
- }
- if (ans) chkfree(ans);
- }
-#endif /*IMAGEN*/
-
- /* Try to get around major UNIX screw of smashing files.
- * This still isn't perfect (screws up with long filenames) but...
- * 1. Write out to <newname>
- * 2. Rename <name> to <oldname> (may have to delete existing <oldname>)
- * 3. Rename <newname> to <name>.
- */
- fncons(oldname,ev_fno1,o_name,ev_fno2); /* Set up "old" filename */
- fncons(newname,ev_fnn1,o_name,ev_fnn2); /* Set up "new" filename */
- unlink(newname); /* Ensure we don't clobber */
- unhoard(); /* Now give up saved FD */
-#if !(V6) /* Standard V6 doesn't have access call */
- if(statres >= 0) /* If file exists, */
- { if(access(o_name, 2) != 0) /* check for write access */
- { ferr_wopn();
- res = 0; /* Failure */
- goto wdone;
- }
- }
-#endif /*-V6*/
-#ifdef STDWRITE
- if(flags&WF_ASK)
- { if((o_file = fopen(newname, "w")) ==0) /* Create new output file */
- { ferr_wopn();
- res = 0; /* Failure */
- goto wdone;
- }
- setbuf(o_file,obuf); /* Ensure always have buffer */
- }
- else /* New stuff */
-#endif /*STDWRITE*/
- {
-#if !(TOPS20)
- if((ofd = creat(newname,ev_filmod)) < 0)
-#else
- if((ofd = open(newname,O_WRONLY|O_UNCONVERTED)) < 0)
-#endif /*TOPS20*/
- { ferr_wopn();
- res = 0; /* Failure */
- goto wdone;
- }
- }
- if (styp==WF_SBUFF)
- set_fn(o_name); /* Won, so set default fn for buff */
-#if IMAGEN
- saynow("Writing ");
- switch(styp)
- { case WF_SBUFF: saytoo(b->b_fn); break;
- case WF_SREG: saytoo("region"); break;
-#if FX_WLASTKILL
- case WF_SKILL: saytoo("last kill"); break;
-#endif
- }
- sayntoo("...");
-#else
- saynow("Writing...");
-#endif /*-IMAGEN*/
-
-#if !(TOPS20) /* T20 does all this already */
- if(statres >= 0) /* Get old file's modes */
- { /* Try to duplicate them */
- /* Do chmod first since after changing owner we may not
- ** have permission to change mode, at least on V6.
- */
- chmod(newname,statb.st_mode & 07777);
-#if V6
- chown(newname, (statb.st_gid<<8)|(statb.st_uid&0377));
-#else
- chown(newname,statb.st_uid,statb.st_gid);
-#endif /*-V6*/
- }
-#if V6
- /* If no old file existed, and we are a V6 system, try to set
- * the modes explicitly. On V7 we're OK because the user can
- * diddle "umask" to get whatever is desired.
- * On TOPS-20 of course everything is all peachy.
- */
- else chmod(newname, ev_filmod);
-#endif /*V6*/
-#endif /*TOPS20*/
-
-
-#ifdef STDWRITE
- if(flags&WF_ASK)
- { switch(styp)
- {
- case WF_SBUFF:
- dotcnt = e_blen();
- e_gobob();
- break;
- case WF_SREG:
- if((dotcnt = mark_dot - cur_dot) < 0)
- { e_goff(dotcnt);
- dotcnt = -dotcnt;
- }
- else e_gocur();
- break;
- /* WF_SKILL not implemented here */
- }
- while(--dotcnt >= 0)
- putc(sb_getc(((SBBUF *)b)), o_file);
- e_gocur();
- fflush(o_file); /* Force everything out */
- res = ferror(o_file); /* Save result of stuff */
- fclose(o_file); /* Now flush FD */
- }
- else /* New stuff */
-#endif /*STDWRITE*/
- {
- switch(styp)
- {
- case WF_SBUFF:
- res = sb_fsave((SBBUF *)b, ofd);
- break;
- case WF_SREG:
- e_gocur();
- sd = e_copyn((chroff)(mark_dot - cur_dot));
- res = sbx_aout(sd, 2, ofd);
- sbs_del(sd);
- break;
-#if FX_WLASTKILL
- case WF_SKILL:
- res = sbx_aout(kill_ring[kill_ptr], 2, ofd);
- break;
-#endif
- }
- close(ofd);
- }
- if(errno = res)
- { ferr(" Output error");
- res = 0; /* Failure */
- goto wdone;
- }
- else
- res = 1; /* Success so far */
- if(styp == WF_SBUFF)
- f_bufnotmod(); /* Reset "buffer modified" flag */
-
- /* Here we effect the screw-prevention steps explained earlier. */
- /* TOPS-20, with generation numbers, need not worry about this. */
-#if TOPS20
- saynow("Written");
-
-#else /*-TOPS20*/
-#if IMAGEN /* KLH -- This conditional bracketting is prone to lossage */
- /* Only create the .BAK file once per editing session!! */
- if ((styp==WF_SBUFF) || !(b->b_flags & B_BACKEDUP))
- { if (styp==WF_SBUFF)
- b->b_flags |= B_BACKEDUP;
-#endif /*IMAGEN*/
- unlink(oldname); /* remove any existing "old" file */
- if(link(o_name,oldname) == 0) /* Rename current to "old" */
- unlink(o_name);
- /* Here is the critical point... if we stop here, there is no
- * longer any file with the appropriate filename!!!
- */
-#if IMAGEN
- }
- else
- unlink(o_name);
-#endif /*IMAGEN*/
- if(link(newname,o_name) == 0) /* Rename "new" to current */
- { unlink(newname);
-#if IMAGEN
- sayntoo("OK");
-#else
- saynow("Written");
-#endif /*-IMAGEN*/
- }
- else
- { dingtoo("rename error!");
- res = 0;
- }
-#endif /*-TOPS20*/
-
-#if IMAGEN
- /* Update the last-modified time for the file in this buffer */
- if ((styp == WF_SBUFF) && b->b_fn)
- { stat(b->b_fn, &s);
- b->b_mtime = s.st_mtime;
- }
-#endif /*IMAGEN*/
-
-wdone:
- hoard(); /* Get back a retained FD */
- return(res);
-}
-\f
-/* FNCONS(dest,pre,f_name,post)
- * Specialized routine to cons up a filename string into "dest",
- * given prefix and postfix strings to be added onto last component of
- * filename.
- */
-char *
-fncons(dest, pre, f_name, post)
-char *dest,*pre,*f_name,*post;
-{ register char *cp, *cp2;
- char *last_fname();
-
- cp = dest;
- *cp = 0; /* Make dest string null initially */
- cp2 = last_fname(f_name); /* Get pointer to beg of last name */
- strncat(cp,f_name,cp2-f_name); /* Copy first part of filename */
- if(pre) strcat(cp, pre); /* If prefix exists, add it on */
- cp = last_fname(cp); /* Recheck in case levels added */
- strcat(cp, cp2); /* Now add last name */
- if(cp2 = post) /* If there's a postfix, must check */
- { cp[FNAMELEN-strlen(cp2)] = 0; /* and cut dest so postfix */
- strcat(cp, cp2); /* will fit on end. */
- }
- return(dest);
-}
-
-/* LAST_FNAME(string)
- * Get the last component of a file name. Returns pointer to
- * start of component; does NOT copy string!
- */
-char *
-last_fname(f_name)
-char *f_name;
-{ register char *cp, *p;
- register int c;
-
- p = f_name; /* pointer to last slash */
- cp = p;
- while(c = *cp++)
- if(c == '/')
- p = cp; /* point to after the slash */
- return(p);
-}
-
-/* SET_FN(string)
- * Set the default filename for current buffer to "string".
- */
-set_fn (string)
-char *string;
-{ register struct buffer *b;
- register char *str;
-#if IMAGEN
- register char *cp;
- register int len;
-#endif /*IMAGEN*/
- char *strdup();
-
- b = cur_buf;
- str = strdup(string); /* Copy now in case copying self */
- if(b->b_fn)
- chkfree(b->b_fn);
- b -> b_fn = str;
-#if IMAGEN
- /* Do mode determination based on file name (HACK HACK) */
- len = strlen(str);
- b->b_flags &= ~(B_CMODE|B_TEXTMODE);
- if (len > 4)
- { if (strcmp(&str[len - 5], "draft") == 0)
- b->b_flags |= B_TEXTMODE;
- else
- { cp = &str[len - 4];
- if (strcmp(cp, ".txt") == 0 ||
- strcmp(cp, ".mss") == 0)
- b->b_flags |= B_TEXTMODE;
- }
- }
- if (len > 2)
- { cp = &str[len - 2];
- if (strcmp(cp, ".h") == 0 || strcmp(cp, ".c") == 0)
- b->b_flags |= B_CMODE;
- }
-#endif /*IMAGEN*/
- redp(RD_MODE);
-}
-\f
-/* SAVEWORLD - Attempt to save all changes user has made.
- * Currently this amounts to writing out all modified buffers
- * to the files $HOME/+buffername. If a buffer is given as argument,
- * only that buffer is saved.
- * This is only called from the error handling routines with
- * the TTY either gone or in normal (non-edit) mode. The "grunt"
- * flag says whether to output feedback during the saving process.
- */
-saveworld(bp, grunt)
-struct buffer *bp;
-int grunt;
-{ register struct buffer *b;
- register int wfd;
- char sfname[FNAMSIZ];
- struct buffer *sel_mbuf();
-
- unhoard(); /* Ensure a FD is free for writing */
- if(b = bp) goto once;
- while(!bp && (b = sel_mbuf(b)))
- {
- once: strcat(strcat(strcpy(sfname,homedir),"/+"),b->b_name);
- if(grunt) printf("Saving %s...",sfname);
-#if !(TOPS20)
- if((wfd = creat(sfname, ev_filmod)) < 0)
-#else
- if((wfd = open(sfname,O_WRONLY|O_UNCONVERTED)) < 0)
-#endif /*TOPS20*/
- { if(grunt)
- printf(" error - %s\n", strerror(errno));
- }
- else
- { sb_fsave((SBBUF *)b, wfd);
- close(wfd);
- if(grunt) printf("\n");
- }
- b->b_flags &= ~B_MODIFIED;
- }
- hoard();
-}
-
-/* HOARD, UNHOARD - Routines to save a FD for writing, to make sure
- * that we can always write out a buffer no matter how many
- * file descriptors we are currently using.
- */
-hoard() /* Stash away a FD */
-{ if(hoardfd <= 0)
-#if !(TOPS20)
- hoardfd = open("nul:", 1);
-#else
- hoardfd = open("/dev/null", 1);
-#endif
-}
-unhoard() /* Give up our stashed FD so it can be re-used */
-{ close(hoardfd);
- hoardfd = -1;
-}
-\f
-#if IMAGEN
-#include <pwd.h>
-#include <ctype.h>
-
-/*
- * expand_file: expand any ~user-name/ or $env-var/ prefixes in sfn,
- * producing the full name in dfn
- */
-expand_file(dfn, sfn)
-register char *dfn, *sfn;
-{
- register char *sp, *tp;
- register int c;
- register struct passwd *pw;
- char ts[128];
-
- /* HORRIBLE, GROSS, DISGUSTING HACK: if the destination and
- * source strings are identical (same pointer), then do not
- * do any expansion--this happens to work with the current
- * structure very well, since multiple expansions may happen.
- */
- if (dfn == sfn)
- return;
-
- ts[0] = 0;
-
- /* If have a leading $, then expand environment variable */
- if (*sfn == '$')
- { ++sfn;
- tp = ts;
- while (*tp++ = *sfn)
- if (!isalnum(*sfn))
- break;
- else
- ++sfn;
- *--tp = 0; /* Just in case */
- strcpy(ts, getenv(ts)); /* MARGINAL!! */
- }
- /* If have leading ~, then expand login name (null means $HOME) */
- else if (*sfn == '~')
- { ++sfn;
- if (*sfn == '/' || *sfn == 0)
- strcpy(ts, getenv("HOME"));
- else
- { tp = ts;
- while (*sfn && *sfn != '/')
- *tp++ = *sfn++;
- *tp = 0;
- pw = (struct passwd *)getpwnam(ts);
- if (! pw)
- strcpy(ts, "???");
- else
- strcpy(ts, pw->pw_dir);
- }
- }
-
- /* Now, ts is either empty or contains the expansion;
- * sfn has been updated correctly.
- */
- strcpy(dfn, ts);
- strcat(dfn, sfn);
-}
-#endif /*IMAGEN*/
+++ /dev/null
-/* ELLE - Copyright 1982, 1985, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/*
- * EEFILL Fill Mode functions
- */
-
-#include "elle.h"
-
-extern int ev_fcolumn; /* Fill Column variable (defined in EEVINI) */
-#if FX_SFPREF
-char *fill_prefix; /* Fill Prefix variable */
-int fill_plen; /* Length of Fill Prefix (0 = no prefix) */
-#endif /*FX_SFPREF*/
-
-#if FX_FILLMODE
-int fill_mode = 0; /* TRUE when Auto Fill Mode is on */
-int *fill_trig; /* Pointer to fill-trigger chbit array */
-static char *fill_initrig = " \t.,;:)!";
-#endif /*FX_FILLMODE*/
-
-/* Following stuff for testing routines on */
-/*
-
- 1 2 3 4 5 6 7
-0123456789012345678901234567890123456789012345678901234567890123456789012345
-
-Okay... more stuff to hack. Okay. a b c d e f g h i j k l m
-n o p q r s t u v w x y z dfsd stuff to hack 01234 Okay testing
-more stuff to hack. Okay... more stuff to hack more stuff to
-hack. Okay... more stuff to line long stuff to hack. Okay...
-even more gap and. period. okay, end of stuff.
- This is another fence.
-*/
-\f
-
-#if FX_SFCOL
-/* EFUN: "Set Fill Column" */
-f_sfcol()
-{ register int linel;
- char temp[20];
-
- linel = exp_p ? exp : d_curind();
- if(linel < 0) linel = 0;
- say("Fill column = ");
- dottoa(temp,(chroff)linel);
- saytoo(temp);
- ev_fcolumn = linel;
-}
-#endif /*FX_SFCOL*/
-
-
-#if FX_SFPREF
-/* EFUN: "Set Fill Prefix" */
-f_sfpref()
-{ register int i;
- register char *cp;
-
- if((i = cur_dot - e_boldot()) > MAXLINE)
- { ding("Absurd Fill Prefix");
- return;
- }
- if(fill_prefix)
- { chkfree(fill_prefix);
- fill_plen = 0;
- }
- if(i <= 0)
- { fill_prefix = 0;
- cp = "";
- }
- else
- { fill_prefix = cp = memalloc((SBMO)(i+1));
- fill_plen = i;
- e_gobol();
- do { *cp++ = e_getc(); }
- while(--i);
- *cp = 0;
- cp = fill_prefix;
- }
- say("Fill Prefix = \"");
- saytoo(cp);
- saytoo("\"");
-}
-
-
-/* TSTFILLP(lim) - Check for existence of Fill Prefix at current dot. If
- * not there, returns 0 without changing dot. If there, returns
- * 1 and leaves dot immediately after the Fill Prefix.
- * Lim = # of chars allowed to scan from buffer.
- */
-tstfillp(lim)
-int lim;
-{ register int i;
- register char *cp;
- chroff savdot;
-
- if(!(i = fill_plen) || (i > lim))
- return(0);
- savdot = e_dot();
- cp = fill_prefix;
- do { if(*cp++ != e_getc())
- { e_go(savdot);
- return(0);
- }
- } while(--i);
- return(1);
-}
-#endif /*FX_SFPREF*/
-\f
-#if FX_FILLREG || FX_FILLPARA
-
-/* ED_FILL(start, end, flag) - Fill a region.
- * Flag 0 for full filling; extra whitespace is flushed. First
- * word is always retained.
- * 1 for skimpy filling such as Auto-Fill likes.
- * Extra whitespace is NOT flushed, except at
- * beginning of a newly created line.
- * This is not yet implemented however.
- * Note: updates cur_dot to compensate for changes in buffer, and returns
- * there when done!
- * Note: Checks for Fill Prefix when it exists.
- */
-ed_fill(begloc, endloc, flag)
-chroff begloc, endloc;
-int flag;
-{ register int c;
- register int len, lastc;
- chroff savloc;
- int lastbrk;
- int parlen;
-
- parlen = endloc - begloc;
- if(parlen < 0)
- { begloc = endloc;
- parlen = -parlen;
- }
- e_go(begloc);
- len = d_curind(); /* Set up current col */
-
-#if FX_SFPREF
- /* If at beg of line, check for fill prefix and skip over it */
- if((len == 0) && tstfillp(parlen))
- { parlen -= fill_plen;
- len = d_curind();
- }
-#endif /*FX_SFPREF*/
- lastbrk = 0; /* Put next word on no matter what. */
- c = 0;
- for(;;)
- {
-#if ICONOGRAPHICS
- if (c != ')' && c != '"') /* allow for two sp after .) or ." */
-#endif /*ICONOGRAPHICS*/
- lastc = c;
- if(--parlen < 0) break;
- c = e_getc();
- if(c == EOF)
- break;
-#if FX_SFPREF
- /* If at beg of line, check for fill prefix and flush it */
- if((c == LF) && tstfillp(parlen))
- { e_igoff(-(fill_plen+1));
- e_ovwc(c = SP);
- e_deln((chroff)fill_plen);
- parlen -= fill_plen;
- if(cur_dot >= e_dot())
- cur_dot -= fill_plen;
- }
-#endif /*FX_SFPREF*/
- if(c == TAB || c == LF) /* Replace tabs+eols by sps */
- { e_backc(); /* Back up 1 */
- e_ovwc(c = SP);
- }
- if(c == SP)
- { if(lastc == SP)
- { e_rdelc();
- if(cur_dot > e_dot()) --cur_dot;
- continue;
- }
- lastbrk = len;
- if(lastc == '.' || lastc == '!' || lastc == '?'
-#if ICONOGRAPHICS
- || lastc == ':'
-#endif /*ICONOGRAPHICS*/
- )
- { if(--parlen < 0) goto done;
- if((c = e_getc()) == EOF)
- goto done;
- len++;
- if(c != SP)
- { e_backc();
- e_putc(c = SP);
- if(cur_dot >= e_dot()) ++cur_dot;
- }
- }
- }
-#if ICONOGRAPHICS
- if (c == BS) /* adjust for backspaces */
- if ((len -= 2) < 0) len = 0;
-#endif /*ICONOGRAPHICS*/
- /* Normal char */
- if(++len > ev_fcolumn && lastbrk) /* If went too far */
- { c = lastbrk - len; /* Must put EOL at last SP */
- e_igoff(c);
- parlen -= c; /* C is negative, actually adding */
- parlen--;
- e_ovwc(LF);
- lastbrk = 0;
- len = 0;
- c = SP; /* Pretend this char was space */
-#if FX_SFPREF
- if(fill_plen)
- { if(cur_dot >= e_dot())
- cur_dot += fill_plen;
- /* Better hope no nulls in prefix! */
- e_sputz(fill_prefix);
- len = d_curind();
- }
-#endif /*FX_SFPREF*/
- }
- }
-done: savloc = cur_dot;
- e_setcur(); /* Reached paragraph end, set cur_dot temporarily */
- buf_tmod(begloc-cur_dot); /* So that proper range is marked */
- e_gosetcur(savloc); /* Then restore original cur_dot */
-}
-#endif /*FX_FILLREG || FX_FILLPARA*/
-\f
-#if FX_FILLMODE
-
-/* EFUN: "Auto Fill Mode" */
-/* Toggles Auto Fill Mode (a minor mode). */
-f_fillmode()
-{ register char *cp;
- int *chballoc();
-
- fill_mode = fill_mode ? 0 : 1;
- if(!fill_trig)
- { fill_trig = chballoc(128);
- for(cp = fill_initrig; *cp; ++cp)
- chbis(fill_trig, *cp);
- }
- redp(RD_MODE);
-}
-
-/* Called by F_INSSELF to handle char insertion in Auto Fill mode */
-fx_insfill(c)
-int c;
-{
- ed_insn(c,exp);
- if(chbit(fill_trig, c))
- { fill_cur_line();
-
- }
-}
-
-
-fill_cur_line()
-{
- register int foundit, i;
- chroff lastbrkdot, boldot;
-
- boldot = e_boldot();
-
- /* First back up to find place to make first break. */
- e_bwsp();
- lastbrkdot = e_dot();
- foundit = 0;
- for(foundit = 0; foundit >= 0;)
- { if((i = d_curind()) <= ev_fcolumn)
- { if(foundit)
- foundit = -1;
- else break;
- }
- else ++foundit;
- while (!c_wsp (e_rgetc ())) ;
- e_bwsp();
- lastbrkdot = e_dot();
- if(lastbrkdot <= boldot)
- { lastbrkdot = boldot;
- break;
- }
- }
-
- if(foundit)
- ed_fill(lastbrkdot, e_eoldot(), 1);
-}
-#endif /*FX_FILLMODE*/
-\f
-#if IMAGEN
-
-#if FX_TEXTMODE
-/* EFUN: "Text Mode Toggle" (not EMACS) */
-f_textmode()
-{
- cur_buf->b_flags ^= B_TEXTMODE;
- redp(RD_MODE);
-}
-#endif /*FX_TEXTMODE*/
-
-int curr_indent = -1; /* Current indent (for text mode autowrap) */
- /* (misnomered: actually current column) */
-chroff best_break; /* Best break point so far */
-
-
-/* Fill-mode version of "Insert Self" */
-
-fim_insself(c)
-int c;
-{
- register int ind, flags = cur_buf->b_flags;
-
- /* In Text mode, auto-wrap happens at spaces after fill column */
- if (c == SP && flags & B_TEXTMODE && exp == 1 && magic_wrap(c))
- return;
-
- /* In C-mode, tab stops are every 4 columns */
- else if (c == TAB && flags & B_CMODE &&
- (ind = magic_backto_bol()) >= 0)
- ed_indto((ind + 4) & ~3);
- else
- { ed_insn(c, exp);
-
- /* Keep track of indent, once we have a grip on it */
- if (last_cmd == INSCMD && curr_indent != -1)
- { this_cmd = INSCMD; /* Keep the ball rolling */
- if (c == TAB)
- curr_indent = ((curr_indent + 8) & ~7)
- + 8 * (exp - 1);
- else if (c == '\n')
- curr_indent = 0;
- else if (c < SP || c > 0176)
- curr_indent += (2 * exp);
- else
- curr_indent += exp;
- }
- }
-}
-
-/* Fill-mode version of "Delete Character" */
-
-fim_dchar()
-{ /* In C mode, deleting at BOL should do fake TAB preservation */
- if (cur_buf->b_flags & B_CMODE)
- { chroff savdot;
- register int c, indent;
-
- if (e_rgetc() != LF)
- { /* Only hack this at BOL */
- e_getc();
- goto normal;
- }
- e_getc();
- savdot = e_dot();
- indent = 0;
- while ((c = e_getc()) == SP || c == TAB)
- if (c == SP)
- ++indent;
- else
- indent = (indent + 8) & ~7;
- e_rgetc();
- if (indent >= 4)
- { ed_delete(savdot, e_dot());
- ed_indto((indent - 4) & ~3);
- f_begline(); /* HACK!!!! */
- }
- else
- { e_go(savdot);
- ef_deln(exp);
- }
- }
- else
- normal: return (ef_deln(exp));
-}
-
-/* Fill-mode version of "Backward Delete Character" */
-
-fim_bdchar()
-{ register int ind;
-
- /* If in C mode, and deleting into white space at BOL, hack tabs */
- if (exp == 1 && cur_buf->b_flags & B_CMODE &&
- (ind = magic_backto_bol()) > 0)
- ed_indto(ind < 4 ? ind - 1 : ((ind - 4) & ~3));
- else
- return (ef_deln (-exp));
-}
-
-/* Fill-mode version of "CRLF" */
-fim_crlf()
-{ register int i;
-
- if(e_getc() == LF
- && exp == 1
- && e_lblankp() && e_lblankp())
- { e_gocur();
- e_gonl();
- e_setcur();
- ed_delete(e_dot(), e_eoldot());
- }
- else
- { e_gocur();
-#if IMAGEN
- if (cur_buf->b_flags & B_TEXTMODE && exp == 1 &&
- magic_wrap('\n'))
- return;
- else
-#endif /*IMAGEN*/
- if((i = exp) > 0)
- do ed_crins();
- while(--i);
- }
-}
-\f
-/* Do all magic for auto-wrap in Text mode:
- * return as did wrap (i.e., everything is taken care of)
- */
-magic_wrap(tc)
-int tc; /* "trigger char" */
-{
- register int c, indent, i, nc;
- chroff savdot, modstart, breakdot;
-
- savdot = e_dot();
- nc = 0;
- if (last_cmd == INSCMD && curr_indent != -1)
- { indent = curr_indent; /* Already know our indent */
- breakdot = best_break;
- }
- else
- {
-#ifdef INDENTDEBUG
- barf2("Full indent calculation");
-#endif
- for (nc = 0; (c = e_rgetc()) != EOF && c != '\n'; ++nc)
- ; /* nc: # chars to look at */
- if (c == '\n') /* Go back over NL */
- e_getc();
- indent = 0;
-
- /* Search for last line break point, leaving it in breakdot */
- breakdot = (chroff)0;
- while (--nc >= 0)
- { c = e_getc();
- if (c == TAB)
- indent = (indent + 8) & ~7;
- else if (c < SP || c > 0176)
- indent += 2;
- else
- ++indent;
- if ((c == SP || c == TAB) &&
- (breakdot == (chroff)0 || (indent <= ev_fcolumn)))
- breakdot = e_dot();
- }
- }
-
- /* If there is nothing to do, get out */
- if (indent <= ev_fcolumn)
- { e_go(savdot);
- if (tc == SP)
- { curr_indent = indent;
- best_break = (chroff)(savdot + 1); /* Remember here, also */
- this_cmd = INSCMD; /* We do know current indent */
- }
- else if (tc == '\n')
- { curr_indent = 0;
- best_break = (chroff)0;
- this_cmd = INSCMD;
- }
- else
- errbarf("bad trigger");
- return(0);
- }
-
- if (breakdot == (chroff)0)
- {
- /* No breakpoint found or none needed, just break line at end
- */
- e_go(savdot);
- modstart = savdot;
- e_putc('\n');
- }
- else
- {
- /* Get to breakpoint and replace with newline
- */
- e_go(breakdot);
- e_rdelc();
- modstart = e_dot(); /* Remember where changes start */
- e_putc('\n'); /* Insert line break */
- e_go(savdot); /* Get back to trigger point */
- }
- if (e_rgetc() != '\n')
- { /* If not at line start, */
- e_getc();
- e_putc(tc); /* insert trigger character */
-
- /* Once again, compute new indent by backing up to BOL */
- for (nc = 0; (c = e_rgetc()) != EOF && c != '\n'; ++nc)
- ;
- if (c == '\n') /* Go back over NL */
- e_getc();
- indent = 0;
- breakdot = (chroff)0;
- while (--nc >= 0)
- { /* Get back to current dot */
- c = e_getc();
- if (c == TAB)
- indent = (indent + 8) & ~7;
- else if (c < SP || c > 0176)
- indent += 2;
- else
- ++indent;
- if ((c == SP || c == TAB) &&
- (breakdot == (chroff)0 || (indent <= ev_fcolumn)))
- breakdot = e_dot();
- }
- if (breakdot == (chroff)0) /* If no good break found, use dot */
- breakdot = e_dot();
- curr_indent = indent; /* Now we know where we are */
- if (tc == '\n') /* If trigger was NL */
- best_break = (chroff)0; /* indent is 0, and no best break */
- else
- best_break = breakdot; /* This is best break so far */
- }
- else
- { e_getc();
- curr_indent = 0; /* At line start, no indent */
- best_break = (chroff)0; /* Do not have a best break so far */
- }
- ed_setcur();
- buf_tmat(modstart); /* Alert to potential changes */
- this_cmd = INSCMD; /* Say we know where we are */
- return(1);
-}
-
-/* Do lots of magic things for C-mode indent:
- * erase back to BOL iff we are looking back at white space only,
- * returning the indent level of the original dot
- * (< 0 means no erasure done)
- */
-/*#define MYDEBUG /* */
-#ifdef MYDEBUG
-reveal(msg, v1, v2, v3)
-char *msg;
-{
- char ahint[128];
- sprintf(ahint, msg, v1, v2, v3);
- barf2(ahint);
-}
-#endif
-
-magic_backto_bol()
-{
- chroff savdot;
- register int c, indent, nc, i;
-
- savdot = e_dot();
- nc = 0;
- while ((c = e_rgetc()) != EOF && c != LF)
- { ++nc; /* Count # chars */
- if (c != SP && c != TAB)
- { e_go(savdot);
-#ifdef MYDEBUG
- reveal("fail: nc: %d", nc);
-#endif
- return -1;
- }
- }
- if (c == LF) /* Go back over the LF */
- e_getc();
- indent = 0; /* (zero-based indent) */
- savdot = e_dot(); /* BOL is now origin for delete */
- for (i = 1; i <= nc; ++i)
- if ((c = e_getc()) == SP)
- ++indent;
- else /* (tab) */
- indent = (indent + 8) & ~7;
- if (nc > 0) /* Don't bother deleting nothing */
- ed_delete(savdot, e_dot());
-#ifdef MYDEBUG
- reveal("indent: %d, nc: %d, foo: %d", indent, nc, 234);
-#endif
- return(indent);
-}
-#endif /*IMAGEN*/
-\f
-#if ICONOGRAPHICS
-/* Iconographics hack for Auto-Fill mode. Too big and clumsy, but
- * retained for posterity in case it has some obscure feature.
- */
-
-fill_current_line ()
-{
- chroff startpos, endpos, savepos, limitpos;
- int i, foundit;
- SBSTR *savep;
-
- foundit = 0;
- while (d_curind() > ev_fcolumn)
- {
- foundit = 1;
- startpos = e_dot ();
- e_bwsp ();
- while (d_curind() > ev_fcolumn) /* back up to ends of wds*/
- { /* until <= fill column */
- while (!c_wsp (e_rgetc ())) ;
- e_bwsp ();
- }
- if (e_dot () == e_boldot ())
- { /* ding ("Word does not fit in fill column"); */
- return(0);
- }
- savep = e_copyn (startpos - e_dot ());
- e_setcur (); /* ed_delete does gocur */
- ed_delete (savepos = e_dot (), startpos);
-
- f_crlf(); /* Now insert newline */
- e_sputz(fill_prefix); /* With fill prefix */
- startpos += e_dot () - savepos;
- if (d_curind() > ev_fcolumn)
- { ed_delete (savepos, e_dot ());
- sb_sins (cur_buf, savep);
- e_setcur ();
- ding ("Fill prefix > fill column???");
- return(0);
- }
- savepos = e_dot (); /* gun inherited initial whitespace */
- sb_sins (cur_buf, savep);
- e_go (savepos);
- e_fwsp ();
- if ((limitpos = e_dot ()) > startpos) limitpos = startpos;
- /* in case rest of line was white */
- ed_delete (savepos, limitpos);
- e_gosetcur (startpos + savepos - limitpos);
- }
-
- return foundit;
- }
-#endif /*ICONOGRAPHICS*/
+++ /dev/null
-/* ELLE - Copyright 1982, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/* EEHELP - Help function
- */
-
-#include "elle.h" /* include structure definitions */
-
-
-#if FX_DESCRIBE
-/* EFUN: "Describe" */
-/* DESCRIBE - Help-command hack.
-** Crude approximation of EMACS function.
-*/
-static struct buffer *help_buf;
-
-f_describe()
-{ register char *cp;
- register int i, c;
- char str[10];
- struct buffer *savbuf, *b, *make_buf();
- chroff bdot;
-
- saynow("Help for command: ");
- i = cmd_idx(c = cmd_read()); /* Get function idx for cmd */
- if(c&CB_META) sayntoo("M-");
- if(i == FN_PFXMETA)
- { sayntoo("M-");
- i = cmd_idx(c = (cmd_read() | CB_META));
- }
- else if(i == FN_PFXEXT)
- { sayntoo("^X-");
- i = cmd_idx(c = (cmd_read() | CB_EXT));
- }
- str[0] = c&0177;
- str[1] = 0;
- sayntoo(str);
-
- /* Now read in the help file, if necessary */
- savbuf = cur_buf;
- if(help_buf)
- chg_buf(help_buf);
- else
- {
- saynow("Loading ");
- sayntoo(ev_helpfile);
- sayntoo("...");
- chg_buf(help_buf = make_buf(" **HELP**"));
- if(read_file(ev_helpfile) == 0)
- { chg_buf(savbuf);
- kill_buf(help_buf);
- help_buf = 0;
- return;
- }
- }
-
-
- /* Find function index in current buffer */
- cp = str;
- *cp++ = '<';
- *cp++ = 'F';
- cp = dottoa(cp, (chroff)i);
- *cp++ = '>';
- e_gobob();
- if(e_search(str, cp-str, 0) == 0)
- sayntoo(" No help found");
- else
- {
- bdot = e_dot();
- while(!e_lblankp()) e_gonl(); /* Move past 1st blank line */
- b = make_buf(" *SHOW*");
- sb_sins((SBBUF *)b, e_copyn(bdot - e_dot()));
- mk_showin(b); /* Show the stuff */
- kill_buf(b);
- sayclr();
- }
- chg_buf(savbuf);
-}
-#endif /*FX_DESCRIBE*/
+++ /dev/null
-/* ELLE - Copyright 1982, 1985, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/* EEKMAC - Keyboard Macro routines
- * Modelled after the "e_macro.c" for ICONOGRAPHICS
- * by C. D. Tavares, 9/11/82
- */
-
-#include "elle.h"
-
-#if FX_SKMAC /* Entire file is under this conditional! */
-
-int kdef_mode; /* Set when collecting (a "minor mode") */
-static int km_flag = 0; /* 1 = executing, -1 collecting, 0 neither */
-static int km_exp; /* Arg to "Execute Kbd Macro" - # times more to xct */
-static struct buffer *km_buf;
-
-/* EFUN: "Start Kbd Macro" */
-
-f_skmac()
-{ register struct buffer *b;
- struct buffer *make_buf();
-
- if(km_flag)
- { ding("Kbd macro active, ignoring \"Start Kbd Macro\"");
- return;
- }
- if((b = km_buf) == 0)
- b = km_buf = make_buf(" *KBDMAC*");
- ex_reset(b);
- km_flag = -1; /* Say starting macro collection */
- kdef_mode = 1;
- redp(RD_MODE);
-}
-
-/* EFUN: "End Kbd Macro" */
-
-f_ekmac()
-{
- if(km_flag > 0 && (--km_exp >= 0))
- { ex_go((SBBUF *)km_buf, (chroff)0);
- }
- else if(km_flag)
- { km_flag = 0;
- kdef_mode = 0; /* Flush minor mode */
- redp(RD_MODE);
- }
-}
-
-/* EFUN: "Execute Kbd Macro" */
-
-f_xkmac()
-{
- if(km_flag)
- ding("Already in kbd macro!");
- else if(km_buf == 0)
- ding("No kbd macro defined");
- else if((km_exp = exp-1) >= 0)
- {
- ex_go((SBBUF *)km_buf, (chroff) 0);
- km_flag = 1; /* Start macro execution */
- }
-}
-
-/* EFUN: "View Kbd Macro" */
-
-f_vkmac()
-{ register struct buffer *b, *savbuf;
- chroff prmplen;
-
- if(!(b = km_buf))
- { ding("No kbd macro defined");
- return;
- }
- savbuf = cur_buf;
- chg_buf(b);
- e_gobob();
- e_sputz("Current Kbd macro:\n\n");
- prmplen = e_dot();
- mk_showin(b); /* Show the macro buffer temporarily */
- e_gobob();
- chg_buf(savbuf);
- sb_deln((SBBUF *)b, prmplen); /* Flush the prompt */
-}
-\f
-/* KM_GETC - return next command char from kbd macro being executed.
-** This is < 0 if not executing kbd macro. Also responsible for
-** gathering input for kbd macro.
-*/
-km_getc()
-{ register int c;
-
- while (km_flag > 0) /* Executing macro? */
- { c = sb_getc(((SBBUF *)km_buf)); /* Yes, get char */
- if(c != EOF)
- return(c); /* and return as cmd */
-
- if(--km_exp >= 0) /* Macro done. Repeat? */
- ex_go((SBBUF *)km_buf, (chroff)0); /* Yes */
- else km_flag = 0; /* No, stop execution */
- }
- c = tgetc(); /* Get char from user (TTY) */
- if(km_flag < 0) /* Save it if collecting macro */
- { sb_putc(((SBBUF *)km_buf), c);
- }
- return(c);
-}
-
-/* KM_INWAIT() - Return TRUE if any keyboard-macro input waiting.
- */
-km_inwait()
-{ register int c;
- if(km_flag > 0)
- if((c = sb_getc(((SBBUF *)km_buf))) != EOF || (km_exp > 0))
- { sb_backc(((SBBUF *)km_buf));
- return(1);
- }
- return(0);
-}
-
-km_abort ()
-{
- if(km_flag > 0) /* Executing? */
- km_flag = 0; /* Stop */
- else if(km_flag < 0) /* Collecting? */
- f_ekmac(); /* Close it out */
-}
-
-#endif /*FX_SKMAC*/
-\f
-#if 0 /* Old unused stuff */
-static char mode_buf [60];
-
-add_mode (mode)
- char *mode;
- {
- register char *cur, *c, *m;
-
- if (cur_mode != mode_buf)
- {
- strcpy (mode_buf, cur_mode);
- cur_mode = mode_buf;
- }
-
- if (cur_mode [0]) strcat (cur_mode, ", ");
- strcat (cur_mode, mode);
- make_mode ();
- }
-
-remove_mode (mode)
- char *mode;
- {
- register char *cur, *c, *m;
-
- if (*cur_mode == 0) return;
-
- if (cur_mode != mode_buf)
- {
- strcpy (mode_buf, cur_mode);
- cur_mode = mode_buf;
- }
-
- for (cur = cur_mode ; *cur ; cur++)
- if (*cur == *mode) /* 1st char matches */
- {
- for (c = cur, m = mode ; *m && (*m == *c) ; m++, c++) ;
- if (!(*m)) /* ok, mode matched */
- { /* kill leading ", " */
- if (*(cur - 1) == ' ') --cur;
- if (*(cur - 1) == ',') --cur;
- for ( ; *cur = *c ; cur++, c++) ; /* recopy to end */
- make_mode ();
- return;
- }
- }
- }
-#endif /*COMMENT*/
+++ /dev/null
-/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/*
- * EEMAIN ELLE Main Command Loop
- */
-
-#include "elle.h"
-
-#include <stdio.h>
-#if !(V6)
-#include <signal.h>
-#else
-#include "eesigs.h" /* Use this on V6 system */
-#endif /*V6*/
-
-char *argfile[MAXARGFILES]; /* Filename args at startup */
-
-extern int (*sbm_debug)();
-extern int (*sbv_debug)();
-int (*vfy_vec)(); /* If non-zero, routine to verify data
- * after each main-loop command */
-
-main (argc, argv)
-int argc;
-char **argv;
-{
- register int c; /* Current command character */
- register int i;
- static int waitct;
- extern int errsbm();
-#if SUN
- extern int sun_rdevf; /* from EESUN */
-#endif
-#ifdef STKMEM
- char stackm[STKMEM]; /* Allocate some unused stack space */
-#endif /*STKMEM*/
-
- sbv_debug = errsbm; /* Load with addrs of routine to */
- sbm_debug = errsbm; /* process SB and SBM errors. */
-
-#ifdef STKMEM
- sbm_init(&stackm[0],(SBMO)STKMEM); /* Initialize mem alloc rtns */
-#endif /*STKMEM*/
-#if SUN
- sun_main(&argc, argv); /* On SUN, invoke window startup */
-#endif /*SUN*/
-
- setbuf(stdout, (char *)NULL); /* Remove all stdio buffering */
- setbuf(stderr, (char *)NULL); /* in case of error reports. */
-
- waitct = 0; /* debugging */
- doargs(argc,argv); /* Set up args */
- initialize (); /* Initialize the editor */
-
- if (argfile[0]) /* shell line arg */
- find_file(argfile[0]);
-#if MAXARGFILES > 1
- if(argfile[1])
- { f_2winds(); /* Make 2 windows, go to 2nd */
- i = 1;
-#if MAXARGFILES > 2
- for (; i < MAXARGFILES; ++i)
-#endif /* > 2 files */
- find_file(argfile[i]); /* Get further file(s) */
- f_othwind(); /* Move back to 1st window */
- }
-#endif /* > 1 file */
-
- redp(RD_SCREEN|RD_MODE); /* Clear and show mode line */
- setexit(0); /* catch for ints, ^G throws */
-
-/* -----------------------------------------------------------
-** ELLE MAIN LOOP
-**
-*/
- for (;;)
- {
- /* First set up default arg unless last cmd specified it */
- if(this_cmd != ARGCMD)
- { exp = 1; /* Default arg is 1 */
- exp_p = 0; /* Say no explicit arg */
- last_cmd = this_cmd;
- }
- this_cmd = 0;
-
- askclr(); /* If stuff asked, say to clear it */
- if(cmd_wait())
- waitct++;
- else if(rd_type != 0)
- redisplay(); /* Redisplay if needed and no input */
-#if SUN
- sun_rdevf = 1; /* Allow mouse events on this input */
-#endif
- c = cmd_read(); /* Read an editor command */
- sayclr(); /* Ask to clear echo area cleverly */
-
-#if SUN
- if(c != -1) /* SUN may not have real input */
-#endif /* if mouse event happened. */
- cmd_xct(c); /* Execute the command char! */
-
- if(vfy_vec) /* If debugging, */
- (*vfy_vec)(1); /* verify data structs right away */
- }
-}
-\f
-char *prof_file; /* Can specify user profile filename */
-
-doargs(argc,argv)
-int argc;
-char **argv;
-{ register int cnt, c;
- register char **av;
- extern int tibfmsk;
- int argfiles = 0;
- int argsignored = 0;
-
- av = argv;
- cnt = argc;
-
-#if V6 /* V6 doesn't have environment thus no TERM var */
- /* Hack to force terminal type; analyze pgm name to get
- * possible ".type" suffix.
- */
- if(cnt && (c = strlen(*av)))
- while(--c >= 0)
- { switch(av[0][c])
- { case '.':
- tv_stype = &av[0][c+1];
- case '/':
- break;
- default: continue;
- }
- break;
- }
-#endif /*V6*/
-
- while(--cnt > 0)
- { ++av;
- if(*av[0] != '-') /* If not switch, */
- { /* assume it's an input filename */
- if (argfiles < MAXARGFILES)
- argfile[argfiles++] = *av;
- else
- ++argsignored;
- continue;
- }
- c = upcase(av[0][1]);
- switch(c) /* Switches without args */
- { case 'I': /* Allow debug ints */
- dbg_isw = 1;
- continue;
- case '8': /* Ask for 8-bit input */
- tibfmsk = 0377;
- continue;
- case '7': /* Ask for 7-bit input */
- tibfmsk = 0177;
- continue;
-#if IMAGEN
- case 'R': /* Debug redisplay stuff */
- dbg_redp = 1;
- continue;
-#endif /*IMAGEN*/
- }
- if(--cnt <= 0)
- goto stop;
- ++av;
- switch(c) /* Switches with args */
- { case 'T': /* Terminal type */
- tv_stype = *av;
- break;
- case 'P':
- prof_file = *av;
- default:
- goto stop;
- }
- continue;
- stop: printf("ELLE: bad switch: %s\n",*av);
- exit(1);
- }
- if (argsignored > 0)
- { printf("ELLE: more than %d file args, %d ignored.\n",
- MAXARGFILES, argsignored);
- sleep(2); /* Complain but continue after pause */
- }
-}
-\f
-int f_throw(); /* throw function */
-int bite_bag(); /* Error handling routine */
-int hup_exit(); /* Hangup handling routine */
-
-struct majmode ifunmode = { "Fundamental" };
-
-initialize () /* Initialization */
-{
-#if SUN
- extern int sun_winfd;
-#endif
- cur_mode = fun_mode = &ifunmode; /* Set current major mode */
- unrchf = pgoal = -1;
- if(!homedir)
- {
-#if V6
- extern char *logdir();
- homedir = logdir();
-#else /* V7 */
- homedir = getenv("HOME");
-#endif /*-V6*/
- }
-
- sbx_tset((chroff)0,0); /* Create swapout file */
- /* (Temporary hack, fix up later) */
- hoard(); /* Hoard a FD for write purposes */
-
- redp_init(); /* Set up the display routines */
- init_buf(); /* Set up initial buffers */
- set_profile(prof_file); /* Set up user profile */
-
-#if SUN
- if(sun_winfd) sun_init();
-#endif /*SUN*/
-
- /* Set up signal handlers */
-#if 0 /* not really used */
- signal (SIGQUIT, f_throw); /* Quit - on ^G */
-#endif
-#if !(MINIX)
- signal (SIGSYS, bite_bag); /* Bad arg to Sys call */
-#endif
- signal (SIGSEGV, bite_bag); /* Segmentation Violation */
-#if !(COHERENT)
- signal (SIGILL, bite_bag); /* Illegal Instruction interrupt */
- signal (SIGBUS, bite_bag); /* Bus Error interrupt */
-#endif /*-COHERENT*/
-#if !(TOPS20) /* T20 just detaches job */
- signal (SIGHUP, hup_exit); /* Terminal Hangup interrupt */
-#endif /*-TOPS20*/
-}
-
-
-/* NOTE: This routine is not actually used, because ELLE does not
- * allow interrupts to do anything.
- */
-/* EFUN: "Error Throw" */
-f_throw () /* abort whatever is going on */
-{
- ring_bell ();
- curs_lin = -1000; /* make t_curpos do something */
- redp(RD_MOVE); /* crock: cursor seems to move, so fix it */
- signal(SIGQUIT, f_throw); /* rearm signal */
-/* unwind_stack(main); */
- reset(1); /* throw to main loop */
-}
-
-/* RING_BELL - General-purpose feeper when something goes wrong with
- * a function.
- */
-ring_bell()
-{ t_bell(); /* Tell user something's wrong */
-
-#if FX_SKMAC
- f_ekmac(); /* Stop collecting keyboard macro if any */
-#endif /*FX_SKMAC*/
-}
-\f
-/* EFUN: "Return to Superior"
- * Behavior here is somewhat system-dependent. If it is possible to
- * suspend the process and continue later, we do not ask about modified
- * buffers. Otherwise, we do. Questioning can always be forced by using
- * the prefix ^U.
- * Note that here we try to be very careful about not letting the user
- * exit while buffers are still modified, since UNIX flushes the process
- * if we exit. Also, the code here conspires with sel_mbuf to rotate
- * through all modified buffers, complaining about a different one each time,
- * so that the user need not even know how to select a buffer!
- */
-void f_retsup()
-{ register char *reply;
- register int c;
- register struct buffer *b, *b2;
- extern struct buffer *sel_mbuf();
- extern int tsf_pause;
-
- /* If we have capability of pausing and later continuing, do that,
- * except if CTRL-U forces us into question/save/quit behavior.
- */
- if(tsf_pause && (exp_p != 4))
- { clean_exit(); /* Return TTY to normal mode */
- ts_pause(); /* Pause this inferior */
- set_tty(); /* Continued, return to edit mode */
- redp(RD_SCREEN);
- return;
- }
-
- /* Sigh, do more typical "Are you sure" questioning prior to
- * killing the editor permanently.
- */
- b = cur_buf;
- if((b = sel_mbuf(b)) || (b = sel_mbuf((struct buffer *)0)) )
- { if(b2 = sel_mbuf(b))
- reply = ask(
- "Quit: buffers %s, %s,... still have changes - forget them? ",
- b->b_name, b2->b_name);
- else
- reply = ask(
- "Quit: buffer %s still has changes - forget them? ",
- b->b_name);
-
- }
- else
- {
-#if IMAGEN /* Do not ask further if nothing modified */
- barf("Bye");
- clean_exit();
- exit(0);
-#else
- reply = ask("Quit? ");
-#endif /*-IMAGEN*/
- }
-
- if (reply == 0)
- return; /* Aborted, just return */
-
- c = upcase(*reply); /* Get 1st char of reply */
- chkfree(reply);
-
- switch(c)
- { case 'Y':
-#if IMAGEN
- barf("Bye");
-#endif /*IMAGEN*/
- clean_exit();
- exit(0);
-#if 0
- case 'S': /* Suspend command for debugging */
- bkpt();
- return;
-#endif /*COMMENT*/
- default: /* Complain */
- ring_bell();
- case 'N':
- if(b) /* B set if we have any modified buffers */
- { sel_buf(b);
- if(b->b_fn)
- saynow("Use ^X ^S to save buffer");
- else saynow("Use ^X ^W to write out buffer");
- }
- }
-}
-\f
-
-#if FX_WFEXIT
-/* EFUN: "Write File Exit" (not EMACS) - from IMAGEN config */
-void f_wfexit()
-{
- exp_p = 1; /* Ensure f_savefiles asks no questions */
- if (! f_savefiles()) /* Save all modified buffers, but */
- return; /* stay here if any save fails */
- saynow("Bye");
- clean_exit();
- exit(0);
-}
-#endif /*FX_WFEXIT*/
-\f
-/* Subprocess-handling stuff; put here for time being. */
-
-/* EFUN: "Push to Inferior" */
-#if TOPS20
-#include <frkxec.h> /* Support for KCC forkexec() call */
-#endif
-f_pshinf()
-{
- register int res;
- register int (*sav2)(), (*sav3)();
- int pid, status;
- char *shellname;
-#if IMAGEN
- char fullshell[64];
-#endif /*IMAGEN*/
-
- sav2 = signal(SIGINT, SIG_IGN); /* Ignore TTY interrupts */
- sav3 = signal(SIGQUIT, SIG_IGN); /* Ditto TTY "quit"s */
- clean_exit(); /* Restore normal TTY modes */
-
-#if TOPS20
- {
- struct frkxec fx;
- fx.fx_flags = FX_WAIT | FX_T20_PGMNAME;
- fx.fx_name = "SYS:EXEC.EXE";
- fx.fx_argv = fx.fx_envp = NULL;
- if (forkexec(&fx) < 0)
- writerr("Cannot run EXEC");
- }
-#else /*-TOPS20*/
- switch(pid = fork())
- { case -1:
- writerr("Cannot fork");
- break;
- case 0: /* We're the child */
- for(res = 3; res < 20;) /* Don't let inf hack fd's */
- close(res++);
-#if V6
- execl("/bin/sh","-sh",0);
-#else
- signal(SIGINT, SIG_DFL); /* V7 shell wants this?? */
- signal(SIGQUIT, SIG_DFL); /* */
-#if IMAGEN
- if((shellname = getenv("SHELL")) == 0)
- shellname = "sh";
- strcpy(fullshell, "/bin/");
- strcat(fullshell, shellname);
- shellname = fullshell;
-#else
- if((shellname = getenv("SHELL")) == 0)
- shellname = "/bin/sh";
-#endif /*-IMAGEN*/
-
- if((shellname = getenv("SHELL")) == 0)
- shellname = "/bin/sh";
- execl(shellname, shellname, 0);
-#endif /*-V6*/
- writerr("No shell!");
- exit(1);
- break;
- default:
- while((res = wait(&status)) != pid && res != -1);
- break;
- }
-#endif /*-TOPS20*/
-
- signal(SIGINT, sav2); /* Restore signal settings */
- signal(SIGQUIT, sav3);
- set_tty(); /* Restore editor TTY modes */
- redp(RD_SCREEN|RD_MODE); /* Done, redisplay */
-}
-\f
-
-#if 0
-/* Miscellaneous utility routines - memory alloc/free and string hacking.
- * If this page becomes overly large, it can be split off into a separate
- * file called E_MISC.
- */
-char *
-strdup(s)
-char *s; /* Note that STRCPY's return val must be its 1st arg */
-{ char *strcpy();
- return(strcpy(memalloc((SBMO)(strlen(s)+1)), s));
-}
-#endif
-
-char *
-memalloc(size)
-SBMO size;
-{ register SBMA ptr;
- extern SBMA sbx_malloc();
-
- if ((ptr = (SBMA)sbx_malloc(size)) != 0)
- return((char *)ptr);
- barf("ELLE: No memory left");
- askerr();
- return(0); /* If we dare to continue... */
-}
-
-chkfree (ptr)
-SBMA ptr;
-{
- if(!free(ptr))
- { errbarf("Something overwrote an allocated block!");
- askerr();
- }
-}
-
-
-/* USTRCMP - Uppercase String Compare.
- * Returns 0 if mismatch,
- * 1 if full match,
- * -1 if str1 runs out first (partial match)
- */
-ustrcmp(str1,str2)
-char *str1, *str2;
-{ register char *s1, *s2;
- register int c;
- s1 = str1; s2 = str2;
- while(c = *s1++)
- { if(c != *s2 && upcase(c) != upcase(*s2))
- return(0);
- s2++;
- }
- return(c == *s2 ? 1 : -1);
-}
-
-
-/* WRITERR(str) - Output string to standard error output.
-** This is a separate routine to save a little space on calls.
-*/
-writerr(str)
-char *str;
-{ return(writez(2, str));
-}
-
-/* WRITEZ(fd, str) - Miscellaneous general-purpose string output.
- */
-writez(fd,acp)
-int fd;
-char *acp;
-{ register char *cp;
- cp = acp;
- while(*cp++);
- write(fd,acp,cp-acp-1);
-}
+++ /dev/null
-/* ELLE - Copyright 1982, 1985, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/* EEMAKE - IMAGEN configuration functions for interfacing to "make".
- * Written by (I think) Chris Ryland at IMAGEN, who also
- * wrote other functions scattered through ELLE. These are either
- * conditionalized or are commented as being derived from the IMAGEN
- * configuration.
- *
- * KLH: An attempt has been made to keep these routines updated as ELLE
- * changed, but their workings cannot be guaranteed.
- */
-
-
-/*
- * eemake: "make" (and other program) support
- *
- * Next-error depends on programs writing error messages of the form:
- * "file", line n: message
- * which is a de facto standard, at least in some worlds.
- */
-
-#include "elle.h"
-
-#if !(IMAGEN) /* Only with IMAGEN config for now */
-f_xucmd() {}
-f_make() {}
-f_nxterr() {}
-#else
-
-#include <stdio.h>
-
-struct buffer *exec_buf; /* Ptr to "Execution" buffer */
- /* Only external ref is from e_buff.c */
-
-#define MSGLENGTH (scr_wid - 11) /* Max length of message */
-int fresh_make = 1; /* Fresh Execution buffer contents */
-chroff last_error_BOL; /* Dot for last-error's BOL */
-
-/* EFUN: "Execute Unix Command" */
-f_xucmd()
-{
- make_or_unix_cmd(0);
-}
-
-/* EFUN: "Execute Make" */
-f_make()
-{
- make_or_unix_cmd(1);
-}
-
-/* EFUN: "Find Next Error" */
-f_nxterr()
-{
- register struct sbstr *sb;
- register char *cp;
- register int c;
- char file[64], line[32];
-#ifdef ONEWINDOW
- char msg[512];
-#endif
- chroff linedot;
- int lineno;
- register int len;
-
- sel_execbuf();
- if (! fresh_make)
- { e_go(last_error_BOL);
- e_gonl();
- }
- else
- { fresh_make = 0;
- e_gobob();
- last_error_BOL = e_dot();
- }
-
- /* Looking for `"file", line n: msg' */
- if (! e_search("\", line ", 8, 0))
- goto failed;
- linedot = e_dot();
- e_gobol(); /* Found something, get to BOL */
- if (e_getc() != '"')
- goto failed; /* Insist on beginning "file" */
- cp = file; /* Pick up filename */
- while ((c = e_getc()) != '"')
- *cp++ = c;
- *cp = 0;
- e_go(linedot); /* Back to after "line " */
- cp = line;
- while ((c = e_getc()) >= '0' && c <= '9')
- *cp++ = c;
- *cp = 0;
- lineno = atoi(line); /* Pick up line number */
-#ifdef ONEWINDOW
- cp = msg; /* Now get rest of line to msg */
- len = 0; /* But keep length <= MSGLENGTH */
- e_getc(); /* Go past purported space */
- while ((c = e_getc()) != LF && c != EOF && len <= MSGLENGTH)
- { if (c == '\t')
- len = (len + 8) & ~07;
- else if (c < ' ' || c > 0176)
- len += 2;
- else
- ++len;
- *cp++ = c;
- }
- *cp = 0;
- if (len > MSGLENGTH)
- strcat(msg, "...");
-#ifdef DEBUG
- say("file ");
- saytoo(file);
- saytoo(", line ");
- saytoo(line);
- saytoo(", msg: ");
- sayntoo(msg);
-#else
- say(line);
- saytoo(": ");
- sayntoo(msg);
-#endif /*DEBUG*/
-#else /* -ONEWINDOW */
- f_begline(); /* Get to start of line */
- last_error_BOL = e_dot(); /* Remember this position */
- exp_p = 1; /* Make this the new top line */
- exp = 0;
- f_newwin();
- upd_wind(0);
-#endif /*ONEWINDOW*/
-
- /* Now, visit the given file and line */
-#ifdef ONEWINDOW
-#else
- f_othwind(); /* To other window */
-#endif
- find_file(file);
- f_gobeg();
- down_line(lineno - 1);
-#ifdef READJUST /* NAW */
- exp_p = 1;
- exp = cur_win->w_ht / 4; /* Adjust how we look at "error" */
- f_newwin();
-#endif /*READJUST*/
- return;
-
-failed: ding("No more errors!");
- fresh_make = 1; /* Fake-out: pretend starting over */
- return;
-}
-\f
-
-/* Do the "cmd" and put its output in the Execution buffer */
-do_exec(cmd, nicely)
-char *cmd;
-int nicely;
-{
- register int n;
- int status, res, pid, fd[2];
- char nicecmd[256];
- char pipebuff[512];
- struct buffer *b;
-
- b = cur_buf;
- sel_execbuf(); /* Get our execution buffer up */
- ed_reset(); /* Clear it out */
- fresh_make = 1;
- upd_wind(0);
- if (nicely)
- sayntoo(" ...starting up...");
- else
- sayntoo(" ...starting up (nasty person)...");
- pipe(fd);
- switch (pid = fork())
- {
- case -1:
- /* Fork failed, in parent */
- ding("Cannot fork!?!");
- break;
-
- case 0: /* In child */
- for (n = 0; n < 20; ++n)
- if (n != fd[0] && n != fd[1])
- close(n);
- open("/dev/null", 0); /* Give ourselves empty stdin */
- dup(fd[1]);
- dup(fd[1]); /* stdout, stderr out to pipe */
- close(fd[1]); /* Close the pipe itself */
- close(fd[0]);
- if (nicely)
- { strcpy(nicecmd, "nice -4 ");
- strcat(nicecmd, cmd);
- execl("/bin/sh", "sh", "-c", nicecmd, 0);
- }
- else
- execl("/bin/sh", "sh", "-c", cmd, 0);
- write(1, "Cannot execute!", 15);
- _exit(-1);
- break;
-
- default:
- /* Parent */
- close(fd[1]); /* Close the output direction */
- while ((n = read(fd[0], pipebuff, sizeof(pipebuff))) > 0)
- { ed_nsins(pipebuff, n);
- upd_wind(0);
- saynow("Chugging along...");
- }
- close(fd[0]);
- while ((res = wait(&status)) != pid && res != -1)
- ; /* Wait for this fork to die */
- f_bufnotmod(); /* Buffer is fresh */
- saynow("Done!");
- break;
- }
- f_othwind(); /* Back to other window */
- chg_buf(b); /* Back to original buffer */
-}
-
-char last_make_cmd[256]; /* Last Unix/make command */
-int have_last_make_cmd = 0;
-
-make_or_unix_cmd(domake)
-int domake;
-{
-#if APOLLO
- register int nicely = exp == 16; /* modification for apollo */
-#else
- register int nicely = exp != 16;
-#endif /*-APOLLO*/
- register char *reply, *cmd = 0;
-
- if (domake) /* If "make"-style, */
- { int savp = exp_p;
- exp_p = 1;
- f_savefiles(); /* write modified files quietly */
- exp_p = savp;
- }
- if (exp_p || ! domake)
- { /* Arg given make, or Unix command */
- reply = ask((! domake) ? "Unix command: " : "Command: ");
- if (! reply)
- return;
- if (*reply == 0)
- { if (have_last_make_cmd)
- cmd = &last_make_cmd[0];
- else
- { chkfree(reply);
- ding("No previous command!");
- return;
- }
- }
- else
- cmd = reply;
- if (cmd != &last_make_cmd[0]) /* Update last command */
- strcpy(last_make_cmd, cmd);
- have_last_make_cmd = 1;
- say("Command: ");
- sayntoo(cmd);
- do_exec(cmd, nicely);
- chkfree(reply);
- }
- else if (have_last_make_cmd)
- { say("Command: ");
- sayntoo(last_make_cmd);
- do_exec(last_make_cmd, nicely);
- }
- else
- { saynow("Command: make");
- do_exec("make", nicely);
- }
-}
-\f
-sel_execbuf()
-{ if(!exec_buf)
- { /* Make execution buffer; don't let anyone kill it */
- exec_buf = make_buf("Execution");
- exec_buf->b_flags |= B_PERMANENT;
- }
- popto_buf(exec_buf);
-}
-
-/* Utility: pop the given buffer to a window, getting into 2-window mode */
-popto_buf(b)
-register struct buffer *b;
-{
- /* See if we already have this buffer in a visible window */
- if (b == cur_win->w_buf)
- { if (oth_win == 0)
- { f_2winds();
- f_othwind(); /* Get back to our window */
- }
- }
- else if (oth_win != 0 && b == oth_win->w_buf)
- f_othwind();
- else if (oth_win == 0)
- { /* One window mode */
- f_2winds(); /* Get two, get into second */
- sel_buf(b); /* Select our new buffer */
- }
- else
- { f_othwind(); /* Get to other window */
- sel_buf(b); /* and select our buffer */
- }
-}
-
-#endif /*IMAGEN*/
+++ /dev/null
-#define PROF_VER (1)
-
-struct profile {
-int version;
-int chrvcnt; char *chrvec;
-int metavcnt; char *metavec;
-int extvcnt; char *extvec;
-int menuvcnt; char *menuvec;
-};
-
-struct stored_profile {
-unsigned char version[2];
-unsigned char chrvcnt[2], chrvec[2];
-unsigned char metavcnt[2], metavec[2];
-unsigned char extvcnt[2], extvec[2];
-unsigned char menuvcnt[2], menuvec[2];
-};
-
-#define prof_pack(p, n) ((p)[0] = (n) & 0xFF, (p)[1] = (n) >> 8)
-#define prof_upack(p) ((p)[0] | ((p)[1] << 8))
+++ /dev/null
-#ifndef _ANSI
-#include <minix/ansi.h>
-#endif
-
-/* eebit.c */
-_PROTOTYPE( int *chballoc, (int size) );
-_PROTOTYPE( int chbit, (int *array, int c) );
-_PROTOTYPE( int chbis, (int *array, int c) );
-_PROTOTYPE( int chbic, (int *array, int c) );
-
-/* eebuff.c */
-_PROTOTYPE( int f_selbuffer, (void) );
-_PROTOTYPE( int f_selxbuffer, (void) );
-_PROTOTYPE( int f_kbuffer, (void) );
-_PROTOTYPE( int f_listbufs, (void) );
-_PROTOTYPE( int f_bufnotmod, (void) );
-_PROTOTYPE( int f_eolmode, (void) );
-_PROTOTYPE( int f_gobeg, (void) );
-_PROTOTYPE( int f_goend, (void) );
-_PROTOTYPE( int f_whatpage, (void) );
-_PROTOTYPE( int init_buf, (void) );
-_PROTOTYPE( struct buffer *make_buf, (char *bname) );
-_PROTOTYPE( struct buffer *find_buf, (char *name) );
-_PROTOTYPE( int sel_buf, (struct buffer *b) );
-_PROTOTYPE( int chg_buf, (struct buffer *newbuf) );
-_PROTOTYPE( int unlk_buf, (struct buffer *bufp) );
-_PROTOTYPE( struct buffer *sel_mbuf, (struct buffer *buf) );
-_PROTOTYPE( struct buffer *sel_mbuf, (struct buffer *buf) );
-_PROTOTYPE( struct buffer *sel_nbuf, (struct buffer *buf) );
-_PROTOTYPE( int kill_buf, (struct buffer *buf) );
-_PROTOTYPE( int zap_buffer, (void) );
-_PROTOTYPE( int ask_kbuf, (struct buffer *buf) );
-_PROTOTYPE( int f_2winds, (void) );
-_PROTOTYPE( int f_1wind, (void) );
-_PROTOTYPE( int f_othwind, (void) );
-_PROTOTYPE( int f_growind, (void) );
-_PROTOTYPE( int f_shrinkwind, (void) );
-_PROTOTYPE( int f_delwind, (void) );
-_PROTOTYPE( int f_sowind, (void) );
-_PROTOTYPE( int f_2modewinds, (void) );
-_PROTOTYPE( int chk2modws, (void) );
-_PROTOTYPE( int init_win, (void) );
-_PROTOTYPE( int chg_win, (struct window *newwin) );
-_PROTOTYPE( struct window *make_win, (int pos, int ht, struct buffer *buf) );
-_PROTOTYPE( int kill_win, (struct window *win) );
-_PROTOTYPE( int mk_showin, (struct buffer *b) );
-_PROTOTYPE( struct window *make_mode, (struct window *bw) );
-_PROTOTYPE( int buf_mod, (void) );
-_PROTOTYPE( int buf_tmat, (chroff dot) );
-_PROTOTYPE( int buf_tmod, (chroff offset) );
-
-/* eecmds.c */
-_PROTOTYPE( int f_pfxmeta, (void) );
-_PROTOTYPE( int f_pfxext, (void) );
-_PROTOTYPE( int f_uarg, (int ch) );
-_PROTOTYPE( int f_negarg, (int ch) );
-_PROTOTYPE( int f_argdig, (int ch) );
-_PROTOTYPE( int f_setprof, (void) );
-_PROTOTYPE( int f_vtbuttons, (void) );
-_PROTOTYPE( int cmd_wait, (void) );
-_PROTOTYPE( int cmd_read, (void) );
-_PROTOTYPE( int cmd_xct, (int ch) );
-_PROTOTYPE( int cmd_idx, (int c) );
-_PROTOTYPE( void set_profile, (char *filename) );
-_PROTOTYPE( int init_menu, (void) );
-
-/* eediag.c */
-_PROTOTYPE( int f_debug, (int ch) );
-_PROTOTYPE( char *vfy_data, (int flag) );
-_PROTOTYPE( int dbg_diag, (void) );
-_PROTOTYPE( int vfy_exer, (int pf, int gcfrq) );
-_PROTOTYPE( int db_prwind, (struct window *w) );
-_PROTOTYPE( char *db_scflgs, (int flags) );
-
-/* eedisp.c */
-_PROTOTYPE( void set_tty, (void) );
-_PROTOTYPE( int clean_exit, (void) );
-_PROTOTYPE( int set_scr, (void) );
-_PROTOTYPE( void redisplay, (void) );
-_PROTOTYPE( int fupd_wind, (struct window *w) );
-_PROTOTYPE( int upd_curs, (chroff adot) );
-_PROTOTYPE( int d_line, (chroff cdot) );
-_PROTOTYPE( int d_ncols, (int lcnt, int ccol) );
-_PROTOTYPE( int d_lupd, (struct window *w, int idx) );
-_PROTOTYPE( int clear_wind, (struct window *w) );
-_PROTOTYPE( int fix_wind, (struct window *win) );
-_PROTOTYPE( int inwinp, (struct window *win, chroff cdot) );
-_PROTOTYPE( int upd_wind, (struct window *win) );
-_PROTOTYPE( int slineq, (struct scr_line *olds, struct scr_line *news) );
-_PROTOTYPE( int upd_line, (int y) );
-_PROTOTYPE( void fillset, (char *str, int cnt, int c) );
-_PROTOTYPE( void fillsp, (char *str, int cnt) );
-_PROTOTYPE( void inspc, (char *cp0, char *cpl, int cnt) );
-_PROTOTYPE( void fix_line, (struct scr_line *slp, struct scr_line *olds) );
-_PROTOTYPE( int sctrin, (char *to, int lim, int ccol) );
-_PROTOTYPE( int inslin, (int line, int n, struct window *win) );
-_PROTOTYPE( int dellin, (int line, int n, struct window *win) );
-_PROTOTYPE( int t_dostandout, (int on) );
-_PROTOTYPE( void t_move, (int y, int x) );
-_PROTOTYPE( int t_docleol, (void) );
-
-/* eeedit.c */
-_PROTOTYPE( int e_reset, (void) );
-_PROTOTYPE( int e_rgetc, (void) );
-_PROTOTYPE( int e_rdelc, (void) );
-_PROTOTYPE( int e_delc, (void) );
-_PROTOTYPE( int e_getc, (void) );
-_PROTOTYPE( int e_backc, (void) );
-_PROTOTYPE( int e_putc, (int c) );
-_PROTOTYPE( int e_peekc, (void) );
-_PROTOTYPE( int e_ovwc, (int ch) );
-_PROTOTYPE( SBSTR *e_copyn, (chroff off) );
-_PROTOTYPE( int e_deln, (chroff off) );
-_PROTOTYPE( int e_setcur, (void) );
-_PROTOTYPE( int e_gosetcur, (chroff dot) );
-_PROTOTYPE( int e_gocur, (void) );
-_PROTOTYPE( int e_gobob, (void) );
-_PROTOTYPE( int e_goeob, (void) );
-_PROTOTYPE( int e_go, (chroff dot) );
-_PROTOTYPE( int e_igoff, (int ioff) );
-_PROTOTYPE( int e_goff, (chroff off) );
-_PROTOTYPE( int e_gobol, (void) );
-_PROTOTYPE( int e_goeol, (void) );
-_PROTOTYPE( int e_gonl, (void) );
-_PROTOTYPE( int e_gopl, (void) );
-_PROTOTYPE( chroff e_dot, (void) );
-_PROTOTYPE( chroff e_nldot, (void) );
-_PROTOTYPE( chroff e_pldot, (void) );
-_PROTOTYPE( chroff e_boldot, (void) );
-_PROTOTYPE( chroff e_eoldot, (void) );
-_PROTOTYPE( chroff e_alldot, (SBBUF *sbp, int (*rtn )()) );
-_PROTOTYPE( chroff e_blen, (void) );
-_PROTOTYPE( int ex_reset, (struct buffer *b) );
-_PROTOTYPE( int ex_go, (SBBUF *sbp, chroff loc) );
-_PROTOTYPE( chroff ex_dot, (SBBUF *sbp) );
-_PROTOTYPE( chroff ex_boldot, (SBBUF *sbp, chroff dot) );
-_PROTOTYPE( chroff ex_alldot, (SBBUF *sbp, int (*rtn )(), chroff dot) );
-_PROTOTYPE( int ex_gonl, (SBBUF *sbp) );
-_PROTOTYPE( int ex_goeol, (SBBUF *sbp) );
-_PROTOTYPE( int ex_gobol, (SBBUF *sbp) );
-_PROTOTYPE( int ex_gopl, (SBBUF *sbp) );
-_PROTOTYPE( chroff ex_blen, (SBBUF *sbp) );
-_PROTOTYPE( int e_gofwsp, (void) );
-_PROTOTYPE( int e_gobwsp, (void) );
-_PROTOTYPE( int e_goline, (int i) );
-_PROTOTYPE( int e_lblankp, (void) );
-_PROTOTYPE( int e_insn, (int ch, int cnt) );
-_PROTOTYPE( int e_sputz, (char *acp) );
-_PROTOTYPE( int boleq, (chroff dot1, chroff dot2) );
-_PROTOTYPE( char *dottoa, (char *str, chroff val) );
-_PROTOTYPE( int e_gobpa, (void) );
-_PROTOTYPE( int e_goepa, (void) );
-_PROTOTYPE( int exp_do, (int (*rpos )(), int (*rneg )()) );
-_PROTOTYPE( int e_fwsp, (void) );
-_PROTOTYPE( int e_bwsp, (void) );
-_PROTOTYPE( int c_wsp, (int ch) );
-_PROTOTYPE( int c_pwsp, (int ch) );
-_PROTOTYPE( int delimp, (int c) );
-_PROTOTYPE( int e_wding, (chroff *adot, int n) );
-_PROTOTYPE( chroff e_wdot, (chroff dot, int n) );
-_PROTOTYPE( int e_gowd, (int n) );
-_PROTOTYPE( int e_search, (char *mstr, int mlen, int backwards) );
-
-/* eeerr.c */
-_PROTOTYPE( int f_bkpt, (void) );
-_PROTOTYPE( int bpt, (void) );
-_PROTOTYPE( char *strerror, (int num) );
-_PROTOTYPE( int errsbm, (int type, int (*adr )(), char *str, int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12) );
-_PROTOTYPE( int bite_bag, (int fault) );
-_PROTOTYPE( int hup_exit, (void) );
-_PROTOTYPE( int errint, (void) );
-_PROTOTYPE( int askerr, (void) );
-_PROTOTYPE( char *asklin, (char *acp) );
-
-/* eef1.c */
-_PROTOTYPE( int f_insself, (int c) );
-_PROTOTYPE( int f_quotins, (void) );
-_PROTOTYPE( int f_crlf, (void) );
-_PROTOTYPE( int f_fchar, (void) );
-_PROTOTYPE( int f_bchar, (void) );
-_PROTOTYPE( int f_dchar, (void) );
-_PROTOTYPE( int f_bdchar, (void) );
-_PROTOTYPE( int ef_deln, (int x) );
-_PROTOTYPE( int f_delspc, (void) );
-_PROTOTYPE( int f_tchars, (void) );
-_PROTOTYPE( int f_fword, (void) );
-_PROTOTYPE( int f_bword, (void) );
-_PROTOTYPE( int f_kword, (void) );
-_PROTOTYPE( int f_bkword, (void) );
-_PROTOTYPE( int f_twords, (void) );
-_PROTOTYPE( int f_ucword, (void) );
-_PROTOTYPE( int f_lcword, (void) );
-_PROTOTYPE( int f_uciword, (void) );
-_PROTOTYPE( int case_word, (int downp) );
-
-/* eef2.c */
-_PROTOTYPE( int f_begline, (void) );
-_PROTOTYPE( int f_endline, (void) );
-_PROTOTYPE( int f_nxtline, (void) );
-_PROTOTYPE( int f_prvline, (void) );
-_PROTOTYPE( int f_dnrline, (void) );
-_PROTOTYPE( int f_uprline, (void) );
-_PROTOTYPE( int f_oline, (void) );
-_PROTOTYPE( int f_delblines, (void) );
-_PROTOTYPE( int f_kline, (void) );
-_PROTOTYPE( int f_bkline, (void) );
-_PROTOTYPE( int f_goline, (void) );
-_PROTOTYPE( int down_bline, (int arg) );
-_PROTOTYPE( int down_line, (int x) );
-_PROTOTYPE( int f_setmark, (void) );
-_PROTOTYPE( int f_exchmark, (void) );
-_PROTOTYPE( int f_kregion, (void) );
-_PROTOTYPE( int f_copreg, (void) );
-_PROTOTYPE( int f_ucreg, (void) );
-_PROTOTYPE( int f_lcreg, (void) );
-_PROTOTYPE( int ef_creg, (int downp) );
-_PROTOTYPE( int f_fillreg, (void) );
-_PROTOTYPE( int chkmark, (void) );
-_PROTOTYPE( int f_fpara, (void) );
-_PROTOTYPE( int f_bpara, (void) );
-_PROTOTYPE( int f_mrkpara, (void) );
-_PROTOTYPE( int f_fillpara, (void) );
-
-/* eef3.c */
-_PROTOTYPE( int f_appnkill, (void) );
-_PROTOTYPE( int f_unkill, (void) );
-_PROTOTYPE( int f_unkpop, (void) );
-_PROTOTYPE( int f_indatm, (void) );
-_PROTOTYPE( int f_indnl, (void) );
-_PROTOTYPE( int f_backind, (void) );
-_PROTOTYPE( int f_indcomm, (void) );
-_PROTOTYPE( int f_indrel, (void) );
-_PROTOTYPE( int insertmatch, (int c) );
-_PROTOTYPE( int f_matchbrack, (void) );
-_PROTOTYPE( int matchonelevel, (int mc) );
-
-/* eefd.c */
-_PROTOTYPE( int f_newwin, (void) );
-_PROTOTYPE( int f_nscreen, (void) );
-_PROTOTYPE( int f_pscreen, (void) );
-_PROTOTYPE( int f_othnscreen, (void) );
-_PROTOTYPE( int f_lwindbord, (void) );
-_PROTOTYPE( int f_scupwind, (void) );
-_PROTOTYPE( int f_scdnwind, (void) );
-_PROTOTYPE( int f_mvwtop, (void) );
-_PROTOTYPE( int f_mvwbot, (void) );
-_PROTOTYPE( int d_screen, (int rep) );
-_PROTOTYPE( int scroll_win, (int n) );
-_PROTOTYPE( int d_curind, (void) );
-_PROTOTYPE( int indtion, (chroff lin) );
-_PROTOTYPE( int inindex, (chroff lin, int xpos) );
-_PROTOTYPE( int d_gopl, (void) );
-_PROTOTYPE( int d_gonl, (void) );
-_PROTOTYPE( int d_goloff, (int cnt) );
-_PROTOTYPE( int d_fgoloff, (int cnt) );
-_PROTOTYPE( int d_fixcur, (void) );
-_PROTOTYPE( int d_backup, (int nlin) );
-
-/* eefed.c */
-_PROTOTYPE( int ed_insert, (int c) );
-_PROTOTYPE( int ed_insn, (int ch, int cnt) );
-_PROTOTYPE( int ed_crins, (void) );
-_PROTOTYPE( int ed_sins, (char *s) );
-_PROTOTYPE( int ed_nsins, (char *s, int i) );
-_PROTOTYPE( int ed_indto, (int goal) );
-_PROTOTYPE( int ed_setcur, (void) );
-_PROTOTYPE( int ed_go, (chroff dot) );
-_PROTOTYPE( int ed_goff, (chroff off) );
-_PROTOTYPE( int ed_igoff, (int ioff) );
-_PROTOTYPE( int ed_reset, (void) );
-_PROTOTYPE( int ed_deln, (chroff off) );
-_PROTOTYPE( int ed_delete, (chroff dot1, chroff dot2) );
-_PROTOTYPE( int ed_kill, (chroff dot1, chroff dot2) );
-_PROTOTYPE( int kill_push, (SBSTR *sdp) );
-_PROTOTYPE( int ed_case, (chroff dot1, chroff dot2, int downp) );
-_PROTOTYPE( int upcase, (int ch) );
-
-/* eefile.c */
-_PROTOTYPE( int f_ffile, (void) );
-_PROTOTYPE( int f_rfile, (void) );
-_PROTOTYPE( int f_vfile, (void) );
-_PROTOTYPE( int u_r_file, (char *prompt) );
-_PROTOTYPE( int f_ifile, (void) );
-_PROTOTYPE( int f_sfile, (void) );
-_PROTOTYPE( int f_savefiles, (void) );
-_PROTOTYPE( int f_wfile, (void) );
-_PROTOTYPE( int f_wreg, (void) );
-_PROTOTYPE( int f_wlastkill, (void) );
-_PROTOTYPE( int hack_file, (char *prompt, int (*rtn )()) );
-_PROTOTYPE( int find_file, (char *f_name) );
-_PROTOTYPE( int read_file, (char *f_name) );
-_PROTOTYPE( int ins_file, (char *f_name) );
-_PROTOTYPE( int ferr_ropn, (void) );
-_PROTOTYPE( int ferr_wopn, (void) );
-_PROTOTYPE( int ferr, (char *str) );
-_PROTOTYPE( char *fncons, (char *dest, char *pre, char *f_name, char *post) );
-_PROTOTYPE( char *last_fname, (char *f_name) );
-_PROTOTYPE( int set_fn, (char *string) );
-_PROTOTYPE( int saveworld, (struct buffer *bp, int grunt) );
-_PROTOTYPE( int hoard, (void) );
-_PROTOTYPE( int unhoard, (void) );
-_PROTOTYPE( int expand_file, (char *dfn, char *sfn) );
-
-/* eefill.c */
-_PROTOTYPE( int f_sfcol, (void) );
-_PROTOTYPE( int f_sfpref, (void) );
-_PROTOTYPE( int tstfillp, (int lim) );
-_PROTOTYPE( int ed_fill, (chroff begloc, chroff endloc, int flag) );
-_PROTOTYPE( int f_fillmode, (void) );
-_PROTOTYPE( int fx_insfill, (int c) );
-_PROTOTYPE( int fill_cur_line, (void) );
-_PROTOTYPE( int f_textmode, (void) );
-_PROTOTYPE( int fim_insself, (int c) );
-_PROTOTYPE( int fim_dchar, (void) );
-_PROTOTYPE( int fim_bdchar, (void) );
-_PROTOTYPE( int fim_crlf, (void) );
-_PROTOTYPE( int magic_wrap, (int tc) );
-_PROTOTYPE( int reveal, (char *msg, int v1, int v2, int v3) );
-_PROTOTYPE( int magic_backto_bol, (void) );
-_PROTOTYPE( int fill_current_line, (void) );
-
-/* eehelp.c */
-_PROTOTYPE( int f_describe, (void) );
-
-/* eekmac.c */
-_PROTOTYPE( int f_skmac, (void) );
-_PROTOTYPE( int f_ekmac, (void) );
-_PROTOTYPE( int f_xkmac, (void) );
-_PROTOTYPE( int f_vkmac, (void) );
-_PROTOTYPE( int km_getc, (void) );
-_PROTOTYPE( int km_inwait, (void) );
-_PROTOTYPE( int km_abort, (void) );
-_PROTOTYPE( int add_mode, (char *mode) );
-_PROTOTYPE( int remove_mode, (char *mode) );
-
-/* eemain.c */
-_PROTOTYPE( int doargs, (int argc, char **argv) );
-_PROTOTYPE( int initialize, (void) );
-_PROTOTYPE( int f_throw, (void) );
-_PROTOTYPE( int ring_bell, (void) );
-_PROTOTYPE( void f_retsup, (void) );
-_PROTOTYPE( void f_wfexit, (void) );
-_PROTOTYPE( int f_pshinf, (void) );
-_PROTOTYPE( char *memalloc, (SBMO size) );
-_PROTOTYPE( int chkfree, (SBMA ptr) );
-_PROTOTYPE( int ustrcmp, (char *str1, char *str2) );
-_PROTOTYPE( int writerr, (char *str) );
-_PROTOTYPE( int writez, (int fd, char *acp) );
-
-/* eemake.c */
-_PROTOTYPE( int f_xucmd, (void) );
-_PROTOTYPE( int f_make, (void) );
-_PROTOTYPE( int f_nxterr, (void) );
-_PROTOTYPE( int f_xucmd, (void) );
-_PROTOTYPE( int f_make, (void) );
-_PROTOTYPE( int f_nxterr, (void) );
-_PROTOTYPE( int do_exec, (char *cmd, int nicely) );
-_PROTOTYPE( int make_or_unix_cmd, (int domake) );
-_PROTOTYPE( int sel_execbuf, (void) );
-_PROTOTYPE( int popto_buf, (struct buffer *b) );
-
-/* eequer.c */
-_PROTOTYPE( int f_querep, (void) );
-_PROTOTYPE( int f_repstr, (void) );
-_PROTOTYPE( int f_repline, (void) );
-_PROTOTYPE( int ed_dorep, (int type, struct majmode *mode) );
-
-/* eeques.c */
-#if 0
-_PROTOTYPE( char *ask, (char *string, char *arg1, char *arg2, char *arg3) );
-#else
-char *ask();
-#endif
-_PROTOTYPE( int askclr, (void) );
-_PROTOTYPE( int say, (char *str) );
-_PROTOTYPE( int saynow, (char *str) );
-_PROTOTYPE( int saytoo, (char *str) );
-_PROTOTYPE( int sayntoo, (char *str) );
-_PROTOTYPE( int ding, (char *str) );
-_PROTOTYPE( int dingtoo, (char *str) );
-_PROTOTYPE( int saylntoo, (char *str, int n) );
-_PROTOTYPE( int sayclr, (void) );
-#if 0
-_PROTOTYPE( int sayall, (char *str, int flags, int len) );
-#else
-int sayall();
-#endif
-_PROTOTYPE( int yellat, (char *str, int line) );
-_PROTOTYPE( int yelltoo, (char *str) );
-_PROTOTYPE( int errbarf, (char *str) );
-_PROTOTYPE( int barf, (char *str) );
-_PROTOTYPE( int barf2, (char *str) );
-
-/* eesite.c */
-_PROTOTYPE( int ts_inp, (void) );
-_PROTOTYPE( int ts_init, (void) );
-_PROTOTYPE( int ts_enter, (void) );
-_PROTOTYPE( int ts_exit, (void) );
-_PROTOTYPE( int tpoke, (int cmd, int bn, int val) );
-_PROTOTYPE( int ts_pause, (void) );
-
-/* eesrch.c */
-_PROTOTYPE( int f_srch, (void) );
-_PROTOTYPE( int f_rsrch, (void) );
-_PROTOTYPE( int lin_search, (int backwards) );
-_PROTOTYPE( int srchint, (void) );
-_PROTOTYPE( char *srch_ask, (char *prompt) );
-_PROTOTYPE( int f_risrch, (void) );
-_PROTOTYPE( int f_isrch, (void) );
-_PROTOTYPE( int i_search, (int back) );
-
-/* eeterm.c */
-_PROTOTYPE( int t_init, (void) );
-_PROTOTYPE( int t_fatal, (char *str) );
-_PROTOTYPE( int t_enter, (void) );
-_PROTOTYPE( int t_exit, (void) );
-_PROTOTYPE( int t_clear, (void) );
-_PROTOTYPE( int t_curpos, (int lin, int col) );
-_PROTOTYPE( int t_backspace, (void) );
-_PROTOTYPE( int t_bell, (void) );
-_PROTOTYPE( int t_cleol, (void) );
-_PROTOTYPE( int t_inslin, (int n, int bot) );
-_PROTOTYPE( int t_dellin, (int n, int bot) );
-_PROTOTYPE( int t_inschr, (int n, char *str) );
-_PROTOTYPE( int t_delchr, (int n) );
-_PROTOTYPE( int t_standout, (int on) );
-_PROTOTYPE( int t_direct, (int lin, int col, char *str, int len) );
-_PROTOTYPE( int tput, (int ch) );
-_PROTOTYPE( int tputz, (char *str) );
-_PROTOTYPE( int tputn, (char *str, int cnt) );
-_PROTOTYPE( int tbufls, (void) );
-_PROTOTYPE( int tgetc, (void) );
-_PROTOTYPE( int tinwait, (void) );
-
-/* eevini.c */
+++ /dev/null
-/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/*
- * EEQUER Query-Replace and Replace-String functions
- */
-
-#include "elle.h" /* include structure definitions */
-
-/* EFUN: "Query Replace" */
-/* Crude approximation of EMACS function.
- */
-f_querep()
-{ static struct majmode iqrpmode = { "Query Replace" };
- ed_dorep(0, &iqrpmode);
-}
-
-/* EFUN: "Replace String" */
-/* Similar to Query Replace and uses same code.
- */
-f_repstr()
-{ static struct majmode irepmode = { "Replace String" };
- ed_dorep(1, &irepmode);
-}
-
-#if FX_REPLINE
-/* EFUN: "Replace in Line" (not EMACS) */
-/* Acts like Replace String but only operates on current line.
-** Currently a big crock.
-** Feature of crockishness is that Unkill Pop (M-Y) will restore old
-** line.
-*/
-f_repline()
-{
- extern struct buffer *make_buf();
- struct buffer *b, *oldb = cur_buf;
- static struct majmode rlmode = { "Replace in Line" };
-
- if(!(b = make_buf(" **LINE**")))
- { ring_bell();
- return;
- }
- f_kline(); /* Kill line(s) from original buffer */
- chg_buf(b); /* Switch to temp buffer */
- f_unkill(); /* Get killed stuff into temp buffer */
- e_gosetcur((chroff)0); /* Starting at beginning, */
- ed_dorep(1, &rlmode); /* Execute Replace String on it. */
- ed_kill((chroff)0, e_blen()); /* Now kill everything in it, */
- chg_buf(oldb); /* switch back to original buffer, */
- f_unkill(); /* and restore new stuff! */
- kill_buf(b); /* Now flush temporary buffer. */
-}
-#endif
-
-
-/* Note that the major mode is set without changing the buffer's major
- * mode. When the function is done, the current major mode is reset
- * from the buffer mode.
- */
-ed_dorep(type, mode) /* 0 = Query Replace, 1 = Replace String */
-int type;
-struct majmode *mode;
-{ register int c;
- register int olen, allflg;
- char *srch_ask();
- char *opromp, *npromp;
- char *nstr, *ostr; /* Note ostr is == to srch_str */
- int nlen;
- chroff last_loc;
-#if IMAGEN
- int nrepled = 0;
- char replmsg[64];
-#endif /*IMAGEN*/
-
- /* Set mode, then get search string and replace string */
-#if IMAGEN
- cur_win->w_buf->b_flags |= B_QUERYREP;
-#else
- cur_mode = mode; /* Set major mode pointer */
-#endif /*-IMAGEN*/
-
- redp(RD_MODE);
- nstr = 0;
-#if IMAGEN
- opromp = "Old string: ";
- npromp = "New string: ";
-#else
- opromp = "Replace string: ";
- npromp = "with string: ";
-#endif /*-IMAGEN*/
- if((ostr = srch_ask(opromp)) == 0)
- goto done;
- olen = srch_len; /* srch_ask sets this! */
- if((nstr = ask("%s%s %s", opromp, ostr, npromp)) == 0)
- goto done;
- nlen = ask_len;
-
- /* Now enter search and subcommand loop */
- allflg = type; /* Unless 0 for Query Rep, replace all */
- for(;;)
- { last_loc = cur_dot;
- if(e_search(ostr,olen,0) == 0)
- break;
- ed_setcur(); /* Cursor moved */
- redisp:
- if(!allflg) redisplay(); /* Update screen */
- getcmd:
- if(!allflg) c = cmd_read();
- else c = SP;
- switch(c)
- {
-#if IMAGEN
- case 'n':
-#endif /*IMAGEN*/
- case DEL: /* Don't replace, go on */
- continue;
-#if IMAGEN
- case ',':
-#endif /*IMAGEN*/
- case '.': /* Replace and exit */
- case SP: /* Replace, go on */
- ed_delete(cur_dot,(chroff)(cur_dot-olen));
- ed_nsins(nstr,nlen);
-#if IMAGEN
- ++nrepled;
-#endif /*IMAGEN*/
- if(c == '.') goto done;
- continue;
-#if IMAGEN
- default:
-#endif /*IMAGEN*/
- case '?': /* Show options */
-#if IMAGEN
- saynow("\
-' '=>change, 'n'=>don't, '.'=>change, quit, '!'=>change rest, '^'=>back up");
-#else
- saynow("\
-SP=Replace, DEL=Don't, ESC=Stop, !=Replace all, ^=Back up, .=Replace & Stop");
-#endif /*-IMAGEN*/
- goto getcmd;
- case '^': /* Return to last place found */
- ed_go(last_loc);
- goto redisp;
-
- case CTRL('G'):
- case ESC: /* Exit where we are */
- goto done;
-
- case CTRL('L'): /* Redisplay */
- redp(RD_SCREEN);
- goto redisp;
-
- case '!': /* Replace all the rest */
- allflg++;
- goto getcmd;
-
-#if !(IMAGEN)
- case ',': /* Replace and show */
- case CTRL('R'): /* Enter edit mode recursively */
- case CTRL('W'): /* Delete once and ^R */
- saynow("not implemented");
- goto getcmd;
- default: /* Exit and re-read char */
- unrchf = c;
- goto done;
-#endif /*-IMAGEN*/
- }
- }
-done:
-#if IMAGEN
- cur_win->w_buf->b_flags &= ~B_QUERYREP;
-#else
- cur_mode = cur_buf->b_mode;
-#endif /*-IMAGEN*/
-
- redp(RD_MODE);
- if(nstr) /* Free nstr (but not ostr, it's == srch_str!) */
- chkfree(nstr);
-#if IMAGEN
- if (nrepled <= 0)
- saynow("No replacements done");
- else
- { sprintf(replmsg, "Replaced %d occurences", nrepled);
- saynow(replmsg);
- }
-#endif /*IMAGEN*/
-}
+++ /dev/null
-/* ELLE - Copyright 1982, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/* EEQUES - Handle queries and status displays
- */
-#include "elle.h"
-
-/*
- * Ask -- ask the user for some input on the lowest line of the screen
- *
- * The arg is a string in printf form, followed by up to three args
- * for the printf string
- *
- * The string is read into a sort of mini buffer, only the
- * last line of which is visible on the screen. All editing
- * features are available to the user to edit the input string.
- * When the delim character is typed, input is terminated and
- * The input string is passed back to the caller.
- * The delim is either an escape or a cr.
- * IT IS UP TO THE CALLER TO FREE THIS MEMORY.
- *
- * Note that the actual length of the returned string can be found
- * in the global variable ask_len. This is a crock but allows
- * callers to hack nulls in arg strings if they want to.
- */
-
-int chg_win();
-struct window *make_mode();
-
-static int ask_lin; /* Saved cursor location when ask is done */
-static int ask_blen; /* Non-zero if buffer contains something */
-static int ask_cnt; /* Incremented by ask(), cleared by askclr() */
-
-/* Table of allowed functions during ASK */
-static char askftab[] = {
- FN_PFXMETA, FN_INSSELF, FN_BEGLINE, FN_ENDLINE, FN_BCHAR, FN_FCHAR,
- FN_DCHAR, FN_BDCHAR, FN_TCHARS, FN_QUOTINS, FN_UARG, FN_BKPT,
- FN_DEBUG,
- FN_GOBEG, FN_GOEND, FN_FWORD, FN_BWORD, FN_KWORD, FN_BKWORD,
- FN_UCWORD, FN_LCWORD, FN_UCIWORD, FN_ARGDIG, FN_NEWWIN, FN_KLINE,
- FN_UNKILL, FN_BKLINE,
- 0
-};
-
-char *
-ask (string, arg1, arg2, arg3)
-char *string, *arg1, *arg2, *arg3;
-
-{ register int i, c;
- register char *s;
- struct window *oldwin;
- char *newline; /* where output line goes */
- char cbuf[200]; /* For prompt string creation */
- int p_length; /* length of prompt */
- chroff anslen; /* Length of answer */
- int funnum; /* Crock stuff */
-#if FX_FILLMODE
- extern int fill_mode;
- int ofillmode = fill_mode; /* Gotta turn this one off */
- fill_mode = 0;
-#endif /*FX_FILLMODE*/
-
- oldwin = cur_win;
- chg_win (ask_win);
- ed_reset(); /* Flush contents & request redisp */
- ask_lin = cur_win->w_pos; /* Set here in case never redisp */
- ask_cnt++; /* Bump # of times called */
-
- /* copy 'string' into line */
- cbuf[0] = 0;
-asklp: sprintf (&cbuf[strlen(cbuf)], string, arg1, arg2, arg3);
- p_length = strlen(cbuf); /* Find how long it is */
-
- /* now let the user type in */
- for(;;)
- {
- if ((rd_type & (RDS_WINFLGS|RD_MODE)) && tinwait () == 0)
- {
- e_gobob(); /* Gross crock: insert prompt */
- e_sputz(cbuf); /* Ugh, bletch */
- cur_dot += p_length; /* Temporarily update loc */
- redp(RD_WINRES); /* Do complete re-crunch */
- upd_wind((struct window *)0); /* Don't interrupt */
- /* Ensure mode line is spiffy too. This should
- ** only have to be invoked the first time ask_win
- ** redisplay is done, and never thereafter.
- */
- if(rd_type&RD_MODE) /* If mode also needs it, */
- fupd_wind(make_mode(user_win)); /* do it */
-
- upd_curs(cur_dot);
- rd_type &= ~(RDS_WINFLGS|RD_MODE);
- ask_lin = curs_lin; /* Remember line cursor on */
- tbufls();
-
- e_gobob(); /* More crock: Remove prompt */
- sb_deln((SBBUF *)cur_buf,(chroff)p_length); /* Ugh etc. */
- cur_dot -= p_length; /* Restore loc */
- e_gocur();
- }
- exp = 1;
- exp_p = 0;
- cont: this_cmd = 0;
- c = cmd_read();
-
- if (
-#if !(ICONOGRAPHICS)
- c == ESC ||
-#endif /*-ICONOGRAPHICS*/
- c == LF || c == CR)
- break;
- if (c == BELL) /* ^G means punt.. */
- { chg_win(oldwin);
- ask_blen = 1; /* Assume buffer has something */
- ding((char *)0); /* Clear echo window */
- ask_cnt = 0; /* Nothing for askclr to do */
-#if FX_SKMAC
- km_abort();
-#endif /*FX_SKMAC*/
-#if FX_FILLMODE
- fill_mode = ofillmode;
-#endif /*FX_FILLMODE*/
- return(0); /* Return 0 to indicate we quit */
- }
- /* This censoring section is a real crock! */
- funnum = cmd_idx(c); /* Map key to command */
- while(funnum == FN_PFXMETA) /* Allow META prefix */
- funnum = cmd_idx(c = CB_META|cmd_read());
- for(s = askftab; (i = *s&0377); ++s)
- if(funnum == i) break;
- switch(i)
- { default: /* Permissible function */
- cmd_xct(c);
- break;
- case FN_NEWWIN: /* Wants redisplay, do specially */
- clear_wind(ask_win);
- break;
- case 0: /* Illegal function */
- ring_bell();
-#if FX_SKMAC
- km_abort();
-#endif /*FX_SKMAC*/
- continue;
- }
- if(this_cmd == ARGCMD)
- goto cont;
- }
-
- if((anslen = e_blen()) > 255) /* Ridiculously long? */
- { strcpy(cbuf,"Huh? Try again - ");
-#if FX_SKMAC
- km_abort();
-#endif /*FX_SKMAC*/
- goto asklp;
- }
- i = anslen;
- e_gobob(); /* Go to start of buffer */
- e_sputz(cbuf); /* Re-insert prompt so buffer == screen */
- ask_blen = i + 1; /* Say buffer has something in it */
-
- s = memalloc((SBMO)(i + 1)); /* Allocate fixed loc for answer */
- newline = s; /* Return ptr to allocated string */
- ask_len = i; /* And return (via global) length of string */
- if(i) do { *s++ = e_getc(); }
- while(--i);
- *s = '\0'; /* make sure string terminated */
- chg_win(oldwin);
-#if FX_FILLMODE
- fill_mode = ofillmode;
-#endif /*FX_FILLMODE*/
- return (newline); /* return pointer to data */
-}
-
-/* ASKCLR - Clears the echo area (but not immediately) if the last thing
-** done to it was an ask() call. Note that invoking a SAY routine
-** specifically causes this to be a no-op; SAYCLR must be done instead.
-*/
-askclr()
-{
- if(ask_cnt) sayclr(); /* Zap if need be */
-}
-\f
-/* SAY - put up some text on bottom line.
- * Does this intelligently; text stays up until next SAY or
- * screen refresh.
- * SAYNOW - like SAY but forces display right away
- * SAYTOO - adds to existing stuff
- * SAYNTOO - ditto but forces output right away.
- * DING - Ring_bell then SAYNOW
- * DINGTOO - is to DING as SAYNTOO is to SAYNOW.
- * SAYCLR - Clears echo area (but not immediately)
- */
-#define SAY_NOW 01 /* Force display immediately */
-#define SAY_TOO 02 /* Add to existing stuff */
-#define SAY_BEL 04 /* Ding bell prior to text */
-#define SAY_LEN 010 /* String length specified by 3rd arg */
-
-say(str) char *str; { sayall(str, 0); }
-saynow(str) char *str; { sayall(str, SAY_NOW); }
-saytoo(str) char *str; { sayall(str, SAY_TOO); }
-sayntoo(str) char *str; { sayall(str, SAY_NOW|SAY_TOO); }
-ding(str) char *str; { sayall(str, SAY_NOW|SAY_BEL); }
-dingtoo(str) char *str; { sayall(str, SAY_NOW|SAY_TOO|SAY_BEL); }
-saylntoo(str,n) char *str; { sayall(str, SAY_NOW|SAY_TOO|SAY_LEN, n); }
-sayclr() { sayall((char *)0, 0); }
-
-sayall(str,flags,len)
-char *str;
-int flags, len;
-{ register struct window *w;
- register f;
-
- f = flags;
- w = cur_win;
-
- ask_cnt = 0; /* Always reset this */
- if(str == 0 && ask_blen == 0) /* If clearing, and buff empty */
- return; /* nothing to do. */
- chg_win(ask_win);
- if(f&SAY_TOO)
- e_goeob(); /* Add to end of existing stuff */
- else e_reset(); /* Flush previous stuff if any */
- if(str)
- { if(f&SAY_LEN) /* Insert string to post up */
- ed_nsins(str,len);
- else e_sputz(str);
- }
- ask_blen = e_dot(); /* Remember whether buffer has something */
-
- e_setcur(); /* and remember to set dot */
- if(f&SAY_NOW)
- { if(f&SAY_BEL)
- ring_bell();
- redp(RD_WINRES);
- upd_wind((struct window *)0);
- tbufls();
- }
- else redp(RD_WINRES); /* Set for this window */
- chg_win(w); /* Back to previous window */
-
- /* redisplay() does a special check for ask_win->w_redp, so we
- ** don't need to set a global flag like RD_CHKALL.
- */
-}
-\f
-/* YELLAT -- post string on specified line of screen, immediately.
- * Differs from SAYNOW and SAYNTOO in that NO buffer
- * manipulation is done; screen image is hacked directly.
- */
-
-yellat(str, line)
-char *str;
-register int line;
-{ register struct scr_line *s;
-
- s = scr[line];
- strncpy(s->sl_nlin, str, scr_wd0);
- s->sl_ncol = strlen(str);
-#if IMAGEN
- s->sl_flg |= SL_REDO;
-#endif
- upd_line(line);
- tbufls();
-}
-
-/* YELLTOO -- Append string to previous echo line of screen, immediately.
-** Uses the ask_lin variable which is set by ask().
-** Currently this function is only needed for srchint() in EESRCH.
-*/
-yelltoo(str)
-char *str;
-{ register int i;
- register struct scr_line *s;
- char nstr[MAXLINE];
-
- s = scr[ask_lin];
- i = s->sl_col;
- nstr[0] = 0;
- strncat(strncat(nstr, s->sl_line, i), /* Make new string */
- str, MAXLINE - i);
- yellat(nstr, ask_lin); /* Post it */
-}
-\f
-/* BARF - output a message on the bottom line of the screen,
-** bypassing everything (window, buffer, screen image).
-** Does NOT know about SAY's stuff and does not update it!
-** Use only in dire straits...
-** ERRBARF - same but uses a standard error-message prefix.
-*/
-
-errbarf(str)
-char *str;
-{
- barf("\007ELLE Internal Error: ");
- tputz(str);
- tbufls();
-}
-
-barf(str)
-char *str;
-{
- ask_cnt = 0; /* Ensure askclr() disabled */
- t_curpos(scr_ht - ECHOLINES, 0); /* goto echo area */
- t_cleol();
- tputz(str);
- tbufls();
- curs_col = -1000; /* Say we dunno where cursor is now */
-}
-
-#if IMAGEN
-/* Same, but do it far from harm's way */
-barf2(str)
-char *str;
-{
- t_curpos (scr_ht - 1, scr_wid - strlen(str) - 8);
- t_cleol ();
- tputz(str);
- tputz(" --M--");
- tbufls();
- tgetc(); /* Read any char & discard */
- curs_col = -1000; /* Say we dunno where cursor is now */
-}
-#endif /*IMAGEN*/
+++ /dev/null
-/* ELLE - Copyright 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/* EESIGS.H
- * This file is only provided for inclusion only by V6 systems, where
- * the standard /usr/include/signal.h file may not exist and thus we
- * need to do our own definitions.
- */
-
-/* Signals marked with "*" cause a core image dump
- * if not caught or ignored. */
-
-#define SIGHUP 1 /* Hangup (eg dialup carrier lost) */
-#define SIGINT 2 /* Interrupt (user TTY interrupt) */
-#define SIGQUIT 3 /* * Quit (user TTY interrupt) */
-#define SIGILL 4 /* * Illegal Instruction (not reset when caught) */
-#define SIGTRAP 5 /* * Trace Trap (not reset when caught) */
-#define SIGIOT 6 /* * IOT instruction */
-#define SIGEMT 7 /* * EMT instruction */
-#define SIGFPE 8 /* * Floating Point Exception */
-#define SIGKILL 9 /* Kill (cannot be caught or ignored) */
-#define SIGBUS 10 /* * Bus Error */
-#define SIGSEGV 11 /* * Segmentation Violation */
-#define SIGSYS 12 /* * Bad argument to system call */
-#define SIGPIPE 13 /* Write on a pipe with no one to read it */
-#define SIGALRM 14 /* Alarm Clock */
-#define SIGTERM 15 /* Software termination signal (from "kill" pgm) */
-
-#define SIG_DFL (int (*)())0 /* Arg to "signal" to resume default action */
-#define SIG_IGN (int (*)())1 /* Arg to "signal" to ignore this sig */
+++ /dev/null
-/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/* EESITE Site dependent frobs
- * Primarily TS_ routines for TTY control. Most site-dependent
- * routine is TS_INP for detection of TTY input.
- */
-
-#define _MINIX 1
-
-#include "elle.h"
-
-#if !(V6)
-#include <signal.h> /* For SIGTSTP in ts_pause */
-#else
-#include "eesigs.h"
-#endif
-
-int tsf_pause = 0; /* Set if ts_pause works. Ref'd by equit in e_main */
-
-#if !(SYSV || BBN) /* SYSV and BBN have weird tty calls */
-
-#if MINIX
-#include <sys/ioctl.h>
-#include <termios.h>
-struct termios origterm, newterm;
-#else
-#if V6
- /* Normal V6 declarations, must provide explicitly */
-struct sgttyb {
- char sg_ispeed;
- char sg_ospeed;
- char sg_erase;
- char sg_kill;
- int sg_flags;
-};
-#define ECHO (010)
-#define CRMOD (020)
-#define RAW (040)
-#else
- /* Normal V7 UNIX declarations, can use include file */
-#include <sgtty.h>
-#endif
-
-struct sgttyb nstate; /* Both V6 and V7 */
-struct sgttyb ostate; /* Both V6 and V7 */
-#endif /*!(SYSV || BBN)*/
-#endif /*!MINIX*/
-
-
-#if BBN /* BBN system frobs */
-#include "/sys/sys/h/modtty.h"
-struct modes nstate;
-struct modes ostate;
-#endif /*BBN*/
-
-#if DNTTY /* DN TTY frobs */
-#include <tty.h>
-char partab[2]; /* to satisfy obscene ref in tty.h */
-#endif /*DNTTY*/
-
-
-#if (UCB || TOPS20) /* UCB, TOPS20 additional frobs */
-#include <sys/ioctl.h> /* For ts_inp() and tldisc */
-#if IMAGEN
-struct tchars otchars, ntchars; /* Original and new tchars */
-#endif /*IMAGEN*/
-#endif /*(UCB || TOPS20)*/
-
-#if SYSV /* System V (and PC/IX) crocks */
-#include <termio.h>
-#include <sys/ioctl.h>
-
-struct termio /* terminal i/o status flags */
- origterm, /* status of terminal at start of ELLE */
- newterm; /* status of terminal when using ELLE */
-#endif /*SYSV*/
-
-/* TS_INP
- * Ask system if terminal input is available (on file descriptor 0).
- * Returns non-zero if so, else returns zero.
- * Very important that this call NOT hang or block in any way,
- * because it is used to detect type-ahead by the user;
- * return should be immediate whether or not input is waiting.
- */
-ts_inp()
-{
-#if BBN /* Idiosyncratic */
- int cap_buf[2];
- capac (0, &cap_buf[0], 4);
- return (cap_buf[0]);
-#endif /*BBN*/
-
-#if (DNTTY || ONYX) /* Have "empty()" syscall */
- return(empty(0) ? 0 : 1);
-#endif /*DNTTY || ONYX*/
-#if (UCB || TOPS20) /* Have FIONREAD ioctl */
- long retval;
- if(ioctl(0,FIONREAD,&retval)) /* If this call fails, */
- return(0); /* assume no input waiting */
- return((retval ? 1 : 0));
-#endif /*UCB || TOPS20*/
-#if COHERENT
- int retval;
- ioctl(0, TIOCQUERY, &retval);
- return((retval ? 1 : 0));
-#endif /*COHERENT*/
-#if VENIX86
- struct sgttyb iocbuf;
- ioctl(0, TIOCQCNT, &iocbuf);
- return(iocbuf.sg_ispeed != 0 );
-#endif /*VENIX86*/
-
-#if !(BBN||COHERENT||DNTTY||ONYX||TOPS20||UCB||VENIX86)
- return(0); /* Default - never any type-ahead, sigh */
-#endif
-}
-
-
-/* TS_INIT()
- * Get terminal information from system, initialize things for
- * ts_enter and ts_exit. This is called before t_init.
- * Must set "trm_ospeed".
- */
-ts_init()
-{
-#if DNTTY
- signal(16,1); /* DN peculiar - turn off ctl-A */
-#endif /*DNTTY*/
-
-#if !(MINIX || SYSV || BBN) /* Normal UNIX stuff */
- ioctl(1, TIOCGETP, &ostate); /* Remember old state */
- nstate = ostate; /* Set up edit-mode state vars */
- nstate.sg_flags |= RAW; /* We'll want raw mode */
- nstate.sg_flags &= ~(ECHO|CRMOD); /* with no echoing */
- trm_ospeed = ostate.sg_ospeed;
-
-#if (IMAGEN && UCB)
- /* Get around 4.1+ remote/local flow control bug (from Gosmacs) */
- ioctl(0, TIOCGETC, &otchars); /* Save original tchars */
- ntchars = otchars;
- ntchars.t_startc = -1; /* Kill start/stop */
- ntchars.t_stopc = -1;
- ioctl(0, TIOCSETC, &ntchars);
-#endif /*IMAGEN && UCB*/
-#endif /*!(SYSV || BBN)*/
-
-#if BBN
- modtty(1, M_GET | M_MODES, &ostate, sizeof(ostate)); /* Save old */
- modtty(1, M_GET | M_MODES, &nstate, sizeof(nstate)); /* Setup new */
- nstate.t_erase = nstate.t_kill = nstate.t_intr = nstate.t_esc =
- nstate.t_eof = nstate.t_replay = 0377;
- nstate.t_quit = BELL; /* ^G */
- nstate.t_breaks = TB_ALL; /* break on all */
- nstate.t_iflags &= ~TI_ECHO & ~TI_NOSPCL & ~TI_CRMOD;
- /* no echos, specials on, no CR -> LF*/
- nstate.t_iflags |= TI_CLR_MSB; /* ignore parity */
- nstate.t_oflags &= ~TO_CRMOD & ~TO_AUTONL; /* no CR -> NL */
- if (trm_flags & NOXONOFF)
- nstate.t_oflags &= ~TO_XONXOFF;
- else
- nstate.t_oflags |= TO_XONXOFF;
-
- nstate.t_oflags |= TO_CLR_MSB; /* no special high bits */
- nstate.t_pagelen = 0; /* no paging of output */
- trm_ospeed = ostate.t_ospeed;
-#endif /*BBN*/
-
-#if MINIX
- tcgetattr(0, &origterm); /* How things are now */
- newterm = origterm; /* Save them for restore on exit */
-
- /* input flags */
- newterm.c_iflag |= IGNBRK; /* Ignore break conditions.*/
- newterm.c_iflag &= ~INLCR; /* Don't map NL to CR on input */
- newterm.c_iflag &= ~ICRNL; /* Don't map CR to NL on input */
- newterm.c_iflag &= ~BRKINT; /* Do not signal on break.*/
- newterm.c_iflag &= ~IXON; /* Disable start/stop output control.*/
- newterm.c_iflag &= ~IXOFF; /* Disable start/stop input control.*/
-
- /* output flags */
- newterm.c_oflag &= ~OPOST; /* Disable output processing */
-
- /* line discipline */
- newterm.c_lflag &= ~ISIG; /* Disable signals.*/
- newterm.c_lflag &= ~ICANON; /* Want to disable canonical I/O */
- newterm.c_lflag &= ~ECHO; /* Disable echo.*/
- newterm.c_lflag &= ~ECHONL; /* Disable separate NL echo.*/
- newterm.c_lflag &= ~IEXTEN; /* Disable input extensions.*/
-
- newterm.c_cc[VMIN] = 1; /* Min. chars. on input (immed) */
- newterm.c_cc[VTIME] = 0; /* Min. time delay on input (immed) */
-
- /* Make it stick */
- tcsetattr(0, TCSANOW, &newterm);
-#endif /*MINIX*/
-
-#if SYSV
- ioctl(0, TCGETA, &origterm); /* How things are now */
- newterm = origterm; /* Save them for restore on exit */
-
- /* input flags */
- newterm.c_iflag |= IGNBRK; /* Ignore break conditions.*/
- newterm.c_iflag &= ~INLCR; /* Don't map NL to CR on input */
- newterm.c_iflag &= ~ICRNL; /* Don't map CR to NL on input */
- newterm.c_iflag &= ~BRKINT; /* Do not signal on break.*/
- newterm.c_iflag &= ~IXON; /* Disable start/stop output control.*/
- newterm.c_iflag &= ~IXOFF; /* Disable start/stop input control.*/
-
- /* line discipline */
- newterm.c_lflag &= ~ISIG; /* Disable signals.*/
- newterm.c_lflag &= ~ICANON; /* Want to disable canonical I/O */
- newterm.c_lflag &= ~ECHO; /* Disable echo.*/
-
- newterm.c_cc[4] = 1; /* Min. chars. on input (immed) */
- newterm.c_cc[5] = 1; /* Min. time delay on input (immed) */
-
- /* Make it stick */
- ioctl(0, TCSETA, &newterm);
-#endif /*SYSV*/
-
-#if (UCB || TOPS20)
- { int tldisc;
- ioctl(0, TIOCGETD, &tldisc); /* Find line discipline */
-
-/* The flag IGN_JOB_CONTROL has been introduced to allow job control haters
- * to simply ignore the whole thing. When ELLE is compiled with
- * -DIGN_JOB_CONTROL, it will exit properly when the Return to Superior
- * command is executed.
-*/
-#if SIGTSTP
-#ifndef IGN_JOB_CONTROL
- if(tldisc == NTTYDISC) tsf_pause = 1;
-#endif
-#endif /*SIGTSTP*/
-
- }
-#endif /*UCB || TOPS20*/
-}
-
-/* TS_ENTER()
- * Tell system to enter right terminal mode for editing.
- * This is called before t_enter.
- */
-ts_enter()
-{
-#if !(MINIX || SYSV || BBN)
- ioctl(1, TIOCSETP, &nstate);
-#if IMAGEN && UCB
- ioctl(0, TIOCSETC, &ntchars); /* Restore new tchars */
-#endif /*IMAGEN && UCB*/
-#endif /*!(SYSV||BBN)*/
-
-#if BBN
- modtty (1, M_SET | M_MODES, &nstate, sizeof (nstate));
-#endif /*BBN*/
-
-#if MINIX
- /* Make it behave as previously defined in ts_init */
- tcsetattr(0, TCSANOW, &newterm);
-#endif /*SYSV*/
-
-#if SYSV
- /* Make it behave as previously defined in ts_init */
- ioctl(0, TCSETA, &newterm);
-#endif /*SYSV*/
-
-#if DNTTY /* DN hackery! Enable 8-bit input so as to read meta bit. */
- if(dbg_isw)
- { tpoke(TH_CSET,T_2FLGS2,EEI); /* Enable ints */
- tpoke(TH_CSETB,T_QUIT, 0377); /* Turn off QUIT intrpt */
- }
- else if(trm_flags & TF_METAKEY)
- tpoke(TH_CSET,T_2FLGS2,T2_LITIN); /* Turn on 8-bit input! */
-#endif /*DNTTY*/
-}
-
-/* TS_EXIT
- * Tell system to restore old terminal mode (we are leaving edit mode).
- * This is called after t_exit.
- */
-ts_exit()
-{
-#if DNTTY
- if(dbg_isw)
- tpoke(TH_CCLR,T_2FLGS2,EEI); /* Turn off EEI bit */
- else if(trm_flags & TF_METAKEY)
- tpoke(TH_CCLR,T_2FLGS2,T2_LITIN); /* Turn off 8-bit input */
-#endif /*DNTTY*/
-
-#if !(MINIX || SYSV || BBN)
- ioctl(1, TIOCSETP, &ostate); /* SYSV and BBN don't use stty */
-#if IMAGEN && UCB
- ioctl(0, TIOCSETC, &otchars); /* Restore original tchars */
-#endif /*IMAGEN && UCB*/
-#endif /*!(SYSV || BBN)*/
-
-#if BBN
- modtty (1, M_SET | M_MODES, &ostate, sizeof (ostate));
-#endif /*BBN*/
-
-#if MINIX
- tcsetattr(0, TCSANOW, &origterm);
-#endif /*MINIX*/
-
-#if SYSV
- ioctl(0, TCSETA, &origterm);
-#endif /*SYSV*/
-}
-
-#if DNTTY
-int thkcmd[] { 0, 0, -1 };
-tpoke(cmd,bn,val)
-int cmd, bn, val;
-{
- thkcmd[0] = cmd|bn;
- thkcmd[1] = val;
- if(ttyhak(0,&thkcmd) < 0)
- return(-1);
- else return(thkcmd[1]);
-}
-#endif /*DNTTY*/
-
-
-/* TS_PAUSE - Stop process and return control of TTY to superior.
- * There is also a flag variable, TSF_PAUSE, which indicates
- * whether or not this routine will actually do anything.
- */
-#if TOPS20
-#include <jsys.h>
-#endif
-
-ts_pause()
-{
-#if TOPS20
- int acs[5];
- jsys(HALTF, acs);
-#endif
-
-#if UCB
-#if SIGTSTP
- signal(SIGTSTP, SIG_DFL);
-#if BSD4_2
-#define mask(s) (1 << ((s)-1))
- sigsetmask(sigblock(0) &~ mask(SIGTSTP));
-#endif /*BSD4_2*/
- kill(0, SIGTSTP);
-#if BSD4_2
- sigblock(mask(SIGTSTP));
-#endif /*BSD4_2*/
-#endif /*SIGTSTP*/
-#endif /*UCB*/
-}
-
-ts_winsize()
-{
-#ifdef TIOCGWINSZ
- struct winsize winsize;
-
- if (ioctl(1, TIOCGWINSZ, &winsize) == 0) {
- if (winsize.ws_row != 0) scr_ht = winsize.ws_row;
- if (winsize.ws_col != 0) scr_wid = winsize.ws_col;
- }
-#endif
-}
+++ /dev/null
-/* ELLE - Copyright 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/*
- * EESITE.H Site-dependent switches & definitions
- */
-
-/* CONDITIONAL COMPILATION SWITCHES */
-
-#define V6 0 /* Running on V6 system (else V7 assumed) */
-
-#define APOLLO 0 /* Running on an Apollo system */
-#define BBN 0 /* Running on BBN system (tty stuff) */
-#define BSD4_2 0 /* Running on 4.2BSD system */
-#define COHERENT 0 /* Running on Coherent IBM-PC system */
-#define DNTTY 0 /* Running on SRI V6 Deafnet system (tty stuff) */
-#define HPUX 0 /* Running on Hewlett-Packard System V + */
-#define MINIX 1 /* Running on MINIX (IBM-PC) system */
-#define ONYX 0 /* Running on ONYX Z8000 system */
-#define PCIX 0 /* Running on PC/IX (IBM-PC) system */
-#define SUN 0 /* Running on SUN workstation system */
-#define SYSV 0 /* Running on Unix System V (or perhaps Sys III) */
-#define TOPS20 0 /* Running on TOPS-20 KCC C implementation */
-#define UCB 0 /* Running on 2.8, 2.9, or 4.x BSD sys (tty stuff) */
-#define VENIX86 0 /* Running on Venix86 (IBM-PC) system */
-
-#define ICONOGRAPHICS 0 /* Using Iconographics configuration version */
-#define IMAGEN 0 /* Using Imagen configuration version */
-
-/* Resolve system dependencies */
-#if SUN
-#undef BSD4_2
-#define BSD4_2 1 /* SUN uses 4.2BSD */
-#endif
-
-#if BSD4_2
-#undef UCB
-#define UCB 1 /* 4.2 is special case of general UCB stuff */
-#endif /*BSD4_2*/
-
-#if (PCIX || HPUX)
-#undef SYSV
-#define SYSV 1 /* PC/IX & HP-UX are based on System III & V (resp) */
-#endif
-\f
-/* Set system or site dependent stuff here */
-
-#if V6
-#define void int /* May need this for other systems too */
-#endif
-
-/* Changes to parameters (elle.h) or variable defaults (e_vinit.c) */
-
-#if COHERENT
-#define EVFNO2 0 /* "Old" filename postfix - use no old file! */
-#define EVFNN2 "+" /* "New" filename postfix */
-#define TX_COHIBM 1 /* Ensure Coherent IBM-PC console support included */
-#endif /*COHERENT*/
-
-#if DNTTY
-#define EVLLEN 60 /* Short line length for TDDs */
-#endif /*DNTTY*/
-
-#if HPUX
-#define EVFNO2 "~" /* Same as CCA Emacs. Sorts last in listing. */
-#endif /*HPUX*/
-
-#if MINIX
-#define EVFNO2 ".bak" /* "Old" filename postfix */
-#define EVMARKSHOW "Mark set"
-#define EVCCOL (33) /* Use this as Comment Column */
-#define EVMVPCT 1 /* 1% - Try to use minimal window repositioning */
-#define EVMODWSO 1 /* Use mode window standout if can */
-#define STRERROR 1 /* Say that implementation provides strerror() */
-
-#include <sys/types.h>
-#include <string.h>
-#include <unistd.h>
-#include <stdio.h>
-#endif /*MINIX*/
-
-#if ONYX
-#define STKMEM (4*512) /* ONYX Z8000 seems to have less room avail */
-#endif /*ONYX*/
-
-#if BSD4_2
-#define FNAMELEN 255 /* Max size of last filename component */
-#define FNAMSIZ 400 /* Max size of complete filename */
-#endif /*BSD4_2*/
-
-#if TOPS20
-#define EVHELPFILE "elle:help.dat" /* T20 ELLE help file */
-#define EVPROFBINFILE "ellep.b1" /* T20 binary profile file */
-#define EVPROFTEXTFILE "ellep.e" /* T20 ASCII profile file */
-#define EVFNO2 0 /* No old filename postfix (T20 has generations) */
-#define EVFNN2 0 /* No new filename postfix (T20 has generations) */
-#define FNAMELEN (40*3) /* Max size of non-directory filename component */
-#define FNAMSIZ (40*5) /* Max size of complete filename */
-#define STRERROR 1 /* Say that implementation provides strerror() */
-#endif /*TOPS20*/
-
-#if VENIX86
-#define TIBFSIZ 1 /* Venix86 block reads in raw mode */
-#endif /*VENIX86*/
-
-/* Configuration settings */
-
-#if ICONOGRAPHICS
-#define EVFNO2 "@" /* "Old" filename postfix */
-#define EVMARKSHOW "Set."
-#define PARABLOCK 1 /* Values meaningful only for ICONOGRAPHICS */
-#define PARALINE 2
-#define TXC_VISBEL 1 /* Use visible bell if possible */
-#endif /*ICONOGRAPHICS*/
-
-#if IMAGEN
-#define EVFNO2 ".BAK" /* "Old" filename postfix */
-#define EVMARKSHOW "Mark set"
-#define TOBFSIZ (10*80) /* Size of TTY output buffer */
-#define ECHOLINES 2 /* Use 2 echo-area lines, not 1 */
-#define MAXARGFILES 10 /* Several startup filename args */
-#endif /*IMAGEN*/
-\f
-/* Now set any defaults for things not already defined */
-
-/* TERMINAL SUPPORT SWITCHES */
-/* Only those terminals which have a switch defined here */
-/* will be included in ELLE's "hardwired" support. */
-/* Switch name: Compiles support for: */
-#ifndef TX_TERMCAP
-#define TX_TERMCAP 1 /* * - most TERMCAP-defined terminals */
-#endif
-#ifndef TX_H19
-#define TX_H19 1 /* "H19" - Heath/Zenith-19 */
-#endif
-#ifndef TX_DM2500
-#define TX_DM2500 1 /* "DM2500","DM3025" - Datamedia 2500 */
-#endif
-#ifndef TX_COHIBM
-#define TX_COHIBM 0 /* "COHIBM" - Coherent IBM-PC console */
-#endif
-#ifndef TX_TVI925
-#define TX_TVI925 0 /* "TVI925" - TeleVideo 925 */
-#endif
-#ifndef TX_OM8025
-#define TX_OM8025 0 /* "OM8025" - Omron 8025AG */
-#endif
-
-#ifndef TXC_VISBEL /* Non-zero if want to use visible bell */
-#define TXC_VISBEL 0
-#endif
-
-/* Default terminal type string, used if ELLE cannot get type either
-** from $TERM or from startup args.
-*/
-#ifndef TXS_DEFAULT
-#define TXS_DEFAULT "H19" /* Default terminal type string */
-#endif
-
-/* Combination parameter/switch definitions */
-
-/* STKMEM - System-dependent stack allocation crock, defines amount of
- * stack memory to grab for general-purpose use. This is mainly
- * useful for PDP-11s or machines with similarly brain-damaged
- * address space hardware. A PDP-11 memory segment is 8K bytes,
- * or 16 512-byte blocks, and the stack segment quarantines all of
- * this space even though the actual stack may only use a miniscule
- * portion of it.
- */
-
-/* Use this if compiling for a PDP11 system, otherwise leave undefined.. */
-#if (V6 || 0)
-#define STKMEM (8*512) /* Use half a PDP11 segment */
-#endif
-
-/* These defaults are in eesite.h so ELLEC can get at them too. */
-#ifndef EVPROFBINFILE /* Location of binary user profile, relative to HOME */
-#define EVPROFBINFILE ".ellepro.b1"
-#endif
-#ifndef EVPROFTEXTFILE /* Location of ASCII user profile (used by ELLEC) */
-#define EVPROFTEXTFILE ".ellepro.e"
-#endif
+++ /dev/null
-/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/*
- * EESRCH Searching functions
- */
-
-#include "elle.h"
-#if !(V6)
-#include <signal.h>
-#else
-#include "eesigs.h" /* Use this on V6 system */
-#endif /*V6*/
-
-/*
- * Buffer String Search routines
- *
- * If no search string is provided, a string that was previously
- * used in the last search is once again used.
- */
-
-/* EFUN: "String Search" */
-f_srch()
-{ return (lin_search (0));
-}
-
-/* EFUN: "Reverse String Search" */
-f_rsrch()
-{ return (lin_search (1));
-}
-
-/* LIN_SEARCH - Main routine for non-incremental String Search. Asks for
- * a search string and looks for it.
- */
-lin_search (backwards)
-int backwards;
-{ register char *mem; /* item to be searched for */
- register int res;
- int srchint(), (*sav_srchalarm)();
- char *srch_ask();
- chroff savdot;
-
- savdot = cur_dot; /* Save original loc */
-
-#if ICONOGRAPHICS
- if((mem = srch_ask(backwards ? "Reverse Search%s%s%s"
- : "Search%s%s%s"))==0)
- return;
-#else
- if((mem = srch_ask(backwards ? "Reverse Search: " : "Search: "))==0)
- return;
-#endif /*-ICONOGRAPHICS*/
- sav_srchalarm = signal(SIGALRM,/*&*/srchint); /* Handle timeout */
- alarm(1); /* One sec from now */
-
- res = e_search(mem,srch_len,backwards); /* Search for str! */
-
- alarm(0); /* Turn off alarm */
- signal(SIGALRM,sav_srchalarm); /* Restore old handler */
-
- if(res) /* Search won? */
- { ed_setcur();
- return;
- }
-
- /* Search failed */
- e_gosetcur(savdot);
- ding("Search Failed");
-}
-
-srchint()
-{ yelltoo(" ...");
-}
-
-char *
-srch_ask(prompt)
-char *prompt;
-{ register char *ans, *old;
-
-#if ICONOGRAPHICS
- if (srch_str)
- ans = ask(prompt, " (", srch_str, "): ");
- else ans = ask (prompt, ": ", "", "");
- if (ans == 0) return (0);
-#else
- if((ans = ask(prompt)) == 0)
- return(0); /* user punted ... */
-#endif /*-ICONOGRAPHICS*/
- old = srch_str;
- if (*ans == '\0')
- { chkfree(ans);
- if ((ans = old) == 0) /* no string specified */
- { dingtoo("Nothing to search for");
- return(0);
- }
-#if !(ICONOGRAPHICS)
- saylntoo(old, srch_len); /* Show what old string is */
-#endif /*-ICONOGRAPHICS*/
- }
- else
- { if (old)
- chkfree(old); /* free up old srch string */
- srch_str = ans;
- srch_len = ask_len;
- }
- return(ans);
-}
-\f
-#if 0
- Incremental Search stuff.
-Description of EMACS behavior:
- ^Q quotes next char.
- DEL cancels last char. If this cancelled a match, point is moved
- to previous match.
- If not all of input can be found, it is not discarded. Can rub out,
- discard unmatched stuff with ^G, exit, etc.
- ^S repeats search forward; ^R repeats backward.
- If empty string, either
- changes direction (if not same)
- or brings back previous string
- ESC exits. If empty string, changes to non-incremental string search.
- ^G of a winning search aborts, exits, and moves point back to origin.
- ^G of a failing search discards the input that wasn''t found.
- Other C- or M- chars exit and are executed.
-ELLE also interprets ^H (BS) as DEL, because some keyboards make it hard to
- type DEL and there is no way the user can
- re-bind the incremental-search commands.
-#endif /*COMMENT*/
-
-#if FX_ISRCH
-/* EFUN: "Incremental Search" */
-f_isrch() { i_search(0); }
-#endif /*FX_ISRCH*/
-
-#if FX_RISRCH
-/* EFUN: "Reverse Search" */
-f_risrch() { i_search(1); }
-#endif /*FX_RISRCH*/
-
-#if FX_ISRCH || FX_RISRCH
-
-i_search(back)
-int back; /* Current mode: 0 if forward, 1 if backward */
-{ register int c;
- register int inpcnt; /* # chars in current input srch str */
- int inpgood; /* Length of last winning string */
- char inpstr[ISRCHLIM]; /* Holds current input search string */
- chroff inpdot[ISRCHLIM]; /* Holds winning addrs for each */
- struct window *savwin;
- int winning; /* 1 = currently winning, 0 = currently failing */
- int pref, shown;
- int f_insself(), (*(cmd_fun()))();
-
- winning = 1;
- inpcnt = 0;
- inpgood = 0;
- inpdot[0] = cur_dot;
- savwin = cur_win;
-
- /* Set up prompt and read all TTY input thus far */
- shown = 0;
- sloop: c = cmd_wait(); /* See if any command input waiting */
- if(shown || !c)
- { e_setcur(); /* Assume we moved around, so set cur_dot */
- chg_win(ask_win);
- ed_reset(); /* Flush contents & invoke redisplay */
- ed_sins(back ? "R-search: " : "I-search: ");
- ed_nsins(inpstr, inpcnt);
- if(!winning) ed_sins("\t(FAILING)");
- upd_wind((struct window *)0); /* Force ask_win update */
- if(c)
- { upd_curs(cur_dot);
- tbufls();
- }
- chg_win(savwin);
- shown = 1; /* Say search prompt has been shown */
- }
- if(!c) /* If no user input waiting, show buffer */
- { redp(RD_MOVE); /* Cursor moved in window */
- redisplay();
- }
- c = cmd_read(); /* Get input char */
- switch(c)
- { case DEL: /* Cancel last char */
- case BS: /* Hard to type DEL on some kbds */
- if(inpcnt <= 0) goto sloop;
- if(--inpcnt > inpgood) goto sloop;
- winning = 1;
- if(inpcnt == inpgood) goto sloop;
- inpgood--;
- ed_go(inpdot[inpcnt]);
- goto sloop;
-
- case CTRL('Q'):
- c = cmd_read(); /* Quote next char */
- break;
- case CTRL('S'):
- pref = 0;
- goto ctlsr;
- case CTRL('R'):
- pref = 1;
- goto ctlsr;
-
- case CTRL('G'):
- if(winning)
- { ed_go(inpdot[0]);
- goto sdone;
- }
- inpcnt = inpgood;
- winning = 1;
- goto sloop;
- case ESC:
- case CR:
- if(inpcnt)
- goto sdone;
- lin_search(back);
- return;
- default:
- if(f_insself != cmd_fun(c))
- { unrchf = c;
- goto sdone;
- }
- case TAB: /* Strange self-inserting char */
- break;
- }
- if(inpcnt >= ISRCHLIM-1)
- { ding("I-search str too long");
- sleep(1);
- goto sdone;
- }
- inpstr[inpcnt++] = c;
- if(!winning) goto sloop;
-
- /* Now search for string. (Arm alarm interrupt?) */
- /* cur_dot has current location cursor is at; we want to back off
- * from this so a repeated search will find the same location if
- * appropriate. */
- e_igoff(back ? inpcnt : -(inpcnt-1));
-dosrch:
- winning = e_search(inpstr,inpcnt,back);
- if (winning)
- { inpgood = inpcnt; /* Remember last win length */
- inpdot[inpcnt] = e_dot(); /* and location */
- }
- else e_gocur(); /* Back to start position */
- goto sloop;
-
- ctlsr: if (pref != back)
- { back = pref;
- if(inpcnt <= 0) goto sloop;
- }
- if(inpcnt <= 0)
- { if(!srch_str || (inpcnt = srch_len) <= 0)
- goto sloop;
- bcopy((SBMA)srch_str, (SBMA)inpstr, srch_len);
- inpcnt = srch_len;
- unrchf = c; /* Repeat cmd after display */
- shown = 1; /* Force search-string display */
- goto sloop;
- }
- goto dosrch;
-
- sdone:
- if(srch_str) chkfree(srch_str);
- srch_str = memalloc((SBMO)(inpcnt+1));
- bcopy((SBMA)inpstr,(SBMA)srch_str,inpcnt); /* Copy into srch_str */
- srch_len = inpcnt;
- e_setcur();
- chg_win(ask_win);
- ed_reset();
- chg_win(savwin);
- redp(RD_CHKALL);
-}
-#endif /*FX_ISRCH || FX_RISRCH*/
+++ /dev/null
-/* ELLE - Copyright 1982, 1984, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/*
- * EETERM ELLE Terminal Driver.
- * Directly supports DM2500, H-19, Omron 8025AG, Coherent/IBM-PC, TVI925.
- * Others also supported if using TX_TERMCAP.
- */
-
-#include "elle.h"
-
-/* Define terminal indices (there may be holes but C preprocessor is too
- * stupid to let us close them). Should be one TN_ definition for every
- * hardwired terminal type, even though whether or not it is actually
- * compiled depends on which TX_ switches are defined.
- */
-#define TN_TERMCAP 0
-#define TN_DM2500 1
-#define TN_H19 2
-#define TN_OM8025 3
-#define TN_COHIBM 4 /* Coherent IBM-PC console */
-#define TN_TVI925 5
-
-#if TX_COHIBM && !(TX_H19) /* Ensure H19 defined if COHIBM is. */
-#define TX_H19 1
-#endif
-
-#ifndef TXS_DEFAULT /* If no default is explicitly specified */
-#define TXS_DEFAULT "H19" /* Then settle for H-19 */
-#endif /*TXS_DEFAULT*/
-\f
-
-
-extern char *tv_stype; /* If set, specifies terminal type */
-extern int tibfmsk; /* Crock to mask off parity (meta) bit */
-static int tv_padc; /* Pad character to use */
-static int tv_cspeed; /* # msec per char (set from trm_ospeed) */
-static int tv_type; /* Index of selected terminal type */
-
-/* Internal functions */
-static void tpadn(), tpad();
-
-/* Character speed table, indexed by system output speed value (0-017).
- * Value in table is 100 * <# msec used per character>.
- */
-static int cspdtab[] =
-{ /* Val Idx Baud CPS Time/char in msec */
- 0, /* 0 Hangup - ---- */
- 13333, /* 1 50 7.5 133.33 (Baudot) */
- 10000, /* 2 75 10 100.0 (Baudot) */
- 10000, /* 3 110 10 100.0 */
- 8200, /* 4 134.5 12.2 82.0 (IBM2741) */
- 6666, /* 5 150 15 66.6666 */
- 5000, /* 6 200 20 50.0 */
- 3333, /* 7 300 30 33.3333 */
- 1666, /* 8 600 60 16.6666 */
- 833, /* 9 1200 120 8.3333 */
- 555, /* 10 1800 180 5.5555 */
- 416, /* 11 2400 240 4.1666 */
- 208, /* 12 4800 480 2.0833 */
- 104, /* 13 9600 960 1.04166 */
- 0, /* 14 Ext A ? ? */
- 0 /* 15 Ext B ? ? */
-};
-
-#if TX_TERMCAP
-/* Declarations for TERMCAP stuff. Only EETERM knows about them. */
-
-/* Termcap routines */
-extern int tgetent(), tgetnum(), tgetflag(), tputs();
-extern char *tgetstr(), *tgoto();
-static int getcap(); /* Internal routines */
-static void putpad(), putnpad(), putpar();
-
-/* Gross disgusting externals that must be defined for TERMCAP rtns */
-char PC; /* Pad char */
-char *BC; /* Backspace to use, if not ^H */
-char *UP; /* Cursor up */
-short ospeed; /* Terminal output speed */
-
-/* Termcap numerical values/flags */
-static int
- tc_am, /* TRUE if has auto-wrap */
- tc_km; /* TRUE if meta key exists */
-
-/* Termcap capability strings we want to know about */
-
-struct tcap { char tcicod1, tcicod2, *tccap; };
-static struct tcap tcap[] = {
-#define TC_al tcap[0].tccap /* Add (insert) line */
- {'a','l', 0},
-#define TC_AL tcap[1].tccap /* Add N lines */
- {'A','L', 0},
-#define TC_bc tcap[2].tccap /* Backspace Char (for BC) */
- {'b','c', 0},
-#define TC_ce tcap[3].tccap /* Erase to end of line (CLEOL) */
- {'c','e', 0},
-#define TC_cl tcap[4].tccap /* Clear screen */
- {'c','l', 0},
-#define TC_cm tcap[5].tccap /* Cursor motion */
- {'c','m', 0},
-#define TC_dc tcap[6].tccap /* Delete char */
- {'d','c', 0},
-#define TC_DC tcap[7].tccap /* Delete N chars */
- {'D','C', 0},
-#define TC_dl tcap[8].tccap /* Delete line */
- {'d','l', 0},
-#define TC_DL tcap[9].tccap /* Delete N lines */
- {'D','L', 0},
-#define TC_dm tcap[10].tccap /* Delete mode on */
- {'d','m', 0},
-#define TC_ed tcap[11].tccap /* Delete mode off */
- {'e','d', 0},
-#define TC_ei tcap[12].tccap /* Insert mode off */
- {'e','i', 0},
-#define TC_ia tcap[13].tccap /* Add line while in insert mode (see note) */
- {'i','a', 0},
-#define TC_ic tcap[14].tccap /* Insert blank char */
- {'i','c', 0},
-#define TC_IC tcap[15].tccap /* Insert N blank chars */
- {'I','C', 0},
-#define TC_id tcap[16].tccap /* Delete line while in del mode (see note) */
- {'i','d', 0},
-#define TC_im tcap[17].tccap /* Insert mode on */
- {'i','m', 0},
-#define TC_ip tcap[18].tccap /* Padding to send after char insertion */
- {'i','p', 0},
-#define TC_mm tcap[19].tccap /* String to set (turn on) meta-key mode */
- {'m','m', 0},
-#define TC_mo tcap[20].tccap /* String to reset (turn off) meta-key mode */
- {'m','o', 0},
-#define TC_pc tcap[21].tccap /* Pad Char (for PC) */
- {'p','c', 0},
-#define TC_se tcap[22].tccap /* End standout mode */
- {'s','e', 0},
-#define TC_so tcap[23].tccap /* Enter standout mode */
- {'s','o', 0},
-#define TC_te tcap[24].tccap /* String to end programs that use termcap */
- {'t','e', 0},
-#define TC_ti tcap[25].tccap /* String to beg programs that use termcap */
- {'t','i', 0},
-#define TC_up tcap[26].tccap /* Move cursor up (for UP) */
- {'u','p', 0},
-#define TC_vb tcap[27].tccap /* Visible bell */
- {'v','b', 0},
-};
-#define NTCAPS ((sizeof(tcap))/(sizeof(struct tcap))) /* # entries */
-
-/*
- * There are many other things that must be taken into account.
- * The termcap code here will probably not work for many termcap entries,
- * but the only sure way to find out which ones they are is to try them.
- */
-/* Note that the "ia" and "id" strings are not defined by the TERMCAP doc;
- * their usage here is derived from examining other TERMCAP-using programs.
- * Sigh!!!!
- */
-#endif /*TX_TERMCAP*/
-\f
-/* T_INIT is called once only at program startup, to identify the
- * terminal type and set up any one-time things.
- * T_FATAL is only called if some routine detects an error related to the
- * terminal specification, before any initialization is done.
- * It prints a short error message and exits the program.
- * T_ENTER is called after TS_ENTER to set the terminal parameters for
- * editing (as opposed to normal typeout). It may be called
- * several times.
- * T_EXIT is called before TS_EXIT to restore normal typeout modes.
- * It is called on exit from the program, and perhaps other times.
- */
-t_init()
-{
- char *getenv();
-
- /* Set some default parameters */
- scr_ht = 24;
- scr_wid = 79;
- trm_flags = 0;
- tvc_cin = 1; /* Assume 1 char per char I/D pos */
- tvc_cdn = 1;
- tvc_pos = 4; /* Default abs-move cost is 4 chars */
- tvc_bs = 1; /* Default backspace cost is 1 char */
- tv_cspeed = cspdtab[trm_ospeed]; /* Find # msec per char */
-
- /* First must determine terminal type, and check for terminals
- * that are hardwired into ELLE. */
- if(!tv_stype /* String set in command line args? */
-#if !(V6)
- && !(tv_stype = getenv("TERM")) /* or given by TERM var? */
-#endif /*-V6*/
- ) tv_stype = TXS_DEFAULT; /* No, try using default */
- if(0) ; /* Sigh, stupid construct */
-#if TX_H19
- else if(ustrcmp(tv_stype,"H19")) tv_type = TN_H19;
-#endif /*TX_H19*/
-#if TX_OM8025
- else if(ustrcmp(tv_stype,"OM8025")) tv_type = TN_OM8025;
-#endif /*TX_OM8025*/
-#if TX_DM2500
- else if(ustrcmp(tv_stype,"DM2500")) tv_type = TN_DM2500;
- else if(ustrcmp(tv_stype,"DM3025")) tv_type = TN_DM2500;
-#endif /*TX_DM2500*/
-#if TX_COHIBM
- else if(ustrcmp(tv_stype,"COHIBM")) tv_type = TN_COHIBM;
-#endif /*TX_COHIBM*/
-#if TX_TVI925
- else if(ustrcmp(tv_stype,"TVI925")) tv_type = TN_TVI925;
-#endif /*TX_TVI925*/
-#if TX_TERMCAP /* This should be last thing */
- else if(getcap(tv_stype)) tv_type = TN_TERMCAP;
-#endif /*TX_TERMCAP*/
- else t_fatal("type unknown"); /* Ugh, barf and exit */
-
- /* Terminal selected, now initialize parameters for it. */
- switch(tv_type)
- {
-#if TX_DM2500
- case TN_DM2500:
- tv_padc = 0177; /* Use rubout for pad */
- tvc_pos = 3; /* Only 3 chars for abs mov */
- tvc_ci = 2;
- /* tvc_cin = 1; */ /* Default is OK */
- tvc_cd = 2;
- /* tvc_cdn = 1; */ /* Default is OK */
- tvc_ld = 2;
- tvc_ldn = 1;
- tvc_li = 2;
- tvc_lin = 1;
- if(trm_ospeed == 13) /* If 9600, */
- { tvc_cin = 5; /* Sigh, high cost */
- tvc_cdn = 2;
- tvc_lin = 18;
- tvc_ldn = 2;
- }
- trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL|TF_METAKEY;
- break;
-#endif /*TX_DM2500*/
-#if TX_H19
- case TN_H19:
- trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL;
- tvc_ci = 8;
- /* tvc_cin = 1; */ /* default is ok */
- tvc_cd = 0;
- tvc_cdn = 2;
- /* tvc_ld = 0; */ /* Default is OK */
- tvc_ldn = 1 << (trm_ospeed - 7);
- /* tvc_li = 0; */ /* Default is OK */
- tvc_lin = tvc_ldn;
- break;
-#endif /*TX_H19*/
-#if TX_COHIBM
- case TN_COHIBM:
- trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL|TF_METAKEY|TF_DIRVID;
- /* Always use lowest possible costs */
- /* tvc_ci = 0; */ /* Default */
- tvc_cin = 2;
- /* tvc_cd = 0; */ /* Default */
- tvc_cdn = 2;
- /* tvc_ld = 0; */ /* Default */
- tvc_ldn = 2;
- /* tvc_li = 0; */ /* Default */
- tvc_lin = 2;
- break;
-#endif /*TX_COHIBM*/
-#if TX_OM8025
- case TN_OM8025:
- trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL;
- tvc_pos = 6;
- /* tvc_ci = tvc_cd = 0; */ /* Default */
- tvc_cin = 4;
- tvc_cdn = 2;
- /* tvc_ld = tvc_li = 0; */ /* Default */
- tvc_ldn = 10; /* Crude approx */
- tvc_lin = 10;
- if(trm_ospeed > 7) /* If faster than 300 baud */
- trm_flags &= ~TF_IDLIN; /* Turn off LID */
- break;
-#endif /*TX_OM8025*/
-#if TX_TVI925
- case TN_TVI925:
- trm_flags |= TF_IDLIN|TF_IDCHR|TF_CLEOL;
- tvc_ci = tvc_cd = tvc_cin = tvc_cdn
- = tvc_ldn = tvc_lin = 2;
- break;
-#endif /*TX_TVI925*/
- }
- if(tibfmsk < 0) /* If mask is still default -1, set it. */
- tibfmsk = ((trm_flags&TF_METAKEY) ? 0377 : 0177);
-}
-
-/* T_FATAL(str) - prints error message and exits.
-*/
-t_fatal(str)
-char *str;
-{ writerr("ELLE: \"");
- writerr(tv_stype);
- writerr("\" terminal ");
- writerr(str);
- writerr("\n");
- exit(1); /* Terminate with prejudice */
-}
-\f
-/* T_ENTER is called after TS_ENTER to set the terminal parameters for
- * editing (as opposed to normal typeout).
- * Standout mode must initially be off.
- */
-
-t_enter()
-{ switch(tv_type)
- {
-#if TX_TERMCAP
- case TN_TERMCAP:
- putpad(TC_ti);
- if(tc_km) putpad(TC_mm); /* Use meta if poss */
-#if FX_SOWIND
- t_standout(0); /* Ensure standout mode off */
-#endif
- break;
-#endif /*TX_TERMCAP*/
-#if TX_DM2500
- case TN_DM2500:
- tput(030); /* Just in case, flush stray modes */
- break;
-#endif /*TX_DM2500*/
-#if TX_COHIBM
- case TN_COHIBM: /* Note TN_H19 will exist too */
-#endif /*TX_COHIBM*/
-#if TX_H19
- case TN_H19:
- /* Enter ZDS (Heath) mode, then
- * Exit graphics mode (G) Exit ins-char mode (O)
- * exit rev video mode (q) exit hold-screen mode (\)
- * set cursor on (y5)
- */
- tputz("\033[?2h\033G\033O\033q\033\\\033y5");
- /* Set Discard-at-EOL (w)
- * Set no auto-CR (y9)
- * Enable 25th line (x1)
- */
- tputz("\033w\033y9\033x1");
- break;
-#endif /*TX_H19*/
- }
-}
-\f
-/* T_EXIT - Leave editing modes. This function should restore
-** the terminal's modes to what they were before ELLE was started.
-** Standout mode is turned off.
-*/
-
-t_exit()
-{
- switch(tv_type)
- {
-#if TX_TERMCAP
- case TN_TERMCAP:
- if(tc_km) putpad(TC_mo); /* Turn off meta */
- putpad(TC_te);
- break;
-#endif /*TX_TERMCAP*/
-#if TX_DM2500
- case TN_DM2500:
- tput(035); /* Turn on roll mode */
- break;
-#endif /*TX_DM2500*/
-#if TX_COHIBM
- case TN_COHIBM: /* If this exists, TN_H19 will too */
-#endif /*TX_COHIBM*/
-#if TX_H19
- case TN_H19:
- tputz("\033v"); /* Turn EOL-wrap back on */
-#if DNTTY
- tputz("\033<"); /* Return to ANSI mode */
-#endif /*DNTTY*/
- break;
-#endif /*TX_H19*/
- }
-}
-\f
-/* T_CLEAR() - Clears the screen and homes the cursor.
- * Always valid - ELLE refuses to support terminals without this.
- */
-
-t_clear ()
-{ switch(tv_type)
- {
-#if TX_TERMCAP
- case TN_TERMCAP:
- putnpad(TC_cl,scr_ht);
- break;
-#endif /*TX_TERMCAP*/
-#if TX_DM2500
- case TN_DM2500:
- tputz("\036\036"); /* Double Master Clear */
- break;
-#endif /*TX_DM2500*/
-#if TX_COHIBM
- case TN_COHIBM: /* Note TN_H19 will exist too */
-#endif /*TX_COHIBM*/
-#if TX_H19
- case TN_H19:
- tputz("\033E");
- /* tputn(zpadstr,9); */
- break;
-#endif /*TX_H19*/
-#if TX_OM8025
- case TN_OM8025:
- tputz("\033H\033J"); /* Home then CLEOS */
- tpad(1000); /* One second!!!! */
- break;
-#endif /*TX_OM8025*/
-#if TX_TVI925
- case TN_TVI925:
- tput(032); /* ^Z */
- break;
-#endif /*TX_TVI925*/
- }
- curs_lin = curs_col = 0;
-}
-\f
-/* T_CURPOS(y, x) - Absolute move. Place cursor in given position
- * regardless of where it currently is.
- * Updates curs_lin, curs_col.
- * Always valid -- ELLE refuses to support terminals without this.
- */
-
-t_curpos (lin, col)
-register int lin, col;
-{
- if(col > scr_wid) /* Easiest to catch here */
- col = scr_wid;
-
- /* Do absolute positioning */
- switch(tv_type)
- {
-#if TX_TERMCAP
- case TN_TERMCAP:
- putpad(tgoto(TC_cm, col, lin));
- break;
-#endif /*TX_TERMCAP*/
-#if TX_DM2500
- case TN_DM2500:
- tput(014);
- tput(col^0140);
- tput(lin^0140);
- break;
-#endif /*TX_DM2500*/
-#if TX_COHIBM
- case TN_COHIBM: /* If this exists, TN_H19 will too */
-#endif /*TX_COHIBM*/
-#if TX_H19
- case TN_H19:
- tputz("\033Y");
- tput(lin+040);
- tput(col+040);
- break;
-#endif /*TX_H19*/
-#if TX_OM8025
- case TN_OM8025:
- tputz("\033\175");
- tput(0100+((lin+1)>>4));
- tput(0100+((lin+1)&017));
- tput(0100+((col+1)>>4));
- tput(0100+((col+1)&017));
- break;
-#endif /*TX_OM8025*/
-#if TX_TVI925
- case TN_TVI925:
- tputz("\033=");
- tput(lin+040);
- tput(col+040);
- break;
-#endif /*TX_TVI925*/
- }
- curs_lin = lin;
- curs_col = col;
-}
-
-/* T_BACKSPACE() - Back up 1 character position.
- * Updates curs_col.
- * Only valid if tvc_bs has a "reasonable" value ( < 1000)
- */
-
-t_backspace()
-{
-#if TX_TERMCAP
- if(BC) tputz(BC); /* Use alternate BS */
- else
-#endif
- tput('\010'); /* Send BS */
- --curs_col;
-}
-
-/* T_BELL() - Ring terminal's bell (or flash something, or whatever).
- * Forces out all output thus far, to ensure immediate attention.
- * This used to be an unbuffered feep, but was changed to use normal
- * output path in order to avoid messing up terminal escape sequences.
- */
-t_bell()
-{
-#if TXC_VISBEL && TX_TERMCAP
- if(TC_vb)
- tputz(TC_vb); /* Do visible bell if possible */
- else
-#endif
- tput(BELL);
- tbufls(); /* Force it out */
-}
-\f
-/* T_CLEOL() - Clear to End Of Line.
- * Only valid if trm_flags has TF_CLEOL set.
- */
-
-t_cleol ()
-{
- switch(tv_type)
- {
-#if TX_TERMCAP
- case TN_TERMCAP:
- putpad(TC_ce);
- break;
-#endif /*TX_TERMCAP*/
-#if TX_DM2500
- case TN_DM2500:
- tput(027);
- break;
-#endif /*TX_DM2500*/
-#if TX_COHIBM
- case TN_COHIBM: /* If this exists, TN_H19 will too */
-#endif /*TX_COHIBM*/
-#if TX_H19
- case TN_H19:
- tputz("\033K");
- break;
-#endif /*TX_H19*/
-#if TX_OM8025
- case TN_OM8025:
- tputz("\033K");
- tpad(41); /* 1/25 sec padding */
- break;
-#endif /*TX_OM8025*/
-#if TX_TVI925
- case TN_TVI925:
- tputz("\033T");
- break;
-#endif /*TX_TVI925*/
- }
-}
-\f
-/* T_INSLIN(n, bot) - Insert lines in window.
- * n - # blank lines to insert.
- * bot - # of last line of current window
- *
- * The current line is moved down and N blank lines inserted.
- * Lines which are moved past bot are lost.
- * May leave cursor in random place.
- * Only valid if trm_flags has TF_IDLIN set.
- */
-
-t_inslin (n, bot)
-int n; /* number of lines */
-int bot; /* line number of last line in window */
-{ register i, j;
- int savc,savl;
-
- if((i = n) <= 0) return;
- if(bot < (scr_ht-1))
- { savc = curs_col;
- savl = curs_lin;
- t_curpos(bot-i, 0);
- t_dellin(i, scr_ht);
- t_curpos(savl, savc);
- }
- switch(tv_type)
- {
-#if TX_TERMCAP
- case TN_TERMCAP:
- if(TC_AL)
- putpar(TC_AL, i, i);
- else if(TC_ia)
- { putpad(TC_im);
- do { putpad(TC_ia);
- } while(--i);
- putpad(TC_ei);
- }
- else
- do { putnpad(TC_al, scr_ht - curs_lin);
- } while(--i);
- break;
-#endif /*TX_TERMCAP*/
-#if TX_DM2500
- case TN_DM2500:
- tput(020); /* Enter I/D mode */
- do { tput(012); /* Insert line */
- switch(trm_ospeed)
- { case 13: j = 17; break; /* 9600 */
- case 12: j = 8; break; /* 4800 */
- case 11: j = 4; break; /* 2400 */
- case 9: j = 2; break; /* 1200 */
- default: j = 0; break;
- }
- tpadn(j);
- } while(--i);
- tput(030); /* Exit I/D mode */
- break;
-#endif /*TX_DM2500*/
-#if TX_H19
- /* NOTE: H19 supposedly requires 19 ms for each line during line I/D
- * operations.
- * In actual practice, at 9600 baud 25 pads are necessary (24 wont work!)
- * for both I and D. Plus esc-E needs 9 pads.
- */
- case TN_H19:
- do { tputz("\033L");
- switch(trm_ospeed)
- { case 13: j = 25; break;
- case 9: j = 4; break;
- case 7: j = 1; break;
- default: j = 0; break;
- }
- tpadn(j);
- } while(--i);
- break;
-#endif /*TX_H19*/
-#if TX_COHIBM
- case TN_COHIBM:
- do { tputz("\033L"); /* no padding required */
- } while(--i);
- break;
-#endif /*TX_COHIBM*/
-#if TX_OM8025
- case TN_OM8025:
- do { tputz("\033L");
- tpad(100*(scr_ht - curs_lin)); /* .1 per moved line*/
- } while(--i);
- break;
-#endif /*TX_OM8025*/
-#if TX_TVI925
- case TN_TVI925:
- do tputz("\033E");
- while(--i);
- break;
-#endif /*TX_TVI925*/
- }
-}
-\f
-/* T_DELLIN(n, bot) - Delete lines from window.
- * n - # lines to delete.
- * bot - # of last line of current window.
- * The current line, and N-1 following lines, are deleted.
- * Blank lines are inserted past bot.
- * Cursor should be left at original position.
- * Only valid if trm_flags has TF_IDLIN set.
- */
-t_dellin (n, bot)
-int n; /* number of lines */
-int bot; /* line number of last line in window */
-{ register i, j;
- int savl, savc;
-
- if((i = n) <= 0) return;
- switch(tv_type)
- {
-#if TX_TERMCAP
- case TN_TERMCAP:
- if(TC_DL)
- putpar(TC_DL, i, i);
- else if(TC_id)
- { putpad(TC_dm);
- do putpad(TC_id);
- while(--i);
- putpad(TC_ed);
- }
- else
- do { putnpad(TC_dl,scr_ht - curs_lin);
- } while(--i);
-
- break;
-#endif /*TX_TERMCAP*/
-#if TX_DM2500
- case TN_DM2500:
- tput(020);
- do { tput(032);
- if(trm_ospeed >= 13) /* 9600 */
- tput(0177);
- } while(--i);
- tput(030);
- break;
-#endif /*TX_DM2500*/
-#if TX_H19
- case TN_H19:
- do { tputz("\033M");
- switch(trm_ospeed){
- case 13: j = 25; break;
- case 9: j = 4; break;
- case 7: j = 1; break;
- default: j = 0; break;
- }
- tpadn(j);
- } while(--i);
- break;
-#endif /*TX_H19*/
-#if TX_COHIBM
- case TN_COHIBM:
- do { tputz("\033M"); /* no padding required */
- } while(--i);
- break;
-#endif /*TX_COHIBM*/
-#if TX_OM8025
- case TN_OM8025:
- do { tputz("\033M");
- tpad(100*(scr_ht - curs_lin));
- } while(--i);
- break;
-#endif /*TX_OM8025*/
-#if TX_TVI925
- case TN_TVI925:
- do { tputz("\033R");
- } while(--i);
- break;
-#endif /*TX_TVI925*/
- }
- if(bot < (scr_ht-1))
- { savl = curs_lin;
- savc = curs_col;
- t_curpos(bot-n,0);
- t_inslin(n,scr_ht);
- t_curpos(savl,savc);
- }
-}
-\f
-/* T_INSCHR(n, str) - Insert n chars in current line
- * n - # characters to insert
- * str - Pointer to char string. If 0, insert spaces.
- *
- * Insert N characters from string str at current position.
- * The cursor may move but curs_col must be updated.
- * Only valid if trm_flags has TF_IDCHR set.
- */
-t_inschr(n, str)
-int n;
-char *str;
-{ register int i;
- register char *cp;
-
- if((i = n) <= 0) return;
- cp = str;
- switch(tv_type)
- {
-#if TX_TERMCAP
- case TN_TERMCAP:
- putpad(TC_im); /* Go into insert mode */
- if(TC_IC)
- { putpar(TC_IC, i, 1);
- if(cp) tputn(cp, i);
- else do tput(SP); while(--i);
- }
- else do {
- if(TC_ic) putpad(TC_ic);
- if(cp) tput(*cp++);
- else tput(SP);
- if(TC_ip) putpad(TC_ip);
- } while(--i);
- putpad(TC_ei); /* Exit insert mode */
- curs_col += n;
- break;
-#endif /*TX_TERMCAP*/
-#if TX_COHIBM
- case TN_COHIBM: /* If this exists, TN_H19 will too */
-#endif /*TX_COHIBM*/
-#if TX_H19
- case TN_H19:
- tputz("\033@"); /* Enter ins char mode */
- do { if(cp) tput(*cp++);
- else tput(SP);
- } while(--i);
- tputz("\033O"); /* Exit ins char mode */
- curs_col += n;
- break;
-#endif /*TX_H19*/
-#if TX_DM2500
- case TN_DM2500:
- tput(020); /* Enter I/D mode */
- if(trm_ospeed == 13) /* 9600 baud lossage */
- { do {
- tputz(" \177"); /* SP and DEL */
- } while(--i);
- tput(030);
- i = n;
- if(i < 3) /* If close enough, */
- tputn("\010\010", i); /* use BSes */
- else t_curpos(curs_lin, curs_col);
- }
- else /* Not 9600, can win */
- { do { tput(034);
- } while(--i);
- tput(030);
- if(cp == 0) return;
- i = n;
- }
-
- do { if(cp) tput(*cp++);
- else tput(SP);
- } while(--i);
- curs_col += n;
- break;
-#endif /*TX_DM2500*/
-#if TX_OM8025
- case TN_OM8025:
- do {
- tputz("\033@");
- if(cp) tput(*cp++);
- else tput(SP);
- } while(--i);
- curs_col += n;
- break;
-#endif /*TX_OM8025*/
-#if TX_TVI925
- case TN_TVI925:
- do { tputz("\033Q");
- } while(--i);
- if(cp)
- { tputn(cp, n);
- curs_col += n;
- }
- break;
-#endif /*TX_TVI925*/
- }
-}
-\f
-/* T_DELCHR(n) - Delete N chars in current line.
- * Deletes the N characters to the right of the cursor. Remaining
- * chars are shifted left. The cursor should not move.
- * Only valid if trm_flags has TF_IDCHR set.
- */
-t_delchr(n) /* Delete N chars at current loc */
-int n;
-{ register int i;
-
- if((i = n) <= 0) return;
- switch(tv_type)
- {
-#if TX_TERMCAP
- case TN_TERMCAP:
- putpad(TC_dm); /* Enter delete mode */
- if(TC_DC)
- putpar(TC_DC, i, 1);
- else do { /* Delete char while in del mode */
- putpad(TC_dc);
- } while(--i);
- putpad(TC_ed); /* Exit delete mode */
- break;
-#endif /*TX_TERMCAP*/
-#if TX_COHIBM
- case TN_COHIBM: /* If this exists, TN_H19 will too */
-#endif /*TX_COHIBM*/
-#if TX_H19
- case TN_H19:
- do tputz("\033N");
- while(--i);
- break;
-#endif /*TX_H19*/
-#if TX_DM2500
- case TN_DM2500:
- tput(020); /* Enter I/D mode */
- do if(trm_ospeed == 13) /* 9600? */
- tputz("\010\177"); /* BS and DEL */
- else tput(010);
- while(--i);
- tput(030); /* Exit I/D mode */
- break;
-#endif /*TX_DM2500*/
-#if TX_OM8025
- case TN_OM8025:
- do tputz("\033P");
- while (--i);
- break;
-#endif /*TX_OM8025*/
-#if TX_TVI925
- case TN_TVI925:
- do { tputz("\033W");
- } while(--i);
-#endif /*TX_TVI925*/
- }
-}
-\f
-#if FX_SOWIND
-
-/* T_STANDOUT(n) - Enter or leave standout mode.
- * n - 0 to return to normal display mode,
- * 1 to enter standout display mode.
- * This is usually reverse video but may be something else.
- *
- * Only valid if trm_flags has TF_SO set.
- */
-
-t_standout(on)
-int on;
-{
- switch(tv_type)
- {
-#if TX_TERMCAP
- case TN_TERMCAP:
- putpad(on ? TC_so : TC_se);
- break;
-#endif /*TX_TERMCAP*/
-
-#if TX_COHIBM
- case TN_COHIBM: /* Note TN_H19 will exist too */
-#endif /*TX_COHIBM*/
-#if TX_H19
- case TN_H19:
- tputz(on ? "\033p" : "\033q");
- break;
-#endif /*TX_H19*/
- }
-}
-#endif /*FX_SOWIND*/
-\f
-
-/* TPADN(n) - Output N pad chars.
- */
-static void
-tpadn(n)
-int n;
-{ register int i, pad;
- if((i = n) > 0)
- { pad = tv_padc;
- do { tput(pad);
- } while(--i);
- }
-}
-
-/* TPAD(msec) - Output padding for given # of milliseconds.
- */
-static void
-tpad(n)
-int n;
-{ register int i, i2;
-
- i = n;
- while(i > 0)
- { if((i2 = 320) < i) /* So can use integers */
- i2 = i;
- i -= i2;
- i2 *= 100;
- while((i2 -= tv_cspeed) > 0)
- tput(tv_padc);
- }
-}
-#if TX_TERMCAP
-/*
- * Print the string str, interpreting padding.
- */
-int tput(); /* Our output function */
-static void
-putpad(str)
-char *str;
-{ if(str) tputs(str, 1, tput); /* Invoke TERMCAP function */
-}
-static void
-putnpad(str,n)
-char *str;
-int n;
-{ if(str) tputs(str, n, tput);
-}
-static void
-putpar(str, par, n) /* Wish we had tparm() */
-char *str;
-int par,n;
-{ putnpad(tgoto(str, 0, par), n);
-}
-#endif /*TX_TERMCAP*/
-\f
-/*
- * Read in the stuff from termcap upon startup.
- */
-
-#if TX_TERMCAP
-static int tstrlen(), tstrlp();
-
-#ifndef TCAPSLEN
-#define TCAPSLEN 1024 /* Default size of buffer for TERMCAP strings */
-#endif /*-TCAPSLEN*/
-
-static int
-getcap(stype)
-char *stype;
-{ register int i;
- int buflen;
- char *tcbuf, *tcbptr; /* Pointers into termcap buffer */
- char tmpstr[4];
- char tmpbuf[TCAPSLEN]; /* Allocate from stack */
- char *malloc();
- char *realloc();
-
- /* First see if can find the terminal type. */
- if((tgetent(tmpbuf, stype)) != 1)
- return(0);
-
- /* Found it! Set up a string buffer to save the caps. */
- if(!(tcbuf = malloc(TCAPSLEN))) /* Get permanent buffer */
- t_fatal(" - cannot allocate termcap buffer");
- tcbptr = tcbuf;
-
- /* Now gobble all the string caps that ELLE wants to know about. */
- tmpstr[3] = '\0';
- i = NTCAPS;
- do {
- tmpstr[0] = tcap[i].tcicod1; /* Make str of the code */
- tmpstr[1] = tcap[i].tcicod2;
- tcap[i].tccap = tgetstr(tmpstr, &tcbptr); /* Get cap */
- } while(--i);
- buflen = tcbptr - tcbuf; /* String buffer done, finalize */
- if(buflen >= TCAPSLEN)
- t_fatal("description too big!");
- realloc(tcbuf, buflen); /* Free up unused part of buffer */
- /* (this better not move it!!!) */
-
- /* Now get the number/flag stuff that ELLE needs. */
- tc_am = tgetflag("am"); /* auto wrap */
- if (tgetflag("xn")) tc_am = 0; /* auto wrap at 81st char, nice! */
- tc_km = (tgetflag("km") /* TTY has meta key */
- || tgetflag("MT")); /* Alternate version of "km"?? */
- scr_ht = tgetnum("li"); /* Set screen height (# lines) */
- scr_wid = tgetnum("co"); /* Set screen width (# cols) */
- ts_winsize();
-
- /* Now initialize the stupid external vars that TERMCAP rtns want. */
- if(TC_pc) PC = *TC_pc; /* Pad char */
- BC = TC_bc; /* Backspace str (if no BS) */
- UP = TC_up; /* Cursor up */
- ospeed = trm_ospeed; /* Put output speed here */
-
-
- /* Basic data extracted, now mull over it and set the remaining
- * ELLE variables
- */
-#if FX_SOWIND
- if(tgetnum("sg") <= 0) /* If no magic cookie problems */
- { if (TC_so && TC_se) /* And have standout caps, */
- trm_flags |= TF_SO; /* Say has standout cap */
- }
-#endif
-
- if (!(TC_cm && TC_cl))
- t_fatal("lacks cursor addressing or clear screen.");
- tvc_pos = tstrlen(TC_cm); /* Find cost of abs move */
- if(BC) /* Find cost of backspace */
- tvc_bs = tstrlen(BC);
-
- /* Find costs for doing I/D char operations */
- if ((TC_im||TC_ic) && (TC_dm||TC_dc))
- { trm_flags |= TF_IDCHR;
- tvc_ci = tstrlen(TC_im)+tstrlen(TC_ei);
- tvc_cin = tstrlen(TC_ic)+1+tstrlen(TC_ip);
- if(TC_IC) /* If have multi-IC, use it */
- { tvc_ci += tstrlp(TC_IC, 1);
- tvc_cin = 1;
- }
- tvc_cd = tstrlen(TC_dm)+tstrlen(TC_ed);
- tvc_cdn = tstrlen(TC_dc);
- if(TC_DC) /* If have multi-DC, use it */
- { tvc_cd += tstrlp(TC_DC, 1);
- tvc_cdn = 0;
- }
- }
-
- /* Find costs for doing I/D line operations */
- if ((TC_ia || TC_al) && (TC_id || TC_dl))
- { trm_flags |= TF_IDLIN;
- tvc_li = 0; /* Usual case */
- tvc_lin = tstrlen(TC_al);
- if(TC_AL) /* If have multi-IL, use it */
- { tvc_li = tstrlp(TC_AL, 1);
- tvc_lin = tstrlp(TC_AL, 2) - tvc_lin;
- }
- else if(TC_ia)
- { tvc_li = tstrlen(TC_im)+tstrlen(TC_ei);
- tvc_lin = tstrlen(TC_ia);
- }
-
- tvc_ld = 0; /* Usual case */
- tvc_ldn = tstrlen(TC_dl);
- if(TC_DL) /* If have multi-DL, use it */
- { tvc_ld = tstrlp(TC_DL, 1);
- tvc_ldn = tstrlp(TC_DL, 2) - tvc_ld;
- }
- else if(TC_id)
- { tvc_ld = tstrlen(TC_dm)+tstrlen(TC_ed);
- tvc_ldn = tstrlen(TC_id);
- }
- }
-
- if (tc_am)
- { scr_wid--; /* For now, avoid invoking wrap. */
-#if 0
- trm_flags |= AUTOWRAP; /* */
-#endif
- }
- if (TC_ce) trm_flags |= TF_CLEOL; /* Term has CLEOL? */
- if (tc_km) trm_flags |= TF_METAKEY; /* Term has meta key? */
-
- return(1);
-}
-
-/* Pair of routines which conspire in order to find # chars actually output
- * by a particular termcap string.
- */
-static int _tslen; /* Stored count */
-static void _tslinc(ch) { _tslen++; }
-static int
-tstrlen(str)
-char *str;
-{ _tslen = 0;
- if(str && str[0])
- tputs(str, 1, _tslinc); /* Mult padding by just 1 */
- return(_tslen);
-}
-
-static int
-tstrlp(str, par) /* Same but with parameter */
-char *str;
-int par;
-{
-#if 0
- if(str)
- { char *cp = tgoto(str, 0, par);
- int i = strlen(cp);
- while(--i >= 0)
- printf(" %o", *cp++);
- printf("\n");
- }
-#endif
- return !str ? 0 : tstrlen(tgoto(str, 0, par));
-}
-#endif /*TX_TERMCAP*/
-\f
-/* Direct-Video terminal output routine
- * Currently only COHERENT has this capability.
- */
-
-#if COHERENT
-#include <sgtty.h>
-
-struct vidctl {
- int v_position; /* Position in video memory */
- int v_count; /* Number of characters to transfer */
- char *v_buffer; /* Character buffer to read/write */
-};
-/*
- * Attribute masks for TIOVPUTB - attributes occupy odd addresses
- * in video memory.
- */
-#define VNORM 0x07 /* Ordinary Video */
-#define VINTE 0x08 /* Intense video */
-#define VBLIN 0x80 /* Blinking video */
-#define VREVE 0x70 /* Reverse video */
-#define VUNDE 0x01 /* Underline video (mono board) */
-
-/* T_DIRECT(line, col, string, len) - Do direct-video output of string.
- * Puts the string ("len" chars in length) on the screen starting at
- * the X,Y character position given by col, line.
- * This routine is only called if terminal has the "TF_DIRVID" flag set.
- */
-t_direct(lin, col, str, len)
-int lin, col;
-register char *str;
-register int len;
-{ register char *cp;
- char vbuf[MAXLINE*2];
- struct vidctl v;
-
- if(len <= 0) return;
- tbufls(); /* Ensure normal output is forced out */
- v.v_position = (lin*80 + col)*2;
- v.v_count = len*2;
- v.v_buffer = cp = vbuf;
- do {
- *cp++ = *str++;
- *cp++ = VNORM;
- } while(--len);
- ioctl(1, TIOVPUTB, &v);
-}
-#endif /*COHERENT*/
-\f
-/*
- * Terminal Output buffering routines
- */
-
-static char tbuf[TOBFSIZ]; /* Output buffer */
-static int tbufcnt = 0; /* # chars of room left in buffer */
-static char *tbufp = 0; /* Pointer to deposit in buffer */
-
-tput(ch)
-int ch;
-{ if(--tbufcnt < 0)
- tbufls();
- *tbufp++ = ch;
-}
-
-tputz(str)
-char *str;
-{ register int c;
- register char *cp, *tp;
- cp = str;
- tp = tbufp;
- while(c = *cp++)
- { if(--tbufcnt < 0)
- { tbufp = tp;
- tbufls();
- tp = tbufp;
- }
- *tp++ = c;
- }
- tbufp = tp;
-}
-
-tputn(str,cnt)
-char *str;
-int cnt;
-{ register int c;
- register char *cp, *tp;
- cp = str;
- tp = tbufp;
- if((c = cnt) > 0)
- do {
- if(--tbufcnt < 0)
- {
- tbufp = tp;
- tbufls();
- tp = tbufp;
- }
- *tp++ = *cp++;
- } while(--c);
- tbufp = tp;
-}
-
-tbufls()
-{ register int cnt;
-
- if(tbufp
- && (cnt = tbufp - tbuf) > 0) /* # chars written */
- write(1, tbuf, cnt); /* Out they go */
- tbufp = tbuf;
- tbufcnt = TOBFSIZ-1; /* Allow for usual expected decrement */
-}
-\f
-/*
- * Terminal Input buffering routines
- */
-
-int tibfmsk = -1; /* Mask AND'ed with input chars (external) */
-static char tibuf[TIBFSIZ]; /* TTY input buffer */
-static char *tibfp; /* Pointer to read from buffer */
-static int tibfcnt = 0; /* # chars left to be read from buffer */
-
-tgetc()
-{
-#if SUN
- register int c;
- extern int sun_winfd, sun_rdevf;
-
- if(sun_winfd)
- { if(!sun_rdevf)
- return(sun_input(1)&tibfmsk);
- sun_rdevf = 0; /* Check mouse too, but only once! */
- c = sun_input(0);
- if(c != -1) c &= tibfmsk;
- return(c);
- }
-#endif /*SUN*/
- while(--tibfcnt < 0)
- tibfcnt = read(0,(tibfp = tibuf),TIBFSIZ);
- return((*tibfp++)&tibfmsk);
-}
-
-tinwait()
-{ return(tibfcnt > 0 || ts_inp());
-}
+++ /dev/null
-/* ELLE - Copyright 1982, 1987 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/* EEVINI - ELLE initialized variables and array storage.
- * Initial values are defined here, but the vars must be
- * declared in ELLE.H as well so that references from all modules will
- * compile correctly.
- * Arrays are also allocated here, so size re-definitions only require
- * re-compiling this single small module.
- */
-
-#define EXT /* Allocate storage for non-initialized vars */
-#include "elle.h"
-
-#ifndef EVFILMOD
-#if V6
-#define EVFILMOD (0600) /* (int) Default file creation mode on V6 */
-#else
-#define EVFILMOD (0666) /* (int) Default file creation mode on V7, note */
-#endif /*-V6*/ /* paranoids can use V7 "umask" in shell. */
-#endif
-#ifndef EVFNO1
-#define EVFNO1 0 /* (char *) "Old" filename prefix */
-#endif
-#ifndef EVFNN1
-#define EVFNN1 0 /* (char *) "New" filename prefix */
-#endif
-#ifndef EVFNO2
-#define EVFNO2 "O" /* (char *) "Old" filename postfix */
-#endif
-#ifndef EVFNN2
-#define EVFNN2 "N" /* (char *) "New" filename postfix */
-#endif
-#ifndef EVFCOL
-#define EVFCOL (71) /* (int) Initial value for Fill Column */
-#endif
-#ifndef EVCCOL
-#define EVCCOL (40) /* (int) Initial value for Comment Column */
-#endif
-#ifndef EVNWPCT
-#define EVNWPCT 50 /* (int) 50% For random New Window, center cursor. */
-#endif
-#ifndef EVMVPCT
-#define EVMVPCT 67 /* (int) 67% When move off edge, show 67% new stuff */
-#endif
-#ifndef EVMODWSO
-#define EVMODWSO 0 /* (bool) Initial mode window standout mode */
-#endif
-#ifndef EV2MODEWS
-#define EV2MODEWS 1 /* 2-mode-window flag. 0=Never, 1=if SO, 2=always */
-#endif
-#ifndef EVMARKSHOW
-#define EVMARKSHOW 0 /* (char *) String shown for Set Mark */
-#endif
-#ifndef EVHELPFILE /* (char *) Location of ELLE help file. */
-#define EVHELPFILE "/usr/src/elle/help.dat"
-#endif
-
-char *ev_verstr = "ELLE 4.1b"; /* String: Editor name and version # */
-int ev_filmod = EVFILMOD; /* Default file creation mode */
-char *ev_fno1 = EVFNO1; /* "Old" filename prefix */
-char *ev_fnn1 = EVFNN1; /* "New" filename prefix */
-char *ev_fno2 = EVFNO2; /* "Old" filename postfix */
-char *ev_fnn2 = EVFNN2; /* "New" filename postfix */
-
-int ev_fcolumn = EVFCOL; /* Initial value for Fill Column */
-#if FX_INDCOMM
-int ev_ccolumn = EVCCOL; /* Initial value for Comment Column */
-#endif
-
-/* New window selection parameters.
-** Both are expressed as an integer % of window lines (where the whole
-** window is 100), and apply when a new window is selected.
-** ev_nwpct - when "New Window" is called, % of lines between top and cursor.
-** Also applies when screen has changed randomly.
-** ev_mvpct - when cursor moves out of window, this is the % of lines
-** between top and cursor (if moved off top) or between bottom and
-** cursor (if moved off bottom).
-*/
-int ev_nwpct = EVNWPCT; /* New Window cursor loc preference (%) */
-int ev_mvpct = EVMVPCT; /* Moved cursor loc preference (%) */
-
-#if FX_SOWIND
-int ev_modwso = EVMODWSO; /* Initial mode window standout flag */
-#endif
-#if FX_2MODEWINDS
-int ev_2modws = EV2MODEWS; /* Initial 2-mode-wind flag */
-#endif
-char *ev_markshow = EVMARKSHOW; /* String to display when Set Mark done */
-
-char *ev_helpfile = EVHELPFILE; /* Location of ELLE help file */
-char *ev_profile = EVPROFBINFILE; /* Location of ELLE binary user profile */
- /* Note ELLE doesn't use EVPROFTEXTFILE. */
-
-/* Array allocations */
-
-struct scr_line *scr[MAXHT]; /* Array of screen line structures */
-SBSTR *kill_ring[KILL_LEN]; /* Kill ring table */
+++ /dev/null
-/* ELLE - Copyright 1982, 1984 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/*
- * ELLE.H Global ELLE definitions
- */
-
-#ifndef EXT
-#define EXT extern /* Default assumes these are referencing decls */
-#endif
-
-/* Make identifiers unique in 1st 6 chars as per ANSI rule for externals */
-#define tvc_cin tvccin
-#define tvc_cdn tvccdn
-#define tvc_lin tvclin
-#define tvc_ldn tvcldn
-#define ev_fno1 evfno1
-#define ev_fno2 evfno2
-#define ev_fnn1 evfnn1
-#define ev_fnn2 evfnn2
-
-#define ask_sall asksal /* eebuff.c */
-#define ask_save asksav
-#define buf_tmod buftmo
-#define buf_tmat buftma
-#define e_gobob egobob /* eeedit.c */
-#define e_gobol egobol
-#define e_goeob egoeob
-#define e_goeol egoeol
-#define fill_prefix filpfx /* eefill.c */
-#define fill_plen filpln
-#define fill_cur_line filcln
-#define kill_ptr kilptr /* eef3.c */
-#define kill_push kilpsh
-#define ed_insert edinst /* eefed.c */
-#define ed_insn edinsn
-#define ed_deln eddeln
-#define ed_delete eddele
-#define f_fillreg ffilrg /* eejust.c */
-#define f_fillpara ffilpa
-
-#include "eesite.h" /* Insert site-dependent flags and parameters */
-#include "sb.h" /* Insert SB package definitions */
-#include "eeprof.h" /* Insert user profile definition. This is a
- * separate file so ELLEC can use it too. */
-#include "eefidx.h" /* Insert desired function defs */
-
-/* ELLE Compile-time parameter defaults */
-
-#ifndef KILL_LEN
-#define KILL_LEN 8 /* Size of kill ring */
-#endif
-#ifndef MAXHT
-#define MAXHT 72 /* Height (# lines) of largest screen we'll suport */
-#endif
-#ifndef MAXLINE
-#define MAXLINE 132 /* Width (# chars) of largest screen we'll support */
-#endif
-#ifndef FNAMELEN
-#define FNAMELEN 14 /* Sys-dep: Max size of last filename component */
-#endif /* Check FNAMSIZ if you change this. */
-#ifndef FNAMSIZ
-#define FNAMSIZ 100 /* Sys-dep: Max size of complete filename */
-#endif /* This must be at least as large as FNAMELEN! */
-#ifndef ISRCHLIM
-#define ISRCHLIM 50 /* Max # of chars to allow I-search on */
-#endif
-#ifndef TOBFSIZ
-#define TOBFSIZ 80 /* Size of TTY output buffer */
-#endif
-#ifndef TIBFSIZ
-#define TIBFSIZ 50 /* Size of TTY input buffer */
-#endif
-#ifndef ECHOLINES
-#define ECHOLINES 1 /* # of lines for echo area (below mode line) */
-#endif
-#ifndef MAXARGFILES
-#define MAXARGFILES 2 /* # of filename args OK at startup */
-#endif
-
-/* ELLE initialized variables.
- * Initial values are defined in EEVINI.C, but the vars must be
- * declared here as well so that references from all modules will
- * compile correctly.
- */
-
-extern char *ev_verstr; /* String: Editor name and version # */
-extern int ev_filmod; /* Default file creation mode */
-extern char *ev_fno1,*ev_fno2; /* Pre, postfix for "old" filenames */
-extern char *ev_fnn1,*ev_fnn2; /* Pre, postfix for "new" filenames */
-extern int ev_fcolumn; /* Fill Column variable */
-#if FX_INDCOMM
-extern int ev_ccolumn; /* Comment Column variable */
-#endif
-extern int ev_nwpct, ev_mvpct; /* New window selection percentages */
-#if FX_SOWIND
-extern int ev_modwso; /* Initial mode window standout flag */
-#endif
-#if FX_2MODEWINDS
-extern int ev_2modws; /* Initial setting of 2-mode-window flag */
-#endif
-extern char *ev_markshow; /* String to show when Set Mark done */
-extern char *ev_helpfile; /* Location of ELLE help file */
-extern char *ev_profile; /* Filename of ELLE binary user profile */
-extern struct profile def_prof; /* ELLE default user profile */
-
-/* Global variables */
-
-EXT chroff cur_dot; /* Current dot */
-EXT chroff mark_dot; /* Dot for mark */
-EXT int mark_p; /* flag indicating whether mark exists */
-EXT int this_cmd, last_cmd; /* Command type */
-EXT int unrchf; /* Stuffed character back for readcommand */
-EXT int exp; /* Numeric argument for commands */
-EXT int exp_p; /* Flag meaning an arg was given */
-EXT int pgoal; /* Permanent goal column */
-EXT int goal;
-EXT char *srch_str; /* Last search string specified (0 = none) */
-EXT int srch_len; /* Length of srch_str string */
-EXT int ask_len; /* Length of last string returned by "ask" */
-EXT char *homedir; /* User's home directory */
-EXT int kill_ptr; /* Index into kill ring */
-extern SBSTR *kill_ring[]; /* Kill ring table (allocated in eevini) */
-
-/* Editor Command types */
-
-#define KILLCMD 1 /* Kill command, for kill merging */
-#define ARGCMD 2 /* Argument-setter, for main loop */
-#define YANKCMD 3 /* Yank command, for yankpop */
-#define LINECMD 4 /* Next or previous line goal hacking */
-#if IMAGEN
-#define INSCMD 5 /* Simple char-insert command, for autowrap */
-#endif /*IMAGEN*/
-
-/* Misc char definitions */
-#define CTRL(ch) (037&ch)
-#define BELL ('\007') /* Will become \a in ANSI */
-#define BS ('\b')
-#define TAB ('\t')
-#define LF ('\n')
-#define FF ('\f')
-#define CR ('\r')
-#define ESC ('\033')
-#define SP (' ')
-#define DEL ('\177')
-
-#define CB_META (0200) /* Meta bit in command char */
-#define CB_EXT (0400) /* Extend bit in command char */
-#define METIZER ESC
-#define EXTIZER CTRL('X')
-
-/* Terminal parameters - set at runtime startup */
-
-EXT char *tv_stype; /* Terminal type string specified by user/system */
-EXT int scr_ht; /* # lines of main screen area */
-EXT int scr_wid; /* # columns of screen */
-EXT int scr_wd0; /* scr_wid - 1 (for 0-origin stuff) */
-EXT int trm_ospeed; /* Output speed index */
-EXT int tvc_pos; /* Cost for absolute move (# of output chars) */
-EXT int tvc_bs; /* Cost for backspace */
-EXT int tvc_ci, tvc_cin; /* Char ins cost per call, cost per column */
-EXT int tvc_cd, tvc_cdn; /* Char del " " " " " " */
-EXT int tvc_li, tvc_lin; /* Line ins cost per call, cost per line */
-EXT int tvc_ld, tvc_ldn; /* Line del " " " " " " */
-
-EXT int trm_flags; /* Terminal capabilities - bit flags */
- /* Maybe change to word vars someday (faster) */
-#define TF_IDLIN 01 /* Has I/D line */
-#define TF_IDCHR 02 /* Has I/D char */
-#define TF_SO 04 /* Has usable standout mode */
-#define TF_CLEOL 010 /* Has clear-to-eol */
-#define TF_METAKEY 020 /* Has meta key */
-#define TF_DIRVID 040 /* Has direct-video type interface */
-
-
-/* Redisplay definitions */
-
-EXT int curs_lin; /* Line # of current cursor (0 origin) */
-EXT int curs_col; /* Column # of current cursor (0 origin) */
-
-EXT int rd_type; /* Global var: holds redisplay "hints" */
-#define redp(n) rd_type |= (n)
-
-#define RD_SCREEN 01 /* Clear everything and redisplay */
-#define RD_WINDS 02 /* Check all windows for changes (b/emod) */
-#define RD_MODE 04 /* Mode line has changed, update it. */
-#define RD_WINRES 0400 /* Assume all of window was changed (clear b/emod) */
-#define RD_MOVE 010 /* Cursor has moved */
-#define RD_UPDWIN 020 /* Window fixed, must update modified screen lines */
-/*#define RD_ICHR 0 *//* Hint: Char insert done */
-/*#define RD_DCHR 0 *//* Hint: Char del done */
-#define RD_ILIN 0100 /* Hint: Line insert done */
-#define RD_DLIN 0200 /* Hint: Line del done */
-
-/* #define RD_MOVWIN 02000 *//* Window should be re-positioned */
-#define RD_FIXWIN 02000 /* Window needs fixing (call fix_wind) */
-#define RD_TMOD 04000 /* Text changed in this window, check it. */
-#define RD_WINCLR 010000 /* Clear window with CLEOLs (not yet) */
-#define RD_CHKALL 020000 /* Check all windows for redisplay flags */
-#if IMAGEN
-#define RD_REDO 040000 /* Just re-do the entire window, don't think */
-#endif /*IMAGEN*/
-
- /* Flags with global effects, only seen in rd_type */
-#define RDS_GLOBALS (RD_SCREEN|RD_MODE|RD_WINDS|RD_CHKALL)
- /* Flags which are allowed per-window (in w_redp) */
-#define RDS_WINFLGS (~RDS_GLOBALS)
- /* Flags which force FIX_WIND() to do something */
-#define RDS_DOFIX (RD_WINRES|RD_TMOD|RD_FIXWIN|RD_MOVE)
-
-#define CI_CLINE '!' /* Char indicator for continued line */
-#define CI_CNTRL '^' /* Char indicator for control chars */
-#define CI_META '~' /* Char indicator for meta-bit (8th) set */
-#define CI_TOP '|' /* Char indicator for top-bit (9th) set */
-#define MAXCHAR (8+3) /* Longest char representation (TAB) + slop */
-
-/* Definitions for screen structures */
-
-struct scr_line {
- chroff sl_boff; /* Ptr to start of line's text in buffer */
- int sl_len; /* # buffer chars in line (incl NL) */
- char *sl_line; /* Ptr to screen image of line */
- int sl_col; /* # chars in image == # columns used */
- char sl_flg; /* Flags - set if this line modified */
- char sl_cont; /* If line being continued on next, this */
- /* contains 1 plus # extra chars (if any) */
- /* stored at end of this line which shd be */
- /* put at beg of next line. */
- char *sl_nlin; /* New screen image line if modified flag set */
- int sl_ncol;
-};
- /* sl_flg definitions */
-#define SL_MOD 01 /* New line exists, must update to it */
-#define SL_EOL 02 /* Buffer line ends with EOL */
-#define SL_CSO 04 /* Current screen line is in standout mode */
-#define SL_NSO 010 /* New screen line is in standout mode */
-#if IMAGEN
-#define SL_REDO 0100 /* Line should be redone completely */
-#endif /*IMAGEN*/
-
-extern struct scr_line *scr[]; /* Screen line ptrs (allocated in e_vinit) */
-
-
-/* Buffer stuff */
-
-struct buffer
-{ SBBUF b_sb; /* MUST be 1st thing! */
- struct buffer *b_next; /* ptr to next in chain */
- char *b_name; /* text name */
- char *b_fn; /* filename */
- chroff b_dot; /* point (dot) */
- int b_flags; /* misc. bits */
- struct majmode *b_mode; /* Mode of buffer */
-#if IMAGEN
- long b_mtime; /* Last file modification time */
-#endif /*IMAGEN*/
-};
- /* b_flags definitions */
-#define B_MODIFIED 01 /* Buffer is modified */
-#define B_EOLCRLF 0200 /* On = CRLF mode, off = LF mode */
-#if IMAGEN
-#define B_PERMANENT 002 /* buffer cannot be killed */
-#define B_CMODE 004 /* "C" mode (HACK HACK) */
-#define B_BACKEDUP 010 /* Buffer has been backed up once */
-#define B_TEXTMODE 020 /* Text mode (auto-wrap, basically) */
-#define B_QUERYREP 040 /* Query-replace mode (qualifier) */
-#endif /*IMAGEN*/
-
-/* Handy macro to check EOL mode */
-#define eolcrlf(buf) (((struct buffer *)buf)->b_flags&B_EOLCRLF)
-
-/* Buffer pointers */
-
-EXT struct buffer
- *buf_head, /* head of list of all buffers */
- *cur_buf, /* buffer we are editing now */
- *last_buf, /* buffer we were editing before */
- *lines_buf; /* buffer for sep_win */
-
-/* Window stuff */
-
-struct window
-{ struct window *w_next; /* ptr to next in chain */
- int w_flags; /* Window flags */
- int w_pos; /* index of top line */
- int w_ht; /* number of lines */
- struct buffer *w_buf; /* buffer in this window */
- int w_pct; /* % of buffer window is at */
- int w_redp; /* Redisplay hints */
- chroff w_topldot; /* line currently at top of window */
- chroff w_dot; /* Saved dot while not cur_win */
- chroff w_bmod; /* Lower bound of modified text */
- chroff w_emod; /* Upper bound of modified text */
- /* (offset from end of buffer!) */
- chroff w_oldz; /* Buffer len as of last update */
-};
-
-/* Window flags */
-#define W_STANDOUT 01 /* Use terminal's standout mode for window */
-#define W_MODE 02 /* This is a mode window */
-
-/* Window pointers */
-
-EXT struct window
- *win_head, /* head of list of all windows */
- *cur_win, /* window we are now in */
- *user_win, /* current user window */
- *oth_win, /* "other" user window */
- *mode_win, /* window for mode line */
- *ask_win, /* window for ask (echo) area */
- *sep_win; /* window for separation dashes */
-
-/* Major Mode stuff. Each buffer has its own major mode.
- * Only one major mode may be in effect at any time.
- */
-struct majmode {
- char *mjm_name; /* Simple for now */
-};
-EXT struct majmode *fun_mode; /* Fundamental mode - the default */
-EXT struct majmode *cur_mode; /* Current major mode */
-
-/* Minor modes are currently implemented by means of flag variables
- * which have global effects (regardless of buffer or major mode).
- * Each variable has the name "x_mode" where x is the name of the minor
- * mode. These are declared in the modules containing their support code.
- * In the future this may be generalized along the lines of major modes.
- */
-
-
-/* Miscellaneous debug stuff */
-
-EXT int dbgval; /* Set nonzero to do verify stuff */
-EXT int dbg_isw; /* Set to enable interrupts if possible */
-#if IMAGEN
-EXT int dbg_redp; /* Set to debug redisplay algorithms */
-#endif /*IMAGEN*/
-extern int errno;
-
-/* V7 routines for setexit/reset emulation */
-
-#if !(V6)
-#include <setjmp.h>
-EXT jmp_buf env_main;
-#define setexit(a) setjmp(env_main)
-#define reset(a) longjmp(env_main,a)
-#endif /*-V6*/
-
-/* Declare functions returning CHROFF values (offsets into a buffer) */
-
-extern chroff e_dot(),e_nldot(),e_pldot(),e_boldot(),e_eoldot(),
- e_alldot(),ex_boldot(),ex_alldot(),
- ex_blen(),e_blen(),ex_dot(),e_wdot();
-
-extern SBSTR *e_copyn();
-
-/* Some other commonly needed declarations */
-
-extern char *memalloc(), *ask(), *dottoa(), *strdup();
-#if !(V6)
-extern char *getenv();
-#endif /*-V6*/
-#include "eeproto.h" /* function prototypes */
+++ /dev/null
-/* ELLEC - Copyright 1983 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author.
- */
-/* ELLEC - ELLE Compiler
- * Invoked with no arguments, acts as general ELLE compiler filter;
- * reads ASCII profile input, and outputs a binary profile.
- * Otherwise:
- * -Profile Compiles user's profile.
- * HOME/.ellepro.e -> HOME/.ellepro.bN (N = fmt version #)
- * NOTE: on V6, "HOME/" is left out.
- * -Pconf Outputs defprf.c for ELLE (accepts std in) (old -E)
- * -Fconf Outputs eefdef.h for ELLE (accepts std in)
- * -FXconf Outputs eefidx.h for ELLE (accepts std in)
- * -CMconf Outputs config makefile for ELLE ( " )
- * -CSconf arg Outputs config file using "arg" - for V6 config.v6 file.
- * -Pdump Outputs defprf.e user profile (old -P)
- * -Fdump Outputs deffun.e
- */
-
-#if 0
-The ASCII profile file associates command chars with functions.
-It is simply a series of lisp-like expressions of the form
- (keybind <char spec> <fun spec>)
-
- e.g. (keybind "C-Y" "Yank Pop")
-
-Command char specification:
- Allowed prefixes:
- <ch> The char itself
- C- Controlify (zap bits 140)
- ^<ch> Ditto
- M- Meta (add bit 200) - case ignored
- X- Extended (add bit) - case ignored
- To quote a char or char spec, use quoted-string syntax.
-
-Function name specification:
- Function names are specified by quoted strings containing the entire
- long-form ASCII function name. Matching is done case-independently.
-
-#endif /*COMMENT*/
-\f
-
-#include "eesite.h" /* Site specific stuff if any */
-#include <stdio.h>
-#include <ctype.h>
-#include <unistd.h>
-#include "eeprof.h" /* Profile structure definition */
-
-
-#define EFUNMAX 400 /* Maximum # (+1) of functions that can be defined */
-#define KBTSIZ (128*2) /* Initial size of key binding tables */
-
-
-/* EFUN Function definition table.
-** Functions that were copied from the pre-defined table will
-** have a value of NULL in ef_mod.
-*/
-struct fun {
- int ef_idx; /* Function index (same as index of entry) */
- char *ef_name; /* Function name */
- char *ef_adr; /* C routine name in ELLE */
- char *ef_mod; /* Source module that C routine lives in */
-};
-struct fun efuntab[EFUNMAX];
-int efxmax = 0; /* Largest function idx used */
-
-int format_ver = PROF_VER; /* Current version # of binary profile fmt */
-
-/* Keybind mapping tables. There are four separate tables:
-** Simple character. Always 128 single-byte items, indexed by the simple
-** command char. Each item is the corresponding function index.
-** Meta char. Variable number of 2-byte items; first is a command char
-** and second is its function index.
-** Extended char. Same format as Meta char.
-** Menu item (SUN only). Variable number of single-byte items, each
-** a function index.
-**
-*/
-char *chrptr; /* Pointer to simple-char table */
-int chrsiz = 128; /* Current size of table */
-int chrcnt = 0; /* # bytes actually used */
-
-char *mtaptr; /* Pointer to meta-char table */
-int mtasiz = KBTSIZ; /* Current size (twice the # of items) */
-int mtacnt = 0; /* # bytes actually used */
-
-char *extptr; /* Pointer to ext-char table */
-int extsiz = KBTSIZ; /* Current size (twice the # of items) */
-int extcnt = 0; /* # bytes actually used */
-
-char *mnuptr; /* Pointer to menu-item table (SUN only) */
-int mnusiz = KBTSIZ; /* Current size */
-int mnucnt = 0; /* # bytes actually used */
-
-
-#define CB_EXT 0400 /* "X-" prefix on command char */
-#define CB_META 0200 /* "M-" prefix on command char */
-
-
-/* Set up the pre-defined data areas. This includes the
-** predefined function table plus the default profile (keyboard mappings).
-** Note this only contains entries for ef_name and ef_adr.
-*/
-
-struct fun pdfuntab[] = { /* Pre-Defined Function table */
-#define EFUN(rtn,rtnstr,name) 0, name, rtnstr, 0,
-#define EFUNHOLE 0, 0, 0, 0,
-#include "eefdef.h"
-};
-int npdfuns = sizeof(pdfuntab)/sizeof(struct fun); /* # of entries */
-
-#include "defprf.c" /* Insert default profile mapping */
- /* This defines charmap, metamap, and extmap. */
-\f
-/* Stuff for feeble-minded list processor */
-#define NIL ((struct lnode *)0)
-#define LTRUE (<ruenode)
-
-#define LT_VAL 0
-#define LT_STR 1
-#define LT_LIST 2
-#define LT_ATOM 3 /* Should use this later instead of LT_STR */
-
-struct lnode {
- struct lnode *lnxt;
- int ltyp;
- union {
- int lvi;
- char *lvs;
- struct lnode *lvl;
- } lval;
-};
-
-struct lnode ltruenode; /* Constant TRUE */
-
-_PROTOTYPE(int main , (int argc , char **argv ));
-_PROTOTYPE(int doargs , (int argc , char **argv ));
-_PROTOTYPE(char **findkey , (char *cp , char ***aretp , char **tabp , int tabsiz , int elsize ));
-_PROTOTYPE(int nstrcmp , (char *s1 , char *s2 ));
-_PROTOTYPE(int ustrcmp , (char *s1 , char *s2 ));
-_PROTOTYPE(int strueq , (char *s1 , char *s2 ));
-_PROTOTYPE(int do_opcod , (void));
-_PROTOTYPE(int do_opasc , (void));
-_PROTOTYPE(void outkbind , (int c , int fx ));
-_PROTOTYPE(int do_obprof , (void));
-_PROTOTYPE(int mupcase , (int ch ));
-_PROTOTYPE(int upcase , (int ch ));
-_PROTOTYPE(char *qstr , (char *str ));
-_PROTOTYPE(char *charep , (int c ));
-_PROTOTYPE(int do_ocnf , (char *str ));
-_PROTOTYPE(int do_ofcod , (void));
-_PROTOTYPE(int do_ofasc , (void));
-_PROTOTYPE(int do_ofxcod , (void));
-_PROTOTYPE(int compile_stdin , (void));
-_PROTOTYPE(int lrch , (void));
-_PROTOTYPE(struct lnode *lread , (void));
-_PROTOTYPE(void wspfls , (void));
-_PROTOTYPE(struct lnode *lrstr , (int flg ));
-_PROTOTYPE(int islword , (int c ));
-_PROTOTYPE(struct lnode *eval , (struct lnode *lp ));
-_PROTOTYPE(struct lnode *undefall , (struct lnode *lp ));
-_PROTOTYPE(struct lnode *efun , (struct lnode *lp ));
-_PROTOTYPE(struct lnode *keybind , (struct lnode *lp ));
-_PROTOTYPE(struct lnode *keyallun , (void));
-_PROTOTYPE(struct lnode *menuitem , (struct lnode *lp ));
-_PROTOTYPE(int repchar , (char *str ));
-_PROTOTYPE(struct lnode *getln , (void));
-_PROTOTYPE(int numcvt , (char *str , int *anum ));
-_PROTOTYPE(int listcnt , (struct lnode *lp ));
-_PROTOTYPE(char *funname , (int i ));
-_PROTOTYPE(int findfun , (char *name ));
-_PROTOTYPE(int funcnt , (int *arr ));
-_PROTOTYPE(int scpy , (char *from , char *to , int cnt ));
-_PROTOTYPE(char *stripsp , (char *cp ));
-
-int warn();
-int lerr();
-int fatal();
-
-\f
-/* ELLEC argument stuff */
-char *argfile;
-char *outfile;
-int swfilter; /* If no args */
-int swprof; /* -P */
-int swelle; /* -E */
-
-int uproflg; /* Do compilation of user's profile */
-int swpcnf; /* Output defprf.c (C initialization of profile) */
-int swfcnf; /* Output eefdef.h */
-int swfxcnf; /* Output eefidx.h */
-int swcmcnf; /* Output config makefile (makecf.fun) */
-char *swcscnf; /* Output config specially (for V6) */
-int swallc; /* Do all of config stuff */
-int swfdmp; /* Output deffun.e */
-int nfiles; /* # file specs seen */
-
-main(argc,argv)
-int argc;
-char **argv;
-{ register int i;
- register char *cp;
- char temp[300];
-
- /* Initialize LTRUE
- ** (cannot portably initialize a union at compile time)
- */
- ltruenode.ltyp = LT_VAL; /* Set type (other fields zero) */
-
- /* Process switches */
- if(argc <= 1) swfilter++; /* If no args, assume filter */
- else doargs(argc,argv);
-
- /* Initialize function definitions and key bindings from predefs */
- chrptr = malloc(chrsiz);
- mtaptr = malloc(mtasiz);
- extptr = malloc(extsiz);
- mnuptr = malloc(mnusiz);
- if (!chrptr || !mtaptr || !extptr || !mnuptr)
- fatal("cannot init, no memory");
-
- scpy(charmap, chrptr, (chrcnt = sizeof(charmap)));
- scpy(metamap, mtaptr, (mtacnt = sizeof(metamap)));
- scpy( extmap, extptr, (extcnt = sizeof(extmap)));
- if(def_prof.menuvec)
- scpy(def_prof.menuvec, mnuptr, (mnucnt = def_prof.menuvcnt));
-
- for(i = 0; i < npdfuns; ++i) /* Initialize function defs */
- if(pdfuntab[i].ef_name)
- { efuntab[i].ef_idx = i;
- efuntab[i].ef_name = pdfuntab[i].ef_name;
- efuntab[i].ef_adr = stripsp(pdfuntab[i].ef_adr);
- if(efxmax < i) efxmax = i;
- }
-
-
- /* Routines expect input from stdin and output their results
- * to stdout.
- */
- if(argfile)
- if(freopen(argfile,"r",stdin) == NULL)
- fatal("cannot open input file \"%s\"",argfile);
- if(outfile)
- if(freopen(outfile,"w",stdout) == NULL)
- fatal("cannot open output file \"%s\"",outfile);
-
-
- /* Check for general compilation */
- if(swfilter)
- { /* Not really implemented yet */
- fatal("bad usage, see doc");
- }
-
- /* Do profile hacking of some kind */
- if(swprof || swelle)
- { if (compile_stdin()) /* Compile input profile */
- { if(swprof)
- do_opasc(); /* Output ASCII profile (.e) */
- else if(swelle)
- do_opcod(); /* Output bin profile (.b1) */
- }
- exit(0);
- }
-
- /* Check for variousness */
- if(swpcnf)
- { if(compile_stdin()) /* Compile input */
- do_opcod(); /* Output the C initialization code */
- exit(0);
- }
- if(swfxcnf)
- { if(compile_stdin()) /* Compile input */
- do_ofxcod(); /* Output the eefidx.h code */
- exit(0);
- }
- if(swfcnf)
- { if(compile_stdin()) /* Compile input */
- do_ofcod(); /* Output the eefdef.h code */
- exit(0);
- }
- if(swcmcnf || swcscnf)
- { if(compile_stdin()) /* Compile input */
- do_ocnf(swcscnf); /* Output the makecf.fun code */
- exit(0);
- }
- if(swfdmp)
- { if(compile_stdin()) /* Compile input */
- do_ofasc(); /* Output the deffun.e code */
- exit(0);
- }
-
-
- /* Hack user's profile */
- if(!uproflg) exit(0);
- if(!argfile)
- {
- temp[0] = 0;
-#if !V6
- if (cp = getenv("HOME"))
- strcat(temp, cp);
-#if !TOPS20
- strcat(temp,"/");
-#endif /*-TOPS20*/
-#endif /*-V6*/
- strcat(temp, EVPROFTEXTFILE);
- if(freopen(temp,"r",stdin) == NULL)
- fatal("cannot open profile \"%s\"",temp);
- }
- if(!outfile)
- {
- temp[0] = 0;
-#if !V6
- if (cp = getenv("HOME"))
- strcat(temp, cp);
-#if !TOPS20
- strcat(temp,"/");
-#endif /*-TOPS20*/
-#endif /*-V6*/
- strcat(temp, EVPROFBINFILE);
- if(freopen(temp,"wb",stdout) == NULL /* Try binary 1st */
- && freopen(temp,"w",stdout) == NULL)
- fatal("cannot open output profile \"%s\"",temp);
-
- }
- /* Hack user's profile */
- if(compile_stdin()) /* Compile input profile */
- do_obprof(); /* Output the binary */
-
-}
-\f
-#define SW_FLG 0
-#define SW_VAR 1
-#define SW_STR 2
-struct swarg {
- char *sw_name;
- long sw_type;
- int *sw_avar;
- char **sw_astr;
-} swtab[] = {
- "P", SW_FLG, &swprof, 0, /* Old stuff */
- "E", SW_FLG, &swelle, 0,
- "Profile", SW_FLG, &uproflg, 0,
- "Pconf", SW_FLG, &swpcnf, 0,
- "Fconf", SW_FLG, &swfcnf, 0,
- "FXconf", SW_FLG, &swfxcnf, 0,
- "CMconf", SW_FLG, &swcmcnf, 0,
- "CSconf", SW_STR, 0, &swcscnf,
- "Allconf", SW_FLG, &swallc, 0,
- "Pdump", SW_FLG, &swprof, 0,
- "Fdump", SW_FLG, &swfdmp, 0
-};
-
-doargs(argc,argv)
-int argc;
-char **argv;
-{ register int cnt, c;
- register char **av;
- register int i;
- register struct swarg *swp;
- struct swarg *swp2;
- int swerrs = 0;
-
- av = argv;
- cnt = argc;
- nfiles = 0;
-
- while(--cnt > 0)
- { ++av;
- if(*av[0] != '-') /* If not switch, */
- { /* assume it's an input filename */
- nfiles++;
- continue;
- }
- av[0]++;
-
- /* Try to look up switch in table */
- swp = (struct swarg *)findkey(av[0], &swp2, swtab,
- (sizeof(swtab))/(sizeof(struct swarg)),
- (sizeof(struct swarg))/(sizeof(char *)));
- if(swp2)
- { fprintf(stderr,"ellec: ambiguous switch: -%s = %s or %s\n",
- av[0], swp->sw_name, swp2->sw_name);
- goto swdone;
- }
- if(swp) switch(swp->sw_type)
- { case SW_FLG:
- *(swp->sw_avar) = 1;
- goto swdone;
- case SW_VAR:
- *(swp->sw_avar) = 1;
- if(cnt <= 1) goto swdone;
- if(isdigit(*av[1]))
- { *(swp->sw_avar) = atoi(av[1]);
- --cnt;
- goto swargdone;
- }
- goto swdone;
-
- case SW_STR:
- if(cnt <= 1) goto swdone;
- *(swp->sw_astr) = av[1];
- goto swargdone;
-
- default:
- fprintf(stderr,"ellec: bad switch type: %s\n",
- av[0]);
- swerrs++;
- }
-
- stop: fprintf(stderr,"ellec: bad switch: %s\n",*av);
- swerrs++;
- goto swdone;
- swargdone:
- av[0] = 0;
- av++;
- swdone: av[0] = 0;
- }
- if(swerrs) exit(1); /* Stop if any problems */
-}
-
-char **
-findkey(cp, aretp, tabp, tabsiz, elsize)
-register char *cp;
-char ***aretp;
-register char **tabp;
-int tabsiz, elsize;
-{ register char **mp1, **mp2;
- register int i, res;
-
- *aretp = mp1 = mp2 = 0;
- for(i = 0; i < tabsiz; ++i, tabp += elsize)
- { if(res = ustrcmp(cp,*tabp))
- { if(res > 0) return(tabp);
- if(!mp1) mp1 = tabp;
- else mp2 = tabp;
- }
- }
- if(mp2)
- *aretp = mp2; /* Ambiguous */
- return(mp1);
-}
-
-/* NSTRCMP - New string compare.
- * Returns:
- * 2 if str2 > str1 (mismatch)
- * 1 if str2 counted out (str1 > str2)
- * 0 if full match
- * -1 if str1 counted out (str1 < str2)
- * -2 if str1 < str2 (mismatch)
- */
-
-nstrcmp(s1,s2)
-register char *s1, *s2;
-{ register int c, d;
-
- while(c = *s1++)
- { if(c != *s2)
- { if((d = upcase(c) - upcase(*s2)) != 0)
- return(*s2==0 ? 1 : (d > 0 ? 2 : -2));
- }
- ++s2;
- }
- return(*s2 ? -1 : 0);
-}
-
-/* USTRCMP - uppercase string compare.
- * Returns 0 if mismatch,
- * 1 if full match,
- * -1 if str1 runs out first (partial match)
- */
-ustrcmp(s1,s2)
-register char *s1, *s2;
-{ register int c;
-
- if ( ! s1 || ! s2 ) return ( 0 ); /* Check for null ptr */
- while(c = *s1++)
- { if(c != *s2)
- { if(((c ^ *s2) != 040)
- || (upcase(c) != upcase(*s2)))
- return(0);
- }
- s2++;
- }
- return(c == *s2 ? 1 : -1);
-}
-
-strueq(s1,s2)
-char *s1;
-char *s2;
-{ return (ustrcmp(s1, s2) > 0 ? 1 : 0);
-}
-\f
-/* Output C initialization code for default profile (defprf.c) */
-
-do_opcod()
-{ register int i, c, f;
-
- printf("\
-/* This file defines the initial data for ELLE's default user profile.\n\
-** It is automatically generated by ELLEC, and should not be edited.\n\
-*/\n\
-char charmap[] = {\n");
- for(i=0; i < chrcnt; i++)
- { printf("\t%2d,",(f = chrptr[i]&0377));
- printf("\t/* (%3o) %3s",i,charep(i));
- printf(" %s",funname(f));
- printf(" */\n");
- }
-
- printf("};\n char metamap[] = {\n");
- for(i = 0; i < mtacnt; i += 2)
- { printf("\t0%-3o,%3d,",(c = mtaptr[i]&0377),(f = mtaptr[i+1]&0377));
- printf("\t/* %4s",charep(c|CB_META));
- printf(" %s",funname(f));
- printf(" */\n");
- }
-
- printf("};\n char extmap[] = {\n");
- for(i = 0; i < extcnt; i += 2)
- { printf("\t0%-3o,%3d,",(c = extptr[i]&0377),(f = extptr[i+1]&0377));
- printf("\t/* %4s",charep(c|CB_EXT));
- printf(" %s",funname(f));
- printf(" */\n");
- }
- printf("};\n");
- printf("struct profile def_prof = {\n");
- printf(" %d, /* Ver */\n", format_ver);
- printf(" sizeof(charmap), charmap,\n");
- printf(" sizeof(metamap)/2, metamap,\n");
- printf(" sizeof(extmap)/2, extmap, \n");
- printf(" 0, 0\n");
- printf("};\n");
-
-}
-\f
-/* Output ASCII version of default profile */
-
-int oerrs;
-
-do_opasc()
-{ register int i, c, f;
-
- oerrs = 0;
- printf("; ELLE default ASCII profile\n\n");
- printf("(keyallunbind) ; To flush all existing bindings\n\n");
- for(i=0; i < chrcnt; i++)
- outkbind(i, chrptr[i]&0377);
-
- printf("\n; Meta chars\n\n");
- for(i = 0; i < mtacnt; i += 2)
- outkbind(CB_META | (mtaptr[i]&0377), mtaptr[i+1]&0377);
-
- printf("\n ; Extended commands\n\n");
- for(i = 0; i < extcnt; i += 2)
- outkbind(CB_EXT | (extptr[i]&0377), extptr[i+1]&0377);
-
- printf("\n");
- if(oerrs)
- fatal("%d errors encountered, check output file.", oerrs);
-}
-
-void outkbind(c, fx)
-{
- if(fx == 0) /* Allow key to be mapped to nothing. */
- return;
- if(fx <= 0 || fx > efxmax)
- printf(";INTERNAL ERROR: Bad function index %d for key %s\n",
- fx, charep(c));
- else if(efuntab[fx].ef_name == NULL)
- printf(";INTERNAL ERROR: No name for function %d while mapping key %s\n",
- fx, charep(c));
- else {
- printf("(keybind %s \"%s\")\n",
- qstr(charep(c)),efuntab[fx].ef_name);
- return;
- }
- oerrs++;
-}
-\f
-/* Output binary user profile */
-
-do_obprof()
-{ register unsigned int rp; /* Relative "pointer" */
- struct stored_profile st_prof;
-
- rp = sizeof(st_prof); /* Initialize */
-
- /* Fixed by Kochin Chang, July 1995 */
- /* format version should be the first field in compiled profile */
- prof_pack(st_prof.version, format_ver);
-
- prof_pack(st_prof.chrvec, rp);
- prof_pack(st_prof.chrvcnt, chrcnt);
- rp += chrcnt;
-
- prof_pack(st_prof.metavec, rp);
- prof_pack(st_prof.metavcnt, mtacnt/2);
- rp += mtacnt;
-
- prof_pack(st_prof.extvec, rp);
- prof_pack(st_prof.extvcnt, extcnt/2);
- rp += extcnt;
-
- prof_pack(st_prof.menuvec, rp);
- prof_pack(st_prof.menuvcnt, mnucnt);
- rp += mnucnt;
-
- fwrite((char *)&st_prof,sizeof(st_prof),1,stdout);
- fwrite(chrptr,sizeof(char),chrcnt,stdout);
- if(mtacnt) fwrite(mtaptr, sizeof(*mtaptr), mtacnt, stdout);
- if(extcnt) fwrite(extptr, sizeof(*extptr), extcnt, stdout);
- if(mnucnt) fwrite(mnuptr,sizeof(*mnuptr),mnucnt,stdout);
-}
-
-/* Return upper-case version of character */
-mupcase(ch)
-register int ch;
-{ return((ch&(~0177)) | upcase(ch));
-}
-upcase (ch)
-{ register int c;
- c = ch&0177;
- return((('a' <= c) && (c <= 'z')) ? (c - ('a'-'A')) : c);
-}
-
-char *
-qstr(str)
-register char *str;
-{ register int c;
- static char qstrbuf[100];
- register char *cp;
- cp = str;
- while((c = *cp++) && islword(c));
- if(c == 0) return(str); /* No quoting needed */
-
- cp = qstrbuf;
- *cp++ = '"';
- while(*cp++ = c = *str++)
- if(c == '"') *cp++ = c; /* Double the quotes */
- cp[-1] = '"';
- *cp = 0;
- return(qstrbuf);
-}
-
-char *
-charep(c)
-register int c;
-{ static char chrbuf[10];
- register char *cp;
- cp = chrbuf;
- if(c&CB_EXT)
- { *cp++ = 'X';
- *cp++ = '-';
- c &= ~CB_EXT;
- }
- if(c&CB_META)
- { *cp++ = 'M';
- *cp++ = '-';
- c &= ~CB_META;
- }
- if(c <= 037)
- { *cp++ = '^';
- c += 0100;
- }
- if(c == 0177)
- { *cp++ = 'D';
- *cp++ = 'E';
- *cp++ = 'L';
- }
- else *cp++ = c;
- *cp = 0;
- return(chrbuf);
-}
-\f
-/* Output config Makefile (makecf.fun)
- * If argument is 0 (NULL), does Makefile type output.
- * Otherwise uses string for special-purpose output.
- */
-do_ocnf(str)
-char *str;
-{ register struct fun *fnp;
- register int i, mi;
- register char *cp;
- int fmtab[EFUNMAX];
- int nfmods;
- char *modtab[EFUNMAX];
- char *unknown = "unknown-module";
-
- if(str == NULL) /* If not V6 version */
- { printf("# Function module definition file, generated by ELLEC\n");
- printf("FUN_OFILES = ");
- }
-
- nfmods = 0;
-
- funcnt(fmtab); /* Count function occs */
-
- for(i = 1; i <= efxmax; ++i)
- { if(fmtab[i] == 0) continue;
- fnp = &efuntab[i];
-
- if(fnp->ef_name == 0)
- fatal("internal error - no name for function %d", i);
-
- /* Got a function, store its module name if not a dup */
- if ((cp = fnp->ef_mod) == NULL) /* Substitute if undef */
- cp = unknown;
- for(mi=0; mi < nfmods; ++mi)
- if(ustrcmp(cp, modtab[mi]) > 0)
- break;
- if(mi < nfmods) continue;
- modtab[nfmods++] = cp;
- }
-
- /* Now have table of all modules used. Crunch them into output. */
- for(mi=0; mi < nfmods; ++mi)
- if (modtab[mi] != unknown)
- { if(str != NULL) /* V6 version? */
- printf("%s %s\n", str, modtab[mi]);
- else printf("\\\n\t%s.o", modtab[mi]);
- }
- printf("\n");
-}
-\f
-/* Output eefdef.h */
-
-do_ofcod()
-{ register struct fun *fnp;
- register int i;
- char temp[40];
- int fmtab[EFUNMAX];
-
- printf("/* .H Function Definition file, generated by ELLEC */\n");
- printf("/* 0 */ EFUNHOLE /* Always undefined */\n");
-
- funcnt(fmtab); /* Count function occs */
-
- for(i = 1; i <= efxmax ; ++i)
- {
- fnp = &efuntab[i];
- printf("/* %3d */ ", i);
- if(fmtab[i] == 0 || fnp->ef_name == 0)
- printf("EFUNHOLE\n");
- else
- { sprintf(temp, "\"%s\"", fnp->ef_adr);
- printf("EFUN( %-12s, %-14s, \"%s\")\n", fnp->ef_adr,
- temp, fnp->ef_name);
- }
- }
-
-}
-\f
-/* Output ascii version of function def file
-*/
-do_ofasc()
-{ register struct fun *fnp;
- register int i;
- register char *fa, *fm;
-
- printf("; Master Function Definition file\n");
-
- for(i = 1; i <= efxmax ; ++i)
- {
- fnp = &efuntab[i];
- if(fnp->ef_idx == 0) /* No definition for this index? */
- continue;
- if(fnp->ef_name == 0)
- { warn("internal error - no name for function %d", i);
- continue;
- }
-
- if ((fa = fnp->ef_adr) == NULL)
- fa = "unknown-addr";
- if ((fm = fnp->ef_mod) == NULL)
- fm = "unknown-module";
- printf("(efun %d \"%s\" %s %s)\n",
- fnp->ef_idx, fnp->ef_name, fa, fm);
- }
-}
-\f
-/* Output eefidx.h */
-
-do_ofxcod()
-{ register struct fun *fnp;
- register int i;
- register char *cp, *cp2;
- int fmtab[EFUNMAX];
- char tmpstr[100];
-
- printf("\
-/* .H Function Index Definition file, generated by ELLEC */\n");
- printf("\
-/* FN_ defines Function Numbers (indices) for all known functions */\n");
- printf("\
-/* FX_ defines Function eXistence in this ELLE configuration */\n");
-
- funcnt(fmtab); /* Count function occs */
-
- for(i = 1; i <= efxmax ; ++i)
- {
- fnp = &efuntab[i];
- if(fnp->ef_idx == 0) /* No definition for this index? */
- continue;
- if(fnp->ef_adr == 0 || fnp->ef_name == 0)
- { warn("internal error - no addr/name for function %d", i);
- continue;
- }
-
- cp2 = fnp->ef_adr;
- cp = tmpstr;
- while(*cp++ = upcase(*cp2++));
- cp = tmpstr;
- if((*cp++ != 'F') || (*cp++ != '_'))
- cp = tmpstr;
-
- /* Always define FN_ as index */
- printf("#define FN_%-14s %3d /* %s */\n",
- cp, i, fnp->ef_name);
- /* Define FX_ as 0 if unused, else same as FN_ */
- printf("#define FX_%-14s %3d\n", cp,
- (fmtab[i] == 0) ? 0 : i); /* 0 if unused */
- }
-
-}
-\f
-/* Compile input! */
-
-compile_stdin()
-{ register struct lnode *lp;
-
- while((lp = lread()) != NIL)
- eval(lp);
-
- return(1);
-}
-\f
-#define MAXLINE 300
-int llstch = -1;
-int leofflg;
-#define unlrch(c) llstch = c
-
-int lineno = 0;
-char linebuf[MAXLINE];
-char *linecp = linebuf;
-
-lrch()
-{ register int c;
- if((c = llstch) >= 0)
- { if(c == 0 && leofflg)
- return(EOF);
- llstch = -1;
- return(c);
- }
- if((c = getc(stdin)) == EOF)
- { leofflg = 1;
- llstch = 0;
- *linecp = 0;
- linecp = linebuf;
- return(c);
- }
- if(c == '\n')
- { lineno++;
- linecp = linebuf;
- }
- else *linecp++ = c;
- return(c);
-}
-
-struct lnode *
-lread()
-{ register int c;
- register struct lnode *lp, *lp2;
- struct lnode *head;
-
- wspfls();
- if((c = lrch())== EOF)
- return(NIL);
- if(c == ')') /* End of a list? */
- return(NIL);
- if(c == '(') /* Start of a list? */
- { head = lp = getln();
- lp->ltyp = LT_LIST;
- if((head->lval.lvl = lp = lread()) == NIL)
- return(head); /* Return empty list */
- while(lp2 = lread())
- { lp->lnxt = lp2;
- lp = lp2;
- }
- return(head);
- }
-
- /* Atom of some kind */
- if(c=='"')
- { return(lrstr(1));
- }
- unlrch(c);
- return(lrstr(0));
-}
-
-void wspfls()
-{ register int c;
- for(;;)
- { c = lrch();
- if(isspace(c)) continue;
- if(c == ';')
- while((c = lrch()) != '\n')
- if(c == EOF) return;
- break;
- }
- if(c != EOF) unlrch(c);
-}
-
-#define LSMAX 300 /* Max # chars in atom string */
-struct lnode *
-lrstr(flg)
-{ char cbuf[LSMAX];
- register char *cp;
- register int c, i;
- struct lnode *lp;
-
- cp = cbuf;
- i = 0;
-
- while((c = lrch()) != EOF)
- if (flg) switch(c)
- { case '"':
- if((c = lrch()) == EOF)
- return(NIL);
- if(c != '"')
- { unlrch(c);
- goto out;
- }
- default:
- ok:
- if(++i > LSMAX)
- break;
- *cp++ = c;
- continue;
- }
- else
- { if(islword(c)) goto ok;
- unlrch(c);
- break;
- }
- out:
- lp = getln();
- lp->ltyp = LT_STR;
- lp->lval.lvs = malloc(i+1);
- *cp = 0;
- strcpy(lp->lval.lvs, cbuf);
- return(lp);
-}
-islword(c)
-{ return((040 < c && c < 0177
- && c != '(' && c !=')' && c != ';'
- && c != '"' && c != '\\') ? 1 : 0);
-}
-
-\f
-struct lnode *keybind(), *keyallun(), *menuitem(), *efun(),
- *undefall();
-
-struct lfun {
- char *lfname; /* Name of list function */
- struct lnode * (*lfrtn)(); /* Function address */
-} lfntab[] = {
- "keybind", keybind,
- "efun", efun,
- "menuitem", menuitem,
- "keyallunbind", keyallun,
-/* "keyunbind", keyunbind, */ /* Not yet */
- "undefall", undefall,
-/* "undef", undef, */ /* Not yet */
- 0, 0
-};
-
-struct lnode *
-eval(lp)
-register struct lnode *lp;
-{ register struct lnode *flp;
- register struct lfun *lfent;
-
- if(lp->ltyp != LT_LIST)
- return(lp);
- if((flp = lp->lval.lvl) == NIL)
- return(NIL);
- if(flp->ltyp != LT_STR)
- return(NIL);
-
- /* Look up list function and invoke it */
- for(lfent = lfntab; lfent->lfname; lfent++)
- if(strueq(flp->lval.lvs, lfent->lfname))
- return((*(lfent->lfrtn))(flp->lnxt));
-
- lerr("unknown op: (%s)", flp->lval.lvs);
- return(NIL);
-}
-
-\f
-/* UNDEFALL - (undefall)
-** Undefines all functions. Typically used to clear out
-** predefined functions prior to compiling a set of new efuns.
-*/
-struct lnode *
-undefall(lp)
-register struct lnode *lp;
-{
- register int i;
- efxmax = 0; /* Say nothing in function def table! */
- for(i = 0; i < EFUNMAX; ++i)
- { efuntab[i].ef_idx = 0;
- efuntab[i].ef_name = 0;
- efuntab[i].ef_adr = 0;
- efuntab[i].ef_mod = 0;
- }
- return(LTRUE);
-}
-\f
-/* EFUN - (efun <index> <functionname> <address> <module>)
-** Checks out the args and if no problems, stores the function
-** definition in efuntab.
-*/
-struct lnode *
-efun(lp)
-register struct lnode *lp;
-{ struct lnode *nlp;
- register int c, i;
- register struct fun *fnp;
- char *fname, *faddr, *fmod;
- int fni, num;
-
- if(listcnt(lp) < 4)
- { lerr("efun - not enough args");
- return(NIL);
- }
-
- /* First thing should be function index */
- switch(lp->ltyp)
- { case LT_VAL:
- fni = lp->lval.lvi;
- break;
- case LT_STR:
- if(numcvt(lp->lval.lvs, &num))
- { fni = num;
- break;
- }
- default:
- lerr("efun - non-value function index");
- return(NIL);
- }
-
- /* Next thing should be function name */
- lp = lp->lnxt;
- if(lp->ltyp != LT_STR) /* Function name not a string */
- { lerr("efun - non-string function name");
- return(NIL);
- }
- fname = lp->lval.lvs;
-
- /* Next thing should be function addr */
- lp = lp->lnxt;
- if(lp->ltyp != LT_STR) /* Function addr not a string */
- { lerr("efun - non-string function addr");
- return(NIL);
- }
- faddr = lp->lval.lvs;
-
- /* Next thing should be function module */
- lp = lp->lnxt;
- if(lp->ltyp != LT_STR) /* Function module not a string */
- { lerr("efun - non-string function module");
- return(NIL);
- }
- fmod = lp->lval.lvs;
-
- /* Now see if already exists or anything */
- if(fni <= 0 || fni > EFUNMAX)
- { lerr("efun - bad function index %d", fni);
- return(NIL);
- }
- fnp = &efuntab[fni];
- if(fnp->ef_idx != 0)
- {
- if (fnp->ef_idx == fni
- && strueq(fnp->ef_name, fname)
- && strueq(fnp->ef_adr, faddr)
- && (fnp->ef_mod == NULL || strueq(fnp->ef_mod, fmod)))
- goto win; /* Benign redefinition */
-
-lerr("efun - redefining function (%d \"%s\" %s %s)",
- fnp->ef_idx, fnp->ef_name, fnp->ef_adr,
- (fnp->ef_mod ? fnp->ef_mod : "unknown-module"));
- }
- for(i = 0; i < EFUNMAX; ++i)
- { if(efuntab[i].ef_idx == 0) continue;
- if(ustrcmp(efuntab[i].ef_adr,faddr) > 0
- || ustrcmp(efuntab[i].ef_name, fname) > 0)
- { if(i == fni) continue;
- lerr("efun - name or address dup! \"%s\"", fname);
- return(NIL);
- }
- }
-
- /* No problems, store the function def in efuntab! */
-win: fnp->ef_idx = fni;
- fnp->ef_mod = fmod;
- fnp->ef_adr = faddr;
- fnp->ef_name = fname;
-
- if(efxmax < fni) efxmax = fni;
- return(LTRUE);
-}
-
-\f
-/* KEYBIND - (keybind <charspec> <functionname>) */
-
-struct lnode *
-keybind(lp)
-register struct lnode *lp;
-{ struct lnode *nlp;
- register int c, i;
- int fni;
-
- if(lp == NIL || (nlp = lp->lnxt)== NIL)
- return(NIL);
- switch(lp->ltyp)
- { case LT_VAL:
- c = lp->lval.lvi;
- break;
- case LT_LIST:
- return(NIL);
- case LT_STR:
- c = repchar(lp->lval.lvs);
- break;
- }
- if(c == -1)
- return(NIL); /* No such command char name */
-
- lp = nlp;
- if(lp->ltyp != LT_STR) /* Function name not a string */
- { lerr("(keybind) non-string function name");
- return(NIL);
- }
- fni = findfun(lp->lval.lvs);
- if(fni == 0) /* No such function name */
- { lerr("(keybind) no such function - \"%s\"", lp->lval.lvs);
- return(NIL);
- }
- if(c & CB_EXT)
- { c &= ~CB_EXT;
-
- /* Check for redefinition */
- for(i = 0; i < extcnt; i += 2)
- if(c == (extptr[i]&0377)) /* Already there? */
- { if((extptr[i+1]&0377) != fni) /* Yes, check fn */
- lerr("(keybind) redefining X-%s as %d=\"%s\"",
- charep(c), fni, lp->lval.lvs);
- break;
- }
- if(i >= extcnt) /* Didn't find? */
- { if(extcnt >= extsiz)
- { lerr("(keybind) too many X- commands");
- return(NIL); /* Too many EXT cmds */
- }
- i = extcnt; /* Increase size of table */
- extcnt += 2;
- }
- /* Now store new binding */
- extptr[i] = c;
- extptr[i+1] = fni;
- }
- else if(c&CB_META)
- { c &= ~CB_META;
-
- /* Check for redefinition */
- for(i = 0; i < mtacnt; i += 2)
- if(c == (mtaptr[i]&0377)) /* Already there? */
- { if((mtaptr[i+1]&0377) != fni) /* Yes, check fn */
- lerr("(keybind) redefining M-%s as %d=\"%s\"",
- charep(c), fni, lp->lval.lvs);
- break;
- }
- if(i >= mtacnt) /* Didn't find? */
- { if(mtacnt >= mtasiz)
- { lerr("(keybind) too many M- commands");
- return(NIL); /* Too many META cmds */
- }
- i = mtacnt; /* Increase size of table */
- mtacnt += 2;
- }
- /* Now store new binding */
- mtaptr[i] = c;
- mtaptr[i+1] = fni;
- }
- else {
- i = c & 0177;
- if (chrptr[i] && (chrptr[i]&0377) != fni)
- lerr("(keybind) redefining %s as %d=\"%s\"",
- charep(c), fni, lp->lval.lvs);
- chrptr[i] = fni;
- }
- return(LTRUE);
-}
-
-/* KEYALLUNBIND - (keyallunbind) */
-struct lnode *
-keyallun()
-{ register int i;
- register char *cp;
-
-/* fprintf(stderr, "ellec: clearing all key definitions\n"); */
- for(i = 0, cp = chrptr; i < chrcnt; i++)
- *cp++ = 0;
- mtacnt = extcnt = mnucnt = 0;
- return(LTRUE);
-}
-\f
-/* MENUITEM - (menuitem <functionname>) */
-
-struct lnode *
-menuitem(lp)
-register struct lnode *lp;
-{ register int i, fni;
-
- if(lp == NIL)
- return(NIL);
- switch(lp->ltyp)
- { case LT_VAL:
- fni = lp->lval.lvi;
- break;
- case LT_LIST:
- return(NIL);
- case LT_STR:
- fni = findfun(lp->lval.lvs);
- break;
- }
- if(fni == 0) return(NIL); /* Bad val or no such function name */
- for(i = 0; i < mnusiz; i++)
- if(fni == (mnuptr[i]&0377) || mnuptr[i] == 0)
- { mnuptr[i] = fni;
- mnucnt++;
- return(LTRUE);
- }
- return(NIL); /* Too many menu items */
-}
-\f
-repchar(str)
-register char *str;
-{ register int c;
- register int i, l;
-
- if (str == 0) return (-1);
- i = 0;
- l = strlen(str);
- c = (*str++)&0377;
- if(l == 0) return(-1);
- if(l == 1) return(c); /* One-char representation */
- if(c == '^')
- if(l == 2) return((~0140) & mupcase(*str));
- else return(-1);
- c = mupcase(c);
- if (*str == '-')
- { if(*++str == 0) return(-1);
- switch(c)
- { case 'X': return(CB_EXT | mupcase(repchar(str)));
- case 'M': return(CB_META | mupcase(repchar(str)));
- case 'C': return((~0140) & repchar(str));
- }
- }
- if(c == 'S' && upcase(*str) == 'P' && l == 2)
- return(' ');
- if(c == 'D' && upcase(*str++) == 'E' && upcase(*str++) == 'L'
- && *str == 0)
- return(0177);
- return(-1);
-}
-
-struct lnode *
-getln()
-{ return((struct lnode *)calloc(1,sizeof(struct lnode)));
-}
-
-numcvt(str, anum)
-char *str;
-int *anum;
-{ register char *cp;
- register int i, c, sign;
- if((cp = str) == 0)
- return 0;
- i = sign = 0;
- if(*cp == '-')
- cp++, sign++;
- while(c = *cp++)
- if(!isdigit(c)) return(0);
- else i = 10*i + (c - '0');
- *anum = sign ? -i : i;
- return(1);
-}
-
-
-
-listcnt(lp)
-register struct lnode *lp;
-{ register int i;
- i = 0;
- while(lp)
- ++i, lp = lp->lnxt;
- return(i);
-}
-\f
-/* FUNNAME - Given function index, return function name.
-** Always wins; returns "unknown" for bad indices.
-*/
-char *
-funname(i)
-register int i;
-{
- register char *cp = NULL;
- if(0 < i && i <= efxmax && (cp = efuntab[i].ef_name))
- return cp;
- return("unknown function");
-}
-
-findfun(name)
-register char *name;
-{ register int i;
- if((i = efxmax) > 0)
- { do { if(strueq(name, efuntab[i].ef_name))
- return(i);
- } while(--i);
- return(0);
- }
- return(0);
-}
-
-
-/* FUNCNT - Scan all key bindings, counting each occurrence of every
-** function index.
-** This is used to determine which functions are actually used.
-*/
-funcnt(arr)
-register int *arr; /* Pointer to array of EFUNMAX ints */
-{
- register int i;
-
- for(i = 0; i < EFUNMAX; ++i) /* Clear the array */
- arr[i] = 0;
-
- for(i = 0; i < chrcnt; ++i) /* Scan bindings */
- arr[chrptr[i]&0377]++;
- for(i = 0; i < mtacnt; i += 2)
- arr[mtaptr[i+1]&0377]++;
- for(i = 0; i < extcnt; i += 2)
- arr[extptr[i+1]&0377]++;
-}
-
-scpy(from,to,cnt)
-register char *from,*to;
-register int cnt;
-{ if(cnt > 0)
- do { *to++ = *from++; }
- while(--cnt);
-}
-
-/* STRIPSP - strip spaces from string. Returns ptr to start. */
-char *
-stripsp(cp)
-register char *cp;
-{
- register char *ep, *lastp;
- while(*cp == ' ') ++cp;
- if (*cp)
- { ep = cp + strlen(cp); /* Point to null ending the str */
- while (*--ep == ' ');
- *++ep = 0; /* Tie it off */
- }
- return cp;
-}
-\f
-warn(str,a,b,c,d,e,f,g,h,i)
-char *str;
-{
- fprintf(stderr, "ellec: ");
- fprintf(stderr, str, a,b,c,d,e,f,g,h,i);
- fprintf(stderr, "\n");
-}
-
-lerr(str,a,b,c,d,e,f,g,h,i)
-char *str;
-{
- warn(str, a,b,c,d,e,f,g,h,i);
- *linecp = 0; /* Tie off current line buffer */
- fprintf(stderr, " Line %d: %s\n", lineno, linebuf);
-}
-
-fatal(str,a,b,c,d,e,f,g,h,i)
-char *str;
-{
- warn(str, a,b,c,d,e,f,g,h,i);
- exit(1);
-}
-
+++ /dev/null
-/* SB - Copyright 1982 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author. In all cases
- * the source code and any modifications thereto must remain
- * available to any user.
- *
- * This is part of the SB library package.
- * Any software using the SB library must likewise be made
- * quasi-public, with freely available sources.
- */
-
-#ifdef COMMENT
-
-The initials "SB" stand for "String Block" or "String Buffer".
-
-SBBUFFER - A SB buffer containing a sbstring opened for editing.
-SBFILE - A structure holding file-specific information for all
- SDBLKs pointing to that file.
-SBSTRING - A SB string; conceptually a single string, but actually
- a linked list of SDBLKs. Unless opened by a SBBUFFER,
- only a few operations are allowed on SBSTRINGs (creating,
- copying, deleting).
-SDBLK - One of the linked nodes constituting a sbstring. Each SDBLK
- node points to a continuous string either in memory or
- on disk, or both.
-SBLK - Another name for SDBLK.
-SMBLK - An allocated chunk of memory. Also refers to the node structure
- maintained by the SBM memory management routines, which
- points to the actual chunk of memory.
-SBM - Name of the memory management package. SBM routines are used
- to allocate memory in general, and are not just for
- use by SB routines.
-
-************ MACHINE DEPENDENT DEFINITIONS **********
-
- The following compile time definitions represent machine
-dependent parameters which are intended mainly for use only by SBM and
-SBSTR routines. Other programs should use them with caution. Note
-that a great deal of code assumes that type "int" corresponds to a basic
-machine word (as per C Reference Manual).
-
- The current definitions will only work for machines which have
-1, 2, 4, or 8 "char" bytes in a machine word. Any other size will
-require some changes to the definitions and possibly to some places
-using them.
-
-WORD - integer-type definition corresponding to machine word.
-WDSIZE - # addressable char bytes in a machine word. (1, 2, 4, 8)
-WDBITS - # low order bits in an address, ie log2(WDSIZE). (0, 1, 2, 3)
-WDMASK - Mask for low order bits of address (0, 1, 3, 7)
-CHAR_MASK - If defined, machine does sign-extension on chars, and
- they must be masked with this value.
-
- Note that the macro for WDBITS has no mathematical significance
-other than being an expression which happens to evaluate into the right
-constant for the 4 allowed values of WDSIZE, and in fact it is this
-crock which restricts WDSIZE! If C had a base 2 logarithm expression
-then any power of 2 could be used.
-
-Values for machines
- WORD WDSIZE WDBITS WDMASK
- PDP11, Z8000, I8086 int 2 1 01
- VAX11, M68000, PDP10 int 4 2 03
-
-#endif /* COMMENT */
-\f
-/* First try to define a few things in a semi-portable way
-*/
-#include "eesite.h"
-#ifdef __STDC__ /* Implementation supports ANSI stuff? */
-#include <limits.h> /* Get sizes for char stuff */
-#define _SBMUCHAR 1 /* Can use "unsigned char" */
-#define _SBMCHARSIGN (CHAR_MIN < 0) /* True if "char" is sign-extended */
-#define CHAR_MASK (UCHAR_MAX)
-
-#else /* not ANSI */
-#ifndef _SBMUCHAR /* Default assumes no "unsigned char" */
-#define _SBMUCHAR 0
-#endif
-#ifndef _SBMCHARSIGN /* Default assumes "char" is sign-extended */
-#define _SBMCHARSIGN 1
-#endif
-#ifndef CHAR_MASK /* Default assumes "char" is 8 bits */
-#define CHAR_MASK 0377
-#endif
-#endif /* not ANSI */
-
-/* Define "sb_uchartoint" as a macro which ensures that an unsigned
-** character value is converted properly to an int value.
-*/
-#if (_SBMUCHAR || (_SBMCHARSIGN==0))
-#define sb_uchartoint(a) (a) /* No fear of sign extension */
-#else
-#define sb_uchartoint(a) ((a)&CHAR_MASK) /* Bah, sign extension */
-#endif
-
-
-/* Defs for machines with a base-2 WDSIZE. Yes, the (int) is indeed necessary
- * (to allow implicit conversion to long where needed - the PDP11 compiler
- * is known to lose without it, because sizeof is cast as "unsigned int"
- * which loses big in long masks!)
- */
-#define WORD int
-#define WDSIZE ((int)(sizeof(WORD)))
-#define WDMASK (WDSIZE-1)
-#define WDBITS ((WDSIZE>>2)+(1&WDMASK))
-
-#define rnddiv(a) ((a)>>WDBITS) /* # words, rounded down */
-#define rndrem(a) ((a)&WDMASK) /* # bytes remaining past wd bndary */
-#define rnddwn(a) ((a)&~WDMASK) /* Round down to word boundary */
-#define rndup(a) rnddwn((a)+WDSIZE-1) /* Round up to word boundary */
-
-#ifdef COMMENT /* The following are for machines without a base-2 WDSIZE */
-#define rnddiv(a) ((a)/WDSIZE)
-#define rndrem(a) ((a)%WDSIZE)
-#define rnddwn(a) ((a)-rndrem(a))
-#define rndup(a) rnddwn((a)+WDSIZE-1)
-#undef WDMASK /* These become meaningless and anything */
-#undef WDBITS /* which uses them should be changed! */
-#endif /* COMMENT */
-
-/* The following 3 definitions are somewhat machine-dependent,
- * but are specifically intended for general use and work for all
- * currently known C implementations.
- * SBMO must be an integer-type object large enough to hold
- * the largest difference in SBMA pointers, and must not be
- * used in signed comparisons.
- */
-
-typedef long chroff; /* CHROFF - Char offset in disk/sbstr */
-typedef unsigned int SBMO; /* SBMO - Char offset in memory */
-typedef
-#if _SBMUCHAR
- unsigned
-#endif
- char *SBMA; /* SBMA - Pointer to char loc in memory */
-
-
-
-/* The following definitions tend to be system-dependent. Only the
- * SBM and SBSTR routines use them.
- */
-#define SB_NFILES 32 /* # of open files we can hack. Actually
- * this is max FD value plus 1. */
-#define SB_BUFSIZ 512 /* Optimal buffer size (system block size) */
-#define SB_SLOP (16*WDSIZE) /* # slop chars to tolerate for allocations */
-
-#define SMNODES (20) /* # SM or SD nodes to create when needed */
-#define SMCHUNKSIZ (16*512) /* # bytes of mem to create (via sbrk) " " */
-#define MAXSBMO ((SBMO)-1) /* Used in SBM only */
- /* MAXSBMO should be the largest possible SBMO value. */
-\f
-#define EOF (-1)
-#define SBFILE struct sbfile
-#define SBBUF struct sbbuffer
-#define SBSTR struct sdblk /* Start of a sbstring */
-
-struct sbfile {
- int sfflags; /* Various flags */
- int sffd; /* FD for file (-1 if none) */
- struct sdblk *sfptr1; /* Ptr to 1st node in phys list */
- chroff sflen; /* Original length of file FD is for */
-};
-
- /* Definition of SBBUF string/buffer */
-struct sbbuffer {
- SBMA sbiop; /* I/O pointer into in-core text */
- int sbrleft; /* # chars left for reading */
- int sbwleft; /* # chars left for writing */
- int sbflags; /* Various flags */
- chroff sbdot; /* Logical pos for start of current sdblk */
- chroff sboff; /* Offset into current sdblk (if no smblk)*/
- struct sdblk *sbcur; /* Pointer to current SD block of string */
-};
- /* Flags for "sbflags" */
-#define SB_OVW 01 /* Over-write mode */
-#define SB_WRIT 02 /* Written; smuse needs to be updated from sbiop */
-
- /* NOTE: An unused sbbuf structure should be completely zeroed.
- * This will cause routines to handle it properly
- * if they are accidentally pointed at it.
- */
-
- /* Definition of SDBLK */
-struct sdblk {
- struct sdblk *slforw; /* Logical sequence forward link */
- struct sdblk *slback; /* Logical sequence backward link */
- int sdflags;
- struct sdblk *sdforw; /* Physical sequence (disk) */
- struct sdblk *sdback; /* ditto - backptr for easy flushing */
- struct smblk *sdmem; /* Mem pointer, 0 if no in-core version */
- SBFILE *sdfile; /* File pointer, 0 if no disk version */
- chroff sdlen; /* # chars in disk text */
- chroff sdaddr; /* Disk address of text */
-};
- /* Flags for "sdflags" */
-#define SD_LOCK 0100000 /* Locked because opened by a SBBUF */
-#define SD_LCK2 0040000 /* Locked for other reasons */
-#define SD_MOD 0020000 /* Modified, mem blk is real stuff */
-#define SD_NID 0323 /* Node ID marks active (not on freelist) */
-#define SD_LOCKS (SD_LOCK|SD_LCK2)
-
-/* Note sdback is ONLY needed for fixing up phys list when a sdblk is
- * deleted (so as to find previous blk in phys list). Perhaps it shd
- * be flushed (ie only use SDFORW)? How to do deletions - use circular
- * list? Sigh.
- */
-
- /* Definition of SMBLK (used by SBM routines) */
-struct smblk {
- struct smblk *smforw; /* Links to other mem blks, in phys order */
- struct smblk *smback;
- int smflags; /* Type, in-use flags */
- SBMA smaddr; /* Mem address of text */
- SBMO smlen; /* # bytes in mem block */
- SBMO smuse; /* # bytes "used" in block */
-};
- /* Flags for "smflags" */
-#define SM_USE 0100000 /* Block is in use (mem free if off) */
-#define SM_NXM 040000 /* Block mem is non-existent */
-#define SM_EXT 020000 /* Block mem owned by external (non-SBM) rtn*/
-#define SM_MNODS 010000 /* Block holds SMBLK nodes */
-#define SM_DNODS 04000 /* Block holds SDBLK nodes */
-#define SM_NID 0315 /* Node in-use identifier (low byte) */
-
-/* Error handler type values */
-#define SBMERR 0 /* Error in SBM package */
-#define SBXERR 1 /* Error in SBSTR package */
-#define SBFERR 2 /* "Error" - SBSTR package found a file overwritten.
- * Non-zero return will continue normally. */
-
-
-/* Redefine certain external symbols to be unique in the first 6 chars
-** to conform with ANSI requirements.
-*/
-#define sbm_nfre sbmnfre /* SBM stuff */
-#define sbm_nfor sbmnfor
-#define sbm_nmov sbmnmov
-#define sbm_ngc sbmngc
-#define sbx_ndget sbxndg /* SBSTR stuff */
-#define sbx_ndel sbxnde
-#define sbx_ndfre sbxndf
-#define sbx_sdcpy sbxsdc
-#define sbx_sdgc sbxsdg
-#define sbe_sdlist sbesls /* SBERR stuff */
-#define sbe_sdtab sbestb
-#define sbe_sds sbesds
-#define sbe_sbvfy sbesbv
-#define sbe_sbs sbesbs
-
-/* Forward declarations */
-extern SBMA sbm_lowaddr; /* For roundoff purposes */
-
-extern SBFILE sbv_tf; /* SBFILE for temp swapout file */
-extern int (*sbv_debug)(); /* Error handler address */
-extern off_t lseek(); /* For sbstr code mostly */
-extern char *mktemp();
-extern char *malloc();
-extern char *calloc();
-extern SBBUF *sb_open();
-extern SBSTR *sb_close(), *sb_fduse(), *sbs_cpy(), *sbs_app(), *sb_cpyn(),
- *sb_killn();
-extern struct sdblk *sbx_ready();
-extern chroff sb_tell(), sb_ztell(), sbs_len();
-\f
-/* Definition of SB_GETC, SB_PUTC, SB_BACKC macros */
-
-#define sb_putc(s,c) (--((s)->sbwleft) >= 0 ? \
- (*(s)->sbiop++ = c) : sb_sputc(s,c))
-#define sb_getc(s) (--((s)->sbrleft) >= 0 ? \
- sb_uchartoint(*(s)->sbiop++) : sb_sgetc(s))
-#define sb_peekc(s) ((s)->sbrleft > 0 ? \
- sb_uchartoint(*(s)->sbiop) : sb_speekc(s))
-
-/* WARNING - sb_backc must ONLY be used if last operation was a
- * successful sb_getc!! For slow but sure invocation use sb_rgetc.
- */
-#define sb_backc(s) (++(s->sbrleft), --(s->sbiop))
-
-#include "sbproto.h" /* function prototypes */
+++ /dev/null
-
-#include "sb.h"
-
-/* BCOPY(from,to,cnt) - Copy string of bytes.
- * Normally this routine is an assembly-language library routine,
- * but not all systems have it. Hence this C-language version
- * which tries to be fairly machine-independent.
- * Attempts to be clever about using word moves instead of byte moves.
- * Does not hack overlapping backward moves.
- */
-bcopy(from, to, cnt) /* Copy count bytes from -> to */
-register SBMA from;
-register SBMA to;
-register unsigned cnt;
-{
- if(!cnt)
- return;
- while(rndrem((int)from)) /* Get source aligned */
- { *to++ = *from++;
- if(--cnt == 0) return;
- }
- if(rndrem((int)to) == 0) /* Do word move if dest now aligned */
- { register unsigned tmp;
- tmp = cnt;
- if((cnt = rnddiv(cnt)) > 4)
- { sbm_wcpy((int *)from, (int *)to, cnt);
- if((cnt = rndrem(tmp)) == 0)
- return; /* No leftover bytes, all done */
- tmp -= cnt; /* Ugh, must update pointers */
- from += tmp;
- to += tmp;
- }
- else cnt = tmp; /* Not worth call overhead */
- }
- do { *to++ = *from++; } /* Finish up with byte loop */
- while(--cnt);
-}
-
-/* SBM_WCPY - word-move auxiliary routine.
- * This is a separate routine so that machines with only a few
- * registers have a chance to use them for the word copy loop.
- * This cannot be made part of BCOPY without doing some
- * unnecessary pointer conversions and using extra variables
- * (since most compilers will not accept type casts on lvalues,
- * which are needed to treat (char *) as (int *)).
- */
-sbm_wcpy(from, to, cnt)
-register int *from, *to;
-register unsigned cnt;
-{
- if(cnt)
- do { *to++ = *from++; }
- while(--cnt);
-}
+++ /dev/null
-/* SB - Copyright 1982 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author. In all cases
- * the source code and any modifications thereto must remain
- * available to any user.
- *
- * This is part of the SB library package.
- * Any software using the SB library must likewise be made
- * quasi-public, with freely available sources.
- */
-
-#define PRINT /* Include printout stuff */
-
-#include "sb.h"
-#include <stdio.h>
-
-extern struct smblk *sbm_nfl;
-extern struct smblk *sbm_list;
-extern struct sdblk *sbx_nfl;
-
-#ifdef PRINT
-#define PRF(stmt) {if(p) stmt;}
-#define PRFBUG(str,stmt) {if(p) stmt;else return(str);}
-#define PRFBAD(str,stmt) {if(p) stmt; return(str);}
-#else
-#define PRF(stmt) ;
-#define PRFBUG(str,stmt) return(str);
-#define PRFBAD(str,stmt) return(str);
-#endif
-
-#ifndef NPTRS
-#define NPTRS (1000) /* Catch loops of period less than this. */
-#endif
-
-int sbe_dec = 0; /* Set nonzero to use decimal printout */
-
-struct ptab {
- int pt_pflag; /* Printflag value */
- char *pt_err; /* Error string return */
- int pt_xerr; /* Error index return */
- int pt_hidx; /* Highest freelist entry */
- int pt_nsto; /* # entries stored in table */
- int pt_cnt; /* # of entry store attempts */
- struct smblk *pt_tab[NPTRS];
-};
-
-_PROTOTYPE( char *sbe_sdtab, (struct ptab *pt, int p, int phys) );
-_PROTOTYPE( char *sbe_schk, (struct sdblk *sd, struct ptab *pt) );
-_PROTOTYPE( int sbe_tbent, (struct ptab *pt, struct smblk *sm) );
-
-#define PTF_PRF 01 /* Do printout stuff */
-#define PTF_OVFERR 02 /* Complain if table overflows */
-#define PTF_SDPHYS 04 /* Follow SD phys links (else logical links) */
-
-struct flgt {
- int flg_bit;
- int flg_chr;
-};
-
-_PROTOTYPE( char *sbe_fstr, (int flags, struct flgt *fp) );
-
-char *sbe_mvfy(), *sbe_mfl(), *sbe_mlst(); /* SBM */
-char *sbe_sbvfy(), *sbe_sbs(); /* SBBUF */
-char *sbe_svfy(), *sbe_sdlist(), *sbe_sdtab(), *sbe_schk(); /* SD */
-char *sbe_fstr(); /* Misc utility */
-\f
-
-/* SBE_MEM() - Print out memory usage list
-*/
-sbe_mem()
-{
- printf("\nMemory Usage:\n");
- printf("\tsbm_nfl : %6o\n",sbm_nfl);
- printf("\tsbm_list: %6o\n",sbm_list);
- printf("\tsmblk nodes are %o bytes long.\n",sizeof (struct smblk));
-
- sbe_mlst(1); /* Scan mem list, printing stuff. */
-}
-
-/* SBE_MVFY() - Verify memory allocation structures
- * Returns error message (0 if no errors found).
- */
-char *
-sbe_mvfy()
-{ register char *res;
-
- if((res = sbe_mfl(0))
- || (res = sbe_mlst(0)))
- return(res);
- return(0);
-}
-\f
-/* SBM Debugging Routines */
-
-struct flgt smflgtab[] = {
- SM_USE, 'U',
- SM_NXM, 'N',
- SM_EXT, 'E',
- SM_MNODS,'M',
- SM_DNODS,'D',
- 0,0
-};
-
-static char smfhelp[] = "U-Used, N-NXM, E-External, M-SMnodes, D-SDnodes";
-static char smhdline[] = "\
- SM: back smaddr smlen smuse smflags";
-
-/* SBE_MFL(printflag) - Verify/Print memory freelist
- * Returns error message (0 if no errors found).
- */
-char *
-sbe_mfl(p)
-int p;
-{ register struct smblk *sm;
- register int i;
- struct ptab smtab; /* For loop detection */
-
- PRF(printf("Tracing SM node freelist --\n"))
- PRF(printf(" Maximum loop detection size is %d.", NPTRS))
- if((sm = sbm_nfl) == 0)
- { PRF(printf("\n\tNo list.\n"))
- return(0); /* Null freelist is ok */
- }
- smtab.pt_pflag = p ? PTF_PRF : 0;
- smtab.pt_nsto = smtab.pt_cnt = 0;
- i = 0; /* Print 8 addrs/line */
- for(; sm; sm = sm->smforw)
- {
- PRF(printf("%s%7o->", (i==0 ? "\n " : ""), sm))
- if(++i >= 8) i = 0;
- if(sbe_tbent(&smtab, sm) < 0) /* If hit loop, stop */
- PRFBAD("SM freelist loop",
- printf("\nLOOP - %o seen as node %d!!\n",
- sm, smtab.pt_xerr))
- if(sm->smflags)
- { PRF((i = 0, printf("\nFreelist node has flags:\n")))
- PRFBUG("Free SM flagged", sbe_smp(sm, 0))
- }
- }
- PRF(printf("\nEnd - %d nodes on SM freelist.\n", smtab.pt_cnt))
- return(0);
-}
-
-/* SBE_MLST(printflag) - Verify/Print allocated memory list.
- * Returns error message (0 if no errors found).
- */
-char *
-sbe_mlst(p)
-int p;
-{ register struct smblk *sm, *smf, *smb;
- char *nextaddr = NULL;
- int i;
- struct ptab smtab; /* For loop detection */
-
- PRF(printf("Tracing mem list -- \n"))
- if((sm = sbm_list) == 0)
- { PRF(printf("\tNo list?!\n"))
- if(sbm_nfl) /* Ensure rest are 0 too */
- return("No mem list?!!");
- return(0);
- }
-
- smtab.pt_pflag = p;
- smtab.pt_cnt = smtab.pt_nsto = 0;
- smb = 0;
- PRF(printf(" Flags: %s\n%s\n", smfhelp, smhdline))
- for(; sm; sm = smf)
- { PRF(printf(" %6o: ",sm))
- if(sbe_tbent(&smtab, sm) < 0)
- PRFBAD("Loop in mem list!!",
- printf("LOOP - seen as node %d!!\n", smtab.pt_xerr))
-
- if(sm->smback == smb)
- PRF(printf("^ ")) /* Back ptr OK */
-
- else PRFBUG("Bad back ptr!",
- printf("%6o BAD Backptr!!\n\t ",sm->smback))
-
- if((sm->smflags&0377)!= SM_NID)
- PRFBUG("SM: bad node ID",
- printf("BAD - no node ID!\n\t "))
- PRF(printf((sm->smflags&SM_USE) ? " " : "FREE "))
- if(sm->smlen == 0)
- PRFBUG("SM: len 0",
- printf("Zero-length area!"))
- if((sm->smflags&SM_USE)==0
- && rndrem(sm->smaddr - sbm_lowaddr))
- PRFBUG("Bad free-mem block",
- printf("Bad free-mem block"))
- PRF(sbe_smp(sm, 1)) /* Print out rest of info */
-
- if(nextaddr != sm->smaddr
- && smtab.pt_cnt != 1) /* 1st time needs init */
- { PRFBUG("Alignment error!",
- printf("\t BAD!! %6o expected; ",nextaddr))
-#if !(MINIX)
- PRF((i = sm->smaddr - nextaddr) > 0
- ? printf("%d skipped.\n",i)
- : printf("%d overlapped.\n",-i))
-#endif
- }
- nextaddr = sm->smaddr + sm->smlen;
- smf = sm->smforw;
- smb = sm; /* Save ptr to back */
- }
- PRF(printf("End = %6o\n",nextaddr))
- return(0);
-}
-
-#ifdef PRINT
-sbe_smp(sm,type)
-register struct smblk *sm;
-int type;
-{
- if(type==0)
- printf(" %6o: %s ", sm,
- ((sm->smflags&SM_USE) ? " " : "FREE"));
- printf("%6o: ", sm->smaddr);
- printf((sbe_dec ? "%5d. %5d." : "%6o %6o"), sm->smlen, sm->smuse);
- printf(" %7o = %s\n", sm->smflags, sbe_fstr(sm->smflags, smflgtab));
-}
-#endif /*PRINT*/
-\f
-/* SD (SBSTR) debugging routines */
-
-struct flgt sdflgtab[] = {
- SD_LOCK, 'L',
- SD_LCK2, 'T',
- SD_MOD, '*',
- 0,0
-};
-
-static char sdfhelp[] = "\
-<f> flags: *-MOD (disk outofdate), L-LOCK, T-LCK2 (temp)";
-static char sdhdline[] = "\
-<f> SD: slforw slback sdflgs sdforw sdback sdmem sdfile sdaddr sdlen";
-
-
-/* SBE_SFL(printflag) - Verify/Print SD freelist
- * Returns error message (0 if no errors found).
- */
-char *
-sbe_sfl(p)
-int p;
-{ register struct sdblk *sd;
- register int i;
- struct ptab sdtab; /* For loop detection */
-
- PRF(printf("Tracing SDBLK node freelist --\n"))
- PRF(printf(" Maximum loop detection size is %d.", NPTRS))
- if((sd = sbx_nfl) == 0)
- { PRF(printf("\n\tNo list.\n"))
- return(0); /* Null freelist is ok */
- }
- sdtab.pt_pflag = p ? PTF_PRF : 0;
- sdtab.pt_nsto = sdtab.pt_cnt = 0;
- i = 0; /* Print 8 addrs/line */
- for(; sd; sd = sd->slforw)
- {
- PRF(printf("%s%7o->", (i==0 ? "\n " : ""), sd))
- if(++i >= 8) i = 0;
- if(sbe_tbent(&sdtab, sd) < 0) /* If hit loop, stop */
- PRFBAD("SD freelist loop",
- printf("\nLOOP - %o seen as node %d!!",
- sd, sdtab.pt_xerr))
- if(sd->sdflags)
- { PRF((i = 0, printf("\nFreelist node has flags:\n")))
- PRFBUG("Free SD flagged", sbe_psd(sd))
- }
- }
- PRF(printf("\nEnd - %d nodes on SD freelist.\n", sdtab.pt_cnt))
- return(0);
-}
-
-
-
-/* SBE_SDS() - Print out all sdblk data stuff
- */
-sbe_sds()
-{ int sbe_psd();
-
- printf("Printout of all in-use SDBLKs:\n");
- printf(" %s\n", sdfhelp);
- printf("%s\n", sdhdline);
- sbm_nfor(SM_DNODS,sizeof(struct sdblk),sbe_psd,0);
- printf("\n");
-}
-
-/* SBE_PSD - Auxiliary for invocation by SBE_SDS above. */
-sbe_psd(sd)
-register struct sdblk *sd;
-{ register int flags;
-
- flags = sd->sdflags;
- printf("%c%c%c",
- ((flags&SD_MOD) ? '*' : ' '),
- ((flags&SD_LOCK) ? 'L' : ' '),
- ((flags&SD_LCK2) ? 'T' : ' '));
-
- printf(" %7o: %6o %6o %6o %6o %6o %6o %6o %7lo %5ld.\n", sd,
- sd->slforw, sd->slback, sd->sdflags,
- sd->sdforw, sd->sdback, sd->sdmem,
- sd->sdfile, sd->sdaddr, sd->sdlen);
- return(0);
-}
-
-/* SBE_SVFY() - Verify all SD blocks
- * Returns error message (0 if no errors found).
- */
-char *
-sbe_svfy()
-{ register char *res;
- return((res = sbe_sdlist(0,0)) ? res : sbe_sdlist(0,1));
-}
-
-/* SBE_SDLIST(printflag, physflag) - Verify/Print all SD blocks.
- * Show logical lists if physflag 0
- * Show physical lists otherwise
- * Returns error message (0 if no errors found).
- */
-char *
-sbe_sdlist(p,phys)
-int p, phys;
-{ register char *res;
- struct ptab sdtab; /* The SDLIST table to use */
-
- /* First put freelist in table, then scan for all
- * SD nodes. Each active node (not in table) gets
- * its entire list traced forward/backward and added to table.
- */
- if(res = sbe_sdtab(&sdtab, p, phys)) /* Set up freelist table */
- return(res);
-
- /* Freelist entered in table, now scan all SD's */
- res = (char *)sbm_nfor(SM_DNODS,sizeof(struct sdblk),
- sbe_schk, &sdtab);
-
- PRF(printf("\n"))
- return(res);
-}
-
-/* SBE_SDTAB(tableptr, printflag, physflag) - Auxiliary for SBE_SDLIST.
- * Stuffs all freelist SDBLK addresses in table for dup detection.
- * Returns error message (0 if no errors found).
- */
-char *
-sbe_sdtab(pt, p, phys)
-register struct ptab *pt;
-int p, phys;
-{ register struct sdblk *sd;
-
- pt->pt_pflag = (p ? PTF_PRF : 0) | (phys ? PTF_SDPHYS : 0)
- | PTF_OVFERR;
- pt->pt_cnt = pt->pt_nsto = 0; /* Initialize */
-
- /* Stick freelist in table */
- for(sd = sbx_nfl; sd; sd = sd->slforw)
- { if(sbe_tbent(pt, sd) < 0)
- { if(pt->pt_xerr < 0)
- PRFBAD("SD freelist too long",
- printf("SD freelist too long (%d)\n",
- NPTRS))
- PRFBAD("SD freelist loop",
- printf("SD freelist loop at %o\n", pt->pt_xerr))
- }
-
- if(sd->sdflags)
- {
- PRF(printf("Bad free SD, non-zero flag:\n"))
- PRFBUG("Free SD flagged", sbe_psd(sd))
- }
- }
- pt->pt_hidx = pt->pt_nsto; /* Set idx of 1st non-FL entry */
- return(0);
-}
-\f
-/* SBE_SCHK(SDptr, tableptr) - Auxiliary for SBE_SDLIST.
- * If SD not already in table, verifies or prints
- * the complete physical or logical list it's on, and enters all
- * of its SDs into table (to prevent doing it again).
- * Returns 0 if no errors, else error string.
-** There is a problem when the table overflows. The tbent routine
-** wants to add it (wrapping around at bottom) in that case, because
-** that still helps detect loops. But this routine wants to reset
-** the table back (after scanning to head of list) and once it starts
-** scanning forward again it will fail, because some of the SDs are
-** still in the table due to the wraparound! Thus PTF_OVFERR is always
-** set, in order to at least give the right error message.
-*/
-char *
-sbe_schk(sd, pt)
-register struct sdblk *sd;
-struct ptab *pt;
-{ register struct sdblk *sdx;
- register struct smblk *sm;
- struct sbfile *savfile;
- chroff lastaddr;
- int p, savidx, phys;
-
- phys = pt->pt_pflag&PTF_SDPHYS; /* Set up physflag */
- if(phys && (sd->sdfile == 0)) /* Ignore non-phys stuff if phys */
- return(0);
- p = pt->pt_pflag&PTF_PRF; /* Set up printflag */
- savidx = pt->pt_nsto; /* Remember initial extent of table */
-
- if(sbe_tbent(pt, sd) < 0)
- { if(pt->pt_xerr >= 0) /* OK if already in table */
- return(0);
- PRFBAD("Too many SDs",
- printf("Too many SDs for table (%d)\n", NPTRS))
- }
-
- /* Now search backward for start of list */
- while(sdx = (phys ? sd->sdback : sd->slback))
- if(sbe_tbent(pt,sdx) >= 0)
- sd = sdx;
- else break;
- if(sdx)
- { if(pt->pt_xerr < 0) /* Table error? */
- PRFBAD("Too many SDs",
- printf("Too many SDs for table (%d)\n",NPTRS))
- PRF(printf("Backlist loop!! Dup'd node:%s\n",
- (pt->pt_xerr < pt->pt_hidx) ?
- "(on freelist!)" : "" ))
- PRFBUG((phys ? "Phys SD loop" : "SD loop"), sbe_psd(sdx))
- }
- /* Reset table to flush nodes backed over */
- pt->pt_cnt = pt->pt_nsto = savidx;
-
- /* SD now points to start of list. Begin stepping thru list... */
- PRF(printf("---- %sList started: ", (phys ? "Phys " : "")))
- if(phys)
- { savfile = sd->sdfile;
- PRF(printf(" SF: %o, fd= %d, ln= %ld\n",
- savfile,savfile->sffd,savfile->sflen))
- if(savfile->sfptr1 != sd)
- PRFBUG("SFPTR1 bad",
- printf(" BAD!! Sfptr1 %o doesn't match SD %o!!\n",
- savfile->sfptr1, sd))
- lastaddr = 0;
- }
- else PRF(printf("\n"))
-
- PRF(printf("%s\n", sdhdline))
- for(sdx = 0; sd; (sdx = sd, sd = (phys ? sd->sdforw : sd->slforw)))
- {
- PRF(sbe_psd(sd)) /* Print it out */
- if(sdx != (phys ? sd->sdback : sd->slback))
- { if(phys)
- PRFBUG("PSD bad sdback",printf("\tBad phys backptr\n"))
- else
- PRFBUG("SD bad slback",printf("\tBad backptr\n"))
- }
-
- if((sd->sdflags&0377) != SD_NID)
- PRFBUG("Bad SD node ID", printf("\tBad node ID!\n"))
-
-
- if(sd->sdfile && (sd->sdlen < 0 || sd->sdaddr < 0))
- PRFBUG("SD: neg len/addr",
- printf("\tNeg disk len/addr\n"))
- if(phys) goto dophys;
-
- /* Do special stuff for logical list */
- if(sm = sd->sdmem)
- { if((sm->smflags&0377) != SM_NID)
- PRFBUG("SD: bad SM",
- printf("\nBad SMBLK ptr\n"))
- if((sd->sdflags&SD_MOD)==0
- && sd->sdlen != sm->smuse)
- PRFBUG("SD != SM",
- printf("\tBad SMBLK? Len conflict\n"))
- if(sm->smlen < sm->smuse)
- PRFBUG("SD: SM len < use",
- printf("\tBad SMBLK, len < use\n"))
- }
- goto doboth; /* Skip phys stuff */
-
- /* Do special stuff for phys list */
- dophys: if(sd->sdfile != savfile)
- PRFBUG("SD: bad sdfile",
- printf("\tBad sdfile ptr! Shd be %o\n",
- savfile))
- if(sd->sdaddr < lastaddr)
- PRFBUG("SD addr out of order",
- printf("\tBad disk addr, not in order!\n"))
- lastaddr = sd->sdaddr;
- /* Done with special phys stuff */
-
- doboth: if(sbe_tbent(pt, sd) < 0)
- { if(pt->pt_xerr < 0)
- PRFBAD("Too many SDs",
- printf("Too many SDs for table (%d)\n",NPTRS))
-
- PRFBUG("SD loop",
- printf("\tLOOP!! This SD already seen%s.\n",
- (pt->pt_xerr < pt->pt_hidx) ?
- " (on freelist!)" : "" ))
- break;
- }
- }
- PRF(printf("-----------\n"))
- return(0);
-}
-\f
-/* SBE_DSK(SFptr) - Print out disk usage list for specific file
- */
-
-sbe_dsk(sfp)
-SBFILE *sfp;
-{
- printf("SBFILE printout not coded: %o\n",sfp);
-}
-\f
-/* SBBUF structure debugging routines */
-
-struct flgt sbflgtab[] = {
- SB_OVW, 'O',
- SB_WRIT,'W',
- 0,0
-};
-static char sbfhelp[] = "O-Overwrite, W-Write";
-
-/* SBE_SBVFY(SBptr) - Verify a SB-string.
- * Returns error message (0 if no errors found).
- */
-char *
-sbe_sbvfy(sbp)
-SBBUF *sbp;
-{ return(sbe_sbs(sbp,0));
-}
-
-/* SBE_SBS(SBptr, printflag) - Verify/Print SBSTR data stuff
- * Returns error message (0 if no errors found).
- */
-char *
-sbe_sbs(sbp,p)
-SBBUF *sbp;
-int p;
-{ register SBBUF *sb;
- register struct smblk *sm;
- register struct sdblk *sd;
-
- sb = sbp;
- PRF(printf("SBSTR %o: ",sb))
- if(sb == 0)
- PRFBUG(0,printf("Zero pointer???\n"))
-
- /* First print out cryptic summary in case pointers bomb
- * out farther on. */
- PRF(printf(" (io,cur,r,w,f,.,+ = %o,%o,%d,%d,%o,%lo,%lo)\n",
- sb->sbiop, sb->sbcur, sb->sbrleft, sb->sbwleft,
- sb->sbflags, sb->sbdot, sb->sboff))
-
- PRF(printf(" sbflags %5o = %s (%s)\n",
- sb->sbflags, sbe_fstr(sb->sbflags,sbflgtab),
- sbfhelp))
-
- if(sd = sb->sbcur) /* Okay, now try getting pointers */
- sm = sd->sdmem;
- else sm = 0;
-
- PRF(printf(" sbcur %6o",sd))
- if(sd)
- {
- PRF(printf("\n %s\n ", sdhdline))
- PRF(sbe_psd(sd))
-
- if((sd->sdflags&0377) != SD_NID)
- PRFBUG("SBCUR not SD?",printf(" BAD SDBLK ID!! \n"))
- if(sm)
- {
- PRF(printf(" %s\n ", smhdline))
- PRF(sbe_smp(sm,0))
- if((sm->smflags&0377) != SM_NID)
- PRFBUG("SBCUR has bad SM",
- printf(" BAD SMBLK ID!!\n"))
- }
- }
-
-
- PRF(printf(" sbiop %6o",sb->sbiop))
- if(sb->sbiop)
- { if(!sm || sb->sbiop < sm->smaddr
- || sb->sbiop > (sm->smaddr + sm->smlen))
- PRFBUG("Bad SBIOP", printf(" BAD"))
- }
- else if(sb->sbrleft > 0 || sb->sbwleft > 0)
- PRFBUG("Bad SBIOP/cnts", printf(" BAD"))
- PRF(printf("\n"))
-
- PRF(printf(" sbrleft %5o = %5d.",sb->sbrleft, sb->sbrleft))
- if(sb->sbrleft
- && ( !sm
- || sb->sbwleft
- || (sb->sbflags&SB_WRIT)
- || (sb->sbrleft != (sm->smuse - (sb->sbiop - sm->smaddr)))
- ))
- PRFBUG("Bad sbrleft", printf(" BAD"))
- PRF(printf("\n"))
-
- PRF(printf(" sbwleft %5o = %5d.", sb->sbwleft, sb->sbwleft))
- if(sb->sbwleft
- && ( !sm
- || (sb->sbflags&SB_WRIT) == 0
- || (sb->sbwleft > (sm->smlen - (sb->sbiop - sm->smaddr)))
- ))
- PRFBUG("Bad sbwleft", printf(" BAD"))
- PRF(printf("\n"))
-
- PRF(printf(" sbdot %7lo = %7ld.", sb->sbdot, sb->sbdot))
- if(sb->sbdot < 0)
- PRFBUG("Bad sbdot", printf(" BAD"))
-
- PRF(printf("\n sboff %7lo = %7ld.\n", sb->sboff, sb->sboff))
- PRF(printf(" I/O ptr loc: %ld.\n\n", sb_tell(sb)))
-
- return(0);
-}
-\f
-/* SBE_TBENT() - Auxiliary to add and check entries to a pointer table.
- * Note we assume here that smblk ptrs are used, although sdblks
- * can also be hacked. This wins as long as the two kinds of ptrs
- * are basically identical (saves horrible casting problems).
- * Returns index # if successful (between 0 and NPTRS-1 inclusive).
- * Otherwise an error (-1), with relevant info in pt_xerr:
- * -1 if out of room and flag set making it an error
- * 0-n if entry already existed.
- */
-sbe_tbent(pt, sm)
-register struct ptab *pt;
-struct smblk *sm;
-{ register struct smblk **smt;
- register int i;
- int p;
-
- p = pt->pt_pflag&PTF_PRF; /* Set up print flag */
- smt = &(pt->pt_tab[0]);
- if(i = pt->pt_nsto)
- { do {
- if(sm == *smt++)
- { pt->pt_xerr = pt->pt_nsto - i;
- return(-1);
- }
- } while(--i);
- --smt;
- }
-
- i = pt->pt_cnt++;
- if(++(pt->pt_nsto) > NPTRS)
- { if(pt->pt_pflag&PTF_OVFERR)
- { pt->pt_err = "Ptrtab overflow";
- pt->pt_xerr = -1;
- return(-1);
- }
- pt->pt_nsto = NPTRS;
- i %= NPTRS;
- }
- pt->pt_tab[i] = sm;
- return(i);
-}
-
-/* SBE_FSTR(flags, flagtab) - Auxiliary to convert flag word to a string
- * and return pointer to it. Handy for printfs.
- */
-char *
-sbe_fstr(flags, fp)
-register int flags;
-register struct flgt *fp;
-{ static char retstr[17]; /* Max of 16 flags */
- register char *cp;
- cp = retstr;
- for(; fp->flg_bit; ++fp)
- *cp++ = (fp->flg_bit&flags) ? fp->flg_chr : ' ';
- *cp = 0;
- return(retstr);
-}
+++ /dev/null
-/* SB - Copyright 1982 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author. In all cases
- * the source code and any modifications thereto must remain
- * available to any user.
- *
- * This is part of the SB library package.
- * Any software using the SB library must likewise be made
- * quasi-public, with freely available sources.
- */
-
-#if 0
- This file contains the low-level memory allocation
-subroutines which are used by the SBLK routines. The code here
-is quite machine-dependent, and the definitions in "sb.h" should be
-carefully checked to verify that they are correct for the target
-machine.
-
- The ultimate low-level routine is "sbrk()" which must be
-provided by the system''s C library. SBM expects that successive calls
-to sbrk() will return contiguous areas of memory with progressively
-higher addresses. Also, the very first call to sbrk() is assumed to
-return a word-aligned address.
-#endif /*COMMENT*/
-
-#include "sb.h"
-
-#define FUDGE (sizeof(struct smblk)) /* Allow this much fudge in
- allocation, to prevent undue fragmentation */
-
-char *(*sbm_debug)(); /* Debug switch - user-furnished routine */
-
-struct smblk *sbm_nfl; /* Pointer to node freelist */
-struct smblk *sbm_nxtra; /* Reserved extra free node */
-struct smblk *sbm_list; /* Pointer to smblk memory alloc list.
- * ALL smblks are strung onto this list
- * except for the freelist!
- */
-SBMA sbm_lowaddr; /* Lowest word-aligned address we know about.*/
-
-/* If compiling with debug switch set, use special routine in place of
- * sbrk so we can pretend we have a very limited area of free memory.
- */
-#ifdef DBG_SIZE
-#define SBM_SBRK sbm_brk
-char *sbm_brk();
-#else
-#define SBM_SBRK sbrk
-#endif /*DBG_SIZE*/
-
-/* Forward routine declarations */
-#ifdef __NBSD_LIBC
-void *sbrk();
-#else
-char *sbrk();
-#endif
-struct smblk *sbm_nmak(), *sbm_nget(), *sbm_mget(), *sbm_split();
-struct smblk *sbm_lmak(), *sbm_err();
-\f
-/* SBM_INIT - Initialize storage management.
- * If args are zero, normal initialization is done. Otherwise,
- * args are understood to be pointers to an area of memory allocated
- * on the stack (eg by an "int mem[2000]" declaration in MAIN) and
- * initialization will include this area in addition to the
- * unused space between "_end" and the start of the stack segment.
- * This is mostly of use for PDP11s which would otherwise waste a lot
- * of address space.
- * Maybe should have a SBM_RESET() function?
- */
-
-struct smblk *
-sbm_init(xaddr,xlen)
-SBMA xaddr; /* Address of allocated stack area if any */
-SBMO xlen; /* Size of this area */
-{ register struct smblk *sm, *sml;
- register char *cp;
-
- /* Get initial chunk of memory from standard system rtn */
- if((cp = SBM_SBRK(SMNODES*sizeof(struct smblk))) == 0
- || (int) cp == -1)
- return(sbm_err(0,"Can't sbrk"));
- sm = (struct smblk *)cp; /* Better be word-aligned! */
- sbm_lmak(sm,(SBMO)sizeof(struct smblk),SMNODES); /* Make list */
- sbm_nfl = sm; /* Point freelist at it */
- sbm_lowaddr = (SBMA)sm; /* Remember lowest addr seen */
-
- /* Set up 1st node pointing to all memory from here on up.
- * We don't know exactly how much will be available at this point,
- * so we just pretend we have the maximum possible.
- */
- sbm_list = sml = sbm_nget();
- sml->smforw = sml->smback = 0;
- sml->smflags = SM_USE|SM_NID; /* Initial flags */
- sml->smaddr = (SBMA) sml;
- sml->smlen = MAXSBMO; /* Pretend we have lots */
- sml->smuse = (SMNODES * sizeof(struct smblk));
-
- /* Now split off everything above initial allocation as NXM. */
- sm = sbm_split(sml, sm->smuse);
- sml->smflags |= SM_MNODS; /* Mark 1st node as having SM nodes */
- sm->smflags |= SM_NXM; /* Mark 2nd node as NXM */
-
- /* Now possibly set up extra nodes, if stack mem is being allocated
- * (From our viewpoint it looks as if a chunk in the middle of
- * the initial NXM section has been declared usable)
- */
- if(xlen)
- { /* Allow for "extra" static stack memory */
- /* Will lose if xaddr <= 1st NXM! */
- sml = sbm_split(sm, (SBMO)(xaddr - sm->smaddr));
- sbm_split(sml, xlen); /* Split off following NXM */
- sml->smflags &= ~(SM_USE|SM_NXM); /* This node is free mem! */
- }
-
- /* Now set up a small additional node which points to the NXM
- * that we cannot get from SBRK. At this stage, this is just
- * a place-holder, to reserve the node so we don't have to
- * worry about running out of nodes at the same time sbrk stops
- * returning memory.
- * SM points to the NXM that we expect SBRK to dig into.
- */
- sbm_split(sm, sm->smlen - WDSIZE); /* Chop off teensy bit */
- sm->smflags &= ~SM_USE; /* Now mark NXM "free"!! */
-
- /* Finally, reserve an "extra" SM node for use by sbm_nget
- * when it is allocating more freelist node chunks.
- */
- sbm_nxtra = sbm_nget();
-
- return(sbm_list);
-}
-\f
-/* SBM_NGET() - Get a free SM node.
- * Note the hair to provide a spare SM node when
- * we are allocating memory for more SM nodes. This is necessary
- * because sbm_mget and sbm_nget call each other recursively and
- * sbm_mget cannot create any new memory without a SM node to point
- * at the allocated chunk.
- */
-struct smblk *
-sbm_nget()
-{ register struct smblk *sm, *sml;
-
- if(!(sm = sbm_nfl)) /* Get a node from freelist */
- { /* Freelist is empty, try to allocate more nodes. */
-
- /* Put our "spare" smblk on freelist temporarily so that
- * sbm_mget has a chance of winning.
- * Infinite recursion is avoided by a test
- * in sbm_mget which checks sbm_nfl and sbm_nxtra.
- */
- if(!(sm = sbm_nxtra))
- return(sbm_err(0,"Zero sbm_nxtra!"));
- sm->smforw = 0;
- sbm_nfl = sm;
- sbm_nxtra = 0;
-
- /* Try to allocate another chunk of SM nodes. */
- sml = sbm_nmak(sizeof(struct smblk),SM_MNODS);
-
- /* Put the new free nodes (if any) on freelist.
- * Done this way because freelist may have had one or two
- * nodes added to it by sbm_mget, so can't just stick
- * a new pointer in sbm_nfl.
- */
- while(sm = sml)
- { sml = sm->smforw;
- sbm_nfre(sm);
- }
-
- /* Now reserve an extra node again.
- * It is an error if there is nothing on freelist here,
- * because even if sbm_mget failed the "extra node" should
- * still be on freelist. The check for a zero sbm_nxtra
- * above will catch such an error.
- */
- sbm_nxtra = sbm_nget();
-
- /* Now see if anything to return */
- if(!(sm = sbm_nfl)) /* If freelist empty again, */
- return(0); /* give up. */
- }
- sbm_nfl = sm->smforw; /* If win, take it off freelist */
- return(sm); /* Return ptr or 0 if none */
-}
-
-/* SBM_NFRE(sm) - Return a SM node to the SM freelist.
- */
-sbm_nfre(smp)
-struct smblk *smp;
-{ register struct smblk *sm;
- (sm = smp)->smflags = 0;
- sm->smforw = sbm_nfl;
- sbm_nfl = sm;
-}
-
-/* SBM_NMAK(elsize, flag) - Make (allocate & build) a typeless node freelist.
- */
-struct smblk *
-sbm_nmak(elsize, flag)
-SBMO elsize;
-unsigned flag;
-{ register struct smblk *sm, *smp;
- register int cnt;
-
- if((sm = sbm_mget(SMNODES*elsize,SMNODES*elsize)) == 0)
- return(0);
-
- sm->smflags |= flag; /* Indicate type of nodes */
- cnt = sm->smlen/elsize; /* Find # nodes that will fit */
- sm->smuse = cnt * elsize; /* Actual size used */
- smp = (struct smblk *)(sm->smaddr); /* Ptr to 1st loc of mem */
- sbm_lmak(smp, (SBMO)elsize, cnt); /* Build freelist */
- return(smp); /* Return 1st free node. Caller is */
- /* responsible for setting freelist ptr. */
-}
-
-/* SBM_LMAK - Build freelist of typeless nodes.
- * Note this does not allocate memory, it just converts an already
- * allocated memory area.
- */
-struct smblk *
-sbm_lmak(addr, elsize, num)
-SBMA addr;
-SBMO elsize;
-int num;
-{ register struct smblk *sm, *smp;
- register int cnt;
-
- smp = (struct smblk *) addr;
- if((cnt = num) <= 0)
- return(0);
- do { sm = smp; /* Save ptr */
- sm->smforw = (smp = (struct smblk *) ((SBMA)smp + elsize));
- sm->smflags = 0;
- } while(--cnt);
- sm->smforw = 0; /* Last node points to nothing */
- return(sm); /* Return ptr to last node */
-}
-
-/* SBM_NMOV(sm1, sm2, begp, elsize) - Move a typeless node.
- * Copy sm1 to sm2, adjust ptrs, leave sm1 free.
- */
-sbm_nmov(smp1,smp2,begp,elsize)
-struct smblk *smp1, *smp2, **begp;
-int elsize;
-{ register struct smblk *sm;
-
- bcopy((SBMA)smp1,(SBMA)(sm = smp2), elsize); /* Copy the stuff */
- if(sm->smforw) sm->smforw->smback = sm; /* Fix up links */
- if(sm->smback) sm->smback->smforw = sm;
- else *begp = sm;
-}
-\f
-/* SBM_MGET(min,max) - Get a SMBLK with specified amount of memory.
- * Returns 0 if none available.
- * Memory is guaranteed to start on word boundary, but may not
- * end on one. Note that sbm_mfree is responsible for
- * ensuring that free mem starts word-aligned.
- * A subtle but major concern of this code is the number of freelist
- * nodes gobbled by a single call. If the freelist happens to not have
- * enough nodes, then a recursive call to sbm_mget is made (via sbm_nget)
- * in order to allocate a new batch of freelist nodes! sbm_nget will
- * always provide a single "spare" node during such an allocation, but
- * there is only one and it is essential that sbm_mget gobble only ONE
- * (if any) during such a call, which is indicated by sbm_nxtra==0.
- * The maximum # of freelist nodes that sbm_mget can gobble is
- * 2, when (1) NXM memory is obtained, and a SM is needed to point at
- * the new free mem, plus (2) the resulting SM is too big, and has to
- * be split up, which requires another SM for the remainder.
- * The "used-NXM" smblk is set up at init time precisely in order to
- * avoid the necessity of creating it here when sbrk stops winning, since
- * that would require yet another freelist node and make it possible for
- * sbm_mget to gobble 3 during one call -- too many.
- * Further note: the sbm_nfl checks are necessary in order
- * to ensure that a SM node is available for use by sbm_split. Otherwise
- * the calls to sbm_split might create a new SM freelist by gobbling the
- * very memory which we are hoping to return!
- */
-SBMO sbm_chksiz = SMCHUNKSIZ; /* Current chunk size to feed sbrk */
-
-struct smblk *
-sbm_mget(cmin,cmax)
-SBMO cmin,cmax;
-{ register struct smblk *sm, *sml;
- register SBMO csiz;
- register SBMA addr, xaddr;
-
- if((sm = sbm_list) == 0 /* If never done, */
- && (sm = sbm_init((SBMA)0,(SBMO)0)) == 0) /* initialize mem alloc stuff. */
- return(0); /* Can't init??? */
-
- /* Round up sizes to word boundary */
- if(rndrem(cmin)) cmin = rndup(cmin);
- if(rndrem(cmax)) cmax = rndup(cmax);
-
- /* Search for a free block having enough memory.
- * If run into a free-NXM block, always "win", since there may be
- * a combination of preceding free-mem and new mem which will satisfy
- * the request. If it turns out this didn't work, we'll just fail
- * a little farther on.
- */
-retry: csiz = cmin; /* Set size that will satisfy us */
- do {
- if( ((sm->smflags&SM_USE) == 0)
- && ((sm->smlen >= csiz) || (sm->smflags&SM_NXM)) )
- break;
- } while(sm = sm->smforw);
- if(sm == 0)
- return(0); /* Found none that minimum would fit */
-
- if(sm->smflags&SM_NXM)
- { /* Found free area, but it's marked NXM and the system
- * must be persuaded (via sbrk) to let us use that portion
- * of our address space. Grab a good-sized chunk.
- */
- if(sbm_nfl == 0) /* Verify a spare SM node is avail */
- goto getnod; /* Nope, must get one. */
-
- /* Decide amount of mem to ask system for, via sbrk.
- * The fine point here is the check of sbm_nxtra to make sure
- * that, when building more freelist nodes, we don't have
- * to use more than one SM node in the process. If we
- * asked for too much mem, we'd have to use a SM node
- * to hold the excess after splitting.
- */
- csiz = cmax;
- if(sbm_nxtra /* If normal then try for big chunk */
- && csiz < sbm_chksiz) csiz = sbm_chksiz; /* Max */
- if (csiz > sm->smlen) csiz = sm->smlen; /* Min */
-
- /* Get the NXM mem */
- if((addr = (SBMA)SBM_SBRK(csiz)) != sm->smaddr)
- { /* Unexpected value returned from SBRK! */
-
- if((int)addr != 0 && (int)addr != -1)
- { return(sbm_err(0,"SBRK %o != %o", addr,
- sm->smaddr));
-#if 0
- /* If value indicates couldn't get the stuff, then
- * we have probably hit our limit and the rest of
- * NXM should be declared "used" to prevent further
- * hopeless sbrk calls. We split off the portion
- * of NXM that is known for sure to be unavailable,
- * and mark it "used". If a "used NXM" area already
- * exists following this one, the two are merged.
- * The chunk size is then reduced by half, so
- * only log2(SMCHUNKSIZ) attempts will be made, and
- * we try again.
- */
- /* If returned some mem which starts outside
- * the NXM then something is screwed up. */
- if(addr < sm->smaddr
- || (addr >= sm->smaddr+sm->smlen))
- return(sbm_err(0,"SBRK %o != %o",
- addr, sm->smaddr));
- /* Got some mem, falls within NXM.
- * Presumably someone else has called sbrk
- * since last time, so we need to fence off
- * the intervening area. */
- sm = sbm_split((sml=sm),(addr - sm->smaddr));
- sml->smflags |= SM_USE|SM_EXT;
- return(sbm_mget(cmin,cmax));
-#endif /*COMMENT*/
- }
-
- /* Handle case of SBRK claiming no more memory.
- * Gobble as much as we can, and then turn this NXM
- * block into a free-mem block, and leave the
- * remainder in the used-NXM block (which should
- * immediately follow this free-NXM block!)
- */
- if(!(sml = sm->smforw) /* Ensure have used-NXM blk */
- || (sml->smflags&(SM_USE|SM_NXM))
- != (SM_USE|SM_NXM))
- return(sbm_err(0,"No uNXM node!"));
- xaddr = sm->smaddr; /* Use this for checking */
- sm->smuse = 0; /* Use this for sum */
- for(csiz = sm->smlen; csiz > 0;)
- { addr = SBM_SBRK(csiz);
- if((int)addr == 0 || (int)addr == -1)
- { csiz >>= 1;
- continue;
- }
- if(addr != xaddr)
- return(sbm_err(0,"SBRK %o != %o", addr,
- xaddr));
- sm->smuse += csiz;
- xaddr += csiz;
- }
-
- /* Have gobbled as much from SBRK as we could.
- * Turn the free-NXM block into a free-mem block,
- * unless we got nothing, in which case just merge
- * it into the used-NXM block and continue
- * searching from this point.
- */
- if(!(csiz = sm->smuse)) /* Get total added */
- { sm->smflags = sml->smflags; /* Ugh. */
- sbm_mmrg(sm);
- goto retry; /* Keep looking */
- }
- else
- { sml->smaddr = sm->smaddr + csiz;
- sml->smlen += sm->smlen - csiz;
- sm->smlen = csiz;
- sm->smflags &= ~SM_NXM; /* No longer NXM */
- }
- }
-
- /* Here when we've acquired CSIZ more memory from sbrk.
- * If preceding mem area is not in use, merge new mem
- * into it.
- */
- if((sml = sm->smback) &&
- (sml->smflags&(SM_USE|SM_NXM))==0) /* Previous free? */
- { sml->smlen += csiz; /* Yes, simple! */
- sm->smaddr += csiz; /* Fix up */
- if((sm->smlen -= csiz) == 0) /* If no NXM left,*/
- sbm_mmrg(sml); /* Merge NXM node w/prev */
- sm = sml; /* Prev is now winning node */
- }
- else
- { /* Prev node isn't a free area. Split up the NXM
- * node to account for acquired mem, unless we
- * gobbled all the mem available.
- */
- if(sm->smlen > csiz /* Split unless all used */
- && !sbm_split(sm,csiz)) /* Call shd always win */
- return(sbm_err(0,"getsplit err: %o",sm));
- sm->smflags &= ~SM_NXM; /* Node is now real mem */
- }
-
- /* Now make a final check that we have enough memory.
- * This can fail because SBRK may not have been able
- * to gobble enough memory, either because (1) not
- * as much NXM was available as we thought,
- * or (2) we noticed the free-NXM area and immediately
- * gambled on trying it without checking any lengths.
- * In any case, we try again starting from the current SM
- * because there may be more free mem higher up (eg on
- * stack).
- */
- if(sm->smlen < cmin)
- goto retry;
- }
-
- /* Check to see if node has too much mem. This is especially true
- * for memory just acquired via sbrk, which gobbles a huge chunk each
- * time. If there's too much, we split up the area.
- */
- if(sm->smlen > cmax+FUDGE) /* Got too much? (Allow some fudge)*/
- /* Yes, split up so don't gobble too much. */
- if(sbm_nfl) /* If success guaranteed, */
- sbm_split(sm,cmax); /* split it, all's well. */
- else goto getnod;
-
- sm->smuse = 0;
- sm->smflags |= SM_USE; /* Finally seize it by marking "in-use". */
- return(sm);
-
- /* Come here when we will need to get another SM node but the
- * SM freelist is empty. We have to forget about using the area
- * we just found, because sbm_nget may gobble it for the
- * freelist. So, we first force a refill of the freelist, and then
- * invoke ourselves again on what's left.
- */
-getnod:
- if(sml = sbm_nget()) /* Try to build freelist */
- { sbm_nfre(sml); /* Won, give node back, */
- sm = sbm_list; /* and retry, starting over! */
- goto retry;
- }
- /* Failed. Not enough memory for both this request
- * and one more block of SM nodes. Since such a SM_MNODS
- * block isn't very big, we are so close to the limits that it
- * isn't worth trying to do something fancy here to satisfy the
- * original request. So we just fail.
- */
- return(0);
-}
-
-#ifdef DBG_SIZE
-/* Code for debugging stuff by imposing an artificial limitation on size
- * of available memory.
- */
-SBMO sbm_dlim = MAXSBMO; /* Amount of mem to allow (default is max) */
-
-char *
-sbm_brk(size)
-unsigned size;
-{ register char *addr;
-
- if(size > sbm_dlim) return(0);
- addr = sbrk(size);
- if((int)addr == 0 || (int)addr == -1)
- return(0);
- sbm_dlim -= size;
- return(addr);
-}
-#endif /*DBG_SIZE*/
-\f
-/* SBM_MFREE(sm) - Free up an allocated memory area.
- */
-void
-sbm_mfree(sm)
-register struct smblk *sm;
-{ register struct smblk *smx;
- register SBMO crem;
-
- sm->smflags &= ~SM_USE; /* Say mem is free */
- if((smx = sm->smback) /* Check preceding mem */
- && (smx->smflags&(SM_USE|SM_NXM))==0) /* If it's free, */
- sbm_mmrg(sm = smx); /* then merge 'em. */
- if((smx = sm->smforw) /* Check following mem */
- && (smx->smflags&(SM_USE|SM_NXM))==0) /* Again, if free, */
- sbm_mmrg(sm); /* merge them. */
-
- if(sm->smlen == 0) /* Just in case, chk for null blk */
- { if(smx = sm->smback) /* If pred exists, */
- sbm_mmrg(smx); /* merge quietly. */
- else {
- sbm_list = sm->smforw; /* 1st node on list, so */
- sbm_nfre(sm); /* simply flush it. */
- }
- return;
- }
-
- /* This code is slightly over-general for some machines.
- * The pointer subtraction is done in order to get a valid integer
- * offset value regardless of the internal representation of a pointer.
- * We cannot reliably force alignment via casts; some C implementations
- * treat that as a no-op.
- */
- if(crem = rndrem(sm->smaddr - sbm_lowaddr)) /* On word bndry? */
- { /* No -- must adjust. All free mem blks MUST, by fiat,
- * start on word boundary. Here we fix things by
- * making the leftover bytes belong to the previous blk,
- * no matter what it is used for. Prev blk is guaranteed to
- * (1) Exist (this cannot be 1st blk since 1st is known to
- * start on wd boundary) and to be (2) Non-free (else it would
- * have been merged).
- */
- if((smx = sm->smback) == 0) /* Get ptr to prev blk */
- { sbm_err(0,"Align err"); /* Catch screws */
- return;
- }
- crem = WDSIZE - crem; /* Find # bytes to flush */
- if(crem >= sm->smlen) /* Make sure node has that many */
- { sbm_mmrg(smx); /* Flush node to avoid zero length */
- return;
- }
- smx->smlen += crem; /* Make stray bytes part of prev */
- sm->smaddr += crem; /* And flush from current. */
- sm->smlen -= crem;
- }
-}
-\f
-/* SBM_EXP - Expand (or shrink) size of an allocated memory chunk.
- * "nsize" is desired new size; may be larger or smaller than current
- * size.
- */
-struct smblk *
-sbm_exp(sm,size)
-register struct smblk *sm;
-register SBMO size;
-{ register struct smblk *smf;
- register SBMO mexp, pred, succ;
-
- if(sm->smlen >= size) /* Do we want truncation? */
- goto realo2; /* Yup, go split block */
-
- /* Block is expanding. */
- mexp = size - sm->smlen; /* Get # bytes to expand by */
- pred = succ = 0;
- if((smf = sm->smforw) /* See if free mem follows */
- && (smf->smflags&(SM_USE|SM_NXM)) == 0)
- if((succ = smf->smlen) >= mexp)
- goto realo1; /* Quick stuff if succ OK */
-
- if((smf = sm->smback) /* See if free mem precedes */
- && (smf->smflags&(SM_USE|SM_NXM)) == 0)
- pred = smf->smlen;
-
- /* If not enough free space combined on both sides of this chunk,
- * we have to look for a completely new block.
- */
- if(pred+succ < mexp)
- { if((smf = sbm_mget(size,size)) == 0)
- return(0); /* Couldn't find one */
- else pred = 0; /* Won, indicate new block */
- }
-
- /* OK, must copy either into new block or down into predecessor
- * (overlap is OK as long as bcopy moves 1st byte first)
- */
- bcopy(sm->smaddr, smf->smaddr, sm->smlen);
- smf->smflags = sm->smflags; /* Copy extra attribs */
- smf->smuse = sm->smuse;
- if(!pred) /* If invoked sbm_mget */
- { sbm_mfree(sm); /* then must free up old area */
- return(smf); /* and can return immediately. */
- }
- sbm_mmrg(smf); /* Merge current into pred blk */
- sm = smf; /* Now pred is current blk. */
-
- if(succ)
-realo1: sbm_mmrg(sm); /* Merge succ into current blk */
-realo2: if(sm->smlen > size /* If now have too much, */
- && sbm_split(sm, size)) /* split up and possibly */
- sbm_mfree(sm->smforw); /* free up unused space. */
- return(sm);
-
- /* Note that sbm_split can fail if it can't get a free node,
- * which is only possible if we are reducing the size of an area.
- * If it fails, we just return anyway without truncating the area.
- */
-}
-\f
-/* SBM_MMRG(sm) - Merge a memory area with the area following it.
- * The node (and memory area) following the SM pointed to are
- * merged in and the successor node freed up. The flags
- * and smuse of the current SM (which is not moved or anything)
- * remain the same.
- */
-sbm_mmrg(smp)
-struct smblk *smp;
-{ register struct smblk *sm, *sm2;
-
- sm = smp;
- sm->smlen += (sm2 = sm->smforw)->smlen; /* Add succ's len */
- if(sm->smforw = sm2->smforw) /* and fix linkages */
- sm->smforw->smback = sm;
- sbm_nfre(sm2); /* now can flush succ node */
-}
-
-/* SBM_SPLIT - Split up an area (gets a new smblk to point to split-off
- * portion.)
- * Note returned value is ptr to 2nd smblk, since this is a new one.
- * Ptr to 1st remains valid since original smblk stays where it is.
- * NOTE: Beware of splitting up free mem (SM_USE == 0) since sbm_nget may
- * steal it out from under unless precautions are taken! See comments
- * at sbm_mget related to this.
- */
-struct smblk *
-sbm_split(smp,coff)
-struct smblk *smp;
-SBMO coff;
-{ register struct smblk *sm, *smx;
- register SBMO csiz;
-
- if((sm = smp)->smlen <= (csiz = coff))
- return(0);
- if((smx = sbm_nget()) == 0)
- return(0);
- smx->smlen = sm->smlen - csiz; /* Set 2nd size */
- smx->smaddr = sm->smaddr + csiz; /* Set 2nd addr */
- sm->smlen = csiz; /* Take from 1st size */
- smx->smflags = sm->smflags; /* Copy flags */
- if(smx->smforw = sm->smforw) /* Splice 2nd after 1 */
- smx->smforw->smback = smx;
- smx->smback = sm;
- sm->smforw = smx; /* Put 2nd into chain */
- return(smx); /* Return ptr to 2nd smblk */
-}
-
-#if 0 /* Replaced by "bcopy" for system-dep efficiency */
-/* SBM_SCPY - Copy string of bytes. Somewhat machine-dependent;
- * Tries to be clever about using word moves instead of byte moves.
- */
-sbm_scpy(from, to, count) /* Copy count bytes from -> to */
-char *from, *to;
-unsigned count;
-{ register char *s1, *s2;
- register unsigned cnt;
- int tmp;
-
- if((cnt = count) == 0)
- return;
- s1 = from;
- s2 = to;
- while(rndrem((int)s1)) /* Get 1st ptr aligned */
- { *s2++ = *s1++;
- if(--cnt == 0) return;
- }
- if(rndrem((int)s2) == 0) /* Do wd move if ptr 2 now aligned */
- {
-#ifdef DUMBPCC /* Code for dumber (Portable C type) compiler */
- register WORD *ap, *bp;
- tmp = cnt;
- ap = (WORD *) s1;
- bp = (WORD *) s2;
- if(cnt = rnddiv(cnt))
- do { *bp++ = *ap++; }
- while(--cnt);
- if ((cnt = rndrem(tmp)) ==0)
- return;
- s1 = (char *) ap;
- s2 = (char *) bp;
-#else
- /* Tight loop for efficient copying on 11s */
- tmp = cnt;
- if(cnt = rnddiv(cnt))
- do { *((WORD *)s2)++ = *((WORD *)s1)++; }
- while(--cnt);
- if((cnt = rndrem(tmp)) == 0)
- return;
-#endif /*-DUMBPCC*/
- }
- do { *s2++ = *s1++; } /* Finish up with byte loop */
- while(--cnt);
-}
-#endif /*COMMENT*/
-
-struct smblk * /* If it returns at all, this is most common type */
-sbm_err(val,str,a0,a1,a2,a3)
-char *str;
-struct smblk *val;
-{ int *sptr;
-
- sptr = (int *) &sptr; /* Point to self on stack */
- sptr += 5; /* Point to return addr */
- if((int)sbm_debug==1)
- abort();
- if(sbm_debug)
- (*sbm_debug)(0,*sptr,str,a0,a1,a2,a3);
- return(val);
-}
-\f
-/* These routines correspond to the V7 LIBC routines as described
- * in the V7 UPM (3). They should provide satisfactory emulation
- * if the documentation is correct. Replacement is necessary since
- * the SBM routines are jealous and cannot tolerate competition for
- * calls of SBRK; i.e. the memory being managed must be contiguous.
- */
-
-/* Guaranteed to return word-aligned pointer to area of AT LEAST
- * requested size. Area size is rounded up to word boundary.
- */
-
-char *
-malloc(size)
-unsigned size;
-{ register struct smblk *sm, **sma;
- register SBMO siz;
-
- siz = rndup(size + sizeof (struct smblk *)); /* Make room for ptr */
- if((sm = sbm_mget(siz,siz)) == 0)
- return(0);
- *(sma = (struct smblk **)sm->smaddr) = sm; /* Store ptr in addr-1 */
- return((char *)++sma);
-}
-
-char *
-alloc(size) /* For V6 programs - note different failure value! */
-unsigned size;
-{ register char *addr;
- return((addr = malloc(size)) ? addr : (char *) -1);
-}
-
-free(ptr)
-char *ptr;
-{ register struct smblk *sm, **smp;
-
-#ifdef __NBSD_LIBC
- /* In NetBSD, free is a nop if ptr == NULL; */
- if(ptr == NULL)
- return(1);
-#endif
- smp = &((struct smblk **)ptr)[-1]; /* Point to addr-1 */
- sm = *smp; /* Pluck SM ptr therefrom */
- if(((sm->smflags&0377) != SM_NID) || sm->smaddr != (SBMA)smp)
- return((int)sbm_err(0,"free: bad arg %o", ptr));
- sbm_mfree(sm);
- return(1);
-}
-
-char *
-realloc(ptr,size)
-char *ptr;
-unsigned size;
-{ register struct smblk *sm, **smp;
-
- smp = &((struct smblk **)ptr)[-1]; /* Point to addr-1 */
- sm = *smp; /* Pluck SM ptr therefrom */
- if(((sm->smflags&0377) != SM_NID) || (sm->smaddr != (SBMA)smp))
- return((char *)sbm_err(0,"realloc: bad arg %o",ptr));
- if((sm = sbm_exp(sm, rndup(size+(sizeof(struct smblk *))))) == 0)
- return(0);
- *(smp = (struct smblk **)sm->smaddr) = sm; /* Save smblk ptr */
- return((char *)++smp);
-}
-
-char *
-calloc(nelem,elsize)
-unsigned nelem, elsize;
-{ register SBMO cmin;
- register WORD *ip; /* Clear in units of words */
- register char *addr;
-
- if((cmin = nelem*elsize) == 0 /* Find # bytes to get */
- || (addr = malloc(cmin)) == 0) /* Get it */
- return(0);
- ip = (WORD *) addr; /* Set up ptr to area */
- cmin = rnddiv(cmin+WDSIZE-1); /* Find # words to clear */
- do { *ip++ = 0; } while (--cmin); /* Zap the area */
- return(addr);
-}
-\f
-/* SBM_NGC() - Specific routine for GC'ing SMBLK nodes.
- *
- * SBM_XNGC(begp, elsize, type) - Compact nodes of specified type.
- * Scans allocated mem from low to high to find chunks with nodes of
- * the specified type.
- * Flushes current freelist and rebuilds it as scan progresses,
- * such that 1st thing on list is lowest-addr node. When a node is
- * seen that can be moved, new node is acquired from freelist if
- * it exists, otherwise no move is made. If a chunk has been scanned
- * and no active nodes remain, it is flushed and freelist updated.
- * NOTE: This has not yet been verified to work with nodes of any
- * type other than SMBLK.
- */
-
-sbm_ngc()
-{ register struct smblk *sm;
- if(!(sm = sbm_nxtra))
- return((int)sbm_err(0,"Zero sbm_nxtra"));
- sm->smflags |= SM_USE; /* Ensure this one isn't GC'd */
- sbm_xngc(&sbm_nfl, sizeof(struct smblk), SM_MNODS);
- sm->smflags = 0; /* Flush temporary crock */
-}
-sbm_xngc(begp, elsize, flag)
-struct smblk **begp;
-unsigned elsize, flag;
-{ register struct smblk *sm, *chk, *smf;
- struct smblk *ftail, *savtail;
- int cnt, inuse;
-
- *begp = ftail = 0; /* Flush node freelist */
- for(chk = sbm_list; chk; chk = chk->smforw)
- if(chk->smflags&flag)
- { sm = (struct smblk *) chk->smaddr;
- cnt = (chk->smuse)/elsize;
- savtail = ftail;
- inuse = 0;
- smf = *begp;
- /* Set up ptr to 1st freelist node */
- while(--cnt >= 0)
- { /* Here decide if movable */
- if(sm->smflags && smf /* Live and have copy place */
- && (
- (sm->smflags&SM_USE) == 0 /* Free mem? */
- || (sm->smflags&(SM_MNODS|SM_DNODS))
- )
- && sm->smback) /* has backptr (see ncpy) */
- { /* Move the node */
- *begp = smf->smforw; /* Get free node */
- if(smf == ftail)
- ftail = 0;
- if(smf == savtail)
- savtail = 0;
- /* Move node. Already checked for back ptr
- * of 0 since no obvious way to tell where
- * the ptr to list is kept. Sigh.
- */
- sbm_nmov(sm,smf,(struct smblk **)0,elsize);
- /* Get ptr to new freelist node. Note
- * check to ensure that it is not in this
- * same chunk (if it is, no point in moving
- * any nodes!)
- */
- if((smf = *begp) >= chk)
- smf = 0; /* Zero if same chk */
- sm->smflags = 0; /* Make node free */
- }
- /* At this point, not movable */
- if(sm->smflags == 0) /* Free node? */
- { if(ftail) /* Add to freelist */
- ftail->smforw = sm;
- ftail = sm;
- if(*begp == 0)
- *begp = sm;
- sm->smforw = 0;
- }
- else inuse++;
- sm = (struct smblk *)((SBMA)sm + elsize);
- }
- if(inuse == 0 /* All free? */
- && (sm = chk->smback)) /* & not 1st? */
- { if(savtail) /* Edit freelist */
- (ftail = savtail)->smforw = 0;
- else *begp = ftail = 0;
- sbm_mfree(chk);
- chk = sm;
- }
- }
-}
-
-/*
- * Note that proc must return a zero value, or loop aborts and
- * returns that selfsame value.
- */
-sbm_nfor(flag,nodsiz,proc,arg)
-int flag;
-int (*proc)();
-int nodsiz;
-struct sbfile *arg;
-{ register struct smblk *sm, *np;
- register int cnt;
- int res;
-
- for(sm = sbm_list; sm; sm = sm->smforw)
- if(sm->smflags&flag)
- { np = (struct smblk *) sm->smaddr;
- cnt = sm->smuse/nodsiz;
- do {
- if(np->smflags)
- if(res = (*proc)(np,arg))
- return(res);
- np = (struct smblk *)((SBMA)np + nodsiz);
- } while(--cnt);
- }
- return(0);
-}
+++ /dev/null
-#ifndef _ANSI
-#include <minix/ansi.h>
-#endif
-
-/* sbbcpy.c */
-#ifndef _MINIX
-_PROTOTYPE( int bcopy, (SBMA from, SBMA to, unsigned cnt) );
-#endif
-_PROTOTYPE( int sbm_wcpy, (int *from, int *to, unsigned cnt) );
-
-/* sberr.c */
-_PROTOTYPE( int sbe_mem, (void) );
-_PROTOTYPE( char *sbe_mvfy, (void) );
-_PROTOTYPE( char *sbe_mfl, (int p) );
-_PROTOTYPE( char *sbe_mlst, (int p) );
-_PROTOTYPE( int sbe_smp, (struct smblk *sm, int type) );
-_PROTOTYPE( char *sbe_sfl, (int p) );
-_PROTOTYPE( int sbe_sds, (void) );
-_PROTOTYPE( int sbe_psd, (struct sdblk *sd) );
-_PROTOTYPE( char *sbe_svfy, (void) );
-_PROTOTYPE( char *sbe_sdlist, (int p, int phys) );
-_PROTOTYPE( int sbe_dsk, (SBFILE *sfp) );
-_PROTOTYPE( char *sbe_sbvfy, (SBBUF *sbp) );
-_PROTOTYPE( char *sbe_sbs, (SBBUF *sbp, int p) );
-
-/* sbm.c */
-_PROTOTYPE( struct smblk *sbm_init, (SBMA xaddr, SBMO xlen) );
-_PROTOTYPE( struct smblk *sbm_nget, (void) );
-_PROTOTYPE( int sbm_nfre, (struct smblk *smp) );
-_PROTOTYPE( struct smblk *sbm_nmak, (SBMO elsize, unsigned flag) );
-_PROTOTYPE( struct smblk *sbm_lmak, (SBMA addr, SBMO elsize, int num) );
-_PROTOTYPE( int sbm_nmov, (struct smblk *smp1, struct smblk *smp2, struct smblk **begp, int elsize) );
-_PROTOTYPE( struct smblk *sbm_mget, (SBMO cmin, SBMO cmax) );
-_PROTOTYPE( char *sbm_brk, (unsigned size) );
-_PROTOTYPE( void sbm_mfree, (struct smblk *sm) );
-_PROTOTYPE( struct smblk *sbm_exp, (struct smblk *sm, SBMO size) );
-_PROTOTYPE( int sbm_mmrg, (struct smblk *smp) );
-_PROTOTYPE( struct smblk *sbm_split, (struct smblk *smp, SBMO coff) );
-_PROTOTYPE( int sbm_scpy, (char *from, char *to, unsigned count) );
-#if 0
-_PROTOTYPE( struct smblk *sbm_err, (struct smblk *val, char *str, int a0, int a1, int a2, int a3) );
-#else
-struct smblk *sbm_err();
-#endif
-_PROTOTYPE( char *malloc, (unsigned size) );
-_PROTOTYPE( char *alloc, (unsigned size) );
-_PROTOTYPE( int free, (char *ptr) );
-_PROTOTYPE( char *realloc, (char *ptr, unsigned size) );
-_PROTOTYPE( char *calloc, (unsigned nelem, unsigned elsize) );
-_PROTOTYPE( int sbm_ngc, (void) );
-_PROTOTYPE( int sbm_xngc, (struct smblk **begp, unsigned elsize, unsigned flag) );
-_PROTOTYPE( int sbm_nfor, (int flag, int nodsiz, int (*proc )(), struct sbfile *arg) );
-
-/* sbstr.c */
-_PROTOTYPE( SBSTR *sb_close, (SBBUF *sbp) );
-_PROTOTYPE( int sb_setovw, (SBBUF *sbp) );
-_PROTOTYPE( int sb_clrovw, (SBBUF *sbp) );
-_PROTOTYPE( chroff sbx_fdlen, (int fd) );
-_PROTOTYPE( SBSTR *sb_fduse, (int ifd) );
-_PROTOTYPE( int sb_fdcls, (int ifd) );
-_PROTOTYPE( int sbx_fcls, (struct sbfile *sfp) );
-_PROTOTYPE( int sb_fdinp, (SBBUF *sb, int fd) );
-_PROTOTYPE( int sb_fsave, (SBBUF *sb, int fd) );
-_PROTOTYPE( int sb_sgetc, (SBBUF *sb) );
-_PROTOTYPE( int sb_sputc, (SBBUF *sb, int ch) );
-_PROTOTYPE( int sb_speekc, (SBBUF *sb) );
-_PROTOTYPE( int sb_rgetc, (SBBUF *sb) );
-_PROTOTYPE( int sb_rdelc, (SBBUF *sbp) );
-_PROTOTYPE( int sb_deln, (SBBUF *sbp, chroff num) );
-_PROTOTYPE( struct sdblk *sb_killn, (SBBUF *sbp, chroff num) );
-_PROTOTYPE( SBSTR *sb_cpyn, (SBBUF *sbp, chroff num) );
-_PROTOTYPE( int sb_sins, (SBBUF *sbp, struct sdblk *sdp) );
-_PROTOTYPE( SBSTR *sbs_cpy, (SBSTR *sdp) );
-_PROTOTYPE( int sbs_del, (SBSTR *sdp) );
-_PROTOTYPE( SBSTR *sbs_app, (struct sdblk *sdp, struct sdblk *sdp2) );
-_PROTOTYPE( chroff sbs_len, (SBSTR *sdp) );
-_PROTOTYPE( int sb_seek, (SBBUF *sbp, chroff coff, int flg) );
-_PROTOTYPE( int sb_rewind, (SBBUF *sbp) );
-_PROTOTYPE( chroff sb_tell, (SBBUF *sbp) );
-_PROTOTYPE( chroff sb_ztell, (SBBUF *sbp) );
-#if 0
-_PROTOTYPE( struct sdblk *sbx_ready, (SBBUF *sbp, int type, SBMO cmin, SBMO cmax) );
-#else
-struct sdblk *sbx_ready();
-#endif
-_PROTOTYPE( struct sdblk *sbx_next, (SBBUF *sbp) );
-_PROTOTYPE( struct sdblk *sbx_norm, (SBBUF *sbp, int mode) );
-_PROTOTYPE( struct sdblk *sbx_beg, (struct sdblk *sdp) );
-_PROTOTYPE( int sbx_smdisc, (SBBUF *sbp) );
-_PROTOTYPE( int sbx_sbrdy, (SBBUF *sbp) );
-_PROTOTYPE( struct sdblk *sbx_scpy, (struct sdblk *sdp, struct sdblk *sdlast) );
-_PROTOTYPE( struct sdblk *sbx_sdcpy, (struct sdblk *sdp) );
-_PROTOTYPE( struct sdblk *sbx_xcis, (SBBUF *sbp, chroff num, struct sdblk **asd2, chroff *adot) );
-_PROTOTYPE( struct sdblk *sbx_split, (struct sdblk *sdp, chroff coff) );
-_PROTOTYPE( struct smblk *sbx_msplit, (struct smblk *smp, SBMO size) );
-_PROTOTYPE( struct sdblk *sbx_ndel, (struct sdblk *sdp) );
-_PROTOTYPE( int sbx_npdel, (struct sdblk *sdp) );
-_PROTOTYPE( struct sdblk *sbx_ndget, (void) );
-_PROTOTYPE( int sbx_ndfre, (struct sdblk *sdp) );
-_PROTOTYPE( SBMA sbx_malloc, (unsigned size) );
-_PROTOTYPE( struct smblk *sbx_mget, (SBMO cmin, SBMO cmax) );
-_PROTOTYPE( int sbx_comp, (int cmin, int lev) );
-_PROTOTYPE( int sbx_sdgc, (struct sdblk *sdp, int lev) );
-#if 0
-_PROTOTYPE( int sbx_aout, (struct sdblk *sdp, int flag, int fd) );
-#else
-int sbx_aout();
-#endif
-_PROTOTYPE( chroff sbx_qlen, (struct sdblk *sdp) );
-_PROTOTYPE( int sbx_tset, (chroff loff, int align) );
-_PROTOTYPE( struct sdblk *sbx_ffnd, (SBFILE *sfp, chroff size, chroff *aloc) );
-_PROTOTYPE( int sbx_rdf, (int fd, char *addr, int cnt, int skflg, chroff loc) );
-_PROTOTYPE( int sbx_rugpull, (int fd) );
-_PROTOTYPE( int sbx_unpur, (struct sdblk *sd, struct sbfile *sf) );
-#if 0
-_PROTOTYPE( int sbx_err, (int val, char *str, int a0, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int a12) );
-#else
-int sbx_err();
-#endif
-
-/* sbvall.c */
-_PROTOTYPE( char *valloc, (unsigned size) );
+++ /dev/null
-/* SB - Copyright 1982 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author. In all cases
- * the source code and any modifications thereto must remain
- * available to any user.
- *
- * This is part of the SB library package.
- * Any software using the SB library must likewise be made
- * quasi-public, with freely available sources.
- */
-
-#if 0
-Todo stuff:
- New definitions:
- sbbuffer - old sbstr. Abbrev & struct "sbbuff". Macro SBBUFF
- (or SBBUF?)
- sbstring - list of sds. Abbrev sbstr. Macro SBSTR.
- Should *sbstr == *sdblk? Yeah.
- sbfile - as before. Macro SBFILE. (or SBFIL?)
-
- Try to get zero-length sdblks flushed on the fly,
- rather than waiting for moby GC. Also, need to set
- up compaction of SD freelist, as well as SM freelist.
- Make SM freelist compact self-invoked by SBM_MGET?
- Any need for phys disk ptrs other than for tempfile?
- Can do sbm_forn through SDblks to find active sdfiles
- so list isn''t needed for that.
- Can sdback be flushed? (not needed for keeping list sorted,
- or for searching it -- only used when linking
- blocks in or out of list.) Perhaps use circular list?
- If list only used for tmpfile, then to link in/out could
- always start from sfptr1 of tmpfile? Sure, but slow?
- Last SD on phys list could belong to no logical list,
- and denote free space on tmpfile?
-
- --------------------------
-
- An "open" SBBUFFER will allow one to read, write, insert into,
-and delete from a sbstring (a logical character string). "Dot" refers
-to the current logical character position, which is where all
-operations must happen; sb_fseek must be used to change this location.
-There are several states that the I/O can be in:
-!SBCUR ----CLOSED----
- All other elements, including SBIOP, should also be 0.
- Dot is 0.
-SBCUR && !SBIOP ----OPEN/IDLE----
- SBCUR points to a SD block (its SDMEM may or may not exist)
- SBIOP==0 (otherwise it would be open/ready)
- Dot is SBDOT + SBOFF.
- R/Wleft must be 0.
-SBCUR && SBIOP ----OPEN/READY----
- SBCUR points to a SDBLK (SDMEM must exist!)
- SBIOP exists.
- Dot is SBDOT + offset into SMBLK. SBOFF is ignored!
- SB_WRIT flag is set if "smuse" must be updated.
- The R/Wleft counts are set up:
- 1. Rleft 0, Wleft 0 -- Since SBIOP is set, must assume
- counts are too.
- So this means at end of text, no room left.
- Otherwise would imply that setup needs doing.
- 2. Rleft N, Wleft 0 -- At beg or middle of text
- 3. Rleft 0, Wleft N -- At end of text
- 4. Rleft N, Wleft N -- Shouldn''t ever happen
-
- Note that Rleft is always correct. Wleft is sometimes
- set 0 in order to force a call to determine real state.
-
-Note that SBIOP alone is a sufficient test for being OPEN/READY.
-
-The important thing about updating the smblk is to ensure that the "smuse"
-field is correct. This can only be changed by writing or deleting. We assume
-that deletions always update immediately, thus to determine if an update
-is necessary, see if SB_WRIT is set. If so, update smuse before doing
-anything but more writing!!!!
-
-The SDBLK must be marked "modified" whenever a write operation is
-done. We try to do this only the first time, by keeping Wleft zero
-until after the first write. This is also when SB_WRIT gets set.
-However, if in overwrite mode, Wleft must be kept zero in order to
-force the proper actions; SB_WRIT is also not turned on since smuse
-will not change. Note that at EOF, overwrite becomes the same thing
-as insert and is treated identically...
-
- If a SBLK has an in-core copy but no disk copy, it can be
-freely modified. Otherwise, modifications should preferably split
-the block so as to retain "pure" blocks as long as possible. "Pure" blocks
-can always have their in-core versions flushed immediately (unless for
-compaction purposes they''ll need to be written out in the same GC pass).
-Alternatively, mods can simply mark the disk copy "free" and go
-ahead as if no such copy existed.
- No additions or changes to a pure block are allowed, but
-deletions from the end or beginning are always allowed. All other
-changes must split or insert new blocks to accomplish the changes.
-
-Locking:
- SDBLKs are subject to unpredictable relocation, compaction,
-and garbage collecting. There are three ways in which a SDBLK can
-remain fixed:
-
- 1. The SDBLK has the SD_LOCK flag set. This flag is used whenever
- a SBBUF''s SBCUR is pointing to this SDBLK.
- 2. The SDBLK has the SD_LCK2 flag set. This flag is used only
- during execution of various internal routines and should
- not be seen anywhere during execution of user code.
- 3. The SDBLK has no back-pointer (is first block in a sbstring).
- Such SDBLKs cannot be relocated (since it is not known
- what may be pointing to them) but unlike the other 2 cases
- they are still subject to compaction with succeeding SDBLKs.
-
-The SDBLK must be locked with SD_LOCK for as long as it is being
-pointed to by SBCUR. The sole exception is when a SBBUF in the
-OPEN/IDLE state is pointing to the first SDBLK of a sbstring; this
-sdblk is guaranteed not to be moved, since sdblks without a
-back-pointer are never moved. SD_LOCK is asserted as soon as the state
-changes to OPEN/READY, of course. The internal routines take pains to
-always move SD_LOCK as appropriate. Note that only one SD in a
-sbstring can ever have SD_LOCK turned on. SD_LCK2 is an auxiliary flag
-which may appear in more than one SDBLK, for use by low-level routines
-for various temporary reasons; either will prevent the SDBLK from being
-modified in any way by the storage compactor.
-
-SEEKs are a problem because it''s unclear at seek time what will happen
-next, so the excision of the smblk can''t be optimized. If the seek
-happens to land in a sdblk with an existing smblk, there''s no problem;
-but if it''s a sdblk alone, how to decide which part of it to read in???
-If next action is:
- write - split up sdblk and create new one. Read nothing in.
- read - read in 512 bytes starting at disk blk boundary if possible
- else read in 128 bytes starting with selected char
- (include beg of sdblk if less than 64 chars away)
- overwrite - as for read.
- backread - like read but position at end of sdblk.
- delete - split up sdblk, read nothing in.
-
-We solve this through the OPEN/IDLE state, where SBIOP == 0 means SBOFF
-points to logical offset from start of current sdblk, so that the seek
-need not take any action. Only when a specific operation is requested
-will the transition to OPEN/READY take place, at which time we''ll know
-what the optimal excision strategy is. The routine SBX_READY performs
-this function.
-
-The physical links (SDFORW and SDBACK) are only valid when SDFILE is
-set (likewise for SDLEN and SDADDR). In other words, mungs to a sdblk
-must check SDFILE to see whether or not the phys links should be
-altered. Normally they aren''t except during sdblk creation, deletion,
-or swapout, no matter how much the sdblk gets shuffled around
-logically. The disk physical list is kept sorted in order of starting
-addresses. The text blocks indicated can overlap. When a GC is
-necessary, the code must figure out how much space is actually free.
-
--------------- Old woolgathering, ignore rest of this page ---------------
-
-Question: should 512-byte buffers be maintained, one for each SBFILE?
-Or should the in-core text be hacked up to serve for buffering?
-Question is where to point the READ/WRITE system calls. Currently,
-they are pointed directly at the in-core text, and there are no
-auxiliary buffers.
-
-If use auxiliary buffers:
- How to handle flushing, when changing location etc?
- Could be clever about reading from large disk block, only
- get part of it into buffer instead of splitting up in order to
- read a "whole" block.
- Problem: sbstrings can include pieces of several different files.
- Hard to maintain just one buffer per FD without hacking
- done on one sbstring screwing that on another.
-If don''t use buffers:
- Need to have a "chars-left" field in mem blocks, so know how
- much more can be added. Will need heuristics for how much
- extra space to allocate.
-#endif /*COMMENT*/
-\f
-/* Includes, initial definitions */
-
-#include <stdio.h>
-#include "sb.h"
-
-#ifndef V6
-#define V6 0
-#endif
-
-#if V6
-#include <stat.h>
-#else
-#include <sys/types.h>
-#include <sys/stat.h>
-#if MINIX
-#include <fcntl.h> /* For open() flags */
-#else
-#include <sys/file.h> /* For open() flags */
-#endif /* MINIX */
-#endif /*-V6*/
-
-extern int errno;
-extern char *strerror(); /* From ANSI <string.h> */
-
-/* Allocation decls */
-SBFILE sbv_tf; /* SBFILE for temp swapout file */
-int (*sbv_debug)(); /* Error handler address */
-
-
-/* SBX_READY argument flags (internal to SBSTR routines only)
- * The following values should all be unique; the exact value
- * doesn't matter as long as the right SKM flags are given.
- */
-#define SK_READF 0 /* 0-skip fwd, align BOB */
-#define SK_READB (0|SKM_0BACK|SKM_EOB) /* 0-skip bkwd, align EOB */
-#define SK_WRITEF (0|SKM_EOB) /* 0-skip fwd, align EOB */
-#define SK_DELF (4|SKM_0BACK) /* 0-skip bkwd, align BOB */
-#define SK_DELB (4|SKM_EOB) /* 0-skip fwd, align EOB */
-#define SKM_0BACK 01 /* Zero-skip direction: 0 = fwd, set = backwd
- * Don't ever change this value! See SBX_NORM. */
-#define SKM_EOB 02 /* Alignment: 0 = Beg-Of-Buf, set = End-Of-Buf */
-
-/* Note on routine names:
- * "SB_" User callable, deals with sbbufs (usually).
- * "SBS_" User callable, deals with sbstrings only.
- * "SBX_" Internal routine, not meant for external use.
- * "SBM_" Routine handling mem alloc, usually user callable.
- */
-\f
-/* SBBUF Opening, Closing, Mode setting */
-
-/* SB_OPEN(sb,sd) - Sets up SBBUF given pointer to first SD of a sbstring.
- * If SD == 0 then creates null sbstring.
- * Any previous contents of SBBUF are totally ignored!!! If you
- * want to save the stuff, use SB_UNSET.
- * Sets I/O ptr to start of sbstring.
- * Returns 0 if error, else the given SB.
- */
-SBBUF *
-sb_open(sbp,sdp)
-SBBUF *sbp;
-SBSTR *sdp;
-{ register struct sdblk *sd;
- register int cnt;
- register WORD *clrp;
-
- if(!sbp) return((SBBUF *)0);
- if((sd = sdp) == 0)
- { sd = sbx_ndget(); /* Get a fresh node */
- clrp = (WORD *) sd; /* Clear it all */
- cnt = rnddiv(sizeof(struct sdblk));
- do { *clrp++ = 0; } while(--cnt);
- sd->sdflags = SD_NID; /* Except flags of course */
- }
- else if(sd->slback) /* Must be first thing in sbstring */
- return((SBBUF *)0); /* Perhaps could normalize tho */
-
- clrp = (WORD *) sbp; /* Clear sbbuffer stuff */
- cnt = rnddiv(sizeof(SBBUF));
- do { *clrp++ = 0; } while(--cnt);
-
- sbp->sbcur = sd;
- /* Note that SD_LOCK need not be set, because first SDBLK has no
- * backptr. This is desirable to allow storage compactor maximum
- * freedom in merging sdblks.
- */
- /* sd->sdflags |= SD_LOCK; */ /* Lock this one */
- return(sbp);
-}
-
-
-/* SB_CLOSE(sb) - Close a SBBUF.
- * Returns pointer to start of sbstring (first SD).
- * Returns 0 if error.
- */
-SBSTR *
-sb_close(sbp)
-SBBUF *sbp;
-{ register SBBUF *sb;
- register struct sdblk *sd;
-
- if((sb = sbp) == 0) /* Verify pointer */
- return((SBSTR *)0);
- sb_rewind(sb); /* Do most of the work, including unlock */
- sd = sb->sbcur; /* Save ptr to sbstring */
- sb->sbcur = 0; /* Now reset the sbbuffer structure */
- sb->sbflags = 0;
- return(sd);
-}
-
-
-/* SB_SETOVW(sbp) - Set SBBUF Over-write mode for PUTC's.
- * SB_CLROVW(sbp) - Clear ditto.
- */
-sb_setovw(sbp)
-SBBUF *sbp;
-{ register SBBUF *sb;
- if(sb=sbp)
- { sb->sbflags |= SB_OVW;
- sb->sbwleft = 0;
- }
-}
-
-sb_clrovw(sbp)
-SBBUF *sbp;
-{ register SBBUF *sb;
- if(sb=sbp) sb->sbflags &= ~SB_OVW;
-}
-\f
-/* SBSTRING file system operations (see also sb_fsave) */
-
-/* SB_FDUSE(fd) - Make a sbstring for given file.
- * FD is an open file descriptor.
- * Returns pointer to a SBSTR containing the given file, or 0 if error.
- * The FD must not be closed until a SB_FDCLS is done to
- * purge memory of any blocks pointing at the file.
- * ** Maybe allocate sbfile structs with sbx_ndget, i.e. overlay on
- * ** top of sdblk node?? Wd this screw verify, GC, etc? Maybe not if
- * ** SD_LCK2 set...
- */
-
-struct sbfile *sbv_ftab[SB_NFILES];
-
-chroff
-sbx_fdlen(fd)
-int fd;
-{
-#if !V6
- struct stat statb;
-#else
- struct statb statb;
- chroff len;
- struct {int hiwd ; int lowd;} foo;
-#endif /*V6*/
-
- if(fstat(fd,&statb) < 0) return((chroff)-1);
-#if V6
- len = statb.i_size1;
- len.hiwd = statb.i_size0 & 0377;
- return(len);
-#else
- return((chroff)statb.st_size);
-#endif /*-V6*/
-}
-
-SBSTR *
-sb_fduse(ifd)
-int ifd;
-{ register struct sdblk *sd;
- register struct sbfile *sf;
- register int fd;
- chroff len;
-
- if((fd = ifd) < 0 || SB_NFILES <= fd /* Check for absurd FD */
- || sbv_ftab[fd]) /* and slot already in use */
- return((SBSTR *)0);
- if((len = sbx_fdlen(fd)) < 0) return((SBSTR *)0);
- sbv_ftab[fd]= sf = (struct sbfile *)sbx_malloc(sizeof(struct sbfile));
- sf->sffd = fd;
- sf->sfptr1 = sd = sbx_ndget();
- sf->sflen = len;
- sd->slforw = 0;
- sd->slback = 0;
- sd->sdforw = 0;
- sd->sdback = 0;
- sd->sdmem = 0;
- sd->sdfile = sf;
- sd->sdlen = len;
- sd->sdaddr = 0;
- return(sd);
-}
-
-/* SB_FDCLS(fd) - Close a file descriptor being used by sbstrings.
- * If arg is -1, closes all FD's that are unused (a "sweep").
- * For specific arg, returns 0 if couldn't close FD because still in use.
- * Perhaps later version of routine could have option to copy
- * still-used SD's to tempfile, and force the FD closed?
- */
-sb_fdcls(ifd)
-int ifd;
-{ register int fd;
-
- if((fd = ifd) >= 0)
- { if(fd >= SB_NFILES) return(0); /* Error of sorts */
- return(sbx_fcls(sbv_ftab[fd]));
- }
- fd = SB_NFILES-1;
- do {
- sbx_fcls(sbv_ftab[fd]);
- } while(--fd); /* Doesn't try FD 0 ! */
- return(1);
-}
-
-sbx_fcls(sfp)
-struct sbfile *sfp;
-{ register struct sbfile *sf;
- register int fd;
-
- if((sf = sfp)==0 /* Ignore null args */
- || sf == &sbv_tf) /* and never close our tempfile! */
- return(0);
- fd = sf->sffd; /* Find sys file descriptor */
- if(sbv_ftab[fd] != sf) /* Ensure consistency */
- return(sbx_err(0,"SF table inconsistency"));
- if(sf->sfptr1) /* Any phys list still exists? */
- return(0); /* Yes, still in use, can't close */
- close(fd); /* Maybe do this when list gone? */
- sbv_ftab[fd] = 0; /* Remove from table */
- free(sf); /* Remove sbfile struct from mem */
-}
-
-/* SB_FDINP(sb,fd) - Returns TRUE if specified fd is still in use
- * by specified sbbuffer.
- */
-sb_fdinp(sb, fd)
-register SBBUF *sb;
-int fd;
-{ register struct sdblk *sd;
- register struct sbfile *sf;
-
- if((sf = sbv_ftab[fd]) == 0
- || (sd = sb->sbcur) == 0)
- return(0);
- sd = sbx_beg(sd); /* Move to beginning of sbstring */
- for(; sd; sd = sd->slforw) /* Scan thru all blocks in string */
- if(sd->sdfile == sf) /* If any of them match, */
- return(1); /* Return tally-ho */
- return(0);
-}
-
-/* SB_FSAVE(sb,fd) - Write entire SBBUF out to specified FD.
- * Returns 0 if successful, else system call error number.
- */
-sb_fsave(sb,fd) /* Write all of given sbbuf to given fd */
-register SBBUF *sb;
-int fd;
-{
- sbx_smdisc(sb);
- return(sbx_aout(sbx_beg(sb->sbcur), 2, fd));
-}
-\f
-/* SBBUF Character Operations */
-
-/* SB_GETC(sb) - Get next char from sbstring.
- * Returns char at current location and advances I/O ptr.
- * Returns EOF on error or end-of-string.
- */
-int
-sb_sgetc(sb)
-register SBBUF *sb;
-{
- if(--(sb->sbrleft) >= 0)
- return sb_uchartoint(*sb->sbiop++);
-
- /* Must do hard stuff -- check ptrs, get next blk */
- sb->sbrleft = 0; /* Reset cnt to zero */
- if(sb->sbcur == 0 /* Make sure sbbuffer there */
- || (int)sbx_ready(sb,SK_READF,0,SB_BUFSIZ) <= 0) /* Normalize & gobble */
- return(EOF);
- return(sb_sgetc(sb)); /* Try again */
-} /* Loop wd be faster, but PDL OV will catch infinite-loop bugs */
-
-
-/* SB_PUTC(sb,ch) - Put char into sbstring.
- * Inserts char at current location.
- * Returns EOF on error, else the char value.
- */
-int
-sb_sputc(sb,ch)
-register SBBUF *sb;
-int ch;
-{
- register struct sdblk *sd;
-
- if(--(sb->sbwleft) >= 0) return(*sb->sbiop++ = ch);
-
- sb->sbwleft = 0; /* Reset cnt to avoid overflow */
- if((sd = sb->sbcur) == 0) /* Verify string is there */
- return(EOF); /* Could perhaps create it?? */
- if(sb->sbflags&SB_OVW) /* If overwriting, handle std case */
- { if(sb->sbiop &&
- --sb->sbrleft >= 0) /* Use this for real count */
- { sd->sdflags |= SD_MOD; /* Win, munging... */
- return(*sb->sbiop++ = ch);
- }
- /* Overwriting and hit end of this block. */
- if((int)sbx_ready(sb,SK_READF,0,SB_BUFSIZ) > 0) /* Re-normalize */
- return(sb_sputc(sb,ch));
-
- /* No blks left, fall through to insert stuff at end */
- }
-
- /* Do canonical setup with heavy artillery */
- if((int)sbx_ready(sb,SK_WRITEF,SB_SLOP,SB_BUFSIZ) <= 0) /* Get room */
- return(EOF); /* Should never happen, but... */
- sb->sbflags |= SB_WRIT;
- sb->sbcur->sdflags |= SD_MOD;
- return(sb_sputc(sb,ch)); /* Try again */
-} /* Loop wd be faster, but PDL OV will catch infinite-loop bugs */
-
-
-/* SB_PEEKC(sb) - Peek at next char from sbstring.
- * Returns char that sb_getc would next return, but without
- * changing I/O ptr.
- * Returns EOF on error or end-of-string.
- */
-int
-sb_speekc(sb)
-register SBBUF *sb;
-{
- if (sb->sbrleft <= 0) /* See if OK to read */
- { if (sb_sgetc(sb) == EOF) /* No, try hard to get next */
- return EOF; /* Failed, return EOF */
- sb_backc(sb); /* Won, back up */
- }
- return sb_uchartoint(*sb->sbiop);
-}
-
-/* SB_RGETC(sb) - Get previous char from sbstring.
- * Returns char prior to current location and backs up I/O ptr.
- * Returns EOF on error or beginning-of-string.
- */
-int
-sb_rgetc(sb)
-register SBBUF *sb;
-{
- register struct smblk *sm;
- register struct sdblk *sd;
-
- if((sd=sb->sbcur) && (sm = sd->sdmem)
- && sb->sbiop > sm->smaddr)
- { if(sb->sbflags&SB_WRIT)
- { sm->smuse = sb->sbiop - sm->smaddr;
- sb->sbwleft = 0;
- sb->sbflags &= ~SB_WRIT;
- }
- sb->sbrleft++;
- return sb_uchartoint(*--sb->sbiop); /* Return char */
- }
- if((int)sbx_ready(sb,SK_READB,SB_BUFSIZ,0) <= 0)
- return(EOF);
- return(sb_rgetc(sb));
-}
-
-/* SB_RDELC(sb) - Delete backwards one char.
- * Returns nothing.
- */
-sb_rdelc(sbp)
-SBBUF *sbp;
-{ register SBBUF *sb;
- register struct sdblk *sd;
-
- if(((sb=sbp)->sbflags&SB_WRIT) /* Handle simple case fast */
- && sb->sbiop > (sd = sb->sbcur)->sdmem->smaddr)
- { sb->sbwleft++;
- sb->sbiop--;
- sd->sdflags |= SD_MOD;
- return;
- }
- else sb_deln(sb,(chroff) -1); /* Else punt... */
-}
-
-/* SB_DELC(sb) - Delete one char forward? */
-/* SB_INSC(sb,ch) - Insert char? (instead of or in addition to PUTC) */
-
-\f
-/* SBBUF string or N-char operations */
-
-/* SB_DELN(sb,chroff) - delete N chars. Negative N means backwards.
- * Differs from sb_killn in that it flushes the text forever,
- * and doesn't return anything.
- */
-
-sb_deln(sbp, num)
-SBBUF *sbp;
-chroff num;
-{
- register struct sdblk *sd;
-
- if(sd = sb_killn(sbp,num))
- sbs_del(sd); /* Punt */
-}
-
-/* SB_KILLN(sb,chroff) - delete N chars, saving. Negative N means backwards.
- * Returns SD pointer to beginning of saved sbstring.
- */
-struct sdblk *
-sb_killn(sbp, num)
-SBBUF *sbp;
-chroff num;
-{ register SBBUF *sb;
- register struct sdblk *sd, *sd2;
- struct sdblk *sdr, *sdx;
- chroff savdot;
-
- if((sd = sbx_xcis((sb=sbp),num,&sdr,&savdot)) == 0)
- return((struct sdblk *)0);
-
- sb->sbcur->sdflags &= ~SD_LOCK; /* Now can flush sbcur lock */
-
- /* SD and SD2 now delimit bounds of stuff to excise.
- * First do direction dependent fixups
- */
- if(num >= 0) /* If deleting forward, */
- sb->sbdot = savdot; /* must reset dot to initial loc */
-
- /* SD and SD2 now in first/last order. Complete SBCUR fixup. */
- sd2 = sdr; /* sdr has ptr to end of stuff */
- if(sd2 = sd2->slforw) /* More stuff after killed list? */
- { sb->sbcur = sd2; /* Yes, point at it */
- sb->sboff = 0; /* Dot already set right */
- }
- else if(sdx = sd->slback) /* See if any prior to killed list */
- { sb->sbcur = sdx; /* Yes, point at it */
- sb->sboff = (sdx->sdmem ? /* Get len of prev blk */
- sdx->sdmem->smuse : sdx->sdlen);
- sb->sbdot -= sb->sboff;
- }
- else sb_open(sb,(SBSTR *)0); /* No stuff left! Create null sbstring */
-
- /* Fix up logical links. Note SD2 points to succ of killed stuff */
- if(sd->slback) /* If previous exists */
- { if(sd->slback->slforw = sd2) /* Point it to succ, and */
- sd2->slback = sd->slback; /* thence to self */
- sd->slback = 0; /* Now init killed list */
- }
- else if(sd2) sd2->slback = 0; /* No prev, clean rest */
- (sd2 = sdr)->slforw = 0; /* Finish killed list */
-
- sb->sbcur->sdflags |= SD_LOCK; /* Ensure current SD now locked */
- sd->sdflags &= ~SD_LCK2; /* And unlock killed list */
- sd2->sdflags &= ~SD_LCK2;
- return(sd);
-}
-
-/* SB_CPYN(sbp,num) - Copy num characters, returns SD to sbstring.
- * Like SB_KILLN but doesn't take chars out of original sbstring.
- */
-SBSTR *
-sb_cpyn(sbp,num)
-SBBUF *sbp;
-chroff num;
-{ register SBBUF *sb;
- register struct sdblk *sd, *sd2;
- struct sdblk *sdr;
- chroff savloc;
-
- sb = sbp;
- if((sd = sbx_xcis(sb,num,&sdr,&savloc)) == 0)
- return((SBSTR *)0);
- sd2 = sbx_scpy(sd,sdr);
- sb_seek(sb,-num,1); /* Return to original loc */
- return(sd2); /* Return val is ptr to head of copy.
- * It needn't be locked, because GC will
- * never move list heads!
- */
-}
-
-/* SB_SINS(sb,sd) - Insert sbstring at current location
- *
- */
-sb_sins(sbp,sdp)
-SBBUF *sbp;
-struct sdblk *sdp;
-{ register SBBUF *sb;
- register struct sdblk *sd, *sdx;
- chroff inslen;
-
- if((sb = sbp)==0
- || (sd = sdp) == 0)
- return(0);
- if(sd->slback) /* Perhaps normalize to beg? */
- return(0);
- if((sdx = (struct sdblk *)sbx_ready(sb,SK_DELB)) == 0) /* Get cur pos ready */
- return(0);
- inslen = sbs_len(sd); /* Save length of inserted stuff */
-
- sd->slback = sdx; /* Fix up links */
- if(sdx->slforw)
- { while(sd->slforw) /* Hunt for end of inserted sbstring */
- sd = sd->slforw;
- sd->slforw = sdx->slforw;
- sd->slforw->slback = sd;
- }
- sdx->slforw = sdp;
- sb->sboff += inslen; /* Set IO ptr to end of new stuff */
- return(1);
-}
-\f
-/* SBSTRING routines - operate on "bare" sbstrings. */
-
-/* SBS_CPY(sd) - Copies given sbstring, returns ptr to new sbstring.
- */
-SBSTR *
-sbs_cpy(sdp)
-SBSTR *sdp;
-{ return(sbx_scpy(sdp,(struct sdblk *)0));
-}
-
-/* SBS_DEL(sd) - Flush a sbstring.
- */
-sbs_del(sdp)
-SBSTR *sdp;
-{ register struct sdblk *sd;
-
- if(sd = sdp)
- while(sd = sbx_ndel(sd));
-}
-
-
-/* SBS_APP(sd1,sd2) - Appends sbstring sd2 at end of sbstring sd1.
- * Returns sd1 (pointer to new sbstring).
- */
-
-SBSTR *
-sbs_app(sdp,sdp2)
-struct sdblk *sdp,*sdp2;
-{ register struct sdblk *sd, *sdx;
-
- if(sd = sdp)
- { while(sdx = sd->slforw)
- sd = sdx;
- if(sd->slforw = sdx = sdp2)
- sdx->slback = sd;
- }
- return(sdp);
-}
-
-/* SBS_LEN(sd) - Find length of sbstring.
- */
-chroff
-sbs_len(sdp)
-SBSTR *sdp;
-{ register struct sdblk *sd;
- register struct smblk *sm;
- chroff len;
-
- if((sd = sdp)==0) return((chroff)0);
- len = 0;
- for(; sd ; sd = sd->slforw)
- { if(sm = sd->sdmem)
- len += (chroff)sm->smuse;
- else len += sd->sdlen;
- }
- return(len);
-}
-\f
-/* SBBUF I/O pointer ("dot") routines */
-
-/* SB_SEEK(sb,chroff,flag) - Like FSEEK. Changes I/O ptr value as
- * indicated by "flag":
- * 0 - offset from beg
- * 1 - offset from current pos
- * 2 - offset from EOF
- * Returns -1 on errors.
- * Seeking beyond beginning or end of sbbuf will leave pointer
- * at the beginning or end respectively.
- * Returns 0 unless error (then returns -1).
- */
-sb_seek(sbp, coff, flg)
-SBBUF *sbp;
-chroff coff;
-int flg;
-{ register SBBUF *sb;
- register struct smblk *sm;
- register struct sdblk *sd;
- SBMO moff;
-
- sb = sbp;
- if((sd = sb->sbcur) == 0) return(-1);
- if(sb->sbiop == 0)
- { switch(flg)
- { case 0: if(coff == 0) /* Optimize common case */
- return(sb_rewind(sb));
- sb->sboff = coff - sb->sbdot; /* Abs */
- break;
- case 1: sb->sboff += coff; /* Rel */
- break;
- case 2: sb->sboff += sb_ztell(sb) + coff;
- break;
- default: return(-1);
- }
- sbx_norm(sb,0);
- return(0);
- }
- if((sm = sd->sdmem) == 0)
- return(sbx_err(-1,"SDMEM 0"));
- moff = sb->sbiop - sm->smaddr; /* Get cur smblk offset */
- if(sb->sbflags&SB_WRIT) /* Update since moving out */
- { sm->smuse = moff;
- sb->sbflags &= ~SB_WRIT;
- }
- sb->sbwleft = 0; /* Always gets zapped */
- switch(flg)
- { case 0: /* Offset from beginning */
- coff -= sb->sbdot + (chroff)moff; /* Make rel */
-
- case 1: /* Offset from current loc */
- break;
-
- case 2: /* Offset from end */
- coff += sb_ztell(sb);
- break;
- default: return(-1);
- }
-
- /* COFF now has relative offset from current location */
- if (-(chroff)moff <= coff && coff <= sb->sbrleft)
- { /* Win! Handle repos-within-smblk */
- sb->sbiop += coff;
- sb->sbrleft -= coff; /* Set r; wleft already 0 */
- return(0);
- }
-
- /* Come here when moving to a different sdblk. */
- sb->sbrleft = 0;
- sb->sbiop = 0;
- sb->sboff = coff + (chroff)moff;
- sbx_norm(sb,0);
- return(0);
-}
-
-/* SB_REWIND(sb) - Go to beginning of sbbuffer.
- * Much faster than using sb_seek. Note that this leaves the sbbuffer
- * in an open/idle state which is maximally easy to compact.
- */
-sb_rewind(sbp)
-SBBUF *sbp;
-{ register SBBUF *sb;
- register struct sdblk *sd;
-
- if((sb = sbp)==0) return;
- sbx_smdisc(sb); /* Ensure I/O disconnected */
- (sd = sb->sbcur)->sdflags &= ~SD_LOCK; /* Unlock current blk */
- sd = sbx_beg(sd); /* Move to beg of sbstring */
- /* Need not lock - see sb_open comments, also sb_close */
- /* sd->sdflags |= SD_LOCK; */ /* Lock onto this one */
- sb->sbcur = sd;
- sb->sbdot = 0;
- sb->sboff = 0;
-}
-
-/* SB_TELL(sb) - Get I/O ptr value for SBBUF.
- * Returns -1 on errors.
- */
-
-chroff
-sb_tell(sbp)
-SBBUF *sbp;
-{ register SBBUF *sb;
- register struct smblk *sm;
- register struct sdblk *sd;
-
- if((sd = (sb=sbp)->sbcur) == 0)
- return((chroff)-1);
- if(sb->sbiop == 0)
- return(sb->sbdot + sb->sboff);
- if((sm = sd->sdmem) == 0)
- return(sbx_err(0,"SDMEM 0"));
- return(sb->sbdot + (unsigned)(sb->sbiop - sm->smaddr));
-}
-
-/* SB_ZTELL(sb) - Get I/O ptr relative to "Z" (EOF).
- * Returns # chars from current location to EOF; 0 if any errors.
- */
-chroff
-sb_ztell(sbp)
-SBBUF *sbp;
-{ register SBBUF *sb;
- register struct smblk *sm;
- register struct sdblk *sd;
-
- if((sd = (sb=sbp)->sbcur) == 0)
- return((chroff)0);
- if(sb->sbiop && (sm = sd->sdmem))
- { if(sb->sbflags&SB_WRIT) /* If actively writing, */
- return(sbs_len(sd->slforw)); /* ignore this blk. */
- /* Note that previous code makes it unnecessary
- * to invoke sbx_smdisc. (otherwise wrong
- * smuse would confuse sbs_len).
- */
- return(sbs_len(sd) - (sb->sbiop - sm->smaddr));
- }
- else
- return(sbs_len(sd) - sb->sboff);
-}
-\f
-/* Code past this point should insofar as possible be INTERNAL. */
-
-/* SBX_READY(sb,type,cmin,cmax) - Set up SBBUF for reading or writing.
- *
- * If no current smblk:
- * reading - set up for reading
- * writing - set up for splitting?
- * If current smblk:
- * reading - if can read, OK. Else position at beg of next sdblk
- * writing - if can write, OK. Else position at end of prev sdblk,
- * or set up for splitting?
- * Types:
- * 0 - Read forward (BOB)
- * 1 - Read backward (EOB)
- * 3 - Write (insert forward) (EOB)
- * 4 - Delete forward (return SD, force BOB-aligned)
- * 5 - Delete backward (return SD, force EOB-aligned)
- * Connected SD is always locked.
- * Returns 0 if error, -1 if EOF-type error, 1 for success.
- *
- * For types 0,1:
- * CMIN,CMAX represent max # chars to read in to left and right of
- * I/O ptr (prev and post). Actual amount read in may be
- * much less, but will never be zero.
- * Successful return guarantees that SBIOP etc. are ready.
- * For type 3:
- * If new block is allocated, CMIN and CMAX represent min, max sizes
- * of the block.
- * Successful return guarantees that SBIOP etc. are ready, but
- * NOTE that SB_WRIT and SD_MOD are not set! If not going to use
- * for writing, be sure to clear sbwleft on return!
- * For types 4,5:
- * CMIN, CMAX are ignored.
- * SBIOP is always cleared. SBOFF is guaranteed to be 0 for
- * type 4, SMUSE for type 5.
- * Return value is a SD ptr; 0 indicates error. -1 isn't used.
- */
-
-struct sdblk *
-sbx_ready(sbp,type,cmin,cmax)
-SBBUF *sbp;
-int type;
-SBMO cmin,cmax;
-{ register SBBUF *sb;
- register struct sdblk *sd;
- register struct smblk *sm;
- int cnt, slop, rem;
- SBMO moff;
-
- if((sd = (sb=sbp)->sbcur) == 0)
- return(0);
- if(sb->sbiop) /* Canonicalize for given operation */
- { if((sm = sd->sdmem)==0)
- return(0);
- moff = sb->sbiop - sm->smaddr; /* Current block offset */
- switch(type)
- {
- case SK_READF: /* Read Forward */
- if(sb->sbrleft > 0) /* Already set up? */
- return(1); /* Yup, fast return */
- sbx_smdisc(sb); /* None left, disc to get next */
- if((sd = sbx_next(sb)) == 0) /* Try to get next blk */
- return(-1); /* At EOF */
- break;
-
- case SK_READB: /* Read Backward */
- if(moff) /* Stuff there to read? */
- { if(sb->sbflags&SB_WRIT) /* Yup, turn writes off */
- { sm->smuse = moff;
- sb->sbflags &= ~SB_WRIT;
- }
- sb->sbwleft = 0;
- return(1);
- }
- sbx_smdisc(sb);
- break;
-
- case SK_WRITEF: /* Writing */
- if(sb->sbrleft <= 0)
- sb->sbwleft = sm->smlen - moff;
- if(sb->sbwleft > 0)
- return(1); /* OK to write now */
- /* NOTE: flags not set!!! */
- sbx_smdisc(sb);
- break;
-
- case SK_DELF: /* Delete forward - force BOB */
- if(sb->sbrleft <= 0) /* At end of blk? */
- { sbx_smdisc(sb); /* Win, unhook */
- return(sbx_next(sb)); /* Return next or 0 if EOF */
- }
- sbx_smdisc(sb); /* Not at end, but see if */
- if(moff == 0) /* at beg of blk? */
- return(sd); /* Fast win! */
- break;
-
- case SK_DELB: /* Delete backward - force EOB */
- if(sb->sbrleft <= 0) /* Win if already EOB */
- { sbx_smdisc(sb);
- return(sd);
- }
- sbx_smdisc(sb);
- break;
-
- default:
- return(0);
- }
- }
-
- /* Schnarf in the text, or whatever.
- * SD points to current sdblk (must be SD_LOCKed)
- * SBDOT must have correct value for this SD
- * SBOFF has offset from there to put I/O ptr at.
- *
- * After normalization, SBOFF is guaranteed to point within
- * the SD. Other guarantees apply to boundary cases, depending
- * on the mode (type) bits.
- */
- sd = sbx_norm(sb,type); /* Normalize I/O pos appropriately */
- sm = sd->sdmem;
- switch(type)
- {
- case SK_READB: /* Read Backward */
- if(sb->sboff == 0) /* Due to normalize, if 0 seen */
- return(-1); /* then we know it's BOF */
- if(sm) goto sekr2;
- else goto sekr1;
-
- case SK_READF: /* Read Forward */
- if(sm) goto sekr2;
- if(sb->sboff == sd->sdlen) /* Normalize means if EOB */
- return(-1); /* then at EOF. */
- sekr1: slop = SB_SLOP;
- sekr3: if(sb->sboff > cmin+slop) /* Too much leading text? */
- { /* Split off leading txt */
- sbx_split(sd,(chroff)(sb->sboff - cmin));
- sd = sbx_next(sb); /* Point to next sdblk */
- sb->sboff = cmin; /* Set correct offset */
- /* (sbx_next assumes 0) */
- }
- if(sd->sdlen > sb->sboff+cmax+slop) /* Too much trailing txt? */
- sbx_split(sd,(chroff)(sb->sboff+cmax));
-
- /* ----- Try to get mem blk to read stuff into ----- */
- /* Note alignment hack for extra efficiency. This ensures
- * that all reads from disk to memory are made with the same
- * source and destination word alignment, so the system kernel
- * only needs byte-moves for the first or last bytes; all
- * others can be word-moves.
- * This works because sbx_mget always returns word-aligned
- * storage, and we use sbx_msplit to trim off the right number
- * of bytes from the start.
- */
- cnt = sd->sdlen; /* Get # bytes we'd like */
- if(rem = rndrem(sd->sdaddr)) /* If disk not word-aligned */
- cnt += rem; /* allow extra for aligning.*/
- if(sm == 0) /* Always true 1st time */
- { sm = sbx_mget(SB_SLOP,cnt); /* Get room (may GC!)*/
- if(sm->smlen < cnt) /* Got what we wanted? */
- { slop = 0; /* NO!! Impose stricter */
- cmin = 0; /* limits. Allow for new */
- cmax = sm->smlen - (WDSIZE-1); /* rem. */
- if(type == SK_READB)
- { cmin = cmax; cmax = 0; }
- goto sekr3; /* Go try again, sigh. */
- }
- }
- else if(sm->smlen < cnt) /* 2nd time shd always win */
- { sbx_err(0,"Readin blksiz err"); /* Internal error, */
- if((cmax /= 2) > 0) goto sekr3; /* w/crude recovery */
- return(0);
- }
- if(rem) /* If disk not word-aligned, hack stuff */
- { sm = sbx_msplit(sm, (SBMO)rem); /* Trim off from beg*/
- sbm_mfree(sm->smback); /* Free the excess */
- }
- sd->sdmem = sm;
- sm->smuse = sd->sdlen;
-
- if(sd->sdfile == 0)
- return(sbx_err(0,"No file")); /* Gasp? */
- if(!sbx_rdf(sd->sdfile->sffd, sm->smaddr, sm->smuse,
- 1, sd->sdaddr))
- return(sbx_err(0,"Readin SD: %o", sd));
- /* ------- */
-
- sekr2: sbx_sbrdy(sb); /* Make it current, pt to beg */
- sb->sbwleft = 0; /* Ensure not set (esp if READB) */
- break;
-
- case SK_WRITEF: /* Write-type seek */
- if(sm == 0)
- { /* Block is on disk, so always split (avoid readin) */
- if(sd->sdlen) /* May be empty */
- { sbx_split(sd, sb->sboff); /* Split at IO ptr */
- sd = sbx_next(sb); /* Move to 2nd part */
- if(sd->sdlen) /* If stuff there, */
- /* split it again. */
- sbx_split(sd, (chroff) 0);
- }
- goto sekwget;
- }
-
- /* Block in memory */
- moff = sm->smuse;
- if(sb->sboff == moff) /* At end of the block? */
- { if(sm->smlen > moff) /* Yes, have room? */
- goto sekw; /* Win, go setup and ret */
- if(sm->smforw /* If next mem blk */
- && (sm->smforw->smflags /* Can have bytes */
- & (SM_USE|SM_NXM))==0 /* stolen from it */
- && (sd->sdflags&SD_MOD) /* and we ain't pure*/
- && sm->smlen < cmax) /* and not too big */
- { /* Then steal some core!! Note that without
- * the size test, a stream of putc's could
- * create a monster block gobbling all mem.
- */
- cmin = cmax - sm->smlen;
- if(cmin&01) cmin++; /* Ensure wd-align */
- if(sm->smforw->smlen <= cmin)
- { sbm_mmrg(sm);
- goto sekw;
- }
- sm->smforw->smlen -= cmin;
- sm->smforw->smaddr += cmin;
- sm->smlen += cmin;
- goto sekw;
- }
- /* Last try... check next logical blk for room */
- if(sd->slforw && (sm = sd->slforw->sdmem)
- && sm->smuse == 0
- && sm->smlen)
- { sd = sbx_next(sb); /* Yup, go there */
- goto sekw;
- }
- }
-
- /* Middle of block, split up to insert */
- sbx_split(sd, sb->sboff); /* Split at IO ptr */
- if(sd->sdmem) /* Unless blk now empty, */
- { sd = sbx_next(sb); /* move to next. */
- if(sd->sdmem) /* If not empty either */
- sbx_split(sd, (chroff) 0); /* Split again */
- }
-
- /* Have empty SD block, get some mem for it */
- sekwget: sd->sdmem = sm = sbx_mget(cmin,cmax);
- sm->smuse = 0;
- sekw: sbx_sbrdy(sb); /* Sets up sbwleft... */
- return(1);
-
- case SK_DELF: /* Delete forward */
- if(sb->sboff == 0) /* At block beg already? */
- return(sd); /* Win, return it */
- sbx_split(sd, sb->sboff); /* No, split up and */
- return(sbx_next(sb)); /* return ptr to 2nd part */
-
- case SK_DELB: /* Delete backward (force EOB align) */
- if(sb->sboff != /* If not at EOB already, */
- (sm ? (chroff)(sm->smuse) : sd->sdlen))
- sbx_split(sd, sb->sboff); /* Then split */
- return(sd); /* And return ptr to 1st part */
- break;
-
- default:
- return(0);
- } /* End of switch */
- return(1);
-}
-
-struct sdblk *
-sbx_next (sbp)
-SBBUF *sbp;
-{ register SBBUF *sb;
- register struct sdblk *sd, *sdf;
- if((sdf = (sd = (sb=sbp)->sbcur)->slforw) == 0)
- return((struct sdblk *)0);
- sb->sbdot += (sd->sdmem ? (chroff)sd->sdmem->smuse : sd->sdlen);
- sb->sboff = 0;
- sd->sdflags &= ~SD_LOCK; /* Unlock current */
- sdf->sdflags |= SD_LOCK; /* Lock next */
- sb->sbcur = sdf;
- return(sdf);
-}
-\f
-/* SBX_NORM(sb,mode) - Normalizes I/O position as desired.
- * The SBBUF must have I/O disconnected (SBIOP==0).
- * Adjusts SBCUR, SBDOT, and SBOFF so that SBOFF is guaranteed
- * to point to a location in the current SD block.
- * The mode flags determine action when there is more than
- * one possible SD that could be pointed to, as is the case
- * when the I/O pos falls on a block boundary (possibly with
- * adjacent zero-length blocks as well).
- * SKM_0BACK - Zero-skip direction.
- * 0 = Skip forward over zero-length blocks.
- * set = Skip backward over zero-length blocks.
- * SKM_EOB - Block-end selection (applies after skipping done).
- * 0 = Point to BOB (Beginning Of Block).
- * set = Point to EOB (End Of Block).
- * Returns the new current SD as a convenience.
- * Notes:
- * The SKM_0BACK flag value is a special hack to search in
- * the right direction when SBOFF is initially 0.
- * None of the mode flags have any effect if the I/O pos falls
- * within a block.
- * Perhaps this routine should flush the zero-length blks it
- * finds, if they're not locked??
- */
-struct sdblk *
-sbx_norm(sbp,mode)
-SBBUF *sbp;
-int mode;
-{ register struct sdblk *sd;
- register struct smblk *sm;
- register SBBUF *sb;
- chroff len;
-
- if((sd = (sb=sbp)->sbcur) == 0)
- { sb->sbdot = 0;
- sb->sboff = 0;
- return(sd);
- }
- sd->sdflags &= ~SD_LOCK; /* Unlock current blk */
-
- if(sb->sboff >= (mode&01)) /* Hack hack to get right skip */
- for(;;) /* Scan forwards */
- { if(sm = sd->sdmem) /* Get length of this blk */
- len = sm->smuse;
- else len = sd->sdlen;
- if(sb->sboff <= len)
- if(sb->sboff < len /* If == and fwd 0-skip, continue */
- || (mode&SKM_0BACK))
- { if((mode&SKM_EOB) /* Done, adjust to EOB? */
- && sb->sboff == 0 /* Yes, are we at BOB? */
- && sd->slback) /* and can do it? */
- { sd = sd->slback; /* Move to EOB */
- sb->sboff = (sm = sd->sdmem)
- ? (chroff)(sm->smuse) : sd->sdlen;
- sb->sbdot -= sb->sboff;
- }
- break;
- }
- if(sd->slforw == 0) /* At EOF? */
- { sb->sboff = len;
- break;
- }
- sd = sd->slforw;
- sb->sboff -= len;
- sb->sbdot += len;
- }
- else /* Scan backwards */
- for(;;)
- { if(sd->slback == 0) /* At BOF? */
- { sb->sboff = 0;
- sb->sbdot = 0; /* Should already be 0, but... */
- break;
- }
- sd = sd->slback;
- if(sm = sd->sdmem) /* Get length of this blk */
- len = sm->smuse;
- else len = sd->sdlen;
- sb->sbdot -= len;
- if((sb->sboff += len) >= 0)
- if(sb->sboff > 0 /* If == 0 and bkwd 0-skip, continue */
- || !(mode&SKM_0BACK))
- { if((mode&SKM_EOB) == 0 /* Done, adjust to BOB? */
- && sb->sboff == len /* Yes, are we at EOB? */
- && sd->slforw) /* and can do it? */
- { sd = sd->slforw; /* Move to BOB */
- sb->sboff = 0;
- sb->sbdot += len;
- }
- break;
- }
- }
- sb->sbcur = sd;
- sd->sdflags |= SD_LOCK;
- return(sd);
-}
-\f
-
-struct sdblk *
-sbx_beg(sdp)
-struct sdblk *sdp;
-{ register struct sdblk *sd, *sdx;
- if(sd = sdp)
- while(sdx = sd->slback)
- sd = sdx;
- return(sd);
-}
-
-
-sbx_smdisc(sbp)
-SBBUF *sbp;
-{ register SBBUF *sb;
- register struct smblk *sm;
- register struct sdblk *sd;
-
- sb = sbp;
- if((sd = sb->sbcur) == 0
- || (sm = sd->sdmem) == 0)
- return;
- if(sb->sbflags&SB_WRIT)
- { sm->smuse = sb->sbiop - sm->smaddr;
- sb->sbflags &= ~SB_WRIT;
- }
- sb->sboff = sb->sbiop - sm->smaddr;
- sb->sbiop = 0;
- sb->sbrleft = sb->sbwleft = 0;
-}
-
-sbx_sbrdy(sbp) /* Sets up SBIOP, SBRLEFT, SBWLEFT */
-SBBUF *sbp;
-{ register SBBUF *sb;
- register struct sdblk *sd;
- register struct smblk *sm;
-
- if((sd = (sb=sbp)->sbcur) == 0
- || (sm = sd->sdmem) == 0)
- return;
- sd->sdflags |= SD_LOCK;
- sb->sbiop = sm->smaddr + sb->sboff;
- if(sb->sbrleft = sm->smuse - sb->sboff)
- sb->sbwleft = 0;
- else sb->sbwleft = sm->smlen - sm->smuse;
-}
-\f
-
-/* SBX_SCPY(sd,sdl) - Copies given sbstring, returns ptr to new sbstring.
- * Only goes as far as sdl (last copied blk); 0 for entire sbstring.
- */
-struct sdblk *
-sbx_scpy(sdp,sdlast)
-struct sdblk *sdp, *sdlast;
-{ register struct sdblk *sd, *sd2, *sdn;
- struct sdblk *sdr;
-
- if((sd = sdp) == 0) return((struct sdblk *)0);
- sdn = 0;
- do {
- sd->sdflags |= SD_LCK2;
- sd2 = sbx_sdcpy(sd);
- if(sd2->slback = sdn)
- { sdn->slforw = sd2;
- sdn->sdflags &= ~SD_LOCKS;
- }
- else sdr = sd2; /* Save 1st */
- sdn = sd2;
- sd->sdflags &= ~SD_LCK2;
- } while(sd != sdlast && (sd = sd->slforw));
- sd2->slforw = 0;
- sd2->sdflags &= ~SD_LOCKS;
- return(sdr);
-}
-
-
-/* SBX_SDCPY(sd) - Copies given sdblk, returns ptr to new blk.
- * Does not set locks, assumes caller does this (which it MUST,
- * to avoid compaction lossage!)
- */
-
-struct sdblk *
-sbx_sdcpy(sdp)
-struct sdblk *sdp;
-{ register struct sdblk *sd, *sd2;
- register struct smblk *sm, *sm2;
-
- if((sd = sdp) == 0) return((struct sdblk *)0);
- sd2 = sbx_ndget(); /* Get a free sdblk */
- bcopy((SBMA)sd, (SBMA)sd2, sizeof(struct sdblk)); /* Copy sdblk data */
- sd2->slforw = 0; /* Don't let it think it's on a list */
- sd2->slback = 0;
- if(sd2->sdfile) /* If has disk copy, */
- { sd->sdforw = sd2; /* Fix phys list ptrs */
- sd2->sdback = sd;
- if(sd2->sdforw)
- sd2->sdforw->sdback = sd2;
- }
- if(sm = sd2->sdmem) /* If has in-core copy, try to */
- { if(sm2 = sbm_mget(sm->smuse,sm->smuse)) /* get mem for it */
- { bcopy(sm->smaddr,sm2->smaddr,sm->smuse);
- sm2->smuse = sm->smuse;
- sd2->sdmem = sm2; /* Point new sd to copy */
- }
- else /* Can't get mem... */
- { if(sd2->sdflags&SD_MOD)
- sbx_aout(sd2,1); /* Swap out the blk */
- sd2->sdmem = 0; /* Don't have incore copy */
- }
- }
- return(sd2);
-}
-\f
-/* SBX_XCIS(sbp,coff,&sdp2,adot) - Internal routine to excise a sbstring,
- * defined as everything between current location and given offset.
- * SD to first sdblk is returned (0 if error)
- * SD2 (address passed as 3rd arg) is set to last sdblk.
- * Both are locked with LCK2 to ensure that pointers are valid.
- * The current location at time of call is also returned via adot.
- */
-struct sdblk *
-sbx_xcis(sbp,num,asd2,adot)
-SBBUF *sbp;
-chroff num, *adot;
-struct sdblk **asd2;
-{ register SBBUF *sb;
- register struct sdblk *sd, *sd2;
- int dirb;
-
- if((sb = sbp) == 0) return((struct sdblk *)0);
- dirb = 0; /* Delete forward */
- if(num == 0) return((struct sdblk *)0); /* Delete nothing */
- if(num < 0) dirb++; /* Delete backward */
-
- if((sd = (struct sdblk *)
- sbx_ready(sb, (dirb ? SK_DELB : SK_DELF))) == 0)
- return((struct sdblk *)0); /* Maybe nothing there */
- sd->sdflags |= SD_LCK2; /* Lock up returned SD */
- *adot = sb->sbdot; /* Save current location */
- sb->sboff += num; /* Move to other end of range */
-
- if((sd2 = (struct sdblk *)
- sbx_ready(sb,(dirb ? SK_DELF : SK_DELB))) == 0)
- { sd->sdflags &= ~SD_LCK2; /* This shd never happen if */
- return( /* we got this far, but... */
- (struct sdblk *)sbx_err(0,"KILLN SD2 failed"));
- }
- sd2->sdflags |= SD_LCK2; /* Lock up other end of stuff */
-
- /* SD and SD2 now delimit bounds of stuff to excise.
- * Now do direction dependent fixups
- */
- if(dirb)
- { /* Backward, current sbdot is ok but must get SD/SD2
- * into first/last order. Also, due to nature of block
- * splitups, a backward delete within single block will leave
- * SD actually pointing at predecessor block.
- */
- if(sd->slforw == sd2) /* If SD became pred, fix things. */
- { sd->sdflags &= ~SD_LCK2; /* Oops, unlock! */
- sd = sd2;
- }
- else /* Just need to swap SD, SD2 ptrs. */
- { /* Goddamit why doesn't C have an */
- /* exchange operator??? */
- *asd2 = sd;
- return(sd2);
- }
- }
- *asd2 = sd2;
- return(sd);
-}
-\f
-/* SBX_SPLIT(sd,chroff) - Splits block SD at point CHROFF (offset from
- * start of block). SD remains valid; it is left locked.
- * The smblk is split too, if one exists, and SMUSE adjusted.
- * If offset 0, or equal to block length, the 1st or 2nd SD respectively
- * will not have a smblk and its sdlen will be 0.
- * (Note that if a smblk exists, a zero sdlen doesn't indicate much)
- */
-struct sdblk *
-sbx_split(sdp, coff)
-struct sdblk *sdp;
-chroff coff;
-{ register struct sdblk *sd, *sdf, *sdx;
-
- if((sd=sdp) == 0)
- return((struct sdblk *)0);
- sd->sdflags |= SD_LOCK;
- if(sd->sdflags&SD_MOD) /* If block has been munged, */
- sbx_npdel(sd); /* Flush from phys list now. */
- sdf = sbx_ndget(); /* Get a sdblk node */
- bcopy((SBMA)sd, (SBMA)sdf, (sizeof (struct sdblk))); /* Copy node */
- /* Note that the flags are copied, so both sdblks are locked and
- * safe from possible GC compaction during call to sbx_msplit...
- */
- if(coff == 0) /* If offset was 0, */
- { /* then 1st SD becomes null */
- if(sdf->sdfile) /* Fix up phys links here */
- { if(sdx = sdf->sdback)
- sdx->sdforw = sdf;
- else sdf->sdfile->sfptr1 = sdf;
- if(sdx = sdf->sdforw)
- sdx->sdback = sdf;
- }
- sdx = sd;
- goto nulsdx;
- }
- else if(sd->sdmem)
- if(coff >= sd->sdmem->smuse)
- goto nulsdf;
- else sdf->sdmem = sbx_msplit(sd->sdmem, (SBMO)coff);
- else if(coff >= sd->sdlen)
-nulsdf: { sdx = sdf;
-nulsdx: sdx->sdforw = 0;
- sdx->sdback = 0;
- sdx->sdmem = 0;
- sdx->sdfile = 0;
- sdx->sdlen = 0;
- sdx->sdaddr = 0;
- goto nulskp;
- }
- if(sd->sdfile)
- { sdf->sdlen -= coff; /* Set size of remainder */
- sdf->sdaddr += coff; /* and address */
- sd->sdlen = coff; /* Set size of 1st part */
-
- /* Link 2nd block into proper place in physical sequence.
- * 1st block is already in right place. Search forward until
- * find a block with same or higher disk address, and insert
- * in front of it. If sdlen is zero, just flush the links,
- * which is OK since the 1st block is what's pointed to anyway.
- */
- if(sdf->sdlen > 0)
- { while((sdx = sd->sdforw) /* Find place to insert */
- && sdf->sdaddr > sdx->sdaddr)
- sd = sdx;
- sdf->sdback = sd; /* Link following sd. */
- if(sdf->sdforw = sd->sdforw)
- sdf->sdforw->sdback = sdf;
- sd->sdforw = sdf;
- sd = sdp; /* Restore pointer */
- }
- else
- { sdf->sdforw = 0;
- sdf->sdback = 0;
- sdf->sdfile = 0; /* Say no disk */
- }
- }
-
-nulskp: sdf->slback = sd; /* Link in logical sequence */
- if(sd->slforw)
- sd->slforw->slback = sdf;
- sd->slforw = sdf;
-
- sdf->sdflags &= ~SD_LOCKS; /* Unlock 2nd but not 1st */
- return(sd); /* Note sd, not sdf */
-}
-
-/* SBX_MSPLIT - Like sbm_split but never fails, and sets
- * SMUSE values appropriately
- */
-struct smblk *
-sbx_msplit(smp, size)
-struct smblk *smp;
-SBMO size;
-{ register struct smblk *sm, *smx;
- register int lev;
-
- lev = 0;
- while((smx = sbm_split((sm = smp), size)) == 0)
- sbx_comp(SB_BUFSIZ,lev++); /* Need to get some smblk nodes */
- if(sm->smlen >= sm->smuse) /* Split across used portion? */
- smx->smuse = 0; /* Nope, new blk is all free */
- else
- { smx->smuse = sm->smuse - sm->smlen;
- sm->smuse = sm->smlen;
- }
- return(smx);
-}
-\f
-/* SBX_NDEL - flush a SD and associated SM. Fixes up logical
- * and physical links properly. Returns ptr to next logical SD.
- * NOTE: if sd->slback does not exist, the returned SD is your
- * only hold on the list, since the SD gets flushed anyway!
- */
-struct sdblk *
-sbx_ndel(sdp)
-struct sdblk *sdp;
-{ register struct sdblk *sd, *sdx;
- register struct smblk *sm;
-
- sd = sdp;
- if(sm = sd->sdmem) /* If smblk exists, */
- { sbm_mfree(sm); /* flush it. */
- sd->sdmem = 0;
- }
- if(sdx = sd->slback)
- sdx->slforw = sd->slforw;
- if(sd->slforw)
- sd->slforw->slback = sdx; /* May be zero */
-
- /* Logical links done, now hack phys links */
- if(sd->sdfile) /* Have phys links? */
- sbx_npdel(sd); /* Yes, flush from phys list */
-
- sdx = sd->slforw;
- sbx_ndfre(sd);
- return(sdx);
-}
-
-sbx_npdel(sdp)
-struct sdblk *sdp;
-{ register struct sdblk *sd, *sdx;
- register struct sbfile *sf;
-
- if((sf = (sd=sdp)->sdfile) == 0)
- return;
- if(sdx = sd->sdback) /* Start of disk file? */
- sdx->sdforw = sd->sdforw;
- else
- sf->sfptr1 = sd->sdforw;
- if(sdx = sd->sdforw)
- sdx->sdback = sd->sdback;
- sd->sdfile = 0;
- sd->sdlen = 0;
-}
-
-\f
-struct sdblk *sbx_nfl; /* Pointer to sdblk node freelist */
-
-struct sdblk *
-sbx_ndget() /* Like sbm_nget but never fails! */
-{ register struct sdblk *sd;
- register int lev;
-
- lev = 0;
- while((sd = sbx_nfl) == 0 /* Get a node */
- /* If fail, make more */
- && (sd = sbm_nmak((sizeof (struct sdblk)),SM_DNODS)) == 0)
- /* If still fail, try GC */
- sbx_comp(sizeof(struct sdblk)*SM_DNODS,lev++);
-
- sbx_nfl = sd->slforw; /* Take it off freelist */
- sd->sdflags = SD_NID;
- return(sd); /* Return ptr to it */
-}
-
-sbx_ndfre(sdp)
-struct sdblk *sdp;
-{ register struct sdblk *sd;
- (sd = sdp)->sdflags = 0;
- sd->slforw = sbx_nfl;
- sbx_nfl = sd;
-}
-
-SBMA
-sbx_malloc(size)
-unsigned size;
-{
- register int lev;
- register SBMA res;
-
- lev = 0;
- while((res = (SBMA)malloc(size)) == 0)
- sbx_comp(size,lev++);
- return(res);
-}
-
-struct smblk *
-sbx_mget(cmin,cmax) /* like sbm_mget but never fails! */
-SBMO cmin, cmax;
-{ register struct smblk *sm;
- register int lev, csiz;
-
- lev = 0;
- csiz = cmax;
- for(;;)
- { if(sm = sbm_mget(csiz,cmax))
- return(sm); /* Won right off... */
- sbx_comp(csiz,lev++); /* Barf, invoke GC */
- if(sm = sbm_mget(csiz,cmax)) /* Then try again */
- return(sm);
- if((csiz >>= 1) < cmin) /* If still short, reduce */
- csiz = cmin; /* request down to min */
- }
-}
-\f
-chroff sbv_taddr; /* Disk addr of place to write into (set by TSET) */
-struct sdblk *sbv_tsd; /* SD that disk addr comes after (set by TSET) */
-
-#define sbx_qlk(sd) (sd->sdflags&SD_LOCKS)
-
-#if 0
- This is the compaction routine, which is the key to the
-entire scheme. Paging text to and from disk is trivial, but the
-ability to merge blocks is the important thing since it allows
-flushing the pointer information as well as the actual text! This
-eliminates fragmentation as a fatal problem.
- There are a variety of ways that storage can be reclaimed:
-
-- "pure" in-core blocks can be flushed instantly.
-- "impure" incore blocks can be written to tempfile storage and flushed.
-- The SM node freelist can be compacted so as to flush memory which is
- used for nothing but holding free nodes.
-- The SD node freelist can be compacted, ditto.
-- SBBUFs can be compacted, by:
- - Merging logically & physically adjacent on-disk pieces
- - merging logically & physically adjacent in-core pieces
- - merging logically adjacent in-core pieces
- - merging logically adjacent disk pieces, by reading in
- and then writing out to tempfile storage.
- Worst case would reduce whole sbstr to single tempfile block.
-
-Problems:
- What is "optimal" algorithm for typical usage?
- Must go over all code to make sure right things get locked
- and unlocked to avoid having rug pulled out from under.
- Could have optional "registration table" for sbstruc; if exist
- in table, can check during GC. If find one, can first
- do sbx_smdisc and then repoint sbcur to 1st block,
- with sbdot of 0 and sboff of sb_tell(). This allows
- reducing whole thing to one block even tho "locked".
- Never touch stuff locked with SD_LCK2, though.
- Also may need way to protect the sbstr SD actually being
- pointed to by current sbx routine processing.
- Could have count of # nodes free for SM and SD; don''t GC
- unless # is some number greater than size of a node block!
- Have different levels of compaction; pass level # down thru calls
- so as to invoke progressively sterner compaction measures.
- Can invoke sbx_comp with any particular level!
- Must have list somewhere of SBBUFs? or maybe OK to scan core
- for SM_DNODS, then scan sdblks?
- Screw: could happen that stuff gets flushed (cuz pure) or even
- written out to tempfile, and then we have to read it back
- in so as to compact more stuff into tempfile... how to avoid?
- If pure stuff small and next to impure stuff, merge?
- Some calls just want to get another free node and don''t need
- new core. How to indicate this? How to decide between
- freeing up used nodes, and creating new node freelist?
-#endif /*COMMENT*/
-/* Compact stuff.
- * General algorithm for getting storage is:
- * 1) allocate from freelist if enough there
- * 2) find unlocked pure smblk to free up
- * 3) find unlocked impure smblks, write out.
- * 4) Compact stuff by reducing # of sdblks. This is key to scheme!
- * Otherwise fragmentation will kill program.
- * Maybe put age cnt in each sbstr? Bump global and set cntr each time
- * sbstr gets major hacking (not just getc/putc).
- */
-extern struct smblk *sbm_list;
-sbx_comp(cmin,lev)
-int cmin, lev;
-{ int sbx_sdgc();
-
- if(lev > 100) /* If program has no way to handle this, */
- abort(); /* then simply blow up. */
- if(lev > 10) /* Too many iterations? Try to warn. */
- return(sbx_err(0,"GC loop, cannot free block of size %d",
- cmin));
-
- /* Step thru core hunting for SD node blocks */
- sbm_nfor(SM_DNODS,sizeof(struct sdblk),sbx_sdgc,lev);
-}
-
-/* Do GC stuff on a sdblk. Guaranteed to exist, but may be locked */
-sbx_sdgc(sdp,lev)
-struct sdblk *sdp;
-int lev;
-{ register struct sdblk *sd, *sdf;
- register struct smblk *sm;
- struct smblk *smf, *sbm_exp ();
- SBMO more;
-
- sd = sdp;
- if(sbx_qlk(sd)) return(0);
- sm = sd->sdmem;
- sdf = sd->slforw;
- if (lev < 4) goto lev3;
-
- /* Level 4 - write out everything possible */
- /* Back up to start of sbstr */
- while((sdf = sd->slback) && !sbx_qlk(sdf))
- sd = sdf;
- if((sdf = sd->slforw) == 0 /* If only 1 blk, ensure on disk */
- || sbx_qlk(sdf))
- { if(sm = sd->sdmem)
- { if(sd->sdflags&SD_MOD) /* If impure, */
- sbx_aout(sd, 1); /* swap out the SD */
- sbm_mfree(sm);
- sd->sdmem = 0;
- }
- return(0);
- }
- /* At least two blocks in string. Set up for flushout. */
- sbx_aout(sd, 0); /* Swapout as much of sbstring as possible */
- return(0);
-
-lev3: /* Level 3 - write out more */
-lev2: /* Level 2 - write out all impure & small pure */
-lev1: if(lev >= 1) /* Level 1 - merge small impure & small pure */
- { if(!sm || !sdf) return(0);
- while(((smf = sdf->sdmem) && !(sdf->sdflags&SD_LOCKS)
- && (more = smf->smuse + sm->smuse) < SB_BUFSIZ) )
- { if(sm->smforw != smf
- && more > sm->smlen) /* If need more rm */
- { sm = sbm_exp(sm,more); /* Get it */
- if(!sm) return(0); /* If none, stop */
- sd->sdmem = sm;
- }
- bcopy(smf->smaddr,
- sm->smaddr + sm->smuse, smf->smuse);
- sm->smuse = more;
- if(sm->smforw == smf)
- { sdf->sdmem = 0;
- sbm_mmrg(sm); /* Merge */
- if(sm->smlen > more+SB_SLOP)
- sbm_mfree(sbm_split(sm, more));
- /* Guaranteed to win since mmrg
- * just freed a mem node */
- }
- sd->sdflags |= SD_MOD;
- if(sdf = sbx_ndel(sdf))
- continue;
- return(0);
- }
- }
-
- if(lev <= 0) /* Level 0 - free up large pure blocks */
- /* Also merge blocks which are adjacent on disk */
- { if(sm)
- { if(sm->smuse == 0)
- sd->sdlen = 0;
- else if((sd->sdflags&SD_MOD) == 0
- && sm->smuse > 64)
- { sbm_mfree(sm);
- sd->sdmem = 0;
- goto lev0adj;
- }
- else goto lev0adj;
- }
-
- if(sd->sdlen == 0 /* Free zero blocks */
- && sd->slback) /* Make sure don't lose list */
- { sbx_ndel(sd);
- if((sd = sdf) == 0)
- return(0);
- sdf = sd->slforw;
- }
- lev0adj: /* Merge blocks if adjacent on disk */
- /* This is common after reading thru large chunks
- * of a file but not modifying it much.
- */
- if((sd->sdflags&SD_MOD) == 0 /* Pure */
- && sdf && (sdf->sdflags&(SD_LOCKS|SD_MOD)) == 0
- && sd->sdfile && (sd->sdfile == sdf->sdfile)
- && (sd->sdaddr + sd->sdlen) == sdf->sdaddr )
- { sd->sdlen += sdf->sdlen;
- sbx_ndel(sdf); /* Flush 2nd */
- if(sm = sd->sdmem)
- { sbm_mfree(sm);
- sd->sdmem = 0;
- }
- }
- return(0);
- }
- return(0);
-}
-\f
-/* SBX_AOUT - output ALL of a hackable sbstring starting at given sdblk.
- * Note that code is careful to do things so that an abort at any
- * time (e.g. write error) will still leave sbstring in valid state.
- * Flag value:
- * 0 - Writes out as many unlocked sdblks as possible, and merges
- * so that resulting sdblk (same one pointed to by arg)
- * incorporates all stuff written out.
- * 1 - Writes out single sdblk indicated, whether unlocked or not.
- * Doesn't free mem or merge anything; does update physlist
- * and flags.
- * 2 - Writes out all sdblks to specified FD/offset, no mods at all,
- * not even to physlist or flags. Good for saving files
- * when something seems wrong. (How to pass fd/off args?)
- * (offset arg not implemented, no need yet; 0 assumed)
- * Returns 0 if successful, else UNIX system call error number.
- */
-
-sbx_aout(sdp,flag,fd)
-struct sdblk *sdp;
-int flag, fd;
-{ register struct sdblk *sd;
- register struct smblk *sm;
- register int cnt;
- int ifd, ofd, skflg, rem;
- chroff inlen;
- extern SBMA sbm_lowaddr; /* Need this from SBM for rndrem */
- char buf[SB_BUFSIZ+16]; /* Get buffer space from stack! */
- /* Allow extra for word-align reads. */
- /* This should be +WDSIZE, but some */
- /* C compilers (eg XENIX) can't handle */
- /* "sizeof" arith in allocation stmts! */
-
- /* This flag and the two ptrs below are needed because UNIX
- * maintains only one I/O ptr per open file, and we can sometimes
- * be reading from/writing to the swapout file at same time.
- * Using DUP() to get a new FD (to avoid seeking back and forth)
- * won't help since both FD's will use the same I/O ptr!!!
- * Lastly, can't depend on returned value of LSEEK to push/pop
- * ptr, since V6 systems don't implement tell() or lseek() directly.
- * So we have to do it by hand...
- */
- int botchflg;
- chroff outptr, inptr;
-
- if((sd = sdp)==0) return;
- ofd = sbv_tf.sffd; /* Default output FD */
- if(flag==0)
- { sbx_tset(sbx_qlen(sd),0);/* Find place for whole string */
- outptr = sbv_taddr; /* We'll have to update wrt ptr */
- }
- else if (flag==1) /* Single SD block, so it's reasonable to
- * try aligning the output with the input. */
- { if(sm = sd->sdmem)
- { cnt = rndrem(sm->smaddr - sbm_lowaddr);
- sbx_tset((chroff)(sm->smuse),cnt);
- }
- else
- { cnt = rndrem(sd->sdaddr);
- sbx_tset(sd->sdlen, cnt);
- }
- outptr = sbv_taddr; /* We'll have to update wrt ptr */
- }
- else /* Outputting a whole sbstring to a file */
- { ofd = fd;
- outptr = 0;
- }
-
- for(; sd;)
- { if(flag==0 && sbx_qlk(sd))
- break; /* Stop when hit locked sdblk */
- if(sm = sd->sdmem)
- { if(cnt = sm->smuse)
- if(write(ofd, sm->smaddr, cnt) != cnt)
- return(sbx_err(errno,"Swapout wrt err"));
- outptr += cnt;
- if(flag==0)
- { sd->sdmem = 0; /* Flush the mem used */
- sbm_mfree(sm);
- }
- inlen = cnt;
- }
- else if(inlen = sd->sdlen)
- { if(sd->sdfile == 0)
- return(sbx_err(errno,"Sdfile 0, SD %o",sd));
- /* Foo on UNIX */
- botchflg = ((ifd = sd->sdfile->sffd) == ofd) ? 1 : 0;
- skflg = 1; /* Always seek first time */
- inptr = sd->sdaddr;
- /* Efficiency hack - set up for first read so that
- * transfer is word-aligned and terminates at end
- * of a disk block.
- */
- rem = rndrem(inptr); /* Get alignment */
- cnt = SB_BUFSIZ - (int)(inptr%SB_BUFSIZ);
- while(inlen > 0)
- {
- if(inlen < cnt) cnt = inlen;
- if(!sbx_rdf(ifd, buf+rem, cnt, skflg, inptr))
- return(sbx_err(errno,"Swapout err, SD %o",sd));
- /* Further seeks depend on botch setting */
- if(skflg = botchflg)
- { if(lseek(ofd,outptr,0) < 0)
- return(sbx_err(errno,
- "Swapout sk err"));
- inptr += cnt;
- }
- if(write(ofd, buf+rem, cnt) != cnt)
- return(sbx_err(errno,
- "Swapout wrt err"));
- outptr += cnt;
- inlen -= cnt;
- cnt = SB_BUFSIZ; /* Now can use full blocks */
- rem = 0; /* Aligned nicely, too! */
- }
- inlen = sd->sdlen;
- }
-
- /* Text written out, now merge block in */
- if(flag == 2) /* No merge if saving file */
- goto donxt;
- if(sd != sdp) /* First block? */
- { sdp->sdlen += inlen; /* No, simple merge */
- sd = sbx_ndel(sd); /* Flush, get next */
- continue;
- }
-
- /* Handle 1st block specially */
- if(sd->sdfile /* Unlink from phys list */
- && sd != sbv_tsd) /* Don't unlink if self */
- sbx_npdel(sd);
- sd->sdlen = inlen;
- sd->sdfile = &sbv_tf;
- sd->sdaddr = sbv_taddr; /* Set from sbx_tset val */
- sd->sdflags &= ~SD_MOD; /* On disk, no longer modified */
-
- /* Now insert into phys list at specified place */
- if(sd == sbv_tsd) /* If already same place */
- goto next; /* Skip linkin. */
- if(sd->sdback = sbv_tsd)
- { sd->sdforw = sbv_tsd->sdforw;
- sd->sdback->sdforw = sd;
- }
- else
- { sd->sdforw = sbv_tf.sfptr1;
- sbv_tf.sfptr1 = sd;
- }
- if(sd->sdforw)
- sd->sdforw->sdback = sd;
-
- next: if(flag==1) /* If only doing 1 sdblk, */
- break; /* stop here. */
- donxt: sd = sd->slforw; /* Done with 1st, get next */
- }
- return(0); /* Win return, no errors */
-}
-
-/* Returns hackable length of a sbstring (ends at EOF or locked block) */
-chroff
-sbx_qlen(sdp)
-struct sdblk *sdp;
-{ register struct sdblk *sd;
- register struct smblk *sm;
- chroff len;
-
- len = 0;
- for(sd = sdp; sd && !sbx_qlk(sd); sd = sd->slforw)
- if(sm = sd->sdmem)
- len += (chroff)sm->smuse;
- else len += sd->sdlen;
- return(len);
-}
-
-\f
-/* SBX_TSET - finds a place on temp swapout file big enough to hold
- * given # of chars. Sets SBV_TADDR to that location, as well
- * as seeking to it so the next write call will output there.
- * This location is guaranteed to have the requested
- * byte alignment (0 = word-aligned).
- */
-sbx_tset(loff, align)
-chroff loff;
-int align;
-{ register int fd;
-
- if(sbv_tf.sffd <= 0)
- { /* Must open the temp file! */
-/* Temporary file mechanism is system-dependent. Eventually this
-** will probably require inclusion of a true c-env header file; for the
-** time being, we can cheat a little by checking O_T20_WILD, which will
-** be defined by <sys/file.h> on TOPS-20. Otherwise, we assume we are
-** on a real Unix.
-*/
-#ifdef O_T20_WILD
- extern char *tmpnam(); /* Use ANSI function */
- fd = open(tmpnam((char *)NULL),
- O_RDWR | O_CREAT | O_TRUNC | O_BINARY);
- if(fd < 0)
- return(sbx_err(0,"Swapout creat err"));
-#else /* Real Unix */
- static char fcp[] = "/tmp/sbd.XXXXXX";
- if((fd = creat(mktemp(fcp),0600)) < 0)
- return(sbx_err(0,"Swapout creat err"));
- /* Must re-open so that we can both read and write to it */
- close(fd);
- if((fd = open(fcp,2)) < 0)
- return(sbx_err(0,"Swapout open err"));
- unlink(fcp); /* Set so it vanishes when we do */
-#endif
-
- sbv_tf.sffd = fd; /* Initialize the sbfile struct */
- sbv_tf.sfptr1 = 0;
- sbv_ftab[fd] = &sbv_tf; /* Record in table of all sbfiles */
- sbv_taddr = 0; /* "Return" this value */
- return; /* Ignore alignment for now */
- }
- sbv_tsd = sbx_ffnd(&sbv_tf, loff+align, &sbv_taddr);
- sbv_taddr += align;
- if(lseek(sbv_tf.sffd, sbv_taddr, 0) < 0)
- return(sbx_err(0,"Swapout seek err: (%d,%ld,0) %d %s",
- sbv_tf.sffd, sbv_taddr, errno, strerror(errno)));
-
-}
-
-/* SBX_FFND - searches disk list of given file for free space of
- * at least size chars. Note that list must be sorted by ascending
- * disk addrs in order for this to work! If sdaddrs are only
- * changed in SBX_SPLIT this will be true.
- * Sets "aloc" to disk address for writing (this is guaranteed to
- * be word-aligned, for efficiency), and returns SD ptr to
- * block which this addr should follow in the physical list. If ptr
- * is 0, it means addr should be 1st thing in list.
- */
-struct sdblk *
-sbx_ffnd(sfp, size, aloc)
-SBFILE *sfp;
-chroff size, *aloc;
-{ register struct sdblk *sd, *sds, *sdl;
- chroff cur;
-
- cur = 0;
- sds = 0;
- sd = sfp->sfptr1;
-redo: for(; sd ; sd = (sds=sd)->sdforw)
- { if(cur < sd->sdaddr) /* Gap seen? */
- { if(size <= (sd->sdaddr - cur)) /* Yes, big enuf? */
- break; /* Yup! */
- } /* No, bump. */
- else if(cur >=(sd->sdaddr + sd->sdlen)) /* No gap but chk */
- continue; /* No overlap, ok */
- /* Bump to next possible gap. */
- cur = sd->sdaddr + sd->sdlen;
- cur = (long)rndup(cur); /* Round up to word boundary! */
- }
- *aloc = cur; /* Return winning addr */
-
- /* Perform verification check -- make sure this really is OK
- * and complain if not. If this never blows up, eventually can
- * take the check out.
- */
- sdl = sd;
- for(sd = sfp->sfptr1; sd; sd = sd->sdforw)
- { if(cur < sd->sdaddr)
- { if(size <= (sd->sdaddr - cur))
- continue;
- }
- else if(cur >= (sd->sdaddr + sd->sdlen))
- continue;
-
- sbx_err(0,"FFND blew it, but recovered. SD %o siz %ld",
- sd, size);
- sd = (sds = sdl)->sdforw;
- goto redo;
- }
-
-
- return(sds); /* Return ptr to block this addr follows */
-}
-
-sbx_rdf(fd,addr,cnt,skflg,loc)
-register int fd;
-char *addr;
-int skflg;
-chroff loc;
-{ register int rres, eres;
- long lres;
- char *errtyp, *ftyp;
- chroff curlen;
-
- errno = 0;
- if(skflg && (lres = lseek(fd, (long)loc, 0)) == -1)
- { errtyp = "Sk err";
- goto errhan;
- }
- if((rres = read(fd, addr, cnt)) != cnt)
- { lres = rres;
- errtyp = "Rd err";
- goto errhan;
- }
- return(rres);
-errhan: /* Handle read or seek error */
- eres = errno;
- if(fd == sbv_tf.sffd) /* See if dealing with swapout file */
- { ftyp = "(swap)";
- curlen = 0;
- }
- else { /* No, normal buffer file. */
- ftyp = "";
- curlen = sbx_fdlen(fd);
- if(sbv_ftab[fd] &&
- (curlen != sbv_ftab[fd]->sflen)) /* File changed? */
- if(sbx_rugpull(fd)) /* Yes, handle special case */
- return(cnt); /* Allow "win" return */
- }
- sbx_err(0,"%s %d:%s, %ld:(%d%s,%o,%d)=%ld (fl %ld)",
- errtyp, eres, strerror(eres),
- loc, fd, ftyp, addr, cnt, lres,
- curlen);
- return(0);
-}
-
-/* SBX_RUGPULL(fd) - Special routine called when package detects that
- * the file indicated by the fd has changed since its original
- * opening. This can happen when a file is over-written by some
- * other program (ED, for example).
- * This means that all sdblks which reference this fd
- * are probably bad. Pass special error back up to the calling
- * program to give it a chance at doing something.
- * Extra credit: scan all sdblks and unpurify all which point to this
- * file, so as to protect everything we still remember about it.
- * Otherwise a GC could flush pure in-core portions.
- */
-sbx_rugpull(fd) /* FD already known to have entry in sbv_ftab */
-register int fd;
-{ int sbx_unpur();
-
- /* First scan all sdblks to save what we still have. */
- /* This does NOT remove the sdfile pointer, so we can still
- * find blocks that are affected. */
- sbm_nfor(SM_DNODS, sizeof(struct sdblk), sbx_unpur, sbv_ftab[fd]);
-
- if((int)sbv_debug == 1 || !sbv_debug)
- return(0); /* Nothing else we can do */
- return((*sbv_debug)(2,(int *)0,"",fd)); /* Let caller handle it */
-}
-sbx_unpur(sd, sf) /* Auxiliary routine for SBX_RUGPULL */
-register struct sdblk *sd;
-register struct sbfile *sf;
-{ if(sd->sdfile == sf /* If sdblk belongs to affected file */
- && sd->sdmem) /* and has in-core version of text, */
- sd->sdflags |= SD_MOD; /* then ensure core version is used */
-}
-
-sbx_err(val,str,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)
-char *str;
-{ int *sptr;
-
- sptr = (int *) &sptr; /* Point to self on stack */
- sptr += 5; /* Point to return addr */
- if((int)sbv_debug == 1)
- { abort();
- }
- if(sbv_debug)
- (*sbv_debug)(1,*sptr,str,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12);
- return(val);
-}
+++ /dev/null
-/* VALLOC - Aligned memory allocator
- * Emulation of the 4.2BSD library routine of the same name.
- * Copyright 1985 by Ken Harrenstien, SRI International
- * This software is quasi-public; it may be used freely with
- * like software, but may NOT be sold or made part of licensed
- * products without permission of the author. In all cases
- * the source code and any modifications thereto must remain
- * available to any user.
- *
- * This is part of the SB library package.
- * Any software using the SB library must likewise be made
- * quasi-public, with freely available sources.
- */
-
-#include "sb.h"
-
-char *
-valloc(size)
-unsigned size;
-{ register int pagmsk;
- register SBMO i;
- register struct smblk *sm, *smr;
- struct smblk *sbm_mget(), *sbm_split();
-
- pagmsk = getpagesize() - 1; /* Get page size in bytes, less 1 */
- if(!(sm = sbm_mget(size+pagmsk, size+pagmsk))) /* Get area big enuf */
- return(0);
- /* Now find # bytes prior to 1st page boundary.
- * This expression gives 0 if already at boundary, else #-1.
- */
- i = pagmsk - ((int)(sm->smaddr) & pagmsk);
- if(i) /* If need to split off preceding stuff, */
- { smr = sbm_split(sm, i+1); /* do so (note i adjusted) */
- sbm_mfree(sm); /* Release preceding mem */
- if(!(sm = smr)) return(0); /* If couldn't split, fail */
- }
- if(i = (sm->smlen - size)) /* See if any trailing stuff */
- { smr = sbm_split(sm, size); /* Yeah, split it off too */
- if(smr) sbm_mfree(smr); /* If couldn't split, excess OK. */
- }
- return((char *)(sm->smaddr));
-}
+++ /dev/null
-; This is the default user profile to emulate "mined" (MINIX editor),
-; as per Andy Tanenbaum.
-
-(keyallunbind)
-
-; Insert self
-(keybind A "Insert Self")
-(keybind B "Insert Self")
-(keybind C "Insert Self")
-(keybind D "Insert Self")
-(keybind E "Insert Self")
-(keybind F "Insert Self")
-(keybind G "Insert Self")
-(keybind H "Insert Self")
-(keybind I "Insert Self")
-(keybind J "Insert Self")
-(keybind K "Insert Self")
-(keybind L "Insert Self")
-(keybind M "Insert Self")
-(keybind N "Insert Self")
-(keybind O "Insert Self")
-(keybind P "Insert Self")
-(keybind Q "Insert Self")
-(keybind R "Insert Self")
-(keybind S "Insert Self")
-(keybind T "Insert Self")
-(keybind U "Insert Self")
-(keybind V "Insert Self")
-(keybind W "Insert Self")
-(keybind X "Insert Self")
-(keybind Y "Insert Self")
-(keybind Z "Insert Self")
-(keybind a "Insert Self")
-(keybind b "Insert Self")
-(keybind c "Insert Self")
-(keybind d "Insert Self")
-(keybind e "Insert Self")
-(keybind f "Insert Self")
-(keybind g "Insert Self")
-(keybind h "Insert Self")
-(keybind i "Insert Self")
-(keybind j "Insert Self")
-(keybind k "Insert Self")
-(keybind l "Insert Self")
-(keybind m "Insert Self")
-(keybind n "Insert Self")
-(keybind o "Insert Self")
-(keybind p "Insert Self")
-(keybind q "Insert Self")
-(keybind r "Insert Self")
-(keybind s "Insert Self")
-(keybind t "Insert Self")
-(keybind u "Insert Self")
-(keybind v "Insert Self")
-(keybind w "Insert Self")
-(keybind x "Insert Self")
-(keybind y "Insert Self")
-(keybind z "Insert Self")
-(keybind 0 "Insert Self")
-(keybind 1 "Insert Self")
-(keybind 2 "Insert Self")
-(keybind 3 "Insert Self")
-(keybind 4 "Insert Self")
-(keybind 5 "Insert Self")
-(keybind 6 "Insert Self")
-(keybind 7 "Insert Self")
-(keybind 8 "Insert Self")
-(keybind 9 "Insert Self")
-(keybind / "Insert Self")
-(keybind : "Insert Self")
-(keybind < "Insert Self")
-(keybind = "Insert Self")
-(keybind > "Insert Self")
-(keybind ? "Insert Self")
-(keybind @ "Insert Self")
-(keybind [ "Insert Self")
-(keybind ] "Insert Self")
-(keybind ^ "Insert Self")
-(keybind # "Insert Self")
-(keybind $ "Insert Self")
-(keybind % "Insert Self")
-(keybind & "Insert Self")
-(keybind ' "Insert Self")
-(keybind * "Insert Self")
-(keybind + "Insert Self")
-(keybind , "Insert Self")
-(keybind - "Insert Self")
-(keybind . "Insert Self")
-(keybind ! "Insert Self")
-(keybind " " "Insert Self")
-(keybind """" "Insert Self")
-(keybind "(" "Insert Self")
-(keybind ")" "Insert Self")
-(keybind ";" "Insert Self")
-(keybind "\" "Insert Self")
-(keybind _ "Insert Self")
-(keybind ` "Insert Self")
-(keybind { "Insert Self")
-(keybind | "Insert Self")
-(keybind } "Insert Self")
-(keybind ~ "Insert Self")
-
-; CTRL char
-(keybind ^A "Beginning of Line")
-(keybind ^B "Backward Word")
-(keybind ^C "Copy Region")
-(keybind ^D "Scroll Window Up")
-(keybind ^E "New Window")
-(keybind ^F "Forward Word")
-(keybind ^H "Backward Delete Character")
-(keybind ^I "Insert Self")
-; open
-(keybind ^K "Kill Region")
-(keybind ^L "Replace in Line")
-(keybind ^M "CRLF")
-(keybind ^N "Kill Word")
-(keybind ^O "Open Line")
-(keybind ^P "Backward Kill Word")
-(keybind ^Q "Write Last Kill")
-(keybind ^R "Replace String")
-(keybind ^S "Push to Inferior")
-(keybind ^T "Kill Line")
-(keybind ^U "Scroll Window Down")
-(keybind ^V "Find File")
-(keybind ^W "Save File")
-(keybind ^X "Prefix Extend")
-(keybind ^Y "Un-kill")
-(keybind ^Z "End of Line")
-(keybind "^\" "Quoted Insert")
-(keybind ^_ "Move to Window Bottom")
-(keybind ^^ "Set/Pop Mark")
-(keybind ^] "Goto Line")
-
-; ESC char
-(keybind ^[ "Prefix Meta")
-(keybind M-0 "Argument Digit")
-(keybind M-1 "Argument Digit")
-(keybind M-2 "Argument Digit")
-(keybind M-3 "Argument Digit")
-(keybind M-4 "Argument Digit")
-(keybind M-5 "Argument Digit")
-(keybind M-6 "Argument Digit")
-(keybind M-7 "Argument Digit")
-(keybind M-8 "Argument Digit")
-(keybind M-9 "Argument Digit")
-(keybind M-A "Append Next Kill")
-(keybind M-B "Select Buffer")
-(keybind M-C "Uppercase Word")
-(keybind M-E "Execute Kbd Macro")
-(keybind M-F "Find File")
-(keybind M-G "Insert File")
-(keybind M-H "Describe")
-(keybind M-I "Uppercase Initial")
-(keybind M-K "Kill Buffer")
-(keybind M-L "Lowercase Region")
-(keybind M-M "Mark Paragraph")
-(keybind M-N "Buffer Not Modified")
-(keybind M-O "Lowercase Word")
-(keybind M-P "Forward Paragraph")
-(keybind M-Q "Query Replace")
-(keybind M-R "Set Profile")
-(keybind M-S "Select Existing Buffer")
-(keybind M-T "Transpose Characters")
-(keybind M-U "Uppercase Region")
-(keybind M-W "Transpose Words")
-(keybind M-X "Return to Superior")
-(keybind M-Y "Un-kill Pop")
-(keybind M-Z "Incremental Search")
-(keybind M-^ "Exchange Point and Mark")
-(keybind M-* "View Kbd Macro")
-(keybind M-[ "Prefix Extend")
-(keybind M-] "Backward Paragraph")
-(keybind M-= "Delete Horizontal Space")
-(keybind M-| "Delete Blank Lines")
-(keybind "M-," "Move to Window Top")
-(keybind "M-;" "Indent for Comment")
-(keybind "M-." "Indent Relative")
-(keybind "M-/" "Start Kbd Macro")
-(keybind "M-\" "End Kbd Macro")
-
-
-; CTRL-X char
-(keybind X-1 "One Window")
-(keybind X-2 "Two Windows")
-(keybind X-A "Up Real Line")
-(keybind X-B "Down Real Line")
-(keybind X-C "Forward Character")
-(keybind X-D "Backward Character")
-(keybind X-G "List Buffers")
-(keybind X-H "Goto Beginning")
-(keybind X-L "Grow Window")
-(keybind X-N "Other Window")
-(keybind X-P "Shrink Window")
-(keybind X-S "Reverse String Search")
-(keybind X-T "String Search")
-(keybind X-U "Next Screen")
-(keybind X-V "Previous Screen")
-(keybind X-X "Return to Superior")
-(keybind X-Y "Goto End")
-
-(keybind X-^A "Up Real Line")
-(keybind X-^B "Down Real Line")
-(keybind X-^C "Forward Character")
-(keybind X-^D "Backward Character")
-(keybind X-^G "List Buffers")
-(keybind X-^H "Goto Beginning")
-(keybind X-^L "Grow Window")
-(keybind X-^N "Other Window")
-(keybind X-^P "Shrink Window")
-(keybind X-^S "Reverse String Search")
-(keybind X-^T "String Search")
-(keybind X-^U "Next Screen")
-(keybind X-^V "Previous Screen")
-(keybind X-^W "New Window")
-(keybind X-^X "Return to Superior")
-(keybind X-^Y "Goto End")
-
-
-(keybind DEL "Delete Character")
.fi
\fIEd\fR is provided for its sentimental value.
If you want a line-oriented editor, try \fIex\fR.
-If you want a good editor, use \fIelle\fR, \fIelvis\fR, or \fImined\fR.
+If you want a good editor, use \fIelvis\fR or \fImined\fR.
.SH "SEE ALSO"
.BR elvis (1),
-.BR elle (1x),
.BR mined (1x).
-MAN= awk.1x dis88.1x elle.1x elvis.1x kermit.1x \
+MAN= awk.1x dis88.1x elvis.1x kermit.1x \
macros.1x mined.1x
.include <bsd.man.mk>
+++ /dev/null
-.so mnx.mac
-.TH ELLE 1x
-.CD "elle \(en ELLE Looks Like Emacs"
-.SX "elle \fIfile\fR [\fIfile2\fR]"
-.FL "\fR(none)"
-.EY "elle file.c" "Start the editor"
-.PP
-\fIELLE\fR (ELLE Looks Like Emacs) is an Emacs clone for
-.MX .
-ELLE is not full Emacs but it has about 80 commands and is quite fast.
-.SP 0.5
-.SS "Key bindings"
-.SP 0.5
-.PP
-\fIMined\fR only has a small number of commands. All of them are either of
-the form CTRL-x or are on the numeric keypad. Emacs, in contrast, has so
-many commands, that not only are all the CTRL-x commands used up, but so
-are all the ESC x (escape followed by x; escape is not a shift character,
-like CTRL). Even this is not enough, so CTRL-X is used as a prefix for
-additional commands. Thus CTRL-X CTRL-L is a command, and so is CTRL-X K.
-Note that what is conventionally written as CTRL-X K really means CTRL-X k.
-In some contexts it is traditional to write CTRL-X as ^X.
-Please note that they mean the same thing.
-.PP
-As a result, many Emacs commands need three or four key strokes to
-execute. Some people think 3-4 key strokes is too many.
-For this reason, Emacs and ELLE allow users to assign their own key bindings.
-In ELLE this is done with \*(OQuser profiles.\*(CQ A user profile is a file listing
-which function is invoked by which key stroke. The user profile is then
-compiled by a program called ellec into binary form. When ELLE starts up
-it checks to see if a file .ellepro.b1 exists in $HOME. If it does, this
-file is read in and overrides the default bindings.
-.PP
-A user profile that simulates the \fImined\fR commands fairly
-well is provided.
-Its installation is described later. If you have never used Emacs,
-it is suggested that you use the \fImined\fR profile.
-If you normally use Emacs, then
-do not install the \fImined\fR profile. You can also make your own using
-\fIellec\fR.
-There is no Mock Lisp.
-.PP
-ELLE has a character-oriented view of the world, not a line oriented
-view, like \fIed\fR.
-It does not have magic characters for searching.
-However, you can use line feed in search patterns.
-For example, to find a line consisting of the three characters
-\*(OQfoo\*(CQ all by themselves on a line, using the mined
-bindings (see below), use the pattern: CTRL-\\ CTRL-J f o o CTRL-\\ CTRL-J.
-The CTRL-\ means to interpret the next character literally, in this case it
-is CTRL-J, which is line feed. You can also search for patterns involving
-multiple lines. For example, to find a line ending in an \*(OQx\*(CQ followed by a
-line beginning with a \*(OQy\*(CQ, use as pattern: x CTRL-\ CTRL-J y.
-.SS "Mined Key Bindings"
-.PP
-These are the key bindings if the binary user profile, \fI.ellepro.b1\fR,
-is installed in $HOME. The ESCAPE key followed by a number followed by a
-command causes that command to be executed \*(OQnumber\*(CQ times. This applies
-both to control characters and insertable characters. CTRL-X refers to a
-\*(OQcontrol character.\*(CQ ESC x refers to an escape character
-followed by x.
-In other words, ^X is a synonym for CTRL-X.
-^X Y refers to CTRL-X followed by y. To abort the current command and go
-back to the main loop of the editor, type CTRL-G, rather than CTRL-\\.
-.PP
-Only a few commands are of the form CTRL-X Y. All of these are also
-bound to CTRL-X CTRL-Y, so you can hold down CTRL and then hit X Y, or
-release control after the X, as you prefer.
-.PP
-The key bindings that are not listed should not be used.
-Some of them actually do things.
-For example, the ANSI escape codes ESC [ x are bound
-to ^X Y for a variety of y.
-.PP
-Some commands work on regions.
-A region is defined as the text between the most recently set mark
-and the cursor.
-.SP 0.5
-.SS "Mined Commands"
-.SP 0.5
-.PP
-If the \fImined\fR profile,
-.I .ellepro.b1
-is installed in your home directory, the following commands will work.
-.sp
-.in +1.75i
-.ta +1.25i
-.ti -1.5i
-\fBCURSOR MOTION\fR
-.ti -1.25i
-arrows Move the cursor in the indicated direction
-.ti -1.25i
-CTRL-A Move cursor to start of current line
-.ti -1.25i
-CTRL-Z Move cursor to end of current line
-.ti -1.25i
-CTRL-F Move cursor forward word
-.ti -1.25i
-CTRL-B Move cursor backward to start of previous word
-.sp
-.ti -1.5i
-\fBSCREEN MOTION\fR
-.ti -1.25i
-Home key Move to first character of the file
-.ti -1.25i
-End key Move to last character of the file
-.ti -1.25i
-PgUp key Scroll window up 22 lines (closer to start of the file)
-.ti -1.25i
-PgDn key Scroll window down 22 lines (closer to end of the file)
-.ti -1.25i
-CTRL-U Scroll window up 1 line
-.ti -1.25i
-CTRL-D Scroll window down 1 line
-.ti -1.25i
-ESC , Move to top of screen
-.ti -1.25i
-CTRL-_ Move to bottom of screen
-.sp
-.ti -1.5i
-\fBMODIFYING TEXT\fR
-.ti -1.25i
-DEL key Delete the character under the cursor
-.ti -1.25i
-Backsp Delete the character to left of the cursor
-.ti -1.25i
-CTRL-N Delete the next word
-.ti -1.25i
-CTRL-P Delete the previous word
-.ti -1.25i
-CTRL-T Delete tail of line (all characters from cursor to end of line)
-.ti -1.25i
-CTRL-O Open up the line (insert line feed and back up)
-.ti -1.25i
-ESC G Get and insert a file at the cursor position (CTRL-G in mined)
-.sp
-.ti -1.5i
-\fBREGIONS\fR
-.ti -1.25i
-CTRL-^ Set mark at current position for use with CTRL-C and CTRL-K
-.ti -1.25i
-CTRL-C Copy the text between the mark and the cursor into the buffer
-.ti -1.25i
-CTRL-K Delete text between mark and cursor; also copy it to the buffer
-.ti -1.25i
-CTRL-Y Yank contents of the buffer out and insert it at the cursor
-.sp
-.ti -1.5i
-\fBMISCELLANEOUS\fR
-.ti -1.25i
-numeric + Search forward (prompts for expression)
-.ti -1.25i
-numeric \(mi Search backward (prompts for expression)
-.ti -1.25i
-CTRL-] ESC n CTRL-[ goes to line n (slightly different syntax than mined)
-.ti -1.25i
-CTRL-R Global replace pattern with string (from cursor to end)
-.ti -1.25i
-CTRL-L Replace pattern with string within the current line only
-.ti -1.25i
-CTRL-W Write the edited file back to the disk
-.ti -1.25i
-CTRL-S Fork off a shell (use CTRL-D to get back to the editor)
-.ti -1.25i
-CTRL-G Abort whatever the editor was doing and wait for command (CTRL-\)
-.ti -1.25i
-CTRL-E Redraw screen with cursor line positioned in the middle
-.ti -1.25i
-CTRL-V Visit (edit) a new file
-.ti -1.25i
-CTRL-Q Write buffer to a file
-.ti -1.25i
-ESC X Exit the editor
-.SP 0.5
-.in -1.75i
-.SS "Non-Mined Commands"
-.LP
-.SP 0.5
-.in +1.75i
-.ta +1.25i
-.ti -1.5i
-\fBCURSOR MOTION\fR
-.ti -1.25i
-ESC P Forward paragraph (a paragraph is a line beginning with a dot)
-.ti -1.25i
-ESC ] Backward paragraph
-.ti -1.25i
-ESC . Indent this line as much as the previous one
-.sp
-.ti -1.5i
-\fBMODIFYING TEXT\fR
-.ti -1.25i
-CTRL-\\ Insert the next character (used for inserting control characters)
-.ti -1.25i
-ESC T Transpose characters
-.ti -1.25i
-ESC W Transpose words
-.ti -1.25i
-ESC = Delete white space (horizontal space)
-.ti -1.25i
-ESC | Delete blank lines (vertical space)
-.sp
-.ti -1.5i
-\fBREGIONS\fR
-.ti -1.25i
-ESC M Mark current paragraph
-.ti -1.25i
-ESC ^ Exchange cursor and mark
-.ti -1.25i
-ESC Y Yank back the next-to-the-last kill (CTRL-Y yanks the last one)
-.ti -1.25i
-ESC A Append next kill to kill buffer
-.sp
-.ti -1.5i
-\fBKEYBOARD MACROS\fR
-.ti -1.25i
-ESC / Start Keyboard Macro
-.ti -1.25i
-ESC \\ End Keyboard Macro
-.ti -1.25i
-ESC * View Keyboard Macro (the PrtSc key on the numeric pad is also a *)
-.ti -1.25i
-ESC E Execute Keyboard Macro
-.sp
-.ti -1.5i
-\fBWINDOW MANAGEMENT\fR
-.ti -1.25i
-^X 1 Enter one window mode
-.ti -1.25i
-^X 2 Enter two window mode
-.ti -1.25i
-^X L Make the current window larger
-.ti -1.25i
-^X P Make the window more petit/petite (Yes, Virginia, they are English)
-.ti -1.25i
-^X N Next window
-.ti -1.25i
-^X W New window
-.sp
-.ti -1.5i
-\fBBUFFER MANAGEMENT\fR
-.ti -1.25i
-numeric 5 Display the list of current files and buffers
-.ti -1.25i
-ESC B Select a buffer
-.ti -1.25i
-ESC S Select an existing buffer
-.ti -1.25i
-ESC N Mark a buffer as NOT modified (even if it really is)
-.sp
-.ti -1.5i
-\fBUPPER AND LOW CASE MANIPULATION\fR
-.ti -1.25i
-ESC I Set first character of word to upper case
-.ti -1.25i
-ESC C Capitalize current word
-.ti -1.25i
-ESC O Make current word ordinary (i.e., lower case)
-.ti -1.25i
-ESC U Set entire region between mark and cursor to upper case
-.ti -1.25i
-ESC L Set entire region between mark and cursor to lower case
-.sp
-.ti -1.5i
-\fBMISCELLANEOUS\fR
-.ti -1.25i
-ESC F Find file and read it into its own buffer
-.ti -1.25i
-ESC Z Incremental search
-.ti -1.25i
-ESC Q Like CTRL-R, but queries at each occurrence (type ? for options)
-.ti -1.25i
-ESC R Reset the user profile from a file
-.ti -1.25i
-ESC H Help (ELLE prompts for the 1 or 2 character command to describe)
-.ti -1.25i
-ESC ; Insert a comment in a C program (generates /* */ for you)
-.ti -1.25i
-^X X Exit the editor (same as ESC X and CTRL-X CTRL-X)
-.in -1.75i
-.fi
-.sp
-The major differences between ELLE
-with the \fImined\fR profile and \fImined\fR itself are:
-.sp
-.nf
-.in +0.25i
-1. The definition of a \*(OQword\*(CQ is different for forward and backward word
-2. The mark is set with CTRL-^ instead of CTRL-@
-3. Use CTRL-G to abort a command instead of CTRL-\\
-4. Use CTRL-\ to literally insert the next character, instead of ALT
-5. CTRL-E adjusts the window to put the cursor in the middle of it
-6. To get and insert a file, use ESC G instead of CTRL-G
-7. To go to line n, type ESC n CTRL-[ instead of CTRL-[ n
-8. You exit with CTRL-X CTRL-X and then answer the question with \*(OQy\*(CQ.
-9. There are many new commands, windows, larger files, etc.
-.fi
-.in -0.25i
-.sp
-.SS "Emacs Key Bindings"
-.PP
-If you do not have the \fImined\fR profile installed, you get the standard
-Emacs key bindings.
-These are listed below.
-Commands not listed are not implemented.
-.sp
-.in +1.75i
-.ta +1.25i
-.ti -1.5i
-\fBCURSOR MOVEMENT\fR
-.ti -1.25i
-CTRL-F Forward one character.
-.ti -1.25i
-CTRL-B Backward one character.
-.ti -1.25i
-CTRL-H Same as CTRL-B: move backward one character.
-.ti -1.25i
-ESC F Forward one word.
-.ti -1.25i
-ESC B Backward one word.
-.ti -1.25i
-CTRL-A Beginning of current line.
-.ti -1.25i
-CTRL-E End of current line.
-.ti -1.25i
-CTRL-N Next line (goes to the next line).
-.ti -1.25i
-CTRL-P Previous line (goes to the previous line).
-.ti -1.25i
-CTRL-V Beginning of next screenful.
-.ti -1.25i
-ESC V Beginning of previous screenful.
-.ti -1.25i
-ESC ]~ Forward Paragraph.
-.ti -1.25i
-ESC [~ Backward Paragraph.
-.ti -1.25i
-ESC < Beginning of whole buffer.
-.ti -1.25i
-ESC > End of whole buffer.
-.sp
-.ti -1.5i
-\fBDELETING\fR
-.ti -1.25i
-CTRL-D Deletes forward one character (the one the cursor is under).
-.ti -1.25i
-DELETE Deletes backward one character (the one to left of cursor).
-.ti -1.25i
-ESC D Kills forward one word.
-.ti -1.25i
-ESC DEL Kills backward one word.
-.ti -1.25i
-CTRL-K Kills the rest of the line (to the right of the cursor).
-.ti -1.25i
-ESC \\ Deletes spaces around the cursor.
-.ti -1.25i
-^X CTRL-O Deletes blank lines around the cursor.
-.sp
-.ti -1.5i
-\fBCASE CHANGE\fR
-.ti -1.25i
-ESC C Capitalizes word : first letter becomes uppercase; rest lower
-.ti -1.25i
-ESC L Makes the whole next word lowercase.
-.ti -1.25i
-ESC U Makes the whole next word uppercase.
-.ti -1.25i
-^X CTRL-L Makes whole region lowercase.
-.ti -1.25i
-^X CTRL-U Makes whole region uppercase.
-.sp
-.ti -1.5i
-\fBSEARCHING\fR (If no string is given, previous string is used)
-.ti -1.25i
-CTRL-S Incremental Search forward; prompts \*(OQI-search:\*(CQ
-.ti -1.25i
-CTRL-R Reverse Incremental Search; prompts \*(OQR-search:\*(CQ
-.HS
-During an incremental search, the following characters have special effects:
-.HS
-.in +1.2i
-.ta +1.0i +0.2i
-.ti -1.2i
-\*(OQnormal\*(CQ - Begin searching immediately.
-.ti -1.2i
-^G - Cancel I-search, return to start.
-.ti -1.2i
-DEL - Erase last char, return to last match.
-.ti -1.2i
-^S, ^R - Repeat search (or change direction).
-.ti -1.2i
-ESC or CR - Exit I-search at current point.
-.sp
-.in -1.2i
-.ta +1.25i
-.ti -1.25i
-ESC % Query Replace. Interactive replace. Type \*(OQ?\*(CQ to see options.
-.ti -1.25i
-^X % Replace String. Like Query Replace, but not interactive
-.sp
-.ti -1.5i
-\fBMARKING AREAS\fR
-.ti -1.25i
-CTRL-^ Set mark
-.ti -1.25i
-^X CTRL-X Exchange cursor and mark.
-.ti -1.25i
-ESC H Mark Paragraph. Sets mark and cursor to surround a para.
-.ti -1.25i
-CTRL-W Wipe-out -- kills a \*(OQregion\*(CQ:
-.ti -1.25i
-ESC W Copy region. Like CTRL-W then CTRL-Y but modifies buffer
-.ti -1.25i
-CTRL-Y Yanks-back (un-kills) whatever you have most recently killed.
-.ti -1.25i
-ESC Y Yanks-back (un-kills) the next most recently killed text.
-.ti -1.25i
-ESC CTRL-W Append Next Kill. Accumulates stuff from several kills
-.sp
-.ti -1.5i
-\fBFILLING TEXT\fR
-.ti -1.25i
-ESC Q Fill the paragraph to the size of the Fill Column.
-.ti -1.25i
-ESC G Fill the region.
-.ti -1.25i
-^X F Set Fill Column. ESC Q will use this line size.
-.ti -1.25i
-^X . Set Fill Prefix. Asks for prefix string
-.ti -1.25i
-^X T Toggles Auto Fill Mode.
-.sp
-.ti -1.5i
-\fBWINDOWS\fR
-.ti -1.25i
-^X 2 Make two windows (split screen).
-.ti -1.25i
-^X 1 Make one window (delete window) (make one screen).
-.ti -1.25i
-^X O Go to Other window.
-.ti -1.25i
-^X ^ Grow window: makes current window bigger.
-.sp
-.ti -1.5i
-\fBBUFFERS\fR
-.ti -1.25i
-^X CTRL-F Find a file and make a buffer for it.
-.ti -1.25i
-^X B Select Buffer: goes to specified buffer or makes new one
-.ti -1.25i
-^X CTRL-B Show the names of the buffers used in this editing session.
-.ti -1.25i
-^X K Kill Buffer.
-.ti -1.25i
-ESC tilde Say buffer is not modified.
-.ti -1.25i
-^X CTRL-M Toggle EOL mode (per-buffer flag).
-.sp
-.ti -1.5i
-\fBKEYBOARD MACRO\fR
-.ti -1.25i
-^X ( Start collecting a keyboard macro.
-.ti -1.25i
-^X ) Stop collecting.
-.ti -1.25i
-^X E Execute the collected macro.
-.ti -1.25i
-^X * Display the collected macro.
-.sp
-.ti -1.5i
-\fBFILES\fR
-.ti -1.25i
-^X CTRL-I Insert a file where cursor is.
-.ti -1.25i
-^X CTRL-R Read a new file into current buffer.
-.ti -1.25i
-^X CTRL-V Same as ^X ^R above (reads a file).
-.ti -1.25i
-^X CTRL-W Write buffer out to new file name.
-.ti -1.25i
-^X CTRL-S Save file: write out buffer to its file name.
-.ti -1.25i
-^X CTRL-E Write region out to new file name.
-.sp
-.ti -1.5i
-\fBMISCELLANEOUS\fR
-.ti -1.25i
-^X CTRL-Z Exit from ELLE.
-.ti -1.25i
-^X ! Escape to shell (CTRL-D to return)
-.ti -1.25i
-CTRL-O Open up line
-.ti -1.25i
-LINEFEED Same as typing RETURN and TAB.
-.ti -1.25i
-CTRL-T Transposes characters.
-.ti -1.25i
-ESC T Transposes words.
-.ti -1.25i
-CTRL-U Makes the next command happen four times.
-.ti -1.25i
-CTRL-U number Makes the next command happen \*(OQnumber\*(CQ times.
-.ti -1.25i
-ESC number Same as CTRL-U number.
-.ti -1.25i
-CTRL-L Refreshes screen.
-.ti -1.25i
-CTRL-U CTRL-L Refresh only the line cursor is on.
-.ti -1.25i
-CTRL-U n CTRL-L Change window so the cursor is on line n
-.ti -1.25i
-CTRL-Q Quote: insert the next character no matter what it is.
-.ti -1.25i
-CTRL-G Quit: use to avoid answering a question.
-.ti -1.25i
-ESC ; Inserts comment (for writing C programs).
-.ti -1.25i
-ESC I Inserts indentation equal to previous line.
-.ti -1.25i
-ESC M Move to end of this line's indentation.
-.ti -1.25i
-CTRL-_ Describe a command (if the command database is online)
-.sp
-.ti -1.5i
-\fBUNUSED CONTROLS\fR
-.ti -1.25i
-CTRL-C Not used.
-.ti -1.25i
-CTRL-Z Not used.
-.ti -1.25i
-CTRL-] Not used.
-.fi
-.in -1.75i
-.sp
-.SP 0.5
-.SS "ELLE profile"
-.PP
-It is possible to create your own user profile.
-The mechanism is different from Emacs, since ELLE does not have Mock Lisp.
-Proceed as follows.
-.LI
-.IT
-Modify \fI.ellepro.e\fR to suit your taste.
-.IT
-Install \fI.ellepro.e\fR in your home directory.
-.IT
-Type:
-.HS
-.Cx "ellec \(enProfile"
-.HS
-.IT
-Check to see if \fI.ellepro.b1\fR has been created.
-If it has, you are ready to go.
-.LX
-.SS "Author"
-.PP
-ELLE was written by Ken Harrenstien of SRI (klh@sri.com).
.PP
.nf
\fB.ashrc\fP ash (shell) startup configuration, \fBash\fP(1)
- \fB.ellepro.b1\fP
- elle (editor) startup configuration (compiled), \fBelle\fP(1)
- \fB.ellepro.e\fP
- elle (editor) startup configuration (text), \fBelle\fP(1)
\fB.exrc\fP ex/vi (editor) startup configuration, \fBvim\fP(1)
\fB.profile\fP
login shell profile configuration
.B elvis
(a
.B vi
-clone),
-.B elle
-(a simple
-.B emacs
-clone),
+clone)
and the old MINIX
.B mined
editor. Of these editors only elvis can recover your file after a system