2 Commits

Author SHA1 Message Date
Serge Vakulenko
b0705e54ab Virtualmips modified to allow access to SRSCtl register.
When only one GPR set supported, opcodes RDPGPR and WRPGPR
behave like MOVE instruction.
2014-05-15 10:48:33 -07:00
Serge Vakulenko
459e3f09ea Kernel startup code modified to support MZ processor.
Based on official MIPS application note
"Boot-CPS: Example Boot Code for MIPS® Cores".
2014-05-14 21:22:48 -07:00
1084 changed files with 13566 additions and 151530 deletions

145
Makefile
View File

@@ -24,23 +24,24 @@ DUINOMITE = sys/pic32/duinomite/DUINOMITE
DUINOMITEUART = sys/pic32/duinomite-uart/DUINOMITE-UART
DUINOMITEE = sys/pic32/duinomite-e/DUINOMITE-E
DUINOMITEEUART = sys/pic32/duinomite-e-uart/DUINOMITE-E-UART
PINGUINO = sys/pic32/pinguino-micro/PINGUINO-MICRO
DIP = sys/pic32/dip/DIP
BAREMETAL = sys/pic32/baremetal/BAREMETAL
RETROONE = sys/pic32/retroone/RETROONE
FUBARINO = sys/pic32/fubarino/FUBARINO
FUBARINOBIG = sys/pic32/fubarino/FUBARINO-UART2CONS-UART1-SRAMC
SDXL = sys/pic32/sdxl/SDXL
RETROONE = sys/pic32/retroone/RETROONE
FUBARINO = sys/pic32/fubarino/FUBARINO
FUBARINOBIG = sys/pic32/fubarino/FUBARINO-UART2CONS-UART1-SRAMC
MMBMX7 = sys/pic32/mmb-mx7/MMB-MX7
# Select target board
TARGET ?= $(MAX32)
# Filesystem and swap sizes.
FS_MBYTES = 100
U_MBYTES = 100
SWAP_MBYTES = 2
FS_KBYTES = 102400
U_KBYTES = 102400
SWAP_KBYTES = 2048
# Set this to the device name for your SD card. With this
# enabled you can use "make installfs" to copy the sdcard.img
# enabled you can use "make installfs" to copy the filesys.img
# to the SD card.
#SDCARD = /dev/sdb
@@ -59,28 +60,108 @@ TARGETDIR = $(shell dirname $(TARGET))
TARGETNAME = $(shell basename $(TARGET))
TOPSRC = $(shell pwd)
CONFIG = $(TOPSRC)/tools/configsys/config
#
# Filesystem contents.
#
BIN_FILES := $(wildcard bin/*)
SBIN_FILES := $(wildcard sbin/*)
GAMES_FILES := $(shell find games -type f ! -path '*/.*')
LIBEXEC_FILES := $(wildcard libexec/*)
LIB_FILES := lib/crt0.o lib/retroImage $(wildcard lib/*.a)
ETC_FILES = etc/rc etc/rc.local etc/ttys etc/gettytab etc/group \
etc/passwd etc/shadow etc/fstab etc/motd etc/shells \
etc/termcap etc/MAKEDEV etc/phones etc/remote
INC_FILES = $(wildcard include/*.h) \
$(wildcard include/sys/*.h) \
$(wildcard include/machine/*.h) \
$(wildcard include/smallc/*.h) \
$(wildcard include/smallc/sys/*.h) \
$(wildcard include/arpa/*.h)
SHARE_FILES = share/re.help share/example/Makefile \
share/example/ashello.S share/example/chello.c \
share/example/blkjack.bas share/example/hilow.bas \
share/example/stars.bas share/example/prime.scm \
share/example/fact.fth share/example/echo.S \
share/example/stdarg.c share/example/skeleton.c \
$(wildcard share/smallc/*)
MANFILES = share/man/ share/man/cat1/ share/man/cat2/ share/man/cat3/ \
share/man/cat4/ share/man/cat5/ share/man/cat6/ share/man/cat7/ \
share/man/cat8/ $(wildcard share/man/cat?/*)
ALLFILES = $(SBIN_FILES) $(ETC_FILES) $(BIN_FILES) $(LIB_FILES) $(LIBEXEC_FILES) \
$(INC_FILES) $(SHARE_FILES) $(GAMES_FILES) \
var/log/messages var/log/wtmp .profile
ALLDIRS = games/ sbin/ bin/ dev/ etc/ tmp/ lib/ libexec/ share/ include/ \
var/ u/ share/example/ share/misc/ share/smallc/ \
var/run/ var/log/ var/lock/ games/ games/lib/ include/sys/ \
include/machine/ include/arpa/ include/smallc/ \
include/smallc/sys/ share/misc/ share/smallc/ include/sys/ \
games/lib/
BDEVS = dev/rd0!b0:0 dev/rd0a!b0:1 dev/rd0b!b0:2 dev/rd0c!b0:3 dev/rd0d!b0:4
BDEVS += dev/rd1!b1:0 dev/rd1a!b1:1 dev/rd1b!b1:2 dev/rd1c!b1:3 dev/rd1d!b1:4
BDEVS += dev/rd2!b2:0 dev/rd2a!b2:1 dev/rd2b!b2:2 dev/rd2c!b2:3 dev/rd2d!b2:4
BDEVS += dev/rd3!b3:0 dev/rd3a!b3:1 dev/rd3b!b3:2 dev/rd3c!b3:3 dev/rd3d!b3:4
BDEVS += dev/swap!b4:64 dev/swap0!b4:0 dev/swap1!b4:1 dev/swap2!b4:2
all: .profile
$(MAKE) -C tools
$(MAKE) -C lib
$(MAKE) -C src install
$(MAKE) kernel
D_CONSOLE = dev/console!c0:0
D_MEM = dev/mem!c1:0 dev/kmem!c1:1 dev/null!c1:2 dev/zero!c1:3
D_TTY = dev/tty!c2:0
D_FD = dev/stdin!c3:0 dev/stdout!c3:1 dev/stderr!c3:2
D_TEMP = dev/temp0!c4:0 dev/temp1!c4:1 dev/temp2!c4:2
U_DIRS = $(addsuffix /,$(shell find u -type d ! -path '*/.svn*'))
U_FILES = $(shell find u -type f ! -path '*/.svn/*')
#U_ALL = $(patsubst u/%,%,$(U_DIRS) $(U_FILES))
CDEVS = $(D_CONSOLE) $(D_MEM) $(D_TTY) $(D_FD) $(D_TEMP)
all: tools build kernel
$(MAKE) fs
fs: sdcard.rd
.PHONY: tools
tools:
$(MAKE) -C tools
kernel: $(TARGETDIR)/Makefile
$(MAKE) -C $(TARGETDIR)
$(TARGETDIR)/Makefile: $(CONFIG) $(TARGETDIR)/$(TARGETNAME)
cd $(TARGETDIR) && ../../../tools/configsys/config $(TARGETNAME)
fs: sdcard.img
.PHONY: lib
lib:
$(MAKE) -C lib
.PHONY: sdcard.img
sdcard.img: $(FSUTIL) rootfs.manifest userfs.manifest
build: tools lib
$(MAKE) -C src install
filesys.img: $(FSUTIL) $(ALLFILES)
rm -f $@
$(FSUTIL) --repartition=fs=$(FS_MBYTES)M:swap=$(SWAP_MBYTES)M:fs=$(U_MBYTES)M $@
$(FSUTIL) --new --partition=1 --manifest=rootfs.manifest $@ .
$(FSUTIL) --new --partition=3 --manifest=userfs.manifest $@ u
$(FSUTIL) -n$(FS_KBYTES) $@
$(FSUTIL) -a $@ $(ALLDIRS)
$(FSUTIL) -a $@ $(CDEVS)
$(FSUTIL) -a $@ $(BDEVS)
$(FSUTIL) -a $@ $(ALLFILES)
$(FSUTIL) -a $@ $(MANFILES)
swap.img:
dd if=/dev/zero of=$@ bs=1k count=$(SWAP_KBYTES)
user.img: $(FSUTIL)
ifneq ($(U_KBYTES), 0)
rm -f $@
$(FSUTIL) -n$(U_KBYTES) $@
(cd u; find . -type d -exec ../$(FSUTIL) -a ../$@ '{}/' \;)
(cd u; find . -type f -exec ../$(FSUTIL) -a ../$@ '{}' \+)
endif
sdcard.rd: filesys.img swap.img user.img
ifneq ($(U_KBYTES), 0)
tools/mkrd/mkrd -out $@ -boot filesys.img -swap swap.img -fs user.img
else
tools/mkrd/mkrd -out $@ -boot filesys.img -swap swap.img
endif
$(FSUTIL):
cd tools/fsutil; $(MAKE)
@@ -94,30 +175,32 @@ clean:
cleanall: clean
$(MAKE) -C lib clean
rm -f sys/pic32/*/unix.hex bin/* sbin/* libexec/*
rm -f games/[a-k]* games/[m-z]* share/man/cat*/*
rm -f games/lib/adventure.dat games/lib/cfscores
rm -f share/re.help share/emg.keys share/misc/more.help
rm -f sys/pic32/*/unix.hex bin/* sbin/* games/[a-k]* games/[m-z]* libexec/* share/man/cat*/*
rm -f games/lib/adventure.dat
rm -f games/lib/cfscores
rm -f share/re.help
rm -f share/misc/more.help
rm -f etc/termcap etc/remote etc/phones
rm -rf share/unixbench
rm -f games/lib/adventure.dat games/lib/cfscores share/re.help share/misc/more.help etc/termcap
rm -f tools/configsys/.depend
rm -f var/log/aculog
rm -rf var/lock share/unixbench
rm -rf var/lock
installfs:
installfs: filesys.img
ifdef SDCARD
@[ -f sdcard.img ] || $(MAKE) sdcard.img
sudo dd bs=32k if=sdcard.img of=$(SDCARD)
sudo dd bs=32k if=sdcard.rd of=$(SDCARD)
else
@echo "Error: No SDCARD defined."
@echo "Error: No SDCARD defined."
endif
# TODO: make it relative to Target
installflash:
sudo pic32prog sys/pic32/fubarino/unix.hex
sudo pic32prog sys/pic32/fubarino/unix.hex
# TODO: make it relative to Target
installboot:
sudo pic32prog sys/pic32/fubarino/bootloader.hex
sudo pic32prog sys/pic32/fubarino/bootloader.hex
.profile: etc/root/dot.profile
.profile: etc/root/dot.profile
cp etc/root/dot.profile .profile

View File

@@ -27,14 +27,6 @@
## Build
To compile everything from sources, you'll need some packages installed, namely:
Berkeley YACC, GNU bison and flex, ELF library and FUSE library.
Under Ubuntu, for example, you can do it by command:
```shell
$ sudo apt-get install bison byacc flex libelf-dev libfuse-dev
```
By default, the system is configured for the Max32 board.
To select another target board, edit a top-level user-specific Makefile called "Makefile.user"
and set a TARGET value:
@@ -53,6 +45,8 @@ TARGET = $(DUINOMITE) # for the Duinomite board with USB console
TARGET = $(DUINOMITEUART) # for the Duinomite board with UART console
TARGET = $(DUINOMITEE) # for the Duinomite E board with USB console
TARGET = $(DUINOMITEEUART) # for the Duinomite E board with UART console
TARGET = $(PINGUINO) # for the Pinguino-Micro board
TARGET = $(DIP) # for the DIP board
TARGET = $(BAREMETAL) # Bare PIC32 chip on a breakout board
TARGET = $(FUBARINO) # Fubarino SD board
TARGET = $(FUBARINOBIG) # Fubarino SD board with 8MB SRAM RAMDISK
@@ -71,7 +65,7 @@ To compile the kernel and build a filesystem image, run:
$ make
```
A resulting root filesystem image is in file `sdcard.img`.
A resulting root filesystem image is in file `sdcard.rd`.
A kernel is in file `unix.hex` in your target board subdirectory.
@@ -82,7 +76,7 @@ Win32DiskImager utility (https://launchpad.net/win32-image-writer/+download).
On Linux, run:
```shell
$ sudo dd if=sdcard.img of=/dev/XYZ
$ sudo dd if=sdcard.rd of=/dev/XYZ
```
Here `XYZ` is a device name of SD card, as recognized by Linux (sdb in my case).
@@ -160,3 +154,13 @@ $ ./pic32
```
Configuration of simulated board is stored in file `pic32_max32.conf`.
## Build packages
For building under Ubuntu you need the following packages installed:
```shell
$ sudo apt-get install byacc libelf-dev
```

View File

@@ -1,7 +1,7 @@
DESTDIR = /usr/local/retrobsd
MACHINE = mips
CC = gcc -m32
CC = gcc
AS = $(CC) -x assembler-with-cpp
LD = ld

1
etc/.gitignore vendored
View File

@@ -1,4 +1,3 @@
phones
remote
termcap
termcap.full

View File

@@ -1,16 +1,16 @@
#
# name getty type status comments
#
console "/libexec/getty std.default" xterm on secure #special
console "/libexec/getty std.default" vt100 on secure #special
# Enable some of these for additional logins. Do NOT enable the same one as the
# console port, or strange things will happen. You can turn off the console port
# if you would rather use the getty on the real tty - it's up to you.
tty0 "/libexec/getty std.default" xterm off secure
tty1 "/libexec/getty std.default" xterm off secure
tty2 "/libexec/getty std.default" xterm off secure
tty3 "/libexec/getty std.default" xterm off secure
tty4 "/libexec/getty std.default" xterm off secure
tty5 "/libexec/getty std.default" xterm off secure
ttyUSB0 "/libexec/getty std.default" xterm off secure
tty0 "/libexec/getty std.default" vt100 off secure
tty1 "/libexec/getty std.default" vt100 off secure
tty2 "/libexec/getty std.default" vt100 off secure
tty3 "/libexec/getty std.default" vt100 off secure
tty4 "/libexec/getty std.default" vt100 off secure
tty5 "/libexec/getty std.default" vt100 off secure
ttyUSB0 "/libexec/getty std.default" vt100 off secure

View File

@@ -181,10 +181,6 @@ int waddstr (WINDOW *, char *);
int wgetstr (WINDOW *, char *);
int wdeleteln (WINDOW *);
void mvcur(int ly, int lx, int y, int x);
void overwrite(WINDOW *win1, WINDOW *win2);
void wclrtobot(WINDOW *win);
int mvprintw(int y, int x, char *fmt, ...);
int mvwprintw(WINDOW *win, int y, int x, char *fmt, ...);
/*
* Used to be in unctrl.h.

View File

@@ -24,9 +24,8 @@ AOUT_OBJS = aout.o mips-dis.o
RANLIB_OBJS = ranlib.o archive.o
HEADERS = a.out.h ar.h nlist.h ranlib.h
vpath %.c $(TOPSRC)/src/cmd/aout $(TOPSRC)/src/cmd/ar $(TOPSRC)/src/cmd/as \
$(TOPSRC)/src/cmd/ld $(TOPSRC)/src/cmd/nm $(TOPSRC)/src/cmd/ranlib \
$(TOPSRC)/src/cmd
vpath %.c $(TOPSRC)/src/cmd/ar $(TOPSRC)/src/cmd/as $(TOPSRC)/src/cmd/ld \
$(TOPSRC)/src/cmd/nm $(TOPSRC)/src/cmd/ranlib $(TOPSRC)/src/cmd
all install depend: $(HEADERS) $(SUBDIR) $(PROG)
-for i in $(SUBDIR); do $(MAKE) -C $$i $(MFLAGS) DESTDIR=$(DESTDIR) $@; done

View File

@@ -1,863 +0,0 @@
#
# Manifest file for RetroBSD root filesystem.
#
default
owner 0
group 0
dirmode 0775
filemode 0664
#
# Directories.
#
dir /bin
dir /dev
dir /etc
dir /lib
dir /libexec
dir /sbin
dir /tmp
dir /u
#
# Character devices.
#
cdev /dev/console
major 0
minor 0
cdev /dev/mem
major 1
minor 0
cdev /dev/kmem
major 1
minor 1
cdev /dev/null
major 1
minor 2
mode 666
cdev /dev/zero
major 1
minor 3
mode 666
cdev /dev/tty
major 2
minor 0
mode 666
cdev /dev/stdin
major 3
minor 0
cdev /dev/stdout
major 3
minor 1
cdev /dev/stderr
major 3
minor 2
cdev /dev/temp0
major 4
minor 0
cdev /dev/temp1
major 4
minor 1
cdev /dev/temp2
major 4
minor 2
#
# Block devices.
#
bdev /dev/rd0
major 0
minor 0
bdev /dev/rd0a
major 0
minor 1
bdev /dev/rd0b
major 0
minor 2
bdev /dev/rd0c
major 0
minor 3
bdev /dev/rd0d
major 0
minor 4
bdev /dev/rd1
major 1
minor 0
bdev /dev/rd1a
major 1
minor 1
bdev /dev/rd1b
major 1
minor 2
bdev /dev/rd1c
major 1
minor 3
bdev /dev/rd1d
major 1
minor 4
bdev /dev/rd2
major 2
minor 0
bdev /dev/rd2a
major 2
minor 1
bdev /dev/rd2b
major 2
minor 2
bdev /dev/rd2c
major 2
minor 3
bdev /dev/rd2d
major 2
minor 4
bdev /dev/rd3
major 3
minor 0
bdev /dev/rd3a
major 3
minor 1
bdev /dev/rd3b
major 3
minor 2
bdev /dev/rd3c
major 3
minor 3
bdev /dev/rd3d
major 3
minor 4
bdev /dev/swap
major 4
minor 64
bdev /dev/swap0
major 4
minor 0
bdev /dev/swap1
major 4
minor 1
bdev /dev/swap2
major 4
minor 2
#
# Files: /
#
file /.profile
#
# Files: /etc
#
file /etc/fstab
file /etc/gettytab
file /etc/group
file /etc/MAKEDEV
mode 0775
file /etc/motd
file /etc/passwd
file /etc/phones
file /etc/rc
mode 0775
file /etc/rc.local
mode 0775
file /etc/remote
file /etc/shadow
file /etc/shells
file /etc/termcap
mode 0444
file /etc/ttys
#
# Files: /bin
#
default
filemode 0775
file /bin/adb
file /bin/adc-demo
file /bin/aout
file /bin/apropos
file /bin/ar
file /bin/as
file /bin/awk
file /bin/basename
file /bin/basic
file /bin/bc
file /bin/cal
file /bin/cat
file /bin/cb
file /bin/cc
file /bin/chat-server
file /bin/chflags
file /bin/chgrp
file /bin/chmod
file /bin/chpass
mode 04755
file /bin/cmp
file /bin/col
file /bin/comm
file /bin/compress
file /bin/cp
file /bin/cpp
file /bin/crontab
file /bin/date
file /bin/dc
file /bin/dd
file /bin/df
mode 02755
file /bin/diff
file /bin/du
file /bin/echo
file /bin/ed
file /bin/egrep
file /bin/emg
file /bin/env
file /bin/expr
file /bin/false
file /bin/fgrep
file /bin/file
file /bin/find
file /bin/forth
file /bin/fstat
mode 02755
file /bin/glcdtest
file /bin/globdump
file /bin/globread
file /bin/globwrite
file /bin/grep
file /bin/groups
file /bin/head
file /bin/hostid
file /bin/hostname
file /bin/id
file /bin/iostat
mode 02755
file /bin/join
file /bin/kill
file /bin/la
file /bin/last
file /bin/lcc
file /bin/lcpp
file /bin/ld
file /bin/ln
file /bin/login
mode 04755
file /bin/lol
file /bin/ls
file /bin/lv
file /bin/mail
mode 04755
file /bin/make
file /bin/man
file /bin/med
file /bin/mesg
file /bin/mkdir
file /bin/more
file /bin/msec
file /bin/mv
file /bin/nice
file /bin/nm
file /bin/nohup
file /bin/ntpdate
file /bin/od
file /bin/pagesize
file /bin/passwd
mode 04755
file /bin/picoc
file /bin/portio
file /bin/pr
file /bin/printenv
file /bin/printf
file /bin/ps
mode 02755
file /bin/pwd
file /bin/pwm
file /bin/ranlib
file /bin/re
file /bin/renice
file /bin/renumber
file /bin/retroforth
file /bin/rev
file /bin/rm
file /bin/rmail
file /bin/rmdir
file /bin/rz
file /bin/scc
file /bin/scm
file /bin/sed
file /bin/setty
file /bin/sh
file /bin/size
file /bin/sl
file /bin/sleep
file /bin/smux
file /bin/sort
file /bin/split
file /bin/strip
file /bin/stty
file /bin/su
mode 04755
file /bin/sum
file /bin/sync
file /bin/sysctl
file /bin/sz
file /bin/tail
file /bin/tar
file /bin/tee
file /bin/telnet
file /bin/test
file /bin/time
file /bin/tip
file /bin/touch
file /bin/tr
file /bin/true
file /bin/tsort
file /bin/tty
file /bin/uname
file /bin/uncompress
file /bin/uniq
file /bin/uucico
file /bin/uuclean
file /bin/uucp
file /bin/uudecode
file /bin/uuencode
file /bin/uulog
file /bin/uuname
file /bin/uupoll
file /bin/uuq
file /bin/uusend
file /bin/uusnap
file /bin/uux
file /bin/uuxqt
file /bin/vi
file /bin/vmstat
mode 02755
file /bin/w
file /bin/wall
mode 02755
file /bin/wc
file /bin/web-client
file /bin/web-server
file /bin/whereis
file /bin/who
file /bin/whoami
file /bin/write
mode 02755
file /bin/xargs
file /bin/zcat
link /bin/[
target /bin/test
link /bin/whatis
target /bin/apropos
link /bin/chfn
target /bin/chpass
link /bin/chsh
target /bin/chpass
link /bin/rb
target /bin/rz
link /bin/rx
target /bin/rz
link /bin/sb
target /bin/sz
link /bin/sx
target /bin/sz
#
# Files: /sbin
#
file /sbin/chown
file /sbin/chroot
mode 04755
file /sbin/cron
file /sbin/devupdate
file /sbin/disktool
file /sbin/fdisk
file /sbin/fsck
file /sbin/init
mode 0700
file /sbin/mkfs
file /sbin/mknod
file /sbin/mkpasswd
file /sbin/mount
file /sbin/pstat
mode 02755
file /sbin/rdprof
file /sbin/reboot
file /sbin/shutdown
mode 04750
file /sbin/talloc
file /sbin/umount
file /sbin/update
file /sbin/updatedb
file /sbin/vipw
link /sbin/bootloader
target /sbin/reboot
link /sbin/fastboot
target /sbin/reboot
link /sbin/halt
target /sbin/reboot
link /sbin/poweroff
target /sbin/reboot
#
# Files: /games
#
default
filemode 0775
dir /games
file /games/adventure
file /games/arithmetic
file /games/atc
file /games/backgammon
file /games/banner
file /games/battlestar
file /games/bcd
file /games/boggle
file /games/btlgammon
file /games/canfield
file /games/cfscores
file /games/cribbage
file /games/factor
file /games/fish
file /games/fortune
file /games/hangman
file /games/mille
file /games/monop
file /games/morse
file /games/number
file /games/ppt
file /games/primes
file /games/quiz
file /games/rain
file /games/robots
file /games/rogue
file /games/sail
file /games/snake
file /games/snscore
file /games/teachgammon
file /games/trek
file /games/worm
file /games/worms
file /games/wump
#
# Files: /games/lib
#
default
filemode 0444
dir /games/lib
file /games/lib/adventure.dat
file /games/lib/battle_strings
file /games/lib/backrules
file /games/lib/bogdict
file /games/lib/cfscores
file /games/lib/crib.instr
mode 0666
file /games/lib/fortunes.dat
file /games/lib/cards.pck
file /games/lib/robots_roll
mode 0666
file /games/lib/snakerawscores
mode 0666
dir /games/lib/atc
file /games/lib/atc/ATC_scores
file /games/lib/atc/crossover
file /games/lib/atc/default
file /games/lib/atc/easy
file /games/lib/atc/game_2
file /games/lib/atc/Game_List
file /games/lib/atc/Killer
dir /games/lib/quiz.k
file /games/lib/quiz.k/africa
file /games/lib/quiz.k/america
file /games/lib/quiz.k/areas
file /games/lib/quiz.k/arith
file /games/lib/quiz.k/asia
file /games/lib/quiz.k/babies
file /games/lib/quiz.k/bard
file /games/lib/quiz.k/chinese
file /games/lib/quiz.k/collectives
file /games/lib/quiz.k/ed
file /games/lib/quiz.k/elements
file /games/lib/quiz.k/europe
file /games/lib/quiz.k/greek
file /games/lib/quiz.k/inca
file /games/lib/quiz.k/index
file /games/lib/quiz.k/latin
file /games/lib/quiz.k/locomotive
file /games/lib/quiz.k/midearth
file /games/lib/quiz.k/morse
file /games/lib/quiz.k/murders
file /games/lib/quiz.k/poetry
file /games/lib/quiz.k/posneg
file /games/lib/quiz.k/pres
file /games/lib/quiz.k/province
file /games/lib/quiz.k/seq-easy
file /games/lib/quiz.k/seq-hard
file /games/lib/quiz.k/sexes
file /games/lib/quiz.k/sov
file /games/lib/quiz.k/spell
file /games/lib/quiz.k/state
file /games/lib/quiz.k/trek
file /games/lib/quiz.k/ucc
#
# Files: /include
#
default
filemode 0664
dir /include
dir /include/arpa
dir /include/machine
dir /include/smallc
dir /include/smallc/sys
dir /include/sys
file /include/alloca.h
file /include/a.out.h
file /include/ar.h
file /include/arpa/inet.h
file /include/assert.h
file /include/ctype.h
file /include/curses.h
file /include/dbm.h
file /include/fcntl.h
file /include/float.h
file /include/fstab.h
file /include/grp.h
file /include/kmem.h
file /include/lastlog.h
file /include/limits.h
file /include/machine/cpu.h
file /include/machine/elf_machdep.h
file /include/machine/float.h
file /include/machine/io.h
file /include/machine/limits.h
file /include/machine/machparam.h
file /include/machine/pic32mx.h
file /include/machine/rd_sdramp_config.h
file /include/machine/sdram.h
file /include/machine/ssd1926.h
file /include/machine/usb_ch9.h
file /include/machine/usb_device.h
file /include/machine/usb_function_cdc.h
file /include/machine/usb_function_hid.h
file /include/machine/usb_hal_pic32.h
file /include/math.h
file /include/mtab.h
file /include/ndbm.h
file /include/nlist.h
file /include/paths.h
file /include/pcc.h
file /include/psout.h
file /include/pwd.h
file /include/ranlib.h
file /include/regexp.h
file /include/setjmp.h
file /include/sgtty.h
file /include/smallc/curses.h
file /include/smallc/fcntl.h
file /include/smallc/signal.h
file /include/smallc/stdio.h
file /include/smallc/sys/gpio.h
file /include/smallc/sys/spi.h
file /include/smallc/wiznet.h
file /include/stab.h
file /include/stdarg.h
file /include/stddef.h
file /include/stdint.h
file /include/stdio.h
file /include/stdlib.h
file /include/string.h
file /include/strings.h
file /include/struct.h
file /include/sys/adc.h
file /include/sys/buf.h
file /include/syscall.h
file /include/sys/callout.h
file /include/sys/clist.h
file /include/sys/conf.h
file /include/sys/debug.h
file /include/sys/dir.h
file /include/sys/disk.h
file /include/sys/dkbad.h
file /include/sys/dk.h
file /include/sys/errno.h
file /include/sys/exec_aout.h
file /include/sys/exec_elf.h
file /include/sys/exec.h
file /include/sysexits.h
file /include/sys/fcntl.h
file /include/sys/file.h
file /include/sys/fs.h
file /include/sys/glcd.h
file /include/sys/glob.h
file /include/sys/gpio.h
file /include/sys/inode.h
file /include/sys/ioctl.h
file /include/sys/kernel.h
file /include/sys/map.h
file /include/sys/mount.h
file /include/sys/msgbuf.h
file /include/sys/mtio.h
file /include/sys/namei.h
file /include/sys/oc.h
file /include/sys/param.h
file /include/sys/picga.h
file /include/sys/proc.h
file /include/sys/ptrace.h
file /include/sys/pty.h
file /include/sys/rd_flash.h
file /include/sys/rdisk.h
file /include/sys/rd_mrams.h
file /include/sys/rd_sdramp.h
file /include/sys/rd_sramc.h
file /include/sys/reboot.h
file /include/sys/resource.h
file /include/sys/select.h
file /include/sys/signal.h
file /include/sys/signalvar.h
file /include/sys/spi_bus.h
file /include/sys/spi.h
file /include/sys/stat.h
file /include/sys/swap.h
file /include/sys/sysctl.h
file /include/sys/syslog.h
file /include/sys/systm.h
file /include/sys/time.h
file /include/sys/times.h
file /include/sys/trace.h
file /include/sys/ttychars.h
file /include/sys/ttydev.h
file /include/sys/tty.h
file /include/sys/types.h
file /include/sys/uart.h
file /include/sys/uio.h
file /include/sys/usb_uart.h
file /include/sys/user.h
file /include/sys/utsname.h
file /include/sys/vm.h
file /include/sys/vmmac.h
file /include/sys/vmmeter.h
file /include/sys/vmparam.h
file /include/sys/vmsystm.h
file /include/sys/wait.h
file /include/term.h
file /include/termios-todo.h
file /include/time.h
file /include/ttyent.h
file /include/tzfile.h
file /include/unistd.h
file /include/utmp.h
file /include/vmf.h
symlink /include/errno.h
target sys/errno.h
symlink /include/signal.h
target sys/signal.h
symlink /include/syslog.h
target sys/syslog.h
#
# Files: /lib
#
file /lib/crt0.o
file /lib/libc.a
file /lib/libcurses.a
file /lib/libtermlib.a
file /lib/libwiznet.a
file /lib/retroImage
#
# Files: /libexec
#
default
filemode 0775
file /libexec/bigram
file /libexec/code
file /libexec/diffh
file /libexec/getty
file /libexec/smallc
file /libexec/smlrc
#
# Files: /share
#
default
filemode 0444
dir /share
dir /share/dict
dir /share/misc
file /share/emg.keys
file /share/re.help
file /share/dict/words
file /share/misc/more.help
#
# Files: /share/example
#
default
filemode 0664
dir /share/example
file /share/example/ashello.S
file /share/example/blkjack.bas
file /share/example/chello.c
file /share/example/echo.S
file /share/example/fact.fth
file /share/example/hilow.bas
file /share/example/Makefile
file /share/example/prime.scm
file /share/example/skeleton.c
file /share/example/stars.bas
file /share/example/stdarg.c
#
# Files: /share/smallc
#
dir /share/smallc
file /share/smallc/adc.c
file /share/smallc/gpio.c
file /share/smallc/hello.c
file /share/smallc/Makefile
file /share/smallc/primelist.c
file /share/smallc/primesum.c
file /share/smallc/q8.c
file /share/smallc/rain.c
file /share/smallc/test1.c
file /share/smallc/test2.c
file /share/smallc/test3.c
file /share/smallc/webserver.c
#
# Files: /share/smallerc
#
dir /share/smallerc
file /share/smallerc/adc.c
file /share/smallerc/gpio.c
file /share/smallerc/hello.c
file /share/smallerc/Makefile
file /share/smallerc/primelist.c
file /share/smallerc/primesum.c
file /share/smallerc/q8.c
file /share/smallerc/rain.c
file /share/smallerc/test1.c
file /share/smallerc/test2.c
file /share/smallerc/test3.c
#
# Files: /var
#
dir /var
dir /var/lock
dir /var/log
dir /var/run
file /var/log/messages
file /var/log/wtmp
#
# Files: /share/man
#
dir /share/man
dir /share/man/cat1
dir /share/man/cat2
dir /share/man/cat3
dir /share/man/cat4
dir /share/man/cat5
dir /share/man/cat6
dir /share/man/cat7
dir /share/man/cat8
file /share/man/cat1/ar.0
file /share/man/cat1/chflags.0
file /share/man/cat1/chpass.0
file /share/man/cat1/cpp.0
file /share/man/cat1/crontab.0
file /share/man/cat1/emg.0
file /share/man/cat1/groups.0
file /share/man/cat1/hostname.0
file /share/man/cat1/id.0
file /share/man/cat1/la.0
file /share/man/cat1/lcc.0
file /share/man/cat1/ld.0
file /share/man/cat1/lv.0
file /share/man/cat1/passwd.0
file /share/man/cat1/printf.0
file /share/man/cat1/ranlib.0
file /share/man/cat1/rz.0
file /share/man/cat1/stty.0
file /share/man/cat1/sz.0
file /share/man/cat1/test.0
file /share/man/cat1/uname.0
file /share/man/cat1/whoami.0
file /share/man/cat1/xargs.0
file /share/man/cat3/vmf.0
file /share/man/cat5/ar.0
file /share/man/cat5/crontab.0
file /share/man/cat5/ranlib.0
file /share/man/cat6/adventure.0
file /share/man/cat6/arithmetic.0
file /share/man/cat6/atc.0
file /share/man/cat6/backgammon.0
file /share/man/cat6/banner.0
file /share/man/cat6/battlestar.0
file /share/man/cat6/bcd.0
file /share/man/cat6/canfield.0
file /share/man/cat6/cribbage.0
file /share/man/cat6/fish.0
file /share/man/cat6/fortune.0
file /share/man/cat6/hangman.0
file /share/man/cat6/mille.0
file /share/man/cat6/monop.0
file /share/man/cat6/number.0
file /share/man/cat6/quiz.0
file /share/man/cat6/rain.0
file /share/man/cat6/robots.0
file /share/man/cat6/rogue.0
file /share/man/cat6/sail.0
file /share/man/cat6/snake.0
file /share/man/cat6/trek.0
file /share/man/cat6/worm.0
file /share/man/cat6/worms.0
file /share/man/cat6/wump.0
file /share/man/cat8/chown.0
file /share/man/cat8/chroot.0
file /share/man/cat8/cron.0
file /share/man/cat8/fdisk.0
file /share/man/cat8/fstat.0
file /share/man/cat8/init.0
file /share/man/cat8/mkfs.0
file /share/man/cat8/mknod.0
file /share/man/cat8/mkpasswd.0
file /share/man/cat8/mount.0
file /share/man/cat8/pstat.0
file /share/man/cat8/reboot.0
file /share/man/cat8/renice.0
file /share/man/cat8/shutdown.0
file /share/man/cat8/sysctl.0
#file /share/man/cat8/talloc.0
file /share/man/cat8/umount.0
file /share/man/cat8/update.0
file /share/man/cat8/vipw.0
link /share/man/cat1/rb.0
target /share/man/cat1/rz.0
link /share/man/cat1/rx.0
target /share/man/cat1/rz.0
link /share/man/cat1/sb.0
target /share/man/cat1/sz.0
link /share/man/cat1/sx.0
target /share/man/cat1/sz.0
link /share/man/cat8/fastboot.0
target /share/man/cat8/reboot.0
link /share/man/cat8/halt.0
target /share/man/cat8/reboot.0
link /share/man/cat1/chfn.0
target /share/man/cat1/chpass.0
link /share/man/cat1/chsh.0
target /share/man/cat1/chpass.0

1
share/.gitignore vendored
View File

@@ -1,4 +1,3 @@
re.help
misc
unixbench
emg.keys

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
all: ashello echo chello stdarg skeleton
all: ashello echo chello
ashello: ashello.o
$(LD) ashello.o -o $@
@@ -10,11 +10,5 @@ chello: chello.o
echo: echo.o
$(LD) $@.o -o $@
stdarg: stdarg.o
$(CC) stdarg.o -o $@
skeleton: skeleton.o
$(CC) skeleton.o -o $@
clean:
rm -f *.o ashello echo chello stdarg skeleton *.dis *~
rm -f *.o ashello echo chello *.dis *~

View File

@@ -1,3 +0,0 @@
makewhatis.sed
man.template
whatis

View File

@@ -1,4 +1,6 @@
main()
extern int printf();
int main()
{
printf ("Hello, SmallC World!\n");
}

View File

@@ -1,38 +0,0 @@
CC = cc
PROG = hello primelist primesum test1 test2 test3 gpio adc rain \
q8
all: $(PROG)
hello: hello.c
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) hello.c
primelist: primelist.c
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) primelist.c
primesum: primesum.c
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) primesum.c
gpio: gpio.c
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) gpio.c
adc: adc.c
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) adc.c
rain: rain.c
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) rain.c
q8: q8.c
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) q8.c
test1: test1.c
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) test1.c
test2: test2.c
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) test2.c
test3: test3.c
$(CC) $(CFLAGS) -o $@ $(LDFLAGS) test3.c
clean:
rm -f *.o $(PROG)

View File

@@ -1,29 +0,0 @@
/*
* Example of reading ADC data.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
char buf[100];
int main(void)
{
int i, fd, value;
for (i=0; i<16; i++) {
sprintf(buf, "/dev/adc%d", i);
fd = open(buf, O_RDWR);
if (fd < 0) {
printf("Error: unable to open %s\n", buf);
} else {
if (read(fd, buf, 20) > 0) {
value = strtol (buf, 0, 0);
printf("adc%-2d = %d\n", i, value);
}
close(fd);
}
}
return 0;
}

View File

@@ -1,26 +0,0 @@
/*
* Example of polling general purpose i/o pins.
*/
#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/gpio.h>
int main(void)
{
int fd, pnum, value;
fd = open ("/dev/porta", O_RDWR);
if (fd < 0) {
perror ("/dev/porta");
return -1;
}
for (pnum=0; pnum<7; pnum++) {
value = ioctl (fd, GPIO_POLL | GPIO_PORT (pnum), 0);
if (value < 0)
perror ("GPIO_POLL");
printf ("port%c = 0x%04x\n", pnum + 'A', value);
}
return 0;
}

View File

@@ -1,6 +0,0 @@
#include <stdio.h>
int main(void)
{
printf("Hello, Smaller C World!\n");
}

View File

@@ -1,35 +0,0 @@
/*
* Print the list of prime numbers up to 100.
*/
#include <stdio.h>
int isprime(int);
int main(void)
{
int n;
for (n=2; n<100; ++n) {
if (isprime(n)) {
printf("%d ", n);
}
}
printf("\n");
}
int isprime(int n)
{
int j;
if (n == 2)
return 1;
if (n % 2 == 0)
return 0;
for (j=3; j*j<=n; j+=2)
if (n % j == 0)
return 0;
return 1;
}

View File

@@ -1,35 +0,0 @@
/*
* Compute the sum of prime numbers up to 10000.
*/
#include <stdio.h>
int isprime(int);
int main(void)
{
int sum, n;
sum = 0;
for (n=2; n<10000; ++n) {
if (isprime(n)) {
sum += n;
}
}
printf("Sum of primes less than 10000: %d\n", sum);
}
int isprime(int n)
{
int j;
if (n == 2)
return 1;
if (n % 2 == 0)
return 0;
for (j=3; j*j<=n; j+=2)
if (n % j == 0)
return 0;
return 1;
}

View File

@@ -1,209 +0,0 @@
/*
* Eight Queens puzzle
*
* (C) 2010 by Mark Sproul
* Open source as per standard Arduino code
* Modified by Pito 12/2012 for SmallC and then by Alexey Frunze for Smaller C
*/
#include <stdio.h>
#define TRUE 1
#define FALSE 0
unsigned int gChessBoard[8];
unsigned int gLoopCounter;
int gValidCount;
int CheckCurrentBoard(void)
{
int ii;
int jj;
int theRow;
int theLongRow;
int theLongColumns;
int bitCount;
//* we know we have 1 in each row,
//* Check for 1 in each column
theRow = 0;
for (ii=0; ii<8; ii++) {
theRow |= gChessBoard[ii];
}
if (theRow != 0x0ff) {
return FALSE;
}
//* we have 1 in each column, now check the diagonals
theLongColumns = 0;
for (ii=0; ii<8; ii++) {
theLongRow = gChessBoard[ii] & 0x0ff;
theLongRow = theLongRow << ii;
theLongColumns |= theLongRow;
}
//* now count the bits
bitCount = 0;
for (ii=0; ii<16; ii++) {
if ((theLongColumns & 0x01) == 0x01) {
bitCount++;
}
theLongColumns = theLongColumns >> 1;
}
if (bitCount != 8) {
return FALSE;
}
//* we now have to check the other diagonal
theLongColumns = 0;
for (ii=0; ii<8; ii++) {
theLongRow = gChessBoard[ii] & 0x0ff;
theLongRow = theLongRow << 8;
theLongRow = theLongRow >> ii;
theLongColumns |= theLongRow;
}
//* now count the bits
bitCount = 0;
for (ii=0; ii<16; ii++) {
if ((theLongColumns & 0x01) == 0x01) {
bitCount++;
}
theLongColumns = theLongColumns >> 1;
}
if (bitCount != 8) {
return FALSE;
}
return TRUE;
}
int CheckForDone(void)
{
int ii;
int weAreDone;
int theRow;
weAreDone = FALSE;
//* we know we have 1 in each row,
//* Check for 1 in each column
theRow = 0;
for (ii=0; ii<8; ii++) {
theRow |= gChessBoard[ii];
}
if (theRow == 0x01) {
weAreDone = TRUE;
}
return weAreDone;
}
void RotateQueens(void)
{
int ii;
int keepGoing;
int theRow;
ii = 0;
keepGoing = TRUE;
while (keepGoing && (ii < 8)) {
theRow = gChessBoard[ii] & 0x0ff;
theRow = (theRow >> 1) & 0x0ff;
if (theRow != 0) {
gChessBoard[ii] = theRow;
keepGoing = FALSE;
} else {
gChessBoard[ii] = 0x080;
}
ii++;
}
}
void PrintChessBoard(void)
{
int ii;
int jj;
int theRow;
char textString[32];
printf("\nLoop= %d\n", gLoopCounter);
printf("Solution count= %d\n", gValidCount);
printf("+----------------+\n");
for (ii=0; ii<8; ii++) {
theRow = gChessBoard[ii];
printf("|");
for (jj=0; jj<8; jj++) {
if (theRow & 0x080) {
printf("Q ");
} else {
printf(". ");
}
theRow = theRow << 1;
}
printf("|\n");
}
printf("+----------------+\n");
}
int main(void)
{
int ii;
printf("\nEight Queens brute force");
printf("\n************************\n");
//* put the 8 queens on the board, 1 in each row
for (ii=0; ii<8; ii++) {
gChessBoard[ii] = 0x080;
}
PrintChessBoard();
gLoopCounter = 0;
gValidCount = 0;
while (1) {
gLoopCounter++;
if (CheckCurrentBoard()) {
gValidCount++;
PrintChessBoard();
} else if ((gLoopCounter % 1000) == 0) {
//PrintChessBoard();
}
RotateQueens();
if (CheckForDone()) {
//int elapsedSeconds;
//int elapsedMinutes;
//int elapsedHours;
//elapsedSeconds = millis() / 1000;
//elapsedMinutes = elapsedSeconds / 60;
//elapsedHours = elapsedMinutes / 60;
printf("----------------------------------\n");
printf("All done\n");
PrintChessBoard();
printf("----------------------------------\n");
//Serial.print("total seconds=");
//Serial.println(elapsedSeconds);
//Serial.print("hours=");
//Serial.println(elapsedHours);
//Serial.print("minutes=");
//Serial.println(elapsedMinutes % 60);
//Serial.print("seconds=");
//Serial.println(elapsedSeconds % 60);
return (1);
}
}
}

View File

@@ -1,129 +0,0 @@
/*
* Example of using termcap library for SmallC.
* 11/3/1980 EPS/CITHEP
*
* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#define CO 80 /* number of columns */
#define LI 24 /* number of lines */
#define CL "\33[H\33[J" /* clear the screen */
#define CM "\33[%u;%uH" /* move the cursor to row, column */
#define BC "\b" /* move cursor left */
#define DN "\33[B" /* move cursor down */
#define ND " " /* move cursor right */
int xpos[5], ypos[5];
char outbuf[BUFSIZ];
void moveto(int col, int row)
{
printf(CM, row, col);
}
void onsig(int n)
{
moveto(0, LI - 1);
fflush(stdout);
_exit(0);
}
int main(void)
{
int x, y, j;
setbuf(stdout, outbuf);
for (j = SIGHUP; j <= SIGTERM; j++)
if (signal(j, SIG_IGN) != SIG_IGN)
signal(j, onsig);
fputs(CL, stdout);
fflush(stdout);
for (j = 5; --j >= 0; ) {
xpos[j] = 2 + rand() % (CO - 4);
ypos[j] = 2 + rand() % (LI - 4);
}
for (j = 0; ; ) {
x = 2 + rand() % (CO - 4);
y = 2 + rand() % (LI - 4);
moveto(x, y);
putchar('.');
moveto(xpos[j], ypos[j]);
putchar('o');
if (j == 0)
j = 4;
else
--j;
moveto(xpos[j], ypos[j]);
putchar('O');
if (j == 0)
j = 4;
else
--j;
moveto(xpos[j], ypos[j]-1);
putchar('-');
fputs(DN, stdout);
fputs(BC, stdout);
fputs(BC, stdout);
fputs("|.|", stdout);
fputs(DN, stdout);
fputs(BC, stdout);
fputs(BC, stdout);
putchar('-');
if (j == 0)
j = 4;
else
--j;
moveto(xpos[j], ypos[j]-2);
putchar('-');
fputs(DN, stdout);
fputs(BC, stdout);
fputs(BC, stdout);
fputs("/ \\", stdout);
moveto(xpos[j]-2, ypos[j]);
fputs("| O |", stdout);
moveto(xpos[j]-1, ypos[j]+1);
fputs("\\ /", stdout);
fputs(DN, stdout);
fputs(BC, stdout);
fputs(BC, stdout);
putchar('-');
if (j == 0)
j = 4;
else
--j;
moveto(xpos[j], ypos[j]-2);
putchar(' ');
fputs(DN, stdout);
fputs(BC, stdout);
fputs(BC, stdout);
putchar(' ');
fputs(ND, stdout);
putchar(' ');
moveto(xpos[j]-2, ypos[j]);
putchar(' ');
fputs(ND, stdout);
putchar(' ');
fputs(ND, stdout);
putchar(' ');
moveto(xpos[j]-1, ypos[j]+1);
putchar(' ');
fputs(ND, stdout);
putchar(' ');
fputs(DN, stdout);
fputs(BC, stdout);
fputs(BC, stdout);
putchar(' ');
xpos[j] = x;
ypos[j] = y;
fflush(stdout);
usleep(100000);
}
}

View File

@@ -1,214 +0,0 @@
#include <stdio.h>
int ga[5];
int main(void)
{
int a, b, c, d;
int arr[5];
int *pi;
char arrc[5];
char *pic;
int s1, s2;
int z;
int t;
int *pip;
int *picp;
int e1, e2;
ga[0] = 10;
ga[1] = 20;
ga[2] = 30;
ga[3] = 40;
ga[4] = 50;
a = 21;
b = 31;
c = 71;
d = 82;
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;
pi = &arr[0];
arrc[0] = 13;
arrc[1] = 23;
arrc[2] = 33;
arrc[3] = 43;
arrc[4] = 53;
pic = &arrc[0];
printf(" 21 + 31 = %d (52)\n", a + b);
printf(" 21 - 31 = %d (-10)\n", a - b);
printf(" 21 & 71 = %d (5)\n", a & c);
printf(" 21 | 82 = %d (87)\n", a | d);
printf(" 21 ^ 82 = %d (71)\n", a ^ d);
printf(" 21 * 82 = %d (1722)\n", a * d);
printf(" 82 %% 21 = %d (19)\n", d % a);
printf(" 82 / 21 = %d (3)\n", d / a);
printf(" *pi = %d (10)\n", *pi);
printf(" *pi + 1 = %d (11)\n", *pi + 1);
printf(" *(pi + 1) = %d (20)\n", *(pi + 1));
printf("&arr[3] - &arr[0] = %d (3)\n", &arr[3] - &arr[0]);
printf(" arr[3]-arr[0] = %d (30)\n", arr[3] - arr[0]);
printf(" arr[3]+arr[0] = %d (50)\n", arr[3] + arr[0]);
printf(" &ga[3] - &ga[0] = %d (3)\n", &ga[3] - &ga[0]);
printf(" ga[3]-ga[0] = %d (30)\n", ga[3] - ga[0]);
printf(" ga[3]+ga[0] = %d (50)\n", ga[3] + ga[0]);
printf("\n");
printf(" *pic = %d (13)\n", *pic);
printf(" *pic + 1 = %d (14)\n", *pic+1);
printf(" *(pic + 1) = %d (23)\n", *(pic+1));
printf("&arrc[3] - &arrc[0] = %d (3)\n", &arrc[3]-&arrc[0]);
printf("\n");
s1 = 3;
s2 = -200;
printf(" 82 << 3 = %d (656)\n", d << s1);
printf(" 82 >> 3 = %d (10)\n", d >> s1);
printf("-200 >> 3 = %d (-25)\n", s2 >> s1);
printf("-200 << 3 = %d (-1600)\n", s2 << s1);
printf("\n");
printf("-s1 = %d (-3)\n", -s1);
printf("-s2 = %d (200)\n", -s2);
printf("\n");
printf("~82 = %d (-83)\n", ~d);
printf("\n");
z = 0;
printf("!82 = %d (0)\n", !d);
printf(" !0 = %d (1)\n", !z);
printf("\n");
printf(" 0 && 0 = %d (0)\n", z && z);
printf(" 0 && 21 = %d (0)\n", z && a);
printf(" 3 && 21 = %d (1)\n", s1 && a);
printf("21 && 3 = %d (1)\n", a && s1);
printf("\n");
printf(" 0 || 0 = %d (0)\n", z || z);
printf(" 0 || 21 = %d (1)\n", z || a);
printf(" 3 || 21 = %d (1)\n", s1 || a);
printf("21 || 3 = %d (1)\n", a || s1);
printf("\n");
pi = 4;
printf("pi++ = %d (4)\n", pi++);
printf(" pi = %d (8)\n", pi);
printf("++pi = %d (12)\n", ++pi);
printf("pi-- = %d (12)\n", pi--);
printf(" pi = %d (8)\n", pi);
printf("--pi = %d (4)\n", --pi);
printf("\n");
pic = 4;
printf("pic++ = %d (4)\n", pic++);
printf(" pic = %d (5)\n", pic);
printf("++pic = %d (6)\n", ++pic);
printf("pic-- = %d (6)\n", pic--);
printf(" pic = %d (5)\n", pic);
printf("--pic = %d (4)\n", --pic);
printf("\n");
t = 4;
printf("t++ = %d (4)\n", t++);
printf(" t = %d (5)\n", t);
printf("++t = %d (6)\n", ++t);
printf("t-- = %d (6)\n", t--);
printf(" t = %d (5)\n", t);
printf("--t = %d (4)\n", --t);
printf("\n");
t = 4;
printf(" t==4 = %d (1)\n", t == 4);
printf(" t==3 = %d (0)\n", t == 3);
printf(" t==5 = %d (0)\n", t == 5);
t = -4;
printf("t==-4 = %d (1)\n", t == -4);
printf("t==-3 = %d (0)\n", t == -3);
printf("t==-5 = %d (0)\n", t == -5);
printf(" t==4 = %d (0)\n", t == 4);
printf(" t==3 = %d (0)\n", t == 3);
printf(" t==5 = %d (0)\n", t == 5);
printf("\n");
t = 4;
printf(" t!=4 = %d (0)\n", t != 4);
printf(" t!=3 = %d (1)\n", t != 3);
printf(" t!=5 = %d (1)\n", t != 5);
t = -4;
printf("t!=-4 = %d (0)\n", t != -4);
printf("t!=-3 = %d (1)\n", t != -3);
printf("t!=-5 = %d (1)\n", t != -5);
printf(" t!=4 = %d (1)\n", t != 4);
printf(" t!=3 = %d (1)\n", t != 3);
printf(" t!=5 = %d (1)\n", t != 5);
printf("\n");
t = 4;
printf(" t<4 = %d (0)\n", t < 4);
printf(" t<3 = %d (0)\n", t < 3);
printf(" t<5 = %d (1)\n", t < 5);
printf("t<-1 = %d (0)\n", t < -1);
printf("\n");
printf(" t<=4 = %d (1)\n", t <= 4);
printf(" t<=3 = %d (0)\n", t <= 3);
printf(" t<=5 = %d (1)\n", t <= 5);
printf("t<=-1 = %d (0)\n", t <= -1);
printf("\n");
t = 4;
printf(" t>4 = %d (0)\n", t > 4);
printf(" t>3 = %d (1)\n", t > 3);
printf(" t>5 = %d (0)\n", t > 5);
printf("t>-1 = %d (1)\n", t > -1);
printf("\n");
printf(" t>=4 = %d (1)\n", t >= 4);
printf(" t>=3 = %d (1)\n", t >= 3);
printf(" t>=5 = %d (0)\n", t >= 5);
printf("t>=-1 = %d (1)\n", t >= -1);
printf("\n");
pi = -100;
printf(" pi<4 = %d (0)\n", pi < (int*)4);
printf(" pi<3 = %d (0)\n", pi < (int*)3);
printf("pi<-100 = %d (0)\n", pi < (int*)-100);
printf(" pi<-1 = %d (1)\n", pi < (int*)-1);
printf("\n");
printf(" pi<=4 = %d (0)\n", pi <= (int*)4);
printf(" pi<=3 = %d (0)\n", pi <= (int*)3);
printf("pi<=-100 = %d (1)\n", pi <= (int*)-100);
printf(" pi<=-1 = %d (1)\n", pi <= (int*)-1);
printf("\n");
pi = -100;
printf(" pi>4 = %d (1)\n", pi > (int*)4);
printf(" pi>3 = %d (1)\n", pi > (int*)3);
printf("pi>-100 = %d (0)\n", pi > (int*)-100);
printf(" pi>-1 = %d (0)\n", pi > (int*)-1);
printf("\n");
printf(" pi>=4 = %d (1)\n", pi >= (int*)4);
printf(" pi>=3 = %d (1)\n", pi >= (int*)3);
printf("pi>=-100 = %d (1)\n", pi >= (int*)-100);
printf(" pi>=-1 = %d (0)\n", pi >= (int*)-1);
printf("\n");
pi = &arr[0];
pip = &arr[3];
printf(" *pip - *pi: %d (30)\n", *pip - *pi);
printf(" pip - pi: %d (3)\n", pip - pi);
printf(" *pip: %d (40)\n", *pip);
printf(" *(pip - 3): %d (10)\n", *(pip - 3));
printf(" *&arr[3]: %d (40)\n", *&arr[3]);
printf("*(&arr[3] - 3): %d (10)\n", *(&arr[3]-3));
}

View File

@@ -1,128 +0,0 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
int aaa;
int bbb;
int ccc;
char gc;
char gbuffer[3];
int gibuffer[4];
int main(void)
{
char b;
int la;
unsigned int u1, u2;
int s1, s2;
unsigned char uc1, uc2;
char sc1, sc2;
int fd;
char buffer[6];
int ibuffer[7];
printf(" sizeof(uc1): %d 1\n", sizeof(uc1));
printf(" sizeof(sc1): %d 1\n", sizeof(sc1));
printf(" sizeof(u1): %d 4\n", sizeof(u1));
printf(" sizeof(s1): %d 4\n", sizeof(s1));
printf(" sizeof(aaa): %d 4\n", sizeof(aaa));
printf(" sizeof(bbb): %d 4\n", sizeof(bbb));
printf(" sizeof(gc): %d 1\n", sizeof(gc));
printf(" sizeof(buffer): %d 6\n", sizeof(buffer));
printf(" sizeof(ibuffer): %d 28\n", sizeof(ibuffer));
printf(" sizeof(char): %d 1\n", sizeof(char));
printf(" sizeof(int): %d 4\n", sizeof(int));
printf(" sizeof(gbuffer): %d 3\n", sizeof(gbuffer));
printf(" sizeof(gibuffer): %d 16\n", sizeof(gibuffer));
// sizeof(ibuffer[0]) is not supported, so the following can be used...
printf("sizeof(ibuffer)/sizeof(int): %d 7\n", sizeof(ibuffer)/sizeof(int));
aaa = 1;
bbb = 2;
la = 4;
printf("%d 1\n", aaa);
printf("%d 2\n", bbb);
printf("%d 4\n", la);
uc1 = 0x80;
sc1 = 0x80;
s1 = uc1;
s2 = sc1;
printf("unsigned char (0x80) -> int: %d 128\n", s1);
printf(" signed char (0x80) -> int: %d -128\n", s2);
u1 = uc1;
u2 = sc1;
printf("unsigned char (0x80) -> unsigned: %d 128\n", u1);
printf(" signed char (0x80) -> unsigned: %d -128\n", u2);
la = errno;
printf("errno: %d 0\n", la);
write(1, "abcd ", 5);
la = errno;
printf("errno after good write call: %d 0\n", la);
write(10, "abcde", 5);
la = errno;
printf("errno after bad write call: %d 9\n", la);
write(1, "abcd ", 5);
la = errno;
printf("good write after failed should not overwrite errno: %d 9\n", la);
errno = 0;
write(1, "abcd ", 5);
la = errno;
printf("good write after errno set to zero: %d 0\n", la);
la = write(1, "abcd ", 5);
printf("write() return: %d 5\n", la);
la = write(10, "abcd ", 5);
printf("write(bad fd) return: %d -1\n", la);
fd = open("/a.txt", O_WRONLY | O_CREAT, 0666);
if (fd != -1) {
printf("open success\n");
la = write(fd, "abcd\n", 5);
if (la == 5) printf("write success\n"); else printf("write failed\n");
la = close(fd);
if (la != -1) printf("close success\n"); else printf("close failed\n");
} else {
printf("open failed\n");
}
buffer[0] = 0;
buffer[1] = 0;
buffer[2] = 0;
buffer[3] = 0;
buffer[4] = 0;
buffer[5] = 0;
fd = open("/a.txt", O_RDONLY, 0666);
if (fd != -1) {
printf("open success\n");
la = read(fd, buffer, 5);
printf(buffer);
if (la == 5) printf("read success\n"); else printf("read failed\n");
la = close(fd);
if (la != -1) printf("close success\n"); else printf("close failed\n");
} else {
printf("open failed\n");
}
if (buffer[0] != 'a') printf("data0 readback from file MISMATCH\n");
if (buffer[1] != 'b') printf("data1 readback from file MISMATCH\n");
if (buffer[2] != 'c') printf("data2 readback from file MISMATCH\n");
if (buffer[3] != 'd') printf("data3 readback from file MISMATCH\n");
if (buffer[4] != '\n') printf("data4 readback from file MISMATCH\n");
if (buffer[0] != 'a' || buffer[1] != 'b' || buffer[2] != 'c' ||
buffer[3] != 'd' || buffer[4] != '\n') {
printf("data readback from file MISMATCH\n");
} else {
printf("data readback from file OK\n");
}
}

View File

@@ -1,51 +0,0 @@
#include <stdio.h>
void printt(int t, char* str);
int main(void)
{
int t;
t = 0;
if (t) printt(t, "failure"); else printt(t, "success");
t = 1;
if (t) printt(t, "success"); else printt(t, "failure");
t = 8;
if (t) printt(t, "success"); else printt(t, "failure");
t = -2;
if (t) printt(t, "success"); else printt(t, "failure");
printf("\n");
t = 4;
printf("switch test: ");
switch (t) {
case 3:
printf("failure");
break;
case 4:
printf("success");
break;
case 5:
printf("failure");
break;
}
printf("\n");
printf("switch fallthrough test: ");
switch (t) {
case 3:
printf("failure");
break;
case 4:
printf("OKSOFAR: ");
case 5:
printf("success if oksofar printed before this in caps");
break;
}
printf("\n");
}
void printt(int t, char* str)
{
printf("bool test on value %d %s\n", t, str);
}

View File

@@ -9,7 +9,7 @@ include $(TOPSRC)/target.mk
# Programs that live in subdirectories, and have makefiles of their own.
#
SUBDIR = startup-$(MACHINE) libc libm libutil libtermlib libcurses \
libvmf libwiznet share cmd games man
libvmf libwiznet share cmd games
all: $(SUBDIR)

View File

@@ -10,9 +10,9 @@ CFLAGS += -Werror
# Programs that live in subdirectories, and have makefiles of their own.
# /bin
SUBDIR = adb adc-demo aout ar as awk basic cc chflags chpass \
cpp dc diff emg env fdisk find forth fstat glcdtest \
hostname id la lcc lcpp ld levee ls login make man med \
SUBDIR = adb adc-demo ar as awk basic cc chflags chpass \
cpp dc diff env fdisk find forth fstat glcdtest hostname \
id la lcc lcpp ld ls login make man med \
more nm passwd picoc portio printf pwm \
rdprof ranlib re renice retroforth scm setty sl \
sed sh smallc smlrc stty sysctl test uname wiznet xargs \

View File

@@ -1 +0,0 @@
aout

View File

@@ -1,25 +0,0 @@
#
# aout - Display information from a.out files
#
TOPSRC = $(shell cd ../../..; pwd)
include $(TOPSRC)/target.mk
#include $(TOPSRC)/cross.mk
CFLAGS += -Werror -Wall -Os
LDFLAGS +=
AOUTOBJS = aout.o mips-dis.o
all: aout
aout: $(AOUTOBJS)
${CC} ${LDFLAGS} -o aout.elf $(AOUTOBJS) ${LIBS}
${OBJDUMP} -S aout.elf > aout.dis
${SIZE} aout.elf
${ELF2AOUT} aout.elf $@ && rm aout.elf
clean:
rm -f *.o *.0 *.elf aout tags *~ *.dis
install: all
install aout $(DESTDIR)/bin/

View File

@@ -1,5 +1,6 @@
#
# as - Assembler
# aout - Display information from a.out files
#
TOPSRC = $(shell cd ../../..; pwd)
include $(TOPSRC)/target.mk
@@ -8,7 +9,9 @@ include $(TOPSRC)/target.mk
CFLAGS += -Werror -Wall -Os
LDFLAGS +=
all: as
AOUTOBJS = aout.o mips-dis.o
all: as aout
as: as.o
${CC} ${LDFLAGS} -o as.elf as.o ${LIBS}
@@ -16,8 +19,26 @@ as: as.o
${SIZE} as.elf
${ELF2AOUT} as.elf $@ && rm as.elf
aout: $(AOUTOBJS)
${CC} ${LDFLAGS} -o aout.elf $(AOUTOBJS) ${LIBS}
${OBJDUMP} -S aout.elf > aout.dis
${SIZE} aout.elf
${ELF2AOUT} aout.elf $@ && rm aout.elf
clean:
rm -f *.o *.0 *.elf as tags *~ *.dis tests/*.dis tests/*.gcc-dis tests/*.o
rm -f *.o *.0 *.elf as aout tags *~ *.dis tests/*.dis tests/*.gcc-dis tests/*.o
test:
/usr/local/pic32-tools/bin/pic32-as -al example.s
install: all
install as $(DESTDIR)/bin/
install aout $(DESTDIR)/bin/
test.dis-gcc: test.s
$(AS) $< -o test.o
${OBJDUMP} -D test.o > $@
test.dis: test.s as aout
./as $< -o test.o
./aout test.o > $@

View File

@@ -3,7 +3,7 @@ include $(TOPSRC)/target.mk
#include $(TOPSRC)/cross.mk
#CFLAGS = -DCROSS
OBJS = cpp.o cpy.o token.o compat.o doprnt.o
OBJS = cpp.o cpy.o token.o doprnt.o
MAN = cpp.0
MANSRC = cpp.1
@@ -31,7 +31,7 @@ install: all
install cpp $(DESTDIR)/bin/
cp cpp.0 $(DESTDIR)/share/man/cat1/
cpp.o: cpp.c cpp.h y.tab.h config.h
cpp.o: cpp.c y.tab.h
.l.o:
$(LEX) $(LFLAGS) $<
@@ -62,9 +62,3 @@ test:
cmp tests/run9 tests/res9
./cpp < tests/test10 > tests/run10
cmp tests/run10 tests/res10
./cpp < tests/test11 > tests/run11
cmp tests/run11 tests/res11
./cpp < tests/test12 > tests/run12
cmp tests/run12 tests/res12
./cpp < tests/test13 > tests/run13
cmp tests/run13 tests/res13

View File

@@ -1,91 +0,0 @@
/* $OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $ */
/* $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */
/*
* Copyright (c) 1998, 2003-2005, 2010-2011, 2013
* Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.h"
#include <string.h>
#ifndef HAVE_STRLCAT
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return dlen + strlen(s);
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return dlen + (s - src); /* count does not include NUL */
}
#endif /* HAVE_STRLCAT */
#ifndef HAVE_STRLCPY
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return s - src - 1; /* count does not include NUL */
}
#endif /* HAVE_STRLCPY */

View File

@@ -1,14 +0,0 @@
#ifndef COMPAT_H__
#define COMPAT_H__
#include <string.h>
#ifndef HAVE_STRLCPY
size_t strlcpy(char* dst, const char* src, size_t size);
#endif
#ifndef HAVE_STRLCAT
size_t strlcat(char* dst, const char* src, size_t size);
#endif
#endif // COMPAT_H__

View File

@@ -1,11 +0,0 @@
#ifndef CONFIG_H__
#define CONFIG_H__
#define VERSSTR "cpp for RetroBSD"
#define HAVE_UNISTD_H 1
#define HAVE_SYS_WAIT_H 1
//#define HAVE_STRLCPY 1
//#define HAVE_STRLCAT 1
#endif // CONFIG_H__

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,5 @@
/* $Id: cpp.h,v 1.47.2.1 2011/02/26 06:36:40 ragge Exp $ */
/*
* Copyright (c) 2004,2010 Anders Magnusson (ragge@ludd.luth.se).
* Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -12,6 +10,8 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
@@ -24,15 +24,25 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h> /* for obuf */
#ifdef CROSS
# include </usr/include/stdio.h>
# include </usr/include/ctype.h>
#else
# include <stdio.h> /* for obuf */
# include <ctype.h>
#endif
#include <stdlib.h>
#include "config.h"
/* Version string */
#define VERSSTR "cpp for RetroBSD"
typedef unsigned char usch;
extern usch yytext[];
extern usch *stringbuf;
typedef unsigned char uchar;
#ifdef YYTEXT_POINTER
extern char *yytext;
#else
extern char yytext[];
#endif
extern uchar *stringbuf;
extern int trulvl;
extern int flslvl;
@@ -40,7 +50,7 @@ extern int elflvl;
extern int elslvl;
extern int tflag, Cflag, Pflag;
extern int Mflag, dMflag;
extern usch *Mfile;
extern uchar *Mfile;
extern int ofd;
/* args for lookup() */
@@ -48,77 +58,32 @@ extern int ofd;
#define ENTER 1
/* buffer used internally */
#define CPPBUF 512
#ifndef CPPBUF
#if defined(__pdp11__)
#define CPPBUF BUFSIZ
#define BUF_STACK
#elif defined(WIN32)
/* winxp seems to fail > 26608 bytes */
#define CPPBUF 16384
#else
#define CPPBUF (65536*2)
#endif
#endif
#define MAXARGS 20//128 /* Max # of args to a macro. Should be enouth */
#define CPPBUF 512
#define NAMEMAX CPPBUF /* currently pushbackbuffer */
#define BBUFSZ (NAMEMAX+CPPBUF+1)
#define GCCARG 0xfd /* has gcc varargs that may be replaced with 0 */
#define VARG 0xfe /* has varargs */
#define OBJCT 0xff
#define WARN 1 /* SOH, not legal char */
#define CONC 2 /* STX, not legal char */
#define SNUFF 3 /* ETX, not legal char */
#define EBLOCK 4 /* EOT, not legal char */
/* Used in macro expansion */
#define RECMAX 400//10000 /* max # of recursive macros */
extern struct symtab *norep[RECMAX];
extern int norepptr;
extern unsigned short bptr[RECMAX];
extern int bidx;
#define MKB(l,h) (l+((h)<<8))
/* quick checks for some characters */
#define C_SPEC 001
#define C_EP 002
#define C_ID 004
#define C_I (C_SPEC|C_ID)
#define C_2 010 /* for yylex() tokenizing */
#define C_WSNL 020 /* ' ','\t','\r','\n' */
#define iswsnl(x) (spechr[x] & C_WSNL)
extern char spechr[];
/* definition for include file info */
struct includ {
struct includ *next;
const usch *fname; /* current fn, changed if #line found */
const usch *orgfn; /* current fn, not changed */
const uchar *fname; /* current fn, changed if #line found */
const uchar *orgfn; /* current fn, not changed */
int lineno;
int infil;
usch *curptr;
usch *maxread;
usch *ostr;
usch *buffer;
uchar *curptr;
uchar *maxread;
uchar *ostr;
uchar *buffer;
int idx;
void *incs;
const usch *fn;
#ifdef BUF_STACK
usch bbuf[BBUFSZ];
#else
usch *bbuf;
#endif
};
extern struct includ *ifiles;
const uchar *fn;
uchar bbuf[NAMEMAX+CPPBUF+1];
} *ifiles;
/* Symbol table entry */
struct symtab {
const usch *namep;
const usch *value;
const usch *file;
const uchar *namep;
const uchar *value;
const uchar *file;
int line;
};
@@ -145,15 +110,13 @@ struct nd {
#define nd_val n.val
#define nd_uval n.uval
struct symtab *lookup(const usch *namep, int enterf);
usch *gotident(struct symtab *nl);
extern int slow; /* scan slowly for new tokens */
int submac(struct symtab *nl, int);
int kfind(struct symtab *nl);
int doexp(void);
int donex(void);
struct recur; /* not used outside cpp.c */
int subst(struct symtab *, struct recur *);
struct symtab *lookup(const uchar *namep, int enterf);
uchar *gotident(struct symtab *nl);
int slow; /* scan slowly for new tokens */
int pushfile(const usch *fname, const usch *fn, int idx, void *incs);
int pushfile(const uchar *fname, const uchar *fn, int idx, void *incs);
void popfile(void);
void prtline(void);
int yylex(void);
@@ -165,22 +128,18 @@ void setline(int);
void setfile(char *);
int yyparse(void);
void yyerror(const char *);
void unpstr(const usch *);
usch *savstr(const usch *str);
void unpstr(const uchar *);
uchar *savstr(const uchar *str);
void savch(int c);
void mainscan(void);
void putch(int);
void putstr(const usch *s);
void putstr(const uchar *s);
void line(void);
usch *sheap(const char *fmt, ...);
void xwarning(usch *);
void xerror(usch *);
#ifdef HAVE_CPP_VARARG_MACRO_GCC
#define warning(...) xwarning(sheap(__VA_ARGS__))
#define error(...) xerror(sheap(__VA_ARGS__))
#else
#define warning printf
#define error printf
#endif
uchar *sheap(const char *fmt, ...);
void xwarning(uchar *);
void xerror(uchar *);
#define warning(args...) xwarning(sheap(args))
#define error(args...) xerror(sheap(args))
void expmac(struct recur *);
int cinput(void);
void getcmnt(void);

View File

@@ -1,5 +1,3 @@
/* $Id: cpy.y,v 1.18 2010/02/25 15:49:00 ragge Exp $ */
/*
* Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
* All rights reserved.
@@ -60,7 +58,6 @@
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
%{
#include "cpp.h"

View File

@@ -1,939 +0,0 @@
%{
/* $Id: scanner.l,v 1.49 2009/02/14 09:23:55 ragge Exp $ */
/*
* Copyright (c) 2004 Anders Magnusson. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#include <errno.h>
#include "compat.h"
#include "cpp.h"
#include "y.tab.h"
%}
%{
static void cvtdig(int rad);
static int charcon(usch *);
static void elsestmt(void);
static void ifdefstmt(void);
static void ifndefstmt(void);
static void endifstmt(void);
static void ifstmt(void);
static void cpperror(void);
static void pragmastmt(void);
static void undefstmt(void);
static void cpperror(void);
static void elifstmt(void);
static void storepb(void);
static void badop(const char *);
void include(void);
void define(void);
extern int yyget_lineno (void);
extern void yyset_lineno (int);
static int inch(void);
static int scale, gotdef, contr;
int inif;
#ifdef FLEX_SCANNER /* should be set by autoconf instead */
static int
yyinput(char *b, int m)
{
int c, i;
for (i = 0; i < m; i++) {
if ((c = inch()) < 0)
break;
*b++ = c;
if (c == '\n') {
i++;
break;
}
}
return i;
}
#undef YY_INPUT
#undef YY_BUF_SIZE
#define YY_BUF_SIZE (8*65536)
#define YY_INPUT(b,r,m) (r = yyinput(b, m))
#ifdef HAVE_CPP_VARARG_MACRO_GCC
#define fprintf(x, ...) error(__VA_ARGS__)
#endif
#define ECHO putstr((usch *)yytext)
#undef fileno
#define fileno(x) 0
#if YY_FLEX_SUBMINOR_VERSION >= 31
/* Hack to avoid unnecessary warnings */
FILE *yyget_in (void);
FILE *yyget_out (void);
int yyget_leng (void);
char *yyget_text (void);
void yyset_in (FILE * in_str );
void yyset_out (FILE * out_str );
int yyget_debug (void);
void yyset_debug (int bdebug );
int yylex_destroy (void);
#endif
#else /* Assume lex here */
#undef input
#undef unput
#define input() inch()
#define unput(ch) unch(ch)
#endif
#define PRTOUT(x) if (YYSTATE || slow) return x; if (!flslvl) putstr((usch *)yytext);
/* protection against recursion in #include */
#define MAX_INCLEVEL 100
static int inclevel;
%}
D [0-9]
L [a-zA-Z_]
H [a-fA-F0-9]
E [Ee][+-]?{D}+
FS (f|F|l|L)
IS (u|U|l|L)*
WS [\t ]
%s IFR CONTR DEF COMMENT
%%
"\n" { int os = YYSTATE;
if (os != IFR)
BEGIN 0;
ifiles->lineno++;
if (flslvl == 0) {
if (ifiles->lineno == 1)
prtline();
else
putch('\n');
}
if ((os != 0 || slow) && !contr)
return '\n';
contr = 0;
}
"\r" { ; /* Ignore CR's */ }
<IFR>"++" { badop("++"); }
<IFR>"--" { badop("--"); }
<IFR>"==" { return EQ; }
<IFR>"!=" { return NE; }
<IFR>"<=" { return LE; }
<IFR>"<<" { return LS; }
<IFR>">>" { return RS; }
<IFR>">=" { return GE; }
<IFR>"||" { return OROR; }
<IFR>"&&" { return ANDAND; }
<IFR>"defined" { int p, c;
gotdef = 1;
if ((p = c = yylex()) == '(')
c = yylex();
if (c != IDENT || (p != IDENT && p != '('))
error("syntax error");
if (p == '(' && yylex() != ')')
error("syntax error");
return NUMBER;
}
<IFR>{WS}+ { ; }
<IFR>{L}({L}|{D})* {
yylval.node.op = NUMBER;
if (gotdef) {
yylval.node.nd_val
= lookup((usch *)yytext, FIND) != 0;
gotdef = 0;
return IDENT;
}
yylval.node.nd_val = 0;
return NUMBER;
}
[0-9][0-9]* {
if (slow && !YYSTATE)
return IDENT;
scale = yytext[0] == '0' ? 8 : 10;
goto num;
}
0[xX]{H}+{IS}? { scale = 16;
num: if (YYSTATE == IFR)
cvtdig(scale);
PRTOUT(NUMBER);
}
0{D}+{IS}? { scale = 8; goto num; }
{D}+{IS}? { scale = 10; goto num; }
'(\\.|[^\\'])+' {
if (YYSTATE || slow) {
yylval.node.op = NUMBER;
yylval.node.nd_val = charcon((usch *)yytext);
return (NUMBER);
}
if (tflag)
yyless(1);
if (!flslvl)
putstr((usch *)yytext);
}
<IFR>. { return yytext[0]; }
{D}+{E}{FS}? { PRTOUT(FPOINT); }
{D}*"."{D}+({E})?{FS}? { PRTOUT(FPOINT); }
{D}+"."{D}*({E})?{FS}? { PRTOUT(FPOINT); }
^{WS}*#{WS}* { extern int inmac;
if (inmac)
error("preprocessor directive found "
"while expanding macro");
contr = 1;
BEGIN CONTR;
}
{WS}+ { PRTOUT(WSPACE); }
<CONTR>"ifndef" { contr = 0; ifndefstmt(); }
<CONTR>"ifdef" { contr = 0; ifdefstmt(); }
<CONTR>"if" { contr = 0; storepb(); BEGIN IFR; ifstmt(); BEGIN 0; }
<CONTR>"include" { contr = 0; BEGIN 0; include(); prtline(); }
<CONTR>"else" { contr = 0; elsestmt(); }
<CONTR>"endif" { contr = 0; endifstmt(); }
<CONTR>"error" { contr = 0; if (slow) return IDENT; cpperror(); BEGIN 0; }
<CONTR>"define" { contr = 0; BEGIN DEF; define(); BEGIN 0; }
<CONTR>"undef" { contr = 0; if (slow) return IDENT; undefstmt(); }
<CONTR>"line" { contr = 0; storepb(); BEGIN 0; line(); }
<CONTR>"pragma" { contr = 0; pragmastmt(); BEGIN 0; }
<CONTR>"elif" { contr = 0; storepb(); BEGIN IFR; elifstmt(); BEGIN 0; }
"//".*$ { /* if (tflag) yyless(..) */
if (Cflag && !flslvl && !slow)
putstr((usch *)yytext);
else if (!flslvl)
putch(' ');
}
"/*" { int c, wrn;
int prtcm = Cflag && !flslvl && !slow;
extern int readmac;
if (Cflag && !flslvl && readmac)
return CMNT;
if (prtcm)
putstr((usch *)yytext);
wrn = 0;
more: while ((c = input()) && c != '*') {
if (c == '\n')
putch(c), ifiles->lineno++;
else if (c == 1) /* WARN */
wrn = 1;
else if (prtcm)
putch(c);
}
if (c == 0)
return 0;
if (prtcm)
putch(c);
if ((c = input()) && c != '/') {
unput(c);
goto more;
}
if (prtcm)
putch(c);
if (c == 0)
return 0;
if (!tflag && !Cflag && !flslvl)
unput(' ');
if (wrn)
unput(1);
}
<DEF>"##" { return CONCAT; }
<DEF>"#" { return MKSTR; }
<DEF>"..." { return ELLIPS; }
<DEF>"__VA_ARGS__" { return VA_ARGS; }
L?\"(\\.|[^\\"])*\" { PRTOUT(STRING); }
[a-zA-Z_0-9]+ { /* {L}({L}|{D})* */
struct symtab *nl;
if (slow)
return IDENT;
if (YYSTATE == CONTR) {
if (flslvl == 0) {
/*error("undefined control");*/
while (input() != '\n')
;
unput('\n');
BEGIN 0;
goto xx;
} else {
BEGIN 0; /* do nothing */
}
}
if (flslvl) {
; /* do nothing */
} else if (isdigit((int)yytext[0]) == 0 &&
(nl = lookup((usch *)yytext, FIND)) != 0) {
usch *op = stringbuf;
putstr(gotident(nl));
stringbuf = op;
} else
putstr((usch *)yytext);
xx: ;
}
. {
if (contr) {
while (input() != '\n')
;
unput('\n');
BEGIN 0;
contr = 0;
goto yy;
}
if (YYSTATE || slow)
return yytext[0];
if (yytext[0] == 6) { /* PRAGS */
usch *obp = stringbuf;
extern usch *prtprag(usch *);
*stringbuf++ = yytext[0];
do {
*stringbuf = input();
} while (*stringbuf++ != 14);
prtprag(obp);
stringbuf = obp;
} else {
PRTOUT(yytext[0]);
}
yy:;
}
%%
usch *yyp, yybuf[CPPBUF];
int yylex(void);
int yywrap(void);
static int
inpch(void)
{
int len;
if (ifiles->curptr < ifiles->maxread)
return *ifiles->curptr++;
if ((len = read(ifiles->infil, ifiles->buffer, CPPBUF)) < 0)
error("read error on file %s", ifiles->orgfn);
if (len == 0)
return -1;
ifiles->curptr = ifiles->buffer;
ifiles->maxread = ifiles->buffer + len;
return inpch();
}
#define unch(c) *--ifiles->curptr = c
static int
inch(void)
{
int c;
again: switch (c = inpch()) {
case '\\': /* continued lines */
msdos: if ((c = inpch()) == '\n') {
ifiles->lineno++;
putch('\n');
goto again;
} else if (c == '\r')
goto msdos;
unch(c);
return '\\';
case '?': /* trigraphs */
if ((c = inpch()) != '?') {
unch(c);
return '?';
}
switch (c = inpch()) {
case '=': c = '#'; break;
case '(': c = '['; break;
case ')': c = ']'; break;
case '<': c = '{'; break;
case '>': c = '}'; break;
case '/': c = '\\'; break;
case '\'': c = '^'; break;
case '!': c = '|'; break;
case '-': c = '~'; break;
default:
unch(c);
unch('?');
return '?';
}
unch(c);
goto again;
default:
return c;
}
}
/*
* Let the command-line args be faked defines at beginning of file.
*/
static void
prinit(struct initar *it, struct includ *ic)
{
char *a, *pre, *post;
if (it->next)
prinit(it->next, ic);
pre = post = NULL; /* XXX gcc */
switch (it->type) {
case 'D':
pre = "#define ";
if ((a = strchr(it->str, '=')) != NULL) {
*a = ' ';
post = "\n";
} else
post = " 1\n";
break;
case 'U':
pre = "#undef ";
post = "\n";
break;
case 'i':
pre = "#include \"";
post = "\"\n";
break;
default:
error("prinit");
}
strlcat((char *)ic->buffer, pre, CPPBUF+1);
strlcat((char *)ic->buffer, it->str, CPPBUF+1);
if (strlcat((char *)ic->buffer, post, CPPBUF+1) >= CPPBUF+1)
error("line exceeds buffer size");
ic->lineno--;
while (*ic->maxread)
ic->maxread++;
}
/*
* A new file included.
* If ifiles == NULL, this is the first file and already opened (stdin).
* Return 0 on success, -1 if file to be included is not found.
*/
int
pushfile(usch *file)
{
extern struct initar *initar;
struct includ ibuf;
struct includ *ic;
int c, otrulvl;
ic = &ibuf;
ic->next = ifiles;
slow = 0;
if (file != NULL) {
if ((ic->infil = open((char *)file, O_RDONLY)) < 0)
return -1;
ic->orgfn = ic->fname = file;
if (++inclevel > MAX_INCLEVEL)
error("Limit for nested includes exceeded");
} else {
ic->infil = 0;
ic->orgfn = ic->fname = (usch *)"<stdin>";
}
ic->buffer = ic->bbuf+NAMEMAX;
ic->curptr = ic->buffer;
ifiles = ic;
ic->lineno = 1;
ic->maxread = ic->curptr;
prtline();
if (initar) {
*ic->maxread = 0;
prinit(initar, ic);
if (dMflag)
write(ofd, ic->buffer, strlen((char *)ic->buffer));
initar = NULL;
}
otrulvl = trulvl;
if ((c = yylex()) != 0)
error("yylex returned %d", c);
if (otrulvl != trulvl || flslvl)
error("unterminated conditional");
ifiles = ic->next;
close(ic->infil);
inclevel--;
return 0;
}
/*
* Print current position to output file.
*/
void
prtline()
{
usch *s, *os = stringbuf;
if (Mflag) {
if (dMflag)
return; /* no output */
if (ifiles->lineno == 1) {
s = sheap("%s: %s\n", Mfile, ifiles->fname);
write(ofd, s, strlen((char *)s));
}
} else if (!Pflag)
putstr(sheap("# %d \"%s\"\n", ifiles->lineno, ifiles->fname));
stringbuf = os;
}
void
cunput(int c)
{
#ifdef CPP_DEBUG
extern int dflag;
if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c);
#endif
unput(c);
}
int yywrap(void) { return 1; }
static int
dig2num(int c)
{
if (c >= 'a')
c = c - 'a' + 10;
else if (c >= 'A')
c = c - 'A' + 10;
else
c = c - '0';
return c;
}
/*
* Convert string numbers to unsigned long long and check overflow.
*/
static void
cvtdig(int rad)
{
unsigned long long rv = 0;
unsigned long long rv2 = 0;
char *y = yytext;
int c;
c = *y++;
if (rad == 16)
y++;
while (isxdigit(c)) {
rv = rv * rad + dig2num(c);
/* check overflow */
if (rv / rad < rv2)
error("Constant \"%s\" is out of range", yytext);
rv2 = rv;
c = *y++;
}
y--;
while (*y == 'l' || *y == 'L')
y++;
yylval.node.op = *y == 'u' || *y == 'U' ? UNUMBER : NUMBER;
yylval.node.nd_uval = rv;
if ((rad == 8 || rad == 16) && yylval.node.nd_val < 0)
yylval.node.op = UNUMBER;
if (yylval.node.op == NUMBER && yylval.node.nd_val < 0)
/* too large for signed */
error("Constant \"%s\" is out of range", yytext);
}
static int
charcon(usch *p)
{
int val, c;
p++; /* skip first ' */
val = 0;
if (*p++ == '\\') {
switch (*p++) {
case 'a': val = '\a'; break;
case 'b': val = '\b'; break;
case 'f': val = '\f'; break;
case 'n': val = '\n'; break;
case 'r': val = '\r'; break;
case 't': val = '\t'; break;
case 'v': val = '\v'; break;
case '\"': val = '\"'; break;
case '\'': val = '\''; break;
case '\\': val = '\\'; break;
case 'x':
while (isxdigit(c = *p)) {
val = val * 16 + dig2num(c);
p++;
}
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7':
p--;
while (isdigit(c = *p)) {
val = val * 8 + (c - '0');
p++;
}
break;
default: val = p[-1];
}
} else
val = p[-1];
return val;
}
static void
chknl(int ignore)
{
int t;
slow = 1;
while ((t = yylex()) == WSPACE)
;
if (t != '\n') {
if (ignore) {
warning("newline expected, got \"%s\"", yytext);
/* ignore rest of line */
while ((t = yylex()) && t != '\n')
;
}
else
error("newline expected, got \"%s\"", yytext);
}
slow = 0;
}
static void
elsestmt(void)
{
if (flslvl) {
if (elflvl > trulvl)
;
else if (--flslvl!=0) {
flslvl++;
} else {
trulvl++;
prtline();
}
} else if (trulvl) {
flslvl++;
trulvl--;
} else
error("If-less else");
if (elslvl==trulvl+flslvl)
error("Too many else");
elslvl=trulvl+flslvl;
chknl(1);
}
static void
ifdefstmt(void)
{
int t;
if (flslvl) {
/* just ignore the rest of the line */
while (input() != '\n')
;
unput('\n');
yylex();
flslvl++;
return;
}
slow = 1;
do
t = yylex();
while (t == WSPACE);
if (t != IDENT)
error("bad ifdef");
slow = 0;
if (flslvl == 0 && lookup((usch *)yytext, FIND) != 0)
trulvl++;
else
flslvl++;
chknl(0);
}
static void
ifndefstmt(void)
{
int t;
slow = 1;
do
t = yylex();
while (t == WSPACE);
if (t != IDENT)
error("bad ifndef");
slow = 0;
if (flslvl == 0 && lookup((usch *)yytext, FIND) == 0)
trulvl++;
else
flslvl++;
chknl(0);
}
static void
endifstmt(void)
{
if (flslvl) {
flslvl--;
if (flslvl == 0)
prtline();
} else if (trulvl)
trulvl--;
else
error("If-less endif");
if (flslvl == 0)
elflvl = 0;
elslvl = 0;
chknl(1);
}
/*
* Note! Ugly!
* Walk over the string s and search for defined, and replace it with
* spaces and a 1 or 0.
*/
static void
fixdefined(usch *s)
{
usch *bc, oc;
for (; *s; s++) {
if (*s != 'd')
continue;
if (memcmp(s, "defined", 7))
continue;
/* Ok, got defined, can scratch it now */
memset(s, ' ', 7);
s += 7;
#define WSARG(x) (x == ' ' || x == '\t')
if (*s != '(' && !WSARG(*s))
continue;
while (WSARG(*s))
s++;
if (*s == '(')
s++;
while (WSARG(*s))
s++;
#define IDARG(x) ((x>= 'A' && x <= 'Z') || (x >= 'a' && x <= 'z') || (x == '_'))
#define NUMARG(x) (x >= '0' && x <= '9')
if (!IDARG(*s))
error("bad defined arg");
bc = s;
while (IDARG(*s) || NUMARG(*s))
s++;
oc = *s;
*s = 0;
*bc = (lookup(bc, FIND) != 0) + '0';
memset(bc+1, ' ', s-bc-1);
*s = oc;
}
}
/*
* get the full line of identifiers after an #if, pushback a WARN and
* the line and prepare for expmac() to expand.
* This is done before switching state. When expmac is finished,
* pushback the expanded line, change state and call yyparse.
*/
static void
storepb(void)
{
usch *opb = stringbuf;
int c;
while ((c = input()) != '\n') {
if (c == '/') {
if ((c = input()) == '*') {
/* ignore comments here whatsoever */
usch *g = stringbuf;
getcmnt();
stringbuf = g;
continue;
} else if (c == '/') {
while ((c = input()) && c != '\n')
;
break;
}
unput(c);
c = '/';
}
savch(c);
}
cunput('\n');
savch(0);
fixdefined(opb); /* XXX can fail if #line? */
cunput(1); /* WARN XXX */
unpstr(opb);
stringbuf = opb;
slow = 1;
expmac(NULL);
slow = 0;
/* line now expanded */
while (stringbuf > opb)
cunput(*--stringbuf);
}
static void
ifstmt(void)
{
if (flslvl == 0) {
slow = 1;
if (yyparse())
++trulvl;
else
++flslvl;
slow = 0;
} else
++flslvl;
}
static void
elifstmt(void)
{
if (flslvl == 0)
elflvl = trulvl;
if (flslvl) {
if (elflvl > trulvl)
;
else if (--flslvl!=0)
++flslvl;
else {
slow = 1;
if (yyparse()) {
++trulvl;
prtline();
} else
++flslvl;
slow = 0;
}
} else if (trulvl) {
++flslvl;
--trulvl;
} else
error("If-less elif");
}
static usch *
svinp(void)
{
int c;
usch *cp = stringbuf;
while ((c = input()) && c != '\n')
savch(c);
savch('\n');
savch(0);
BEGIN 0;
return cp;
}
static void
cpperror(void)
{
usch *cp;
int c;
if (flslvl)
return;
c = yylex();
if (c != WSPACE && c != '\n')
error("bad error");
cp = svinp();
if (flslvl)
stringbuf = cp;
else
error("%s", cp);
}
static void
undefstmt(void)
{
struct symtab *np;
slow = 1;
if (yylex() != WSPACE || yylex() != IDENT)
error("bad undef");
if (flslvl == 0 && (np = lookup((usch *)yytext, FIND)))
np->value = 0;
slow = 0;
chknl(0);
}
static void
pragmastmt(void)
{
int c;
slow = 1;
if (yylex() != WSPACE)
error("bad pragma");
if (!flslvl)
putstr((usch *)"#pragma ");
do {
c = input();
if (!flslvl)
putch(c); /* Do arg expansion instead? */
} while (c && c != '\n');
ifiles->lineno++;
prtline();
slow = 0;
}
static void
badop(const char *op)
{
error("invalid operator in preprocessor expression: %s", op);
}
int
cinput()
{
return input();
}

View File

@@ -1,22 +0,0 @@
# 1 "<stdin>"
a
a b
a b c
a b c d
__attribute__((__noreturn__))
1 2

View File

@@ -1,21 +0,0 @@
# 1 "<stdin>"
2 2 2 2 2;
(0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0, (0 + 8) + 0,

View File

@@ -1,13 +0,0 @@
# 1 "<stdin>"
long

View File

@@ -15,8 +15,7 @@
f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);
f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) &
f(2 * (0,1))^m(0,1);
f(2 * (2+(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);
int i[] = { 1, 23, 4, 5, };
char c[2][6] = { "hello", "" };

View File

@@ -1,20 +0,0 @@
#define D1(s, ...) s
#define D2(s, ...) s D1(__VA_ARGS__)
#define D3(s, ...) s D2(__VA_ARGS__)
#define D4(s, ...) s D3(__VA_ARGS__)
D1(a)
D2(a, b)
D3(a, b, c)
D4(a, b, c, d)
#define __sun_attr___noreturn__ __attribute__((__noreturn__))
#define ___sun_attr_inner(__a) __sun_attr_##__a
#define __sun_attr__(__a) ___sun_attr_inner __a
#define __NORETURN __sun_attr__((__noreturn__))
__NORETURN
#define X(...)
#define Y(...) 1 __VA_ARGS__ 2
Y(X X() ())

View File

@@ -1,19 +0,0 @@
#define y 2
#define fe(p) sfe(p) p
#define sfe(p) p
#define Y fe(y) y fe(y)
Y;
# define S2B_QMIN 0
# define S2B_CMIN (S2B_QMIN + 8)
#define S2B_1(i) i,
#define S2B_2(i) S2B_1(i) S2B_1(i)
#define S2B_4(i) S2B_2(i) S2B_2(i)
#define S2B_8(i) S2B_4(i) S2B_4(i)
#define S2B_16(i) S2B_8(i) S2B_8(i)
#define S2B_32(i) S2B_16(i) S2B_16(i)
#define S2B_64(i) S2B_32(i) S2B_32(i)
#define S2B_128(i) S2B_64(i) S2B_64(i)
#define S2B_256(i) S2B_128(i) S2B_128(i)
S2B_256(S2B_CMIN + 0)

View File

@@ -1,11 +0,0 @@
#define UL long, foo
#define D(I,F) I
#define E(I) D(I)
E(UL)
#define FOO 1
#if (FOO == 1)
#endif /* FOO */

View File

@@ -1,5 +1,3 @@
/* $Id: token.c,v 1.48.2.2 2011/03/12 17:08:26 ragge Exp $ */
/*
* Copyright (c) 2004,2009 Anders Magnusson. All rights reserved.
*
@@ -39,24 +37,21 @@
* - inch() is like inpch but \\n and trigraphs are expanded.
* - unch() pushes back a character to the input stream.
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#ifdef CROSS
# include </usr/include/string.h>
#else
# include <string.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include "compat.h"
#include "cpp.h"
#include "y.tab.h"
static void cvtdig(int rad);
static int charcon(usch *);
static int charcon(uchar *);
static void elsestmt(void);
static void ifdefstmt(void);
static void ifndefstmt(void);
@@ -80,8 +75,9 @@ extern void yyset_lineno (int);
static int inch(void);
size_t strlcat(char *dst, const char *src, size_t siz);
int inif;
extern int dflag;
#define PUTCH(ch) if (!flslvl) putch(ch)
/* protection against recursion in #include */
@@ -91,16 +87,25 @@ static int inclevel;
/* get next character unaltered */
#define NXTCH() (ifiles->curptr < ifiles->maxread ? *ifiles->curptr++ : inpch())
usch yytext[CPPBUF];
#ifdef YYTEXT_POINTER
static char buf[CPPBUF];
char *yytext = buf;
#else
char yytext[CPPBUF];
#endif
char spechr[256] = {
0, 0, 0, 0, C_SPEC, C_SPEC, 0, 0,
0, C_WSNL, C_SPEC|C_WSNL, 0,
0, C_WSNL, 0, 0,
#define C_SPEC 1
#define C_EP 2
#define C_ID 4
#define C_I (C_SPEC|C_ID)
#define C_2 8 /* for yylex() tokenizing */
static const char spechr[256] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, C_SPEC, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
C_WSNL, C_2, C_SPEC, 0, 0, 0, C_2, C_SPEC,
0, C_2, C_SPEC, 0, 0, 0, C_2, C_SPEC,
0, 0, 0, C_2, 0, C_2, 0, C_SPEC|C_2,
C_I, C_I, C_I, C_I, C_I, C_I, C_I, C_I,
C_I, C_I, 0, 0, C_2, C_2, C_2, C_SPEC,
@@ -117,55 +122,14 @@ char spechr[256] = {
};
/*
* No-replacement array. If a macro is found and exists in this array
* then no replacement shall occur. This is a stack.
*/
struct symtab *norep[RECMAX]; /* Symbol table index table */
int norepptr = 1; /* Top of index table */
unsigned short bptr[RECMAX]; /* currently active noexpand macro stack */
int bidx; /* Top of bptr stack */
static void
unch(int c)
{
--ifiles->curptr;
if (ifiles->curptr < ifiles->bbuf)
error("pushback buffer full");
*ifiles->curptr = (usch)c;
}
static int
eatcmnt(void)
{
int ch;
if (Cflag) { PUTCH('/'); PUTCH('*'); }
for (;;) {
ch = inch();
if (ch == '\n') {
ifiles->lineno++;
PUTCH('\n');
}
if (ch == -1)
return -1;
if (ch == '*') {
ch = inch();
if (ch == '/') {
if (Cflag) {
PUTCH('*');
PUTCH('/');
} else
PUTCH(' ');
break;
}
unch(ch);
ch = '*';
}
if (Cflag) PUTCH(ch);
}
return 0;
*ifiles->curptr = (uchar)c;
}
/*
@@ -182,38 +146,51 @@ static void
fastscan(void)
{
struct symtab *nl;
int ch, i, ccnt/*, onemore*/;
usch *cp;
int ch, i;
goto run;
for (;;) {
ch = NXTCH();
xloop: if (ch == -1)
return;
if (dflag>1)
printf("fastscan ch %d (%c)\n", ch, ch > 31 ? ch : '@');
if ((spechr[ch] & C_SPEC) == 0) {
PUTCH(ch);
continue;
}
switch (ch) {
case EBLOCK:
case WARN:
case CONC:
error("bad char passed");
break;
case '/': /* Comments */
if ((ch = inch()) == '/') {
cppcmt: if (Cflag) { PUTCH(ch); } else { PUTCH(' '); }
if (Cflag) { PUTCH(ch); } else { PUTCH(' '); }
do {
if (Cflag) PUTCH(ch);
ch = inch();
} while (ch != -1 && ch != '\n');
goto xloop;
} else if (ch == '*') {
if (eatcmnt())
return;
if (Cflag) { PUTCH('/'); PUTCH('*'); }
for (;;) {
ch = inch();
if (ch == '\n') {
ifiles->lineno++;
PUTCH('\n');
}
if (ch == -1)
return;
if (ch == '*') {
ch = inch();
if (ch == '/') {
if (Cflag) {
PUTCH('*');
PUTCH('/');
} else
PUTCH(' ');
break;
}
unch(ch);
ch = '*';
}
if (Cflag) PUTCH(ch);
}
} else {
PUTCH('/');
goto xloop;
@@ -236,30 +213,11 @@ cppcmt: if (Cflag) { PUTCH(ch); } else { PUTCH(' '); }
goto xloop;
case '\n': /* newlines, for pp directives */
run2: ifiles->lineno++;
ifiles->lineno++;
do {
PUTCH(ch);
run: ch = NXTCH();
if (ch == '/') {
ch = NXTCH();
if (ch == '/')
goto cppcmt;
if (ch == '*') {
if (eatcmnt())
return;
goto run;
}
unch(ch);
ch = '/';
}
} while (ch == ' ' || ch == '\t');
if (ch == '\\') {
ch = NXTCH();
if (ch == '\n')
goto run2;
unch(ch);
ch = '\\';
}
if (ch == '#') {
ppdir();
continue;
@@ -278,7 +236,7 @@ run: ch = NXTCH();
case '\"': /* strings */
str: PUTCH(ch);
while ((ch = inch()) != '\"') {
PUTCH(ch);
PUTCH(ch);
if (ch == '\\') {
ch = inch();
PUTCH(ch);
@@ -299,16 +257,7 @@ str: PUTCH(ch);
case '5': case '6': case '7': case '8': case '9':
do {
PUTCH(ch);
nxt: ch = NXTCH();
if (ch == '\\') {
ch = NXTCH();
if (ch == '\n') {
goto nxt;
} else {
unch(ch);
ch = '\\';
}
}
ch = NXTCH();
if (spechr[ch] & C_EP) {
PUTCH(ch);
ch = NXTCH();
@@ -356,9 +305,9 @@ con: PUTCH(ch);
ch = NXTCH();
goto xloop;
}
/*onemore =*/ i = ccnt = 0;
i = 0;
do {
yytext[i++] = (usch)ch;
yytext[i++] = (uchar)ch;
ch = NXTCH();
if (ch == '\\') {
ch = NXTCH();
@@ -373,17 +322,14 @@ con: PUTCH(ch);
if (ch < 0)
return;
} while (spechr[ch] & C_ID);
yytext[i] = 0;
unch(ch);
cp = stringbuf;
if ((nl = lookup((usch *)yytext, FIND)) && kfind(nl)) {
putstr(stringbuf);
if ((nl = lookup((uchar *)yytext, FIND)) != 0) {
uchar *op = stringbuf;
putstr(gotident(nl));
stringbuf = op;
} else
putstr((usch *)yytext);
stringbuf = cp;
putstr((uchar *)yytext);
break;
}
}
@@ -398,7 +344,7 @@ sloscan()
zagain:
yyp = 0;
ch = inch();
yytext[yyp++] = (usch)ch;
yytext[yyp++] = (uchar)ch;
switch (ch) {
case -1:
return 0;
@@ -411,24 +357,24 @@ zagain:
yyp = 0;
break;
case '0': case '1': case '2': case '3': case '4': case '5':
case '0': case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9':
/* readin a "pp-number" */
ppnum: for (;;) {
ch = inch();
if (spechr[ch] & C_EP) {
yytext[yyp++] = (usch)ch;
yytext[yyp++] = (uchar)ch;
ch = inch();
if (ch == '-' || ch == '+') {
yytext[yyp++] = (usch)ch;
yytext[yyp++] = (uchar)ch;
} else
unch(ch);
continue;
}
if ((spechr[ch] & C_ID) || ch == '.') {
yytext[yyp++] = (usch)ch;
yytext[yyp++] = (uchar)ch;
continue;
}
}
break;
}
unch(ch);
@@ -437,11 +383,11 @@ ppnum: for (;;) {
return NUMBER;
case '\'':
chlit:
chlit:
for (;;) {
if ((ch = inch()) == '\\') {
yytext[yyp++] = (usch)ch;
yytext[yyp++] = (usch)inch();
yytext[yyp++] = (uchar)ch;
yytext[yyp++] = (uchar)inch();
continue;
} else if (ch == '\n') {
/* not a constant */
@@ -450,7 +396,7 @@ chlit:
ch = '\'';
goto any;
} else
yytext[yyp++] = (usch)ch;
yytext[yyp++] = (uchar)ch;
if (ch == '\'')
break;
}
@@ -461,7 +407,7 @@ chlit:
case ' ':
case '\t':
while ((ch = inch()) == ' ' || ch == '\t')
yytext[yyp++] = (usch)ch;
yytext[yyp++] = (uchar)ch;
unch(ch);
yytext[yyp] = 0;
return(WSPACE);
@@ -469,7 +415,7 @@ chlit:
case '/':
if ((ch = inch()) == '/') {
do {
yytext[yyp++] = (usch)ch;
yytext[yyp++] = (uchar)ch;
ch = inch();
} while (ch && ch != '\n');
yytext[yyp] = 0;
@@ -489,10 +435,7 @@ chlit:
more: while ((c = inch()) && c != '*') {
if (c == '\n')
putch(c), ifiles->lineno++;
else if (c == EBLOCK) {
(void)inch();
(void)inch();
} else if (c == 1) /* WARN */
else if (c == 1) /* WARN */
wrn = 1;
}
if (c == 0)
@@ -516,7 +459,7 @@ chlit:
case '.':
ch = inch();
if (isdigit(ch)) {
yytext[yyp++] = (usch)ch;
yytext[yyp++] = (uchar)ch;
goto ppnum;
} else {
unch(ch);
@@ -525,16 +468,14 @@ chlit:
goto any;
case '\"':
if (tflag)
goto any;
strng:
for (;;) {
if ((ch = inch()) == '\\') {
yytext[yyp++] = (usch)ch;
yytext[yyp++] = (usch)inch();
yytext[yyp++] = (uchar)ch;
yytext[yyp++] = (uchar)inch();
continue;
} else
yytext[yyp++] = (usch)ch;
} else
yytext[yyp++] = (uchar)ch;
if (ch == '\"')
break;
}
@@ -542,26 +483,26 @@ chlit:
return(STRING);
case 'L':
if ((ch = inch()) == '\"' && !tflag) {
yytext[yyp++] = (usch)ch;
if ((ch = inch()) == '\"') {
yytext[yyp++] = (uchar)ch;
goto strng;
} else if (ch == '\'' && !tflag) {
yytext[yyp++] = (usch)ch;
} else if (ch == '\'') {
yytext[yyp++] = (uchar)ch;
goto chlit;
}
unch(ch);
/* FALLTHROUGH */
/* Yetch, all identifiers */
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
case 's': case 't': case 'u': case 'v': case 'w': case 'x':
case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
case 'G': case 'H': case 'I': case 'J': case 'K':
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
case 'Y': case 'Z':
case '_': /* {L}({L}|{D})* */
@@ -569,7 +510,7 @@ chlit:
for (;;) { /* get chars */
ch = inch();
if (isalpha(ch) || isdigit(ch) || ch == '_') {
yytext[yyp++] = (usch)ch;
yytext[yyp++] = (uchar)ch;
} else {
unch(ch);
break;
@@ -643,31 +584,27 @@ yylex()
case NUMBER:
if (yytext[0] == '\'') {
yylval.node.op = NUMBER;
yylval.node.nd_val = charcon((usch *)yytext);
yylval.node.nd_val = charcon((uchar *)yytext);
} else
cvtdig(yytext[0] != '0' ? 10 :
yytext[1] == 'x' || yytext[1] == 'X' ? 16 : 8);
return NUMBER;
case IDENT:
if (strcmp((char *)yytext, "defined") == 0) {
if (strcmp(yytext, "defined") == 0) {
ifdef = 1;
return DEFINED;
}
nl = lookup((usch *)yytext, FIND);
nl = lookup((uchar *)yytext, FIND);
if (ifdef) {
yylval.node.nd_val = nl != NULL;
ifdef = 0;
} else if (nl && noex == 0) {
usch *och = stringbuf;
int i;
uchar *c, *och = stringbuf;
i = kfind(nl);
unch(WARN);
if (i)
unpstr(stringbuf);
else
unpstr(nl->namep);
c = gotident(nl);
unch(1);
unpstr(c);
stringbuf = och;
noex = 1;
return yylex();
@@ -676,7 +613,7 @@ yylex()
}
yylval.node.op = NUMBER;
return NUMBER;
case WARN:
case 1: /* WARN */
noex = 0;
return yylex();
default:
@@ -686,7 +623,7 @@ yylex()
return ch;
}
usch *yyp, yybuf[CPPBUF];
uchar *yyp, yybuf[CPPBUF];
int yywrap(void);
@@ -734,6 +671,41 @@ msdos: if ((c = inpch()) == '\n') {
}
}
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(initial dst) + strlen(src); if retval >= siz,
* truncation occurred.
*/
size_t
strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}
/*
* Let the command-line args be faked defines at beginning of file.
*/
@@ -782,29 +754,30 @@ prinit(struct initar *it, struct includ *ic)
* Return 0 on success, -1 if file to be included is not found.
*/
int
pushfile(const usch *file, const usch *fn, int idx, void *incs)
pushfile(const uchar *file, const uchar *fn, int idx, void *incs)
{
extern struct initar *initar;
struct includ ibuf;
struct includ *ic;
int otrulvl;
ic = &ibuf;
ic = malloc(sizeof(struct includ));
if (ic == NULL)
error("out of memory for %s", file);
ic->next = ifiles;
if (file != NULL) {
if ((ic->infil = open((const char *)file, O_RDONLY)) < 0)
ic->infil = open((const char *)file, O_RDONLY);
if (ic->infil < 0) {
free(ic);
return -1;
}
ic->orgfn = ic->fname = file;
if (++inclevel > MAX_INCLEVEL)
error("Limit for nested includes exceeded");
} else {
ic->infil = 0;
ic->orgfn = ic->fname = (const usch *)"<stdin>";
ic->orgfn = ic->fname = (const uchar *)"<stdin>";
}
#ifndef BUF_STACK
ic->bbuf = malloc(BBUFSZ);
#endif
ic->buffer = ic->bbuf+NAMEMAX;
ic->curptr = ic->buffer;
ifiles = ic;
@@ -821,7 +794,8 @@ pushfile(const usch *file, const usch *fn, int idx, void *incs)
prinit(initar, ic);
initar = NULL;
if (dMflag)
write(ofd, ic->buffer, strlen((char *)ic->buffer));
if (write(ofd, ic->buffer, strlen((char *)ic->buffer)) < 0)
/* ignore */;
fastscan();
prtline();
ic->infil = oin;
@@ -834,11 +808,9 @@ pushfile(const usch *file, const usch *fn, int idx, void *incs)
if (otrulvl != trulvl || flslvl)
error("unterminated conditional");
#ifndef BUF_STACK
free(ic->bbuf);
#endif
ifiles = ic->next;
close(ic->infil);
free(ic);
inclevel--;
return 0;
}
@@ -849,14 +821,15 @@ pushfile(const usch *file, const usch *fn, int idx, void *incs)
void
prtline()
{
usch *s, *os = stringbuf;
uchar *s, *os = stringbuf;
if (Mflag) {
if (dMflag)
return; /* no output */
if (ifiles->lineno == 1) {
s = sheap("%s: %s\n", Mfile, ifiles->fname);
write(ofd, s, strlen((char *)s));
if (write(ofd, s, strlen((char *)s)) < 0)
/* ignore */;
}
} else if (!Pflag)
putstr(sheap("\n# %d \"%s\"\n", ifiles->lineno, ifiles->fname));
@@ -867,8 +840,8 @@ void
cunput(int c)
{
#ifdef CPP_DEBUG
// extern int dflag;
// if (dflag)printf(": '%c'(%d)\n", c > 31 ? c : ' ', c);
extern int dflag;
if (dflag)printf(": '%c'(%d)", c > 31 ? c : ' ', c);
#endif
#if 0
if (c == 10) {
@@ -900,7 +873,7 @@ cvtdig(int rad)
{
unsigned long long rv = 0;
unsigned long long rv2 = 0;
usch *y = yytext;
char *y = yytext;
int c;
c = *y++;
@@ -927,7 +900,7 @@ cvtdig(int rad)
}
static int
charcon(usch *p)
charcon(uchar *p)
{
int val, c;
@@ -1020,8 +993,8 @@ skpln(void)
}
static void
ifdefstmt(void)
{
ifdefstmt(void)
{
int t;
if (flslvl) {
@@ -1033,7 +1006,7 @@ ifdefstmt(void)
while (t == WSPACE);
if (t != IDENT)
error("bad ifdef");
if (lookup((usch *)yytext, FIND) == 0) {
if (lookup((uchar *)yytext, FIND) == 0) {
putch('\n');
flslvl++;
} else
@@ -1042,8 +1015,8 @@ ifdefstmt(void)
}
static void
ifndefstmt(void)
{
ifndefstmt(void)
{
int t;
if (flslvl) {
@@ -1055,7 +1028,7 @@ ifndefstmt(void)
while (t == WSPACE);
if (t != IDENT)
error("bad ifndef");
if (lookup((usch *)yytext, FIND) != 0) {
if (lookup((uchar *)yytext, FIND) != 0) {
putch('\n');
flslvl++;
} else
@@ -1064,7 +1037,7 @@ ifndefstmt(void)
}
static void
endifstmt(void)
endifstmt(void)
{
if (flslvl) {
flslvl--;
@@ -1121,11 +1094,11 @@ elifstmt(void)
error("If-less elif");
}
static usch *
static uchar *
svinp(void)
{
int c;
usch *cp = stringbuf;
uchar *cp = stringbuf;
while ((c = inch()) && c != '\n')
savch(c);
@@ -1137,7 +1110,7 @@ svinp(void)
static void
cpperror(void)
{
usch *cp;
uchar *cp;
int c;
if (flslvl)
@@ -1155,7 +1128,7 @@ cpperror(void)
static void
cppwarning(void)
{
usch *cp;
uchar *cp;
int c;
if (flslvl)
@@ -1185,7 +1158,7 @@ undefstmt(void)
if (sloscan() != WSPACE || sloscan() != IDENT)
error("bad undef");
if (flslvl == 0 && (np = lookup((usch *)yytext, FIND)))
if (flslvl == 0 && (np = lookup((uchar *)yytext, FIND)))
np->value = 0;
chknl(0);
}
@@ -1198,7 +1171,7 @@ pragmastmt(void)
if (sloscan() != WSPACE)
error("bad pragma");
if (!flslvl)
putstr((const usch *)"\n#pragma ");
putstr((const uchar *)"#pragma ");
do {
c = inch();
if (!flslvl)
@@ -1292,7 +1265,7 @@ ppdir(void)
goto out; /* something else, ignore */
i = 0;
do {
bp[i++] = (usch)ch;
bp[i++] = (uchar)ch;
if (i == sizeof(bp)-1)
goto out; /* too long */
ch = inch();

View File

@@ -1 +0,0 @@
emg

View File

@@ -1,53 +0,0 @@
ChangeLog
=========
July 10, 2014 : emg 1.7
-----------------------
Searching now correctly updates line number display.
Remove lots of rarely-used word functions.
Remove search+replace: sed(1) is quicker.
Reduce size of some static buffers.
May 29, 2014 : emg 1.6
----------------------
emg is now part of the RetroBSD tree.
Add PgUp and PgDn scrolling.
March 16, 2014 : emg 1.5
------------------------
Add line number to the mode line.
Implement prompted go to line function.
Remove lesser used expensive movement functions.
Documentation tweaks to reflect above changes.
March 9, 2014 : emg 1.4
-----------------------
Huge whitespace cleanup.
Make the window creation code mode consistent.
Small documentation fix.
March 8, 2014 : emg 1.3
-----------------------
Remove all OpenBSD support. emg is now for RetroBSD only.
Remove tmux alternative keybindings.
Revert Listbuffer command back to CTRL-x CTRL-b.
December 2, 2013 : emg 1.2
--------------------------
Alternate keybindings for RetroBSD users using flow control terminal emulators.
Alternate keybindings for tmux users who are using the default control command.
October 24, 2013 : emg 1.1
--------------------------
Listbuffer command is now CTRL-x l (originally CTRL-x CTRL-b).
This is because the default command keybinding of tmux is CTRL-b.
Search is now executed with <ENTER> instead of <ESC>.
<ESC> felt awkward, plus I don't search for newlines.
Lots of code cleanups (ttyio.c).
Removal of unused #if blocks.
Use panic() everywhere.
Fix all warnings from gcc -Wall.
October 19, 2013 : emg 1.0
--------------------------
Initial version of emg. Current targets are OpenBSD and RetroBSD.

View File

@@ -1,49 +0,0 @@
# emg Makefile
# for RetroBSD
TOPSRC = $(shell cd ../../..; pwd)
include $(TOPSRC)/target.mk
# Some basic CFLAGS.
CFLAGS = -Os -Wall -Werror
# With the extra LDFLAGS, save some bytes.
CFLAGS += -ffunction-sections -fdata-sections
# This reduces code size significantly.
CFLAGS += -mips16
# Set the screen size.
# Will default to FORCE_COLS=80 and FORCE_ROWS=24
# if not set here.
#CFLAGS += -DFORCE_COLS=80 -DFORCE_ROWS=24
# with CFLAGS+= -ffunction-sections -fdata-sections
LDFLAGS += -Wl,--gc-sections
LIBS = -ltermcap -lc
MAN = emg.0
MANSRC = emg.1
OBJS = basic.o buffer.o display.o file.o fileio.o line.o main.o \
random.o region.o search.o tcap.o ttyio.o window.o word.o
all: emg ${MAN}
emg: ${OBJS}
${CC} ${LDFLAGS} -o emg.elf ${OBJS} ${LIBS}
${OBJDUMP} -S emg.elf > emg.dis
${SIZE} emg.elf
${ELF2AOUT} emg.elf $@ && rm emg.elf
${MAN}: ${MANSRC}
${MANROFF} ${MANSRC} > ${MAN}
install: all
install emg ${DESTDIR}/bin/emg
cp ${MAN} ${DESTDIR}/share/man/cat1/
cp -p emg.keys ${DESTDIR}/share/emg.keys
clean:
rm -f *.o *~ *.core *.bak *.dis emg ${MAN}

View File

@@ -1,41 +0,0 @@
emg
===
emg, or Ersatz Mg, is a very tiny Emacs-like text editor created by
combining elements of Ersatz Emacs and Mg (both the mg1a release and the
current OpenBSD-maintained version).
The goal of this editor is to have something Emacs like for RetroBSD
(a release of 2.11BSD for PIC32 microcontrollers). After noticing that the
vi clone RetroBSD is using, VIrus, is GPL-licensed, I decided to provide
a better-licensed editor. I also decided that, as a vi user myself, it would
be easier to create an Emacs clone. Like you, I'm also unsure as to how that
conclusion was reached.
I had initially tried to port Mg to RetroBSD but it was simply too large.
Ersatz Emacs does not build on RetroBSD, as RetroBSD is missing some functions
that Ersatz Emacs requires. It made sense to try to take from each and create
an editor that would work.
In a way, emg has a double meaning: not only is it a combination of
the two programs that comprise it, it is also a substitute Mg after my initial
port failed.
I have cleaned up some code where necessary; emg builds without errors on
RetroBSD.
Patches are also very welcome. I ask that you keep in mind the resource
constraints of RetroBSD: everything must fit in 96K RAM. But of course,
smaller is better.
I've left Chris Baird's Ersatz Emacs README here so others can better
appreciate the history of this software.
As both Ersatz Emacs and Mg are Public Domain, emg is also Public Domain.
Versions of emg up to and including 1.2 also supported OpenBSD; OpenBSD
has since dropped the older headers, such as sgtty.h, and it is not worth
reimplementing these for OpenBSD since OpenBSD maintains Mg.
====================================
Brian Callahan <bcallah@openbsd.org>

View File

@@ -1,39 +0,0 @@
This shar file contains the source to a microemacs-derived text editor
that I have been personally hacking on for over a decade.
Originally this was MicroEMACS 3.6 as released to mod.sources and the
Public Domain by Daniel Lawrence in 1986, and was itself based on the
work of Steve Wilhite and George Jones to MicroEMACS 2.0 (then also
public domain) by Dave Conroy. I would like to reiterate Lawrence's
thanks to them for writing such nice, well structured and documented
code.
"Ersatz-Emacs", as I call it today, is the above text editor throughly
cleansed of routines and features that I personally never use. It is
also an editor MINIX-creator Andy Tanenbaum could describe as "fitting
inside a student's brain" (namely, mine).
This source code should compile cleanly on any "modern" UN*X system
with a termcap/curses library. This release has been tested with
NetBSD and various Linux systems, although in the past when it was
still mostly MicroEMACS, proto-Ersatz-Emacs was an editor of choice on
SunOS, Solaris, Xenix, Minix/i386, and AIX. Supporting these and
similar systems should not be difficult.
I encourage people to personalise this very simple editor to their own
requirements. Please send any useful bug reports and fixes back to me,
but I'm not really interested in incorporating new features unless it
simplifies the program further. Feel free to do a code-fork and
distribute your own perfect text editor.
The title "Ersatz" comes from the category Richard Stallman uses in
MIT AI Memo 519a to describe those editors that are a surface-deep
imitation (key bindings) of "real" ITS Emacs. If you are familiar with
any Emacs-variant editor, you should have few problems with Ersatz.
All source code of this program is in the Public Domain. I am a rabid
Stallmanite weenie, but it would be improper to publish this under a
different licence than it was given to me with.
--
Chris Baird,, <cjb@brushtail.apana.org.au>

View File

@@ -1,289 +0,0 @@
/* This file is in the public domain. */
/*
* The routines in this file move the cursor around on the screen. They
* compute a new value for the cursor, then adjust ".". The display code
* always updates the cursor location, so only moves between lines, or
* functions that adjust the top line in the window and invalidate the
* framing, are hard.
*/
#include <stdlib.h> /* atoi(3), ugh */
#include "estruct.h"
#include "edef.h"
extern int getccol(int bflg);
extern void mlwrite();
extern int mlreplyt();
int forwchar(int f, int n);
int backchar(int f, int n);
int forwline(int f, int n);
int backline(int f, int n);
int pagedown(int f, int n);
int pageup(int f, int n);
/*
* This routine, given a pointer to a LINE, and the current cursor goal
* column, return the best choice for the offset. The offset is returned.
* Used by "C-N" and "C-P".
*/
long getgoal(LINE *dlp)
{
int col = 0;
int dbo = 0;
int newcol, c;
while (dbo != llength(dlp))
{
c = lgetc(dlp, dbo);
newcol = col;
if (c == '\t')
newcol |= 0x07;
else if (c < 0x20 || c == 0x7F)
++newcol;
++newcol;
if (newcol > curgoal)
break;
col = newcol;
++dbo;
}
return (dbo);
}
/*
* Move the cursor to the
* beginning of the current line.
* Trivial.
*/
/* ARGSUSED0 */
int gotobol(int f, int n)
{
curwp->w_doto = 0;
return (TRUE);
}
/*
* Move the cursor to the end of the current line. Trivial. No errors.
*/
/* ARGSUSED0 */
int gotoeol(int f, int n)
{
curwp->w_doto = llength(curwp->w_dotp);
return (TRUE);
}
/*
* Move the cursor backwards by "n" characters. If "n" is less than zero call
* "forwchar" to actually do the move. Otherwise compute the new cursor
* location. Error if you try and move out of the buffer. Set the flag if the
* line pointer for dot changes.
*/
int backchar(int f, int n)
{
LINE *lp;
if (n < 0)
return (forwchar(f, -n));
while (n--)
{
if (curwp->w_doto == 0)
{
if ((lp = lback(curwp->w_dotp)) == curbp->b_linep)
return (FALSE);
curwp->w_dotp = lp;
curwp->w_doto = llength(lp);
curwp->w_flag |= WFMOVE;
curwp->w_dotline--;
}
else
curwp->w_doto--;
}
return (TRUE);
}
/*
* Move the cursor forwards by "n" characters. If "n" is less than zero call
* "backchar" to actually do the move. Otherwise compute the new cursor
* location, and move ".". Error if you try and move off the end of the
* buffer. Set the flag if the line pointer for dot changes.
*/
int forwchar(int f, int n)
{
if (n < 0)
return (backchar(f, -n));
while (n--)
{
if (curwp->w_doto == llength(curwp->w_dotp))
{
if (curwp->w_dotp == curbp->b_linep)
return (FALSE);
curwp->w_dotp = lforw(curwp->w_dotp);
curwp->w_doto = 0;
curwp->w_flag |= WFMOVE;
curwp->w_dotline++;
}
else
curwp->w_doto++;
}
return (TRUE);
}
/*
* move to a particular line. argument (n) must be a positive integer for this
* to actually do anything
*/
int gotoline(int f, int n)
{
if ((n < 1) || (n > curwp->w_bufp->b_lines)) /* if a bogus argument...then leave */
return (FALSE); /* but we should never get here */
/* first, we go to the start of the buffer */
curwp->w_dotp = lforw(curbp->b_linep);
curwp->w_doto = 0;
curwp->w_dotline = 0; /* and reset the line number */
return (forwline(f, n - 1));
}
/*
* Prompt for which line number we want to go to, then execute gotoline()
* with that number as its argument.
*
* Make sure the bounds are within the file.
*
* Bound to M-G
*/
int setline(int f, int n)
{
char setl[6];
int l;
(void)mlreplyt("Go to line: ", setl, 6, 10);
l = atoi(setl); /* XXX: This sucks! */
if (l < 1)
l = 1;
else if (l > curwp->w_bufp->b_lines)
l = curwp->w_bufp->b_lines;
gotoline(f, l);
return (TRUE);
}
/*
* Goto the beginning of the buffer. Massive adjustment of dot. This is
* considered to be hard motion; it really isn't if the original value of dot
* is the same as the new value of dot. Normally bound to "M-<".
*/
/* ARGSUSED0 */
int gotobob(int f, int n)
{
curwp->w_dotp = lforw(curbp->b_linep);
curwp->w_doto = 0;
curwp->w_flag |= WFHARD;
curwp->w_dotline = 0;
return (TRUE);
}
/*
* Move to the end of the buffer. Dot is always put at the end of the file
* (ZJ). The standard screen code does most of the hard parts of update.
* Bound to "M->".
*/
/* ARGSUSED0 */
int gotoeob(int f, int n)
{
curwp->w_dotp = curbp->b_linep;
curwp->w_doto = 0;
curwp->w_flag |= WFHARD;
curwp->w_dotline = curwp->w_bufp->b_lines;
return (TRUE);
}
/*
* Move forward by full lines. If the number of lines to move is less than
* zero, call the backward line function to actually do it. The last command
* controls how the goal column is set. Bound to "C-N". No errors are possible.
*/
int forwline(int f, int n)
{
LINE *dlp;
if (n < 0)
return (backline(f, -n));
if ((lastflag & CFCPCN) == 0)/* Reset goal if last */
curgoal = getccol(FALSE); /* not C-P or C-N */
thisflag |= CFCPCN;
dlp = curwp->w_dotp;
while (n-- && dlp != curbp->b_linep)
{
dlp = lforw(dlp);
curwp->w_dotline++;
}
curwp->w_dotp = dlp;
curwp->w_doto = getgoal(dlp);
curwp->w_flag |= WFMOVE;
return (TRUE);
}
/*
* This function is like "forwline", but goes backwards. The scheme is exactly
* the same. Check for arguments that are less than zero and call your
* alternate. Figure out the new line and call "movedot" to perform the
* motion. No errors are possible. Bound to "C-P".
*/
int backline(int f, int n)
{
LINE *dlp;
if (n < 0)
return (forwline(f, -n));
if ((lastflag & CFCPCN) == 0)/* Reset goal if the */
curgoal = getccol(FALSE); /* last isn't C-P, C-N */
thisflag |= CFCPCN;
dlp = curwp->w_dotp;
while (n-- && lback(dlp) != curbp->b_linep)
{
dlp = lback(dlp);
curwp->w_dotline--;
}
curwp->w_dotp = dlp;
curwp->w_doto = getgoal(dlp);
curwp->w_flag |= WFMOVE;
return (TRUE);
}
/*
* PgDn. Scroll down (FORCE_ROWS - 1).
* Just forwline(f, (FORCE_ROWS -1))
* Bound to C-V
*/
int pagedown(int f, int n)
{
forwline(f, (FORCE_ROWS - 1));
return (TRUE);
}
/*
* PgUp. Scroll up (FORCE_ROWS - 1).
* Just backline(f, (FORCE_ROWS -1))
* Bound to M-V
*/
int pageup(int f, int n)
{
backline(f, (FORCE_ROWS - 1));
return (TRUE);
}
/*
* Set the mark in the current window to the value of "." in the window. No
* errors are possible. Bound to "M-.".
*/
/* ARGSUSED0 */
int setmark(int f, int n)
{
curwp->w_markp = curwp->w_dotp;
curwp->w_marko = curwp->w_doto;
mlwrite("[Mark set]");
return (TRUE);
}

View File

@@ -1,494 +0,0 @@
/* This file is in the public domain. */
/*
* Buffer management. Some of the functions are internal, and some are actually
* attached to user keys. Like everyone else, they set hints for the display
* system.
*/
#include <stdlib.h> /* free(3), malloc(3) */
#include <string.h> /* strncpy(3) */
#include "estruct.h"
#include "edef.h"
extern int mlreply(char *prompt, char *buf, int nbuf);
extern int readin(char fname[]);
extern void mlwrite();
extern void mlerase();
extern int mlyesno(char *prompt);
extern void lfree(LINE *lp);
extern WINDOW *wpopup();
extern LINE *lalloc();
int swbuffer(BUFFER *bp);
int usebuffer(int f, int n);
int nextbuffer(int f, int n);
int killbuffer(int f, int n);
int zotbuf(BUFFER *bp);
int namebuffer(int f, int n);
int listbuffers(int f, int n);
int makelist();
void itoa(char buf[], int width, int num);
int addline(char *text);
int anycb();
BUFFER* bfind(char *bname, int cflag, int bflag);
int bclear(BUFFER *bp);
/*
* make buffer BP current
*/
int swbuffer(BUFFER *bp)
{
WINDOW *wp;
if (--curbp->b_nwnd == 0)
{ /* Last use. */
curbp->b_dotp = curwp->w_dotp;
curbp->b_doto = curwp->w_doto;
curbp->b_markp = curwp->w_markp;
curbp->b_marko = curwp->w_marko;
}
curbp = bp; /* Switch. */
if (curbp->b_active != TRUE)
{ /* buffer not active yet */
/* read it in and activate it */
readin(curbp->b_fname);
curbp->b_dotp = lforw(curbp->b_linep);
curbp->b_doto = 0;
curbp->b_active = TRUE;
}
curwp->w_bufp = bp;
curwp->w_linep = bp->b_linep; /* For macros, ignored */
curwp->w_flag |= WFMODE | WFFORCE | WFHARD; /* Quite nasty */
if (bp->b_nwnd++ == 0)
{ /* First use */
curwp->w_dotp = bp->b_dotp;
curwp->w_doto = bp->b_doto;
curwp->w_markp = bp->b_markp;
curwp->w_marko = bp->b_marko;
return (TRUE);
}
wp = wheadp; /* Look for old */
while (wp != 0)
{
if (wp != curwp && wp->w_bufp == bp)
{
curwp->w_dotp = wp->w_dotp;
curwp->w_doto = wp->w_doto;
curwp->w_markp = wp->w_markp;
curwp->w_marko = wp->w_marko;
break;
}
wp = wp->w_wndp;
}
return (TRUE);
}
/*
* Attach a buffer to a window. The values of dot and mark come from the buffer
* if the use count is 0. Otherwise, they come from some other window.
*/
/* ARGSUSED0 */
int usebuffer(int f, int n)
{
BUFFER *bp;
char bufn[NBUFN];
int s;
if ((s = mlreply("Use buffer: ", bufn, NBUFN)) != TRUE)
return (s);
if ((bp = bfind(bufn, TRUE, 0)) == NULL)
return (FALSE);
return (swbuffer(bp));
}
/* switch to the next buffer in the buffer list
*/
/* ARGSUSED0 */
int nextbuffer(int f, int n)
{
BUFFER *bp;
bp = curbp->b_bufp;
/* cycle through the buffers to find an eligable one */
while ((bp == NULL) || (bp->b_flag & BFTEMP))
{
if (bp == NULL)
bp = bheadp;
else
bp = bp->b_bufp;
}
return (swbuffer(bp));
}
/*
* Dispose of a buffer, by name. Ask for the name. Look it up (don't get too
* upset if it isn't there at all!). Get quite upset if the buffer is being
* displayed. Clear the buffer (ask if the buffer has been changed). Then free
* the header line and the buffer header. Bound to "C-X K".
*/
/* ARGSUSED0 */
int killbuffer(int f, int n)
{
BUFFER *bp;
char bufn[NBUFN];
int s;
if ((s = mlreply("Kill buffer: ", bufn, NBUFN)) != TRUE)
return (s);
if ((bp = bfind(bufn, FALSE, 0)) == NULL) /* Easy if unknown */
return (TRUE);
return (zotbuf(bp));
}
/* kill the buffer pointed to by bp */
int zotbuf(BUFFER *bp)
{
BUFFER *bp1, *bp2;
int s;
if (bp->b_nwnd != 0)
{ /* Error if on screen */
mlwrite("Buffer is being displayed");
return (FALSE);
}
if ((s = bclear(bp)) != TRUE) /* Blow text away */
return (s);
free (bp->b_linep); /* Release header line */
bp1 = 0; /* Find the header */
bp2 = bheadp;
while (bp2 != bp)
{
bp1 = bp2;
bp2 = bp2->b_bufp;
}
bp2 = bp2->b_bufp; /* Next one in chain */
if (bp1 == NULL) /* Unlink it */
bheadp = bp2;
else
bp1->b_bufp = bp2;
free(bp); /* Release buffer block */
return (TRUE);
}
/* Rename the current buffer */
/* ARGSUSED0 */
int namebuffer(int f, int n)
{
BUFFER *bp; /* pointer to scan through all buffers */
char bufn[NBUFN]; /* buffer to hold buffer name */
/* prompt for and get the new buffer name */
ask:
if (mlreply("Change buffer name to: ", bufn, NBUFN) != TRUE)
return (FALSE);
/* and check for duplicates */
bp = bheadp;
while (bp != 0)
{
if (bp != curbp)
{
/* if the names the same */
if (strcmp(bufn, bp->b_bname) == 0)
goto ask; /* try again */
}
bp = bp->b_bufp; /* onward */
}
strncpy(curbp->b_bname, bufn, NBUFN); /* copy buffer name to structure */
curwp->w_flag |= WFMODE; /* make mode line replot */
mlerase();
return (TRUE);
}
/*
* List all of the active buffers. First update the special buffer that holds
* the list. Next make sure at least 1 window is displaying the buffer list,
* splitting the screen if this is what it takes. Lastly, repaint all of the
* windows that are displaying the list. Bound to "C-X C-B".
*/
/* ARGSUSED0 */
int listbuffers(int f, int n)
{
WINDOW *wp;
BUFFER *bp;
int s;
if ((s = makelist()) != TRUE)
return (s);
if (blistp->b_nwnd == 0)
{ /* Not on screen yet */
if ((wp = wpopup()) == NULL)
return (FALSE);
bp = wp->w_bufp;
if (--bp->b_nwnd == 0)
{
bp->b_dotp = wp->w_dotp;
bp->b_doto = wp->w_doto;
bp->b_markp = wp->w_markp;
bp->b_marko = wp->w_marko;
}
wp->w_bufp = blistp;
++blistp->b_nwnd;
}
wp = wheadp;
while (wp != 0)
{
if (wp->w_bufp == blistp)
{
wp->w_linep = lforw(blistp->b_linep);
wp->w_dotp = lforw(blistp->b_linep);
wp->w_doto = 0;
wp->w_markp = 0;
wp->w_marko = 0;
wp->w_flag |= WFMODE | WFHARD;
}
wp = wp->w_wndp;
}
return (TRUE);
}
/*
* This routine rebuilds the text in the special secret buffer that holds the
* buffer list. It is called by the list buffers command. Return TRUE if
* everything works. Return FALSE if there is an error (if there is no
* memory).
*/
int makelist()
{
BUFFER *bp;
LINE *lp;
char *cp1, *cp2;
char b[7], line[128];
int nbytes, s, c;
blistp->b_flag &= ~BFCHG; /* Don't complain! */
if ((s = bclear(blistp)) != TRUE) /* Blow old text away */
return (s);
strncpy (blistp->b_fname, "", 1);
if (addline("AC Size Buffer File") == FALSE ||
addline("-- ------- ------ ----") == FALSE)
return (FALSE);
bp = bheadp;
/* build line to report global mode settings */
cp1 = &line[0];
*cp1++ = ' ';
*cp1++ = ' ';
*cp1++ = ' ';
/* output the list of buffers */
while (bp != 0)
{
if ((bp->b_flag & BFTEMP) != 0)
{ /* Skip magic ones */
bp = bp->b_bufp;
continue;
}
cp1 = &line[0]; /* Start at left edge */
/* output status of ACTIVE flag (has the file been read in? */
if (bp->b_active == TRUE) /* "@" if activated */
*cp1++ = '@';
else
*cp1++ = ' ';
/* output status of changed flag */
if ((bp->b_flag & BFCHG) != 0) /* "*" if changed */
*cp1++ = '*';
else
*cp1++ = ' ';
*cp1++ = ' '; /* Gap */
nbytes = 0; /* Count bytes in buf */
lp = lforw(bp->b_linep);
while (lp != bp->b_linep)
{
nbytes += llength(lp) + 1;
lp = lforw(lp);
}
itoa(b, 6, nbytes); /* 6 digit buffer size */
cp2 = &b[0];
while ((c = *cp2++) != 0)
*cp1++ = (char)c;
*cp1++ = ' '; /* Gap */
cp2 = &bp->b_bname[0]; /* Buffer name */
while ((c = *cp2++) != 0)
*cp1++ = (char)c;
cp2 = &bp->b_fname[0]; /* File name */
if (*cp2 != 0)
{
while (cp1 < &line[2 + 1 + 5 + 1 + 6 + 1 + NBUFN]) /* XXX ??? */
*cp1++ = ' ';
while ((c = *cp2++) != 0)
{
if (cp1 < &line[128 - 1])
*cp1++ = (char)c;
}
}
*cp1 = 0; /* Add to the buffer */
if (addline(line) == FALSE)
return (FALSE);
bp = bp->b_bufp;
}
return (TRUE); /* All done */
}
void itoa(char buf[], int width, int num)
{
buf[width] = 0; /* End of string */
while (num >= 10)
{ /* Conditional digits */
buf[--width] = (char)((num % 10) + '0');
num /= 10;
}
buf[--width] = (char)(num + '0'); /* Always 1 digit */
while (width != 0) /* Pad with blanks */
buf[--width] = ' ';
}
/*
* The argument "text" points to a string. Append this line to the buffer list
* buffer. Handcraft the EOL on the end. Return TRUE if it worked and FALSE if
* you ran out of room.
*/
int addline(char *text)
{
LINE *lp;
int ntext, i;
ntext = strlen(text);
if ((lp = lalloc(ntext)) == NULL)
return (FALSE);
for (i = 0; i < ntext; ++i)
lputc(lp, i, text[i]);
blistp->b_linep->l_bp->l_fp = lp; /* Hook onto the end */
lp->l_bp = blistp->b_linep->l_bp;
blistp->b_linep->l_bp = lp;
lp->l_fp = blistp->b_linep;
if (blistp->b_dotp == blistp->b_linep) /* If "." is at the end */
blistp->b_dotp = lp; /* move it to new line */
return (TRUE);
}
/*
* Look through the list of buffers. Return TRUE if there are any changed
* buffers. Buffers that hold magic internal stuff are not considered; who
* cares if the list of buffer names is hacked. Return FALSE if no buffers
* have been changed.
*/
int anycb()
{
BUFFER *bp;
bp = bheadp;
while (bp != NULL)
{
if ((bp->b_flag & BFTEMP) == 0 && (bp->b_flag & BFCHG) != 0)
return (TRUE);
bp = bp->b_bufp;
}
return (FALSE);
}
/*
* Find a buffer, by name. Return a pointer to the BUFFER structure associated
* with it. If the named buffer is found, but is a TEMP buffer (like the
* buffer list) conplain. If the buffer is not found and the "cflag" is TRUE,
* create it. The "bflag" is the settings for the flags in in buffer.
*/
BUFFER* bfind(char *bname, int cflag, int bflag)
{
BUFFER *bp, *sb;
LINE *lp;
bp = bheadp;
while (bp != 0)
{
if (strcmp(bname, bp->b_bname) == 0)
{
if ((bp->b_flag & BFTEMP) != 0)
{
mlwrite ("Cannot select builtin buffer");
return (0);
}
return (bp);
}
bp = bp->b_bufp;
}
if (cflag != FALSE)
{
if ((bp = (BUFFER *) malloc(sizeof(BUFFER))) == NULL)
return (0);
if ((lp = lalloc(0)) == NULL)
{
free(bp);
return (BUFFER*)0;
}
/* find the place in the list to insert this buffer */
if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0)
{
/* insert at the begining */
bp->b_bufp = bheadp;
bheadp = bp;
}
else
{
sb = bheadp;
while (sb->b_bufp != 0)
{
if (strcmp(sb->b_bufp->b_bname, bname) > 0)
break;
sb = sb->b_bufp;
}
/* and insert it */
bp->b_bufp = sb->b_bufp;
sb->b_bufp = bp;
}
/* and set up the other buffer fields */
bp->b_active = TRUE;
bp->b_dotp = lp;
bp->b_doto = 0;
bp->b_markp = 0;
bp->b_marko = 0;
bp->b_flag = (char)bflag;
bp->b_nwnd = 0;
bp->b_linep = lp;
bp->b_lines = 1;
strncpy(bp->b_fname, "", 1);
strncpy(bp->b_bname, bname, NBUFN);
lp->l_fp = lp;
lp->l_bp = lp;
}
return (bp);
}
/*
* This routine blows away all of the text in a buffer. If the buffer is
* marked as changed then we ask if it is ok to blow it away; this is to save
* the user the grief of losing text. The window chain is nearly always wrong
* if this gets called; the caller must arrange for the updates that are
* required. Return TRUE if everything looks good.
*/
int bclear(BUFFER *bp)
{
LINE *lp;
int s;
if ((bp->b_flag & BFTEMP) == 0 /* Not scratch buffer */
&& (bp->b_flag & BFCHG) != 0 /* Something changed */
&& (s = mlyesno("Discard changes")) != TRUE)
return (s);
bp->b_flag &= ~BFCHG; /* Not changed */
while ((lp = lforw(bp->b_linep)) != bp->b_linep)
lfree(lp);
bp->b_dotp = bp->b_linep; /* Fix "." */
bp->b_doto = 0;
bp->b_markp = 0; /* Invalidate "mark" */
bp->b_marko = 0;
bp->b_lines = 1;
return (TRUE);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,67 +0,0 @@
/* This file is in the public domain. */
/*
* This table is *roughly* in ASCII order, left to right across the
* characters of the command. This expains the funny location of the
* control-X commands.
*/
KEYTAB keytab[] = {
{CTRL | 'A', gotobol},
{CTRL | 'B', backchar},
{CTRL | 'D', forwdel},
{CTRL | 'E', gotoeol},
{CTRL | 'F', forwchar},
{CTRL | 'G', ctrlg},
{CTRL | 'H', backdel},
{CTRL | 'I', tab},
{CTRL | 'K', killtext},
{CTRL | 'L', refresh},
{CTRL | 'M', newline},
{CTRL | 'N', forwline},
{CTRL | 'O', openline},
{CTRL | 'P', backline},
{CTRL | 'Q', quote},
{CTRL | 'R', backsearch},
{CTRL | 'S', forwsearch},
{CTRL | 'T', twiddle},
{CTRL | 'V', pagedown},
{CTRL | 'W', killregion},
{CTRL | 'Y', yank},
{CTLX | '(', ctlxlp},
{CTLX | ')', ctlxrp},
{CTLX | '1', onlywind},
{CTLX | '2', splitwind},
{CTLX | 'B', usebuffer},
{CTLX | 'E', ctlxe},
{CTLX | 'F', setfillcol},
{CTLX | 'K', killbuffer},
{CTLX | 'N', filename},
{CTLX | 'O', nextwind},
{CTLX | 'S', filesave}, /* non-standard */
{CTLX | 'Q', quote}, /* non-standard */
{CTLX | 'X', nextbuffer},
{CTLX | '^', enlargewind},
{CTLX | CTRL | 'B', listbuffers},
{CTLX | CTRL | 'C', quit},
{CTLX | CTRL | 'F', filefind},
{CTLX | CTRL | 'I', insfile},
{CTLX | CTRL | 'R', fileread},
{CTLX | CTRL | 'S', filesave},
{CTLX | CTRL | 'W', filewrite},
{META | '.', setmark},
{META | '<', gotobob},
{META | '>', gotoeob},
{META | 'B', backword},
{META | 'F', forwword},
{META | 'G', setline}, /* non-standard */
{META | 'S', forwsearch}, /* non-standard */
{META | 'V', pageup},
{META | 'W', copyregion},
{META | 'Z', quickexit},
{META | CTRL | 'N', namebuffer},
{0x7F, backdel},
{META | '[', extendedcmd},
{META | 'O', extendedcmd},
{0, 0}
};

View File

@@ -1,78 +0,0 @@
/* This file is in the public domain. */
#ifndef NULL
#define NULL ((void*)0)
#endif
#ifdef maindef
/*
* for MAIN.C
* initialized global definitions
*/
short kbdm[NKBDM] = {CTLX | ')'}; /* Macro */
int fillcol = 72; /* Current fill column */
char pat[NPAT]; /* Search pattern */
char rpat[NPAT]; /* replacement pattern */
int revexist = FALSE;
int eolexist = TRUE; /* does clear to EOL exist */
int sgarbf = TRUE; /* TRUE if screen is garbage */
int mpresf = FALSE; /* TRUE if message in last line */
/* uninitialized global definitions */
int currow; /* Cursor row */
int curcol; /* Cursor column */
int thisflag; /* Flags, this command */
int lastflag; /* Flags, last command */
int curgoal; /* Goal for C-P, C-N */
WINDOW *curwp; /* Current window */
BUFFER *curbp; /* Current buffer */
WINDOW *wheadp; /* Head of list of windows */
BUFFER *bheadp; /* Head of list of buffers */
BUFFER *blistp; /* Buffer for C-X C-B */
short *kbdmip; /* Input pointer for above */
short *kbdmop; /* Output pointer for above */
#else
/*
* for all the other .C files
* initialized global external declarations
*/
extern int fillcol; /* Fill column */
extern short kbdm[]; /* Holds kayboard macro data */
extern char pat[]; /* Search pattern */
extern char rpat[]; /* Replacement pattern */
extern int eolexist; /* does clear to EOL exist? */
extern int revexist; /* does reverse video exist? */
extern char *modename[]; /* text names of modes */
extern char modecode[]; /* letters to represent modes */
extern KEYTAB keytab[]; /* key bind to functions table */
extern int gmode; /* global editor mode */
extern int sgarbf; /* State of screen unknown */
extern int mpresf; /* Stuff in message line */
extern int clexec; /* command line execution flag */
/* initialized global external declarations */
extern int currow; /* Cursor row */
extern int curcol; /* Cursor column */
extern int thisflag; /* Flags, this command */
extern int lastflag; /* Flags, last command */
extern int curgoal; /* Goal for C-P, C-N */
extern WINDOW *curwp; /* Current window */
extern BUFFER *curbp; /* Current buffer */
extern WINDOW *wheadp; /* Head of list of windows */
extern BUFFER *bheadp; /* Head of list of buffers */
extern BUFFER *blistp; /* Buffer for C-X C-B */
extern short *kbdmip; /* Input pointer for above */
extern short *kbdmop; /* Output pointer for above */
#endif
/* terminal table defined only in TERM.C */
#ifndef termdef
extern TERM term; /* Terminal information */
#endif

View File

@@ -1,65 +0,0 @@
/* This file is in the public domain. */
/* EFUNC.H: function declarations and names
*
* This file list all the C code functions used. To add functions, declare it
* here in both the extern function list and the name binding table
*/
extern int ctrlg(); /* Abort out of things */
extern int quit(); /* Quit */
extern int ctlxlp(); /* Begin macro */
extern int ctlxrp(); /* End macro */
extern int ctlxe(); /* Execute macro */
extern int fileread(); /* Get a file, read only */
extern int filefind(); /* Get a file, read write */
extern int filewrite(); /* Write a file */
extern int filesave(); /* Save current file */
extern int filename(); /* Adjust file name */
extern int getccol(); /* Get current column */
extern int gotobol(); /* Move to start of line */
extern int forwchar(); /* Move forward by characters */
extern int gotoeol(); /* Move to end of line */
extern int backchar(); /* Move backward by characters */
extern int forwline(); /* Move forward by lines */
extern int backline(); /* Move backward by lines */
extern int pagedown(); /* PgDn */
extern int pageup(); /* PgUp */
extern int gotobob(); /* Move to start of buffer */
extern int gotoeob(); /* Move to end of buffer */
extern int setfillcol(); /* Set fill column */
extern int setmark(); /* Set mark */
extern int forwsearch(); /* Search forward */
extern int backsearch(); /* Search backwards */
extern int nextwind(); /* Move to the next window */
extern int prevwind(); /* Move to the previous window */
extern int onlywind(); /* Make current window only one */
extern int splitwind(); /* Split current window */
extern int enlargewind(); /* Enlarge display window */
extern int shrinkwind(); /* Shrink window */
extern int listbuffers(); /* Display list of buffers */
extern int usebuffer(); /* Switch a window to a buffer */
extern int killbuffer(); /* Make a buffer go away */
extern int refresh(); /* Refresh the screen */
extern int twiddle(); /* Twiddle characters */
extern int tab(); /* Insert tab */
extern int newline(); /* Insert CR-LF */
extern int openline(); /* Open up a blank line */
extern int quote(); /* Insert literal */
extern int backword(); /* Backup by words */
extern int forwword(); /* Advance by words */
extern int forwdel(); /* Forward delete */
extern int backdel(); /* Backward delete */
extern int killtext(); /* Kill forward */
extern int yank(); /* Yank back from killbuffer */
extern int killregion(); /* Kill region */
extern int copyregion(); /* Copy region to kill buffer */
extern int quickexit(); /* low keystroke style exit */
extern int setline(); /* go to a numbered line */
extern int namebuffer(); /* rename the current buffer */
extern int deskey(); /* describe a key's binding */
extern int insfile(); /* insert a file */
extern int nextbuffer(); /* switch to the next buffer */
extern int forwhunt(); /* hunt forward for next match */
extern int backhunt(); /* hunt backwards for next match */
extern int extendedcmd(); /* parse ANSI/VT100 extended keys */

View File

@@ -1,62 +0,0 @@
.\" This file is in the public domain.
.\"
.\" Basic emg man page.
.\" As both Ersatz Emacs and Mg are Public Domain, emg is also Public Domain.
.\"
.Dd June 17, 2014
.Os
.Dt EMG 1
.Sh NAME
.Nm emg
.Nd very small Emacs-like text editor
.Sh SYNOPSIS
.Nm emg
.Op Ar
.Sh DESCRIPTION
.Nm ,
or Ersatz Mg, is an Emacs-like text editor designed for RetroBSD
and other memory-constrained environments.
.Nm
was originally created to fit into an operating environment of 96K of RAM,
and one in which Mg did not fit and Ersatz Emacs did not build.
By combining parts of each a working editor was created.
.Pp
When invoked without file arguments,
.Nm
creates a
.Qq main
buffer.
This buffer must be renamed
.Ic ( C-x n )
in order to be saved
.Ic ( C-x C-s ) .
.Pp
As both Ersatz Emacs and Mg are Public Domain,
.Nm
is also Public Domain.
.Sh FILES
There is a chart of key bindings in
.Pa /usr/local/share/doc/emg/emg.keys .
Consulting this file is a must.
While
.Nm
strives to maintain compatibility with larger Emacs implementations,
there may be features intentionally left unimplemented in order to keep
.Nm
as small as possible.
.Sh AUTHORS
.Nm
is a combination of Ersatz Emacs and Mg and therefore all authors
for both deserve credit.
Ersatz Emacs and Mg were combined by
.An Brian Callahan Aq Mt bcallah@openbsd.org
to create
.Nm .
.Sh BUGS
None known.
However, patches are appreciated if any are found.
.Sh TODO
It would be nice to have automatic window resizing.
It would also be nice if
.Nm
could clear the screen when quit, like Mg does.

View File

@@ -1,131 +0,0 @@
emg keybindings (July 7, 2014)
Based on Ersatz Emacs (2000/09/14)
M- means to use the <ESC> key prior to using another key
^A means to use the control key at the same time as the 'A' key
------------------------------------------------------------------------------
MOVING THE CURSOR
^F Forward character M-F Forward word
^B Backward character M-B Backward word
^N Next line M-P Front of paragraph
^P Previous line M-N End of paragraph
^A Front of line M-< or [HOME] Start of file
^E End of line M-> or [END] End of file
^V or [PgDn] Scroll down M-V or [PgUp] Scroll up
M-G Go to line Arrow keys are active
------------------------------------------------------------------------------
DELETING & INSERTING
<- Delete previous character M-<- Delete previous word
^D Delete next character M-D Delete next word
^K Delete to end of line ^O Insert line
------------------------------------------------------------------------------
FORMATTING & TRANSPOSING
^Q Quote next key, so that control codes may be entered into text. (or ^X Q)
------------------------------------------------------------------------------
SEARCHING
^S Search forward from cursor position. Type in a string and end it with
ENTER. Either case matches. (or M-S)
^R As above, but reverse search from cursor position.
------------------------------------------------------------------------------
COPYING AND MOVING
M-. Set mark at current position.
^W Delete region.
M-W Copy region to kill buffer.
^Y Yank back kill buffer at cursor.
A region is defined as the area between this mark and the current cursor
position. The kill buffer is the text which has been most recently deleted or
copied.
Generally, the procedure for copying or moving text is:
1) Mark out region using M-. at the beginning and move the cursor to
the end.
2) Delete it (with ^W) or copy it (with M-W) into the kill buffer.
3) Move the cursor to the desired location and yank it back (with ^Y).
------------------------------------------------------------------------------
MULTIPLE BUFFERS
A buffer contains a COPY of a document being edited, and must be saved for
changes to be kept. Many buffers may be activated at once.
^X B Switch to another buffer.
^X ^B Show buffer directory in a window (^X 1 to remove).
^X K Delete a non-displayed buffer.
^X X Switch to next buffer in buffer list.
^X N Change the filename associated with the buffer.
M-^N Change the name of the buffer.
------------------------------------------------------------------------------
READING FROM DISK
^X^F Find file; read into a new buffer created from filename.
(This is the usual way to edit a new file.)
^X^R Read file into current buffer, erasing its previous contents.
No new buffer will be created.
^X^I Insert file into current buffer at cursor's location.
------------------------------------------------------------------------------
SAVING TO DISK
^X^S Save current buffer to disk, using the buffer's filename as the name of
the disk file. Any disk file of that name will be overwritten. (or ^X S)
^X^W Write current buffer to disk. Type in a new filename at the prompt to
write to; it will also become the current buffer's filename.
------------------------------------------------------------------------------
MULTIPLE WINDOWS
Many windows may be visible at once on the screen. Windows may show different
parts of the same buffer, or each may display a different one.
^X 2 Split the current window in two ^X 1 Show only current window
^X O Move cursor to next window ^X ^ Enlarge current window
M-^V Scroll other window down M-^Z Scroll other window up
------------------------------------------------------------------------------
EXITING
^X^C Exit. Any unsaved files will require confirmation.
------------------------------------------------------------------------------
MACROS
^X ( Start recording a keyboard macro. Typing ^G or an error aborts.
^X ) Stop recording macro.
^X E Execute macro.
------------------------------------------------------------------------------
REPEAT & NUMBER PREFIX
^U<number> or M-<number>
Number prefix and universal repeat. May be followed by an integer
(default = 4) and repeats the next command that many times.
Exceptions follow.
^U<number>^L
Reposition the cursor to a particular screen row; i.e., ^U0^L moves the
cursor and the line it is on to the top of the screen. Negative numbers
are from the bottom of the screen.
^U<number>^X F
Set the right margin to column <number> for paragraph formatting.
^U<number>^X^
Enlarge a split window by <number> rows. A negative number shrinks the
window.
------------------------------------------------------------------------------
SPECIAL KEYS
^G Cancel current command.
^L Redraws the screen completely.
------------------------------------------------------------------------------

View File

@@ -1,191 +0,0 @@
/* This file is in the public domain. */
/* ESTRUCT: Structure and preprocessor */
/* internal constants */
#define NFILEN 32 /* maximum # of bytes, file name */
#define NBUFN 16 /* maximum # of bytes, buffer name */
#define NLINE 512 /* maximum # of bytes, line */
#define NKBDM 128 /* maximum # of strokes, keyboard macro */
#define NPAT 80 /* maximum # of bytes, pattern */
#define HUGE 32700 /* Huge number for "impossible" row&col */
#define METACH 0x1B /* M- prefix, Control-[, ESC */
#define BELL 0x07 /* a bell character */
#define TAB 0x09 /* a tab character */
#define CTRL 0x0100 /* Control flag, or'ed in */
#define META 0x0200 /* Meta flag, or'ed in */
#define CTLX 0x0400 /* ^X flag, or'ed in */
#define FALSE 0 /* False, no, bad, etc */
#define TRUE 1 /* True, yes, good, etc */
#define ABORT 2 /* Death, ^G, abort, etc */
#define FIOSUC 0 /* File I/O, success */
#define FIOFNF 1 /* File I/O, file not found */
#define FIOEOF 2 /* File I/O, end of file */
#define FIOERR 3 /* File I/O, error */
#define FIOLNG 4 /* line longer than allowed len */
#define CFCPCN 0x0001 /* Last command was C-P, C-N */
#define CFKILL 0x0002 /* Last command was a kill */
/*
* screen constants
* override with
* CFLAGS += -DFORCE_COLS=XXX -DFORCE_ROWS=XXX
*/
#ifndef FORCE_COLS
#define FORCE_COLS 80
#endif
#ifndef FORCE_ROWS
#define FORCE_ROWS 24
#endif
/*
* XXX:
* Default/sane(?) maximum column and row sizes.
* Taken from mg1a.
*
* Let the user override these with
* CFLAGS += -DMAXCOL=XXX -DMAXROW=XXX
*/
#ifndef MAXCOL
#define MAXCOL 132
#endif
#ifndef MAXROW
#define MAXROW 66
#endif
/*
* There is a window structure allocated for every active display window. The
* windows are kept in a big list, in top to bottom screen order, with the
* listhead at "wheadp". Each window contains its own values of dot and mark.
* The flag field contains some bits that are set by commands to guide
* redisplay; although this is a bit of a compromise in terms of decoupling,
* the full blown redisplay is just too expensive to run for every input
* character
*/
typedef struct WINDOW
{
struct WINDOW *w_wndp; /* Next window */
struct BUFFER *w_bufp; /* Buffer displayed in window */
struct LINE *w_linep; /* Top line in the window */
struct LINE *w_dotp; /* Line containing "." */
long w_doto; /* Byte offset for "." */
struct LINE *w_markp; /* Line containing "mark" */
long w_marko; /* Byte offset for "mark" */
char w_toprow; /* Origin 0 top row of window */
char w_ntrows; /* # of rows of text in window */
char w_force; /* If NZ, forcing row */
char w_flag; /* Flags */
int w_dotline; /* current line number of dot */
} WINDOW;
#define WFFORCE 0x01 /* Window needs forced reframe */
#define WFMOVE 0x02 /* Movement from line to line */
#define WFEDIT 0x04 /* Editing within a line */
#define WFHARD 0x08 /* Better to a full display */
#define WFMODE 0x10 /* Update mode line */
/*
* Text is kept in buffers. A buffer header, described below, exists for every
* buffer in the system. The buffers are kept in a big list, so that commands
* that search for a buffer by name can find the buffer header. There is a
* safe store for the dot and mark in the header, but this is only valid if
* the buffer is not being displayed (that is, if "b_nwnd" is 0). The text for
* the buffer is kept in a circularly linked list of lines, with a pointer to
* the header line in "b_linep". Buffers may be "Inactive" which means the
* files accosiated with them have not been read in yet. These get read in at
* "use buffer" time
*/
typedef struct BUFFER
{
struct BUFFER *b_bufp; /* Link to next BUFFER */
struct LINE *b_dotp; /* Link to "." LINE structure */
long b_doto; /* Offset of "." in above LINE */
struct LINE *b_markp; /* The same as the above two, */
long b_marko; /* but for the "mark" */
struct LINE *b_linep; /* Link to the header LINE */
char b_active; /* window activated flag */
char b_nwnd; /* Count of windows on buffer */
char b_flag; /* Flags */
char b_fname[NFILEN]; /* File name */
char b_bname[NBUFN]; /* Buffer name */
int b_lines; /* Number of lines in file */
} BUFFER;
#define BFTEMP 0x01 /* Internal temporary buffer */
#define BFCHG 0x02 /* Changed since last write */
/*
* The starting position of a region, and the size of the region in
* characters, is kept in a region structure. Used by the region commands
*/
typedef struct
{
struct LINE *r_linep; /* Origin LINE address */
long r_offset; /* Origin LINE offset */
long r_size; /* Length in characters */
} REGION;
/*
* All text is kept in circularly linked lists of "LINE" structures. These
* begin at the header line (which is the blank line beyond the end of the
* buffer). This line is pointed to by the "BUFFER". Each line contains a the
* number of bytes in the line (the "used" size), the size of the text array,
* and the text. The end of line is not stored as a byte; it's implied. Future
* additions will include update hints, and a list of marks into the line
*/
typedef struct LINE
{
struct LINE *l_fp; /* Link to the next line */
struct LINE *l_bp; /* Link to the previous line */
int l_size; /* Allocated size */
int l_used; /* Used size */
char l_text[1]; /* A bunch of characters */
} LINE;
#define lforw(lp) ((lp)->l_fp)
#define lback(lp) ((lp)->l_bp)
#define lgetc(lp, n) ((lp)->l_text[(n)]&0xFF)
#define lputc(lp, n, c) ((lp)->l_text[(n)]=(c))
#define llength(lp) ((lp)->l_used)
/*
* The editor communicates with the display using a high level interface. A
* "TERM" structure holds useful variables, and indirect pointers to routines
* that do useful operations. The low level get and put routines are here too.
* This lets a terminal, in addition to having non standard commands, have
* funny get and put character code too. The calls might get changed to
* "termp->t_field" style in the future, to make it possible to run more than
* one terminal type
*/
typedef struct
{
int t_nrow; /* Number of rows */
int t_ncol; /* Number of columns */
int t_margin; /* min margin for extended lines */
int t_scrsiz; /* size of scroll region " */
void (*t_open) (); /* Open terminal at the start */
void (*t_close) (); /* Close terminal at end */
int (*t_getchar) (); /* Get character from keyboard */
void (*t_putchar) (); /* Put character to display */
void (*t_flush) (); /* Flush output buffers */
void (*t_move) (); /* Move the cursor, origin 0 */
void (*t_eeol) (); /* Erase to end of line */
void (*t_eeop) (); /* Erase to end of page */
void (*t_beep) (); /* Beep */
void (*t_rev) (); /* set reverse video state */
} TERM;
/* structure for the table of initial key bindings */
typedef struct
{
short k_code; /* Key code */
int (*k_fp) (); /* Routine to handle it */
} KEYTAB;

View File

@@ -1,465 +0,0 @@
/* This file is in the public domain. */
/*
* The routines in this file handle the reading and writing of disk files.
* All details about the reading and writing of the disk are in "fileio.c"
*/
#include <string.h> /* strncpy(3) */
#include "estruct.h"
#include "edef.h"
extern int mlreply(char *prompt, char *buf, int nbuf);
extern int swbuffer(BUFFER *bp);
extern void mlwrite();
extern int bclear(BUFFER *bp);
extern int ffropen(char *fn);
extern int ffgetline(char buf[], int nbuf);
extern int ffwopen(char *fn);
extern int ffclose();
extern int ffputline(char buf[], int nbuf);
extern BUFFER *bfind();
extern LINE *lalloc();
int fileread(int f, int n);
int insfile(int f, int n);
int filefind(int f, int n);
int getfile(char fname[]);
int readin(char fname[]);
void makename(char bname[], char fname[]);
int filewrite(int f, int n);
int filesave(int f, int n);
int writeout(char *fn);
int filename(int f, int n);
int ifile(char fname[]);
/*
* Read a file into the current buffer. This is really easy; all you do it
* find the name of the file, and call the standard "read a file into the
* current buffer" code. Bound to "C-X C-R"
*/
int fileread(int f, int n)
{
int s;
char fname[NFILEN];
if ((s = mlreply("Read file: ", fname, NFILEN)) != TRUE)
return (s);
return (readin(fname));
}
/*
* Insert a file into the current buffer. This is really easy; all you do it
* find the name of the file, and call the standard "insert a file into the
* current buffer" code. Bound to "C-X C-I".
*/
int insfile(int f, int n)
{
int s;
char fname[NFILEN];
if ((s = mlreply("Insert file: ", fname, NFILEN)) != TRUE)
return (s);
return (ifile(fname));
}
/*
* Select a file for editing. Look around to see if you can find the fine in
* another buffer; if you can find it just switch to the buffer. If you cannot
* find the file, create a new buffer, read in the text, and switch to the new
* buffer. Bound to C-X C-F.
*/
int filefind(int f, int n)
{
char fname[NFILEN]; /* file user wishes to find */
int s; /* status return */
if ((s = mlreply("Find file: ", fname, NFILEN)) != TRUE)
return (s);
return (getfile(fname));
}
int getfile(char fname[])
{
BUFFER *bp;
LINE *lp;
char bname[NBUFN]; /* buffer name to put file */
int i, s;
for (bp = bheadp; bp != (BUFFER*)0; bp = bp->b_bufp)
{
if ((bp->b_flag & BFTEMP) == 0 && strcmp(bp->b_fname, fname) == 0)
{
if (--curbp->b_nwnd == 0)
{
curbp->b_dotp = curwp->w_dotp;
curbp->b_doto = curwp->w_doto;
curbp->b_markp = curwp->w_markp;
curbp->b_marko = curwp->w_marko;
}
swbuffer(bp);
lp = curwp->w_dotp;
i = curwp->w_ntrows / 2;
while (i-- && lback(lp) != curbp->b_linep)
lp = lback(lp);
curwp->w_linep = lp;
curwp->w_flag |= WFMODE | WFHARD;
mlwrite("[Old buffer]");
return (TRUE);
}
}
makename(bname, fname); /* New buffer name */
while ((bp = bfind(bname, FALSE, 0)) != (BUFFER*)0)
{
s = mlreply("Buffer name: ", bname, NBUFN);
if (s == ABORT) /* ^G to just quit */
return (s);
if (s == FALSE)
{ /* CR to clobber it */
makename(bname, fname);
break;
}
}
if (bp == (BUFFER*)0 && (bp = bfind(bname, TRUE, 0)) == (BUFFER*)0)
{
mlwrite("Cannot create buffer");
return (FALSE);
}
if (--curbp->b_nwnd == 0)
{ /* Undisplay */
curbp->b_dotp = curwp->w_dotp;
curbp->b_doto = curwp->w_doto;
curbp->b_markp = curwp->w_markp;
curbp->b_marko = curwp->w_marko;
}
curbp = bp; /* Switch to it */
curwp->w_bufp = bp;
curbp->b_nwnd++;
return (readin(fname)); /* Read it in */
}
/*
* Read file "fname" into the current buffer, blowing away any text found
* there. Called by both the read and find commands. Return the final status
* of the read. Also called by the mainline, to read in a file specified on
* the command line as an argument.
*/
int readin(char fname[])
{
LINE *lp1, *lp2;
WINDOW *wp;
BUFFER *bp;
char line[NLINE];
int nbytes, s, i;
int nline = 0; /* initialize here to silence a gcc warning */
int lflag; /* any lines longer than allowed? */
bp = curbp; /* Cheap */
if ((s = bclear(bp)) != TRUE) /* Might be old */
return (s);
bp->b_flag &= ~(BFTEMP | BFCHG);
strncpy(bp->b_fname, fname, NFILEN);
if ((s = ffropen(fname)) == FIOERR) /* Hard file open */
goto out;
if (s == FIOFNF)
{ /* File not found */
mlwrite("[New file]");
goto out;
}
mlwrite("[Reading file]");
lflag = FALSE;
while ((s = ffgetline(line, NLINE)) == FIOSUC || s == FIOLNG)
{
if (s == FIOLNG)
lflag = TRUE;
nbytes = strlen(line);
if ((lp1 = lalloc(nbytes)) == NULL)
{
s = FIOERR; /* Keep message on the display */
break;
}
lp2 = lback(curbp->b_linep);
lp2->l_fp = lp1;
lp1->l_fp = curbp->b_linep;
lp1->l_bp = lp2;
curbp->b_linep->l_bp = lp1;
for (i = 0; i < nbytes; ++i)
lputc(lp1, i, line[i]);
++nline;
}
ffclose(); /* Ignore errors */
if (s == FIOEOF)
{ /* Don't zap message! */
if (nline != 1)
mlwrite("[Read %d lines]", nline);
else
mlwrite("[Read 1 line]");
}
if (lflag)
{
if (nline != 1)
mlwrite("[Read %d lines: Long lines wrapped]", nline);
else
mlwrite("[Read 1 line: Long lines wrapped]");
}
curwp->w_bufp->b_lines = nline;
out:
for (wp = wheadp; wp != NULL; wp = wp->w_wndp)
{
if (wp->w_bufp == curbp)
{
wp->w_linep = lforw(curbp->b_linep);
wp->w_dotp = lforw(curbp->b_linep);
wp->w_doto = 0;
wp->w_markp = NULL;
wp->w_marko = 0;
wp->w_flag |= WFMODE | WFHARD;
}
}
if (s == FIOERR || s == FIOFNF) /* False if error */
return (FALSE);
return (TRUE);
}
/*
* Take a file name, and from it fabricate a buffer name. This routine knows
* about the syntax of file names on the target system. I suppose that this
* information could be put in a better place than a line of code.
*/
void makename(char bname[], char fname[])
{
char *cp1, *cp2;
cp1 = &fname[0];
while (*cp1 != 0)
++cp1;
while (cp1 != &fname[0] && cp1[-1] != '/')
--cp1;
cp2 = &bname[0];
while (cp2 != &bname[NBUFN - 1] && *cp1 != 0 && *cp1 != ';')
*cp2++ = *cp1++;
*cp2 = 0;
}
/*
* Ask for a file name, and write the contents of the current buffer to that
* file. Update the remembered file name and clear the buffer changed flag.
* This handling of file names is different from the earlier versions, and is
* more compatable with Gosling EMACS than with ITS EMACS. Bound to "C-X C-W".
*/
int filewrite(int f, int n)
{
WINDOW *wp;
char fname[NFILEN];
int s;
if ((s = mlreply("Write file: ", fname, NFILEN)) != TRUE)
return (s);
if ((s = writeout(fname)) == TRUE)
{
strncpy(curbp->b_fname, fname, NFILEN);
curbp->b_flag &= ~BFCHG;
wp = wheadp; /* Update mode lines */
while (wp != NULL)
{
if (wp->w_bufp == curbp)
wp->w_flag |= WFMODE;
wp = wp->w_wndp;
}
}
return (s);
}
/*
* Save the contents of the current buffer in its associatd file. No nothing
* if nothing has changed (this may be a bug, not a feature). Error if there
* is no remembered file name for the buffer. Bound to "C-X C-S". May get
* called by "C-Z"
*/
int filesave(int f, int n)
{
WINDOW *wp;
int s;
if ((curbp->b_flag & BFCHG) == 0) /* Return, no changes */
return (TRUE);
if (curbp->b_fname[0] == 0)
{ /* Must have a name */
mlwrite("No file name");
return (FALSE);
}
if ((s = writeout(curbp->b_fname)) == TRUE)
{
curbp->b_flag &= ~BFCHG;
wp = wheadp; /* Update mode lines */
while (wp != NULL)
{
if (wp->w_bufp == curbp)
wp->w_flag |= WFMODE;
wp = wp->w_wndp;
}
}
return (s);
}
/*
* This function performs the details of file writing. Uses the file
* management routines in the "fileio.c" package. The number of lines written
* is displayed. Sadly, it looks inside a LINE; provide a macro for this. Most
* of the grief is error checking of some sort.
*/
int writeout(char *fn)
{
LINE *lp;
int nline, s;
if ((s = ffwopen(fn)) != FIOSUC) /* Open writes message */
return (FALSE);
mlwrite("[Writing]"); /* tell us were writing */
lp = lforw(curbp->b_linep); /* First line */
nline = 0; /* Number of lines */
while (lp != curbp->b_linep)
{
if ((s = ffputline(&lp->l_text[0], llength(lp))) != FIOSUC)
break;
++nline;
lp = lforw(lp);
}
if (s == FIOSUC)
{ /* No write error */
s = ffclose();
if (s == FIOSUC)
{ /* No close error */
if (nline != 1)
mlwrite("[Wrote %d lines]", nline);
else
mlwrite("[Wrote 1 line]");
}
}
else /* ignore close error */
ffclose(); /* if a write error */
if (s != FIOSUC) /* some sort of error */
return (FALSE);
return (TRUE);
}
/*
* The command allows the user to modify the file name associated with the
* current buffer. It is like the "f" command in UNIX "ed". The operation is
* simple; just zap the name in the BUFFER structure, and mark the windows as
* needing an update. You can type a blank line at the prompt if you wish.
*/
int filename(int f, int n)
{
WINDOW *wp;
char fname[NFILEN];
int s;
if ((s = mlreply("Name: ", fname, NFILEN)) == ABORT)
return (s);
if (s == FALSE)
strncpy(curbp->b_fname, "", 1);
else
strncpy(curbp->b_fname, fname, NFILEN);
wp = wheadp; /* update mode lines */
while (wp != NULL)
{
if (wp->w_bufp == curbp)
wp->w_flag |= WFMODE;
wp = wp->w_wndp;
}
return (TRUE);
}
/*
* Insert file "fname" into the current buffer, Called by insert file command.
* Return the final status of the read.
*/
int ifile(char fname[])
{
LINE *lp0, *lp1, *lp2;
BUFFER *bp;
char line[NLINE];
int i, s, nbytes;
int nline = 0;
int lflag; /* any lines longer than allowed? */
bp = curbp; /* Cheap */
bp->b_flag |= BFCHG; /* we have changed */
bp->b_flag &= ~BFTEMP; /* and are not temporary */
if ((s = ffropen(fname)) == FIOERR) /* Hard file open */
goto out;
if (s == FIOFNF)
{ /* File not found */
mlwrite("[No such file]");
return (FALSE);
}
mlwrite("[Inserting file]");
/* back up a line and save the mark here */
curwp->w_dotp = lback(curwp->w_dotp);
curwp->w_doto = 0;
curwp->w_markp = curwp->w_dotp;
curwp->w_marko = 0;
lflag = FALSE;
while ((s = ffgetline(line, NLINE)) == FIOSUC || s == FIOLNG)
{
if (s == FIOLNG)
lflag = TRUE;
nbytes = strlen(line);
if ((lp1 = lalloc(nbytes)) == NULL)
{
s = FIOERR; /* keep message on the */
break; /* display */
}
lp0 = curwp->w_dotp; /* line previous to insert */
lp2 = lp0->l_fp; /* line after insert */
/* re-link new line between lp0 and lp2 */
lp2->l_bp = lp1;
lp0->l_fp = lp1;
lp1->l_bp = lp0;
lp1->l_fp = lp2;
/* and advance and write out the current line */
curwp->w_dotp = lp1;
for (i = 0; i < nbytes; ++i)
lputc(lp1, i, line[i]);
++nline;
}
ffclose(); /* Ignore errors */
curwp->w_markp = lforw(curwp->w_markp);
if (s == FIOEOF)
{ /* Don't zap message! */
if (nline != 1)
mlwrite("[Inserted %d lines]", nline);
else
mlwrite("[Inserted 1 line]");
}
if (lflag)
{
if (nline != 1)
mlwrite("[Inserted %d lines: Long lines wrapped]", nline);
else
mlwrite("[Inserted 1 line: Long lines wrapped]");
}
out:
/* advance to the next line and mark the window for changes */
curwp->w_dotp = lforw(curwp->w_dotp);
curwp->w_flag |= WFHARD;
/* copy window parameters back to the buffer structure */
curbp->b_dotp = curwp->w_dotp;
curbp->b_doto = curwp->w_doto;
curbp->b_markp = curwp->w_markp;
curbp->b_marko = curwp->w_marko;
/* we need to update number of lines in the buffer */
curwp->w_bufp->b_lines += nline;
if (s == FIOERR) /* False if error */
return (FALSE);
return (TRUE);
}

View File

@@ -1,121 +0,0 @@
/* This file is in the public domain. */
/*
* The routines in this file read and write ASCII files from the disk. All of
* the knowledge about files is here. A better message writing scheme should
* be used
*/
#include <stdio.h> /* fopen(3), et.al. */
#include "estruct.h"
extern void mlwrite();
int ffropen(char *fn);
int ffwopen(char *fn);
int ffclose();
int ffputline(char buf[], int nbuf);
int ffgetline(char buf[], int nbuf);
FILE *ffp; /* File pointer, all functions */
/*
* Open a file for reading.
*/
int ffropen(char *fn)
{
if ((ffp = fopen(fn, "r")) == NULL)
return (FIOFNF);
return (FIOSUC);
}
/*
* Open a file for writing. Return TRUE if all is well, and FALSE on error
* (cannot create).
*/
int ffwopen(char *fn)
{
if ((ffp = fopen(fn, "w")) == NULL)
{
mlwrite("Cannot open file for writing");
return (FIOERR);
}
return (FIOSUC);
}
/*
* Close a file. Should look at the status in all systems.
*/
int ffclose()
{
if (fclose(ffp) != FALSE)
{
mlwrite("Error closing file");
return (FIOERR);
}
return (FIOSUC);
}
/*
* Write a line to the already opened file. The "buf" points to the buffer,
* and the "nbuf" is its length, less the free newline. Return the status.
* Check only at the newline.
*/
int ffputline(char buf[], int nbuf)
{
int i;
for (i = 0; i < nbuf; ++i)
fputc(buf[i] & 0xFF, ffp);
fputc('\n', ffp);
if (ferror(ffp))
{
mlwrite("Write I/O error");
return (FIOERR);
}
return (FIOSUC);
}
/*
* Read a line from a file, and store the bytes in the supplied buffer. The
* "nbuf" is the length of the buffer. Complain about long lines and lines at
* the end of the file that don't have a newline present. Check for I/O errors
* too. Return status.
*/
int ffgetline(char buf[], int nbuf)
{
int c, i;
i = 0;
while ((c = fgetc(ffp)) != EOF && c != '\n')
{
if (i >= nbuf - 2)
{
buf[nbuf - 2] = c; /* store last char read */
buf[nbuf - 1] = 0; /* and terminate it */
mlwrite("File has long lines");
return (FIOLNG);
}
buf[i++] = c;
}
if (c == EOF)
{
if (ferror(ffp))
{
mlwrite("File read error");
return (FIOERR);
}
if (i != 0)
{
mlwrite("No newline at EOF");
return (FIOERR);
}
return (FIOEOF);
}
buf[i] = 0;
return (FIOSUC);
}

View File

@@ -1,507 +0,0 @@
/* This file is in the public domain. */
/*
* The functions in this file are a general set of line management utilities.
* They are the only routines that touch the text. They also touch the buffer
* and window structures, to make sure that the necessary updating gets done.
* There are routines in this file that handle the kill buffer too. It isn't
* here for any good reason.
*
* Note that this code only updates the dot and mark values in the window
* list. Since all the code acts on the current window, the buffer that we are
* editing must be being displayed, which means that "b_nwnd" is non zero,
* which means that the dot and mark values in the buffer headers are
* nonsense
*/
#include <stdlib.h> /* malloc(3) */
#include "estruct.h"
#include "edef.h"
extern void mlwrite();
extern int backchar(int f, int n);
LINE* lalloc(int used);
void lfree(LINE *lp);
void lchange(int flag);
int linsert(int n, int c);
int lnewline();
int ldelete(int n, int kflag);
int ldelnewline();
void kdelete();
int kinsert(int c);
int kremove(int n);
#define NBLOCK 16 /* Line block chunk size */
#define KBLOCK 1024 /* Kill buffer block size */
char *kbufp = NULL; /* Kill buffer data */
unsigned long kused = 0; /* # of bytes used in KB */
unsigned long ksize = 0; /* # of bytes allocated in KB */
/*
* This routine allocates a block of memory large enough to hold a LINE
* containing "used" characters. The block is always rounded up a bit. Return
* a pointer to the new block, or NULL if there isn't any memory left. Print a
* message in the message line if no space.
*/
LINE* lalloc(int used)
{
LINE *lp;
int size;
size = (used + NBLOCK - 1) & ~(NBLOCK - 1);
if (size == 0) /* Assume that an empty */
size = NBLOCK; /* line is for type-in */
if ((lp = (LINE *) malloc(sizeof(LINE) + size)) == NULL)
{
mlwrite("Cannot allocate %d bytes", size);
return (NULL);
}
lp->l_size = size;
lp->l_used = used;
return (lp);
}
/*
* Delete line "lp". Fix all of the links that might point at it (they are
* moved to offset 0 of the next line. Unlink the line from whatever buffer it
* might be in. Release the memory. The buffers are updated too; the magic
* conditions described in the above comments don't hold here
*/
void lfree(LINE *lp)
{
BUFFER *bp;
WINDOW *wp;
wp = wheadp;
while (wp != NULL)
{
if (wp->w_linep == lp)
wp->w_linep = lp->l_fp;
if (wp->w_dotp == lp)
{
wp->w_dotp = lp->l_fp;
wp->w_doto = 0;
}
if (wp->w_markp == lp)
{
wp->w_markp = lp->l_fp;
wp->w_marko = 0;
}
wp = wp->w_wndp;
}
bp = bheadp;
while (bp != NULL)
{
if (bp->b_nwnd == 0)
{
if (bp->b_dotp == lp)
{
bp->b_dotp = lp->l_fp;
bp->b_doto = 0;
}
if (bp->b_markp == lp)
{
bp->b_markp = lp->l_fp;
bp->b_marko = 0;
}
}
bp = bp->b_bufp;
}
lp->l_bp->l_fp = lp->l_fp;
lp->l_fp->l_bp = lp->l_bp;
free((char *) lp);
}
/*
* This routine gets called when a character is changed in place in the
* current buffer. It updates all of the required flags in the buffer and
* window system. The flag used is passed as an argument; if the buffer is
* being displayed in more than 1 window we change EDIT t HARD. Set MODE if
* the mode line needs to be updated (the "*" has to be set).
*/
void lchange(int flag)
{
WINDOW *wp;
if (curbp->b_nwnd != 1) /* Ensure hard */
flag = WFHARD;
if ((curbp->b_flag & BFCHG) == 0)
{ /* First change, so */
flag |= WFMODE; /* update mode lines */
curbp->b_flag |= BFCHG;
}
wp = wheadp;
while (wp != NULL)
{
if (wp->w_bufp == curbp)
wp->w_flag |= flag;
wp = wp->w_wndp;
}
}
/*
* Insert "n" copies of the character "c" at the current location of dot. In
* the easy case all that happens is the text is stored in the line. In the
* hard case, the line has to be reallocated. When the window list is updated,
* take special care; I screwed it up once. You always update dot in the
* current window. You update mark, and a dot in another window, if it is
* greater than the place where you did the insert. Return TRUE if all is
* well, and FALSE on errors
*/
int linsert(int n, int c)
{
WINDOW *wp;
LINE *lp1, *lp2, *lp3;
char *cp1, *cp2;
int i, doto;
lchange(WFEDIT);
lp1 = curwp->w_dotp; /* Current line */
if (lp1 == curbp->b_linep)
{ /* At the end: special */
if (curwp->w_doto != 0)
{
mlwrite("Bug: linsert");
return (FALSE);
}
if ((lp2 = lalloc(n)) == NULL) /* Allocate new line */
return (FALSE);
lp3 = lp1->l_bp; /* Previous line */
lp3->l_fp = lp2; /* Link in */
lp2->l_fp = lp1;
lp1->l_bp = lp2;
lp2->l_bp = lp3;
for (i = 0; i < n; ++i)
lp2->l_text[i] = c;
curwp->w_dotp = lp2;
curwp->w_doto = n;
return (TRUE);
}
doto = curwp->w_doto; /* Save for later */
if (lp1->l_used + n > lp1->l_size)
{ /* Hard: reallocate */
if ((lp2 = lalloc(lp1->l_used + n)) == NULL)
return (FALSE);
cp1 = &lp1->l_text[0];
cp2 = &lp2->l_text[0];
while (cp1 != &lp1->l_text[doto])
*cp2++ = *cp1++;
cp2 += n;
while (cp1 != &lp1->l_text[lp1->l_used])
*cp2++ = *cp1++;
lp1->l_bp->l_fp = lp2;
lp2->l_fp = lp1->l_fp;
lp1->l_fp->l_bp = lp2;
lp2->l_bp = lp1->l_bp;
free((char *) lp1);
}
else
{ /* Easy: in place */
lp2 = lp1; /* Pretend new line */
lp2->l_used += n;
cp2 = &lp1->l_text[lp1->l_used];
cp1 = cp2 - n;
while (cp1 != &lp1->l_text[doto])
*--cp2 = *--cp1;
}
for (i = 0; i < n; ++i) /* Add the characters */
lp2->l_text[doto + i] = c;
wp = wheadp; /* Update windows */
while (wp != NULL)
{
if (wp->w_linep == lp1)
wp->w_linep = lp2;
if (wp->w_dotp == lp1)
{
wp->w_dotp = lp2;
if (wp == curwp || wp->w_doto > doto)
wp->w_doto += n;
}
if (wp->w_markp == lp1)
{
wp->w_markp = lp2;
if (wp->w_marko > doto)
wp->w_marko += n;
}
wp = wp->w_wndp;
}
return (TRUE);
}
/*
* Insert a newline into the buffer at the current location of dot in the
* current window. The funny ass-backwards way it does things is not a botch;
* it just makes the last line in the file not a special case. Return TRUE if
* everything works out and FALSE on error (memory allocation failure). The
* update of dot and mark is a bit easier then in the above case, because the
* split forces more updating.
*/
int lnewline()
{
WINDOW *wp;
char *cp1, *cp2;
LINE *lp1, *lp2;
int doto;
lchange(WFHARD);
curwp->w_bufp->b_lines++;
lp1 = curwp->w_dotp; /* Get the address and */
doto = curwp->w_doto; /* offset of "." */
if ((lp2 = lalloc(doto)) == NULL) /* New first half line */
return (FALSE);
cp1 = &lp1->l_text[0]; /* Shuffle text around */
cp2 = &lp2->l_text[0];
while (cp1 != &lp1->l_text[doto])
*cp2++ = *cp1++;
cp2 = &lp1->l_text[0];
while (cp1 != &lp1->l_text[lp1->l_used])
*cp2++ = *cp1++;
lp1->l_used -= doto;
lp2->l_bp = lp1->l_bp;
lp1->l_bp = lp2;
lp2->l_bp->l_fp = lp2;
lp2->l_fp = lp1;
wp = wheadp; /* Windows */
while (wp != NULL)
{
if (wp->w_linep == lp1)
wp->w_linep = lp2;
if (wp->w_dotp == lp1)
{
if (wp->w_doto < doto)
wp->w_dotp = lp2;
else
wp->w_doto -= doto;
}
if (wp->w_markp == lp1)
{
if (wp->w_marko < doto)
wp->w_markp = lp2;
else
wp->w_marko -= doto;
}
wp = wp->w_wndp;
}
curwp->w_dotline++;
return (TRUE);
}
/*
* This function deletes "n" bytes, starting at dot. It understands how do
* deal with end of lines, etc. It returns TRUE if all of the characters were
* deleted, and FALSE if they were not (because dot ran into the end of the
* buffer. The "kflag" is TRUE if the text should be put in the kill buffer.
*/
int ldelete(int n, int kflag)
{
LINE *dotp;
WINDOW *wp;
char *cp1, *cp2;
int doto, chunk;
while (n != 0)
{
dotp = curwp->w_dotp;
doto = curwp->w_doto;
if (dotp == curbp->b_linep) /* Hit end of buffer */
return (FALSE);
chunk = dotp->l_used - doto; /* Size of chunk */
if (chunk > n)
chunk = n;
if (chunk == 0)
{ /* End of line, merge */
lchange(WFHARD);
if (ldelnewline() == FALSE
|| (kflag != FALSE && kinsert('\n') == FALSE))
return (FALSE);
--n;
continue;
}
lchange(WFEDIT);
cp1 = &dotp->l_text[doto]; /* Scrunch text */
cp2 = cp1 + chunk;
if (kflag != FALSE)
{ /* Kill? */
while (cp1 != cp2)
{
if (kinsert (*cp1) == FALSE)
return (FALSE);
++cp1;
}
cp1 = &dotp->l_text[doto];
}
while (cp2 != &dotp->l_text[dotp->l_used])
*cp1++ = *cp2++;
dotp->l_used -= chunk;
wp = wheadp; /* Fix windows */
while (wp != NULL)
{
if (wp->w_dotp == dotp && wp->w_doto >= doto)
{
wp->w_doto -= chunk;
if (wp->w_doto < doto)
wp->w_doto = doto;
}
if (wp->w_markp == dotp && wp->w_marko >= doto)
{
wp->w_marko -= chunk;
if (wp->w_marko < doto)
wp->w_marko = doto;
}
wp = wp->w_wndp;
}
n -= chunk;
}
return (TRUE);
}
/*
* Delete a newline. Join the current line with the next line. If the next
* line is the magic header line always return TRUE; merging the last line
* with the header line can be thought of as always being a successful
* operation, even if nothing is done, and this makes the kill buffer work
* "right". Easy cases can be done by shuffling data around. Hard cases
* require that lines be moved about in memory. Return FALSE on error and TRUE
* if all looks ok. Called by "ldelete" only.
*/
int ldelnewline()
{
LINE *lp1, *lp2, *lp3;
WINDOW *wp;
char *cp1, *cp2;
lp1 = curwp->w_dotp;
lp2 = lp1->l_fp;
if (lp2 == curbp->b_linep)
{ /* At the buffer end */
if (lp1->l_used == 0) /* Blank line */
lfree(lp1);
return (TRUE);
}
/* Keep line counts in sync */
curwp->w_bufp->b_lines--;
if (lp2->l_used <= lp1->l_size - lp1->l_used)
{
cp1 = &lp1->l_text[lp1->l_used];
cp2 = &lp2->l_text[0];
while (cp2 != &lp2->l_text[lp2->l_used])
*cp1++ = *cp2++;
wp = wheadp;
while (wp != NULL)
{
if (wp->w_linep == lp2)
wp->w_linep = lp1;
if (wp->w_dotp == lp2)
{
wp->w_dotp = lp1;
wp->w_doto += lp1->l_used;
}
if (wp->w_markp == lp2)
{
wp->w_markp = lp1;
wp->w_marko += lp1->l_used;
}
wp = wp->w_wndp;
}
lp1->l_used += lp2->l_used;
lp1->l_fp = lp2->l_fp;
lp2->l_fp->l_bp = lp1;
free((char *) lp2);
return (TRUE);
}
if ((lp3 = lalloc(lp1->l_used + lp2->l_used)) == NULL)
return (FALSE);
cp1 = &lp1->l_text[0];
cp2 = &lp3->l_text[0];
while (cp1 != &lp1->l_text[lp1->l_used])
*cp2++ = *cp1++;
cp1 = &lp2->l_text[0];
while (cp1 != &lp2->l_text[lp2->l_used])
*cp2++ = *cp1++;
lp1->l_bp->l_fp = lp3;
lp3->l_fp = lp2->l_fp;
lp2->l_fp->l_bp = lp3;
lp3->l_bp = lp1->l_bp;
wp = wheadp;
while (wp != NULL)
{
if (wp->w_linep == lp1 || wp->w_linep == lp2)
wp->w_linep = lp3;
if (wp->w_dotp == lp1)
wp->w_dotp = lp3;
else if (wp->w_dotp == lp2)
{
wp->w_dotp = lp3;
wp->w_doto += lp1->l_used;
}
if (wp->w_markp == lp1)
wp->w_markp = lp3;
else if (wp->w_markp == lp2)
{
wp->w_markp = lp3;
wp->w_marko += lp1->l_used;
}
wp = wp->w_wndp;
}
free((char *) lp1);
free((char *) lp2);
return (TRUE);
}
/*
* Delete all of the text saved in the kill buffer. Called by commands when a
* new kill context is being created. The kill buffer array is released, just
* in case the buffer has grown to immense size. No errors.
*/
void kdelete()
{
if (kbufp != NULL)
{
free((char *) kbufp);
kbufp = NULL;
kused = 0;
ksize = 0;
}
}
/*
* Insert a character to the kill buffer, enlarging the buffer if there isn't
* any room. Always grow the buffer in chunks, on the assumption that if you
* put something in the kill buffer you are going to put more stuff there too
* later. Return TRUE if all is well, and FALSE on errors.
*/
int kinsert(int c)
{
char *nbufp;
if (kused == ksize)
{
if (ksize == 0) /* first time through? */
nbufp = malloc(KBLOCK); /* alloc the first block */
else /* or re allocate a bigger block */
nbufp = realloc(kbufp, ksize + KBLOCK);
if (nbufp == NULL) /* abort if it fails */
return (FALSE);
kbufp = nbufp; /* point our global at it */
ksize += KBLOCK; /* and adjust the size */
}
kbufp[kused++] = c;
return (TRUE);
}
/*
* This function gets characters from the kill buffer. If the character index
* "n" is off the end, it returns "-1". This lets the caller just scan along
* until it gets a "-1" back.
*/
int kremove(int n)
{
if (n >= kused)
return (-1);
else
return (kbufp[n] & 0xFF);
}

View File

@@ -1,469 +0,0 @@
/* This file is in the public domain. */
/*
* This program is in public domain; originally written by Dave G. Conroy.
* This file contains the main driving routine, and some keyboard processing
* code
*/
#define maindef /* make global definitions not external */
#include <string.h> /* strncpy(3) */
#include <stdlib.h> /* malloc(3) */
#include "estruct.h" /* global structures and defines */
#include "efunc.h" /* function declarations and name table */
#include "edef.h" /* global definitions */
#include "ebind.h"
extern void getwinsize();
extern void vtinit();
extern void vttidy();
extern void update();
extern void mlerase();
extern void mlwrite();
extern int mlyesno(char *prompt);
extern void makename(char bname[], char fname[]);
extern int readin(char fname[]);
extern int linsert(int f, int n);
extern int anycb();
extern BUFFER *bfind();
void edinit(char bname[]);
int execute(int c, int f, int n);
int getkey();
int getctl();
int quickexit(int f, int n);
int quit(int f, int n);
int ctlxlp(int f, int n);
int ctlxrp(int f, int n);
int ctlxe(int f, int n);
int ctrlg(int f, int n);
int extendedcmd(int f, int n);
int main(int argc, char *argv[])
{
BUFFER *bp;
char bname[NBUFN]; /* buffer name of file to read */
int c, f, n, mflag;
int ffile; /* first file flag */
int carg; /* current arg to scan */
int basec; /* c stripped of meta character */
/* initialize the editor and process the startup file */
getwinsize(); /* find out the "real" screen size */
strncpy(bname, "main", 5); /* default buffer name */
edinit(bname); /* Buffers, windows */
vtinit(); /* Displays */
ffile = TRUE; /* no file to edit yet */
update(); /* let the user know we are here */
/* scan through the command line and get the files to edit */
for (carg = 1; carg < argc; ++carg)
{
/* set up a buffer for this file */
makename(bname, argv[carg]);
/* if this is the first file, read it in */
if (ffile)
{
bp = curbp;
makename(bname, argv[carg]);
strncpy(bp->b_bname, bname, NBUFN);
strncpy(bp->b_fname, argv[carg], NFILEN);
if (readin(argv[carg]) == ABORT)
{
strncpy(bp->b_bname, "main", 5);
strncpy(bp->b_fname, "", 1);
}
bp->b_dotp = bp->b_linep;
bp->b_doto = 0;
ffile = FALSE;
}
else
{
/* set this to inactive */
bp = bfind(bname, TRUE, 0);
strncpy(bp->b_fname, argv[carg], NFILEN);
bp->b_active = FALSE;
}
}
/* setup to process commands */
lastflag = 0; /* Fake last flags */
curwp->w_flag |= WFMODE; /* and force an update */
loop:
update(); /* Fix up the screen */
c = getkey();
if (mpresf != FALSE)
{
mlerase();
update();
}
f = FALSE;
n = 1;
/* do META-# processing if needed */
basec = c & ~META; /* strip meta char off if there */
if ((c & META) && ((basec >= '0' && basec <= '9') || basec == '-'))
{
f = TRUE; /* there is a # arg */
n = 0; /* start with a zero default */
mflag = 1; /* current minus flag */
c = basec; /* strip the META */
while ((c >= '0' && c <= '9') || (c == '-'))
{
if (c == '-')
{
/* already hit a minus or digit? */
if ((mflag == -1) || (n != 0))
break;
mflag = -1;
}
else
n = n * 10 + (c - '0');
if ((n == 0) && (mflag == -1)) /* lonely - */
mlwrite("Arg:");
else
mlwrite("Arg: %d", n * mflag);
c = getkey(); /* get the next key */
}
n = n * mflag; /* figure in the sign */
}
/* do ^U repeat argument processing */
if (c == (CTRL | 'U'))
{ /* ^U, start argument */
f = TRUE;
n = 4; /* with argument of 4 */
mflag = 0; /* that can be discarded */
mlwrite("Arg: 4");
while (((c = getkey ()) >= '0')
&& ((c <= '9') || (c == (CTRL | 'U')) || (c == '-')))
{
if (c == (CTRL | 'U'))
n = n * 4;
/*
* If dash, and start of argument string, set arg.
* to -1. Otherwise, insert it.
*/
else if (c == '-')
{
if (mflag)
break;
n = 0;
mflag = -1;
}
/*
* If first digit entered, replace previous argument
* with digit and set sign. Otherwise, append to arg.
*/
else
{
if (!mflag)
{
n = 0;
mflag = 1;
}
n = 10 * n + c - '0';
}
mlwrite("Arg: %d", (mflag >= 0) ? n : (n ? -n : -1));
}
/*
* Make arguments preceded by a minus sign negative and change
* the special argument "^U -" to an effective "^U -1".
*/
if (mflag == -1)
{
if (n == 0)
n++;
n = -n;
}
}
if (c == (CTRL | 'X')) /* ^X is a prefix */
c = CTLX | getctl ();
if (kbdmip != NULL)
{ /* Save macro strokes */
if (c != (CTLX | ')') && kbdmip > &kbdm[NKBDM - 6])
{
ctrlg(FALSE, 0);
goto loop;
}
if (f != FALSE)
{
*kbdmip++ = (CTRL | 'U');
*kbdmip++ = n;
}
*kbdmip++ = c;
}
execute(c, f, n); /* Do it */
goto loop;
}
/*
* Initialize all of the buffers and windows. The buffer name is passed down
* as an argument, because the main routine may have been told to read in a
* file by default, and we want the buffer name to be right.
*/
void edinit(char bname[])
{
BUFFER *bp;
WINDOW *wp;
bp = bfind(bname, TRUE, 0); /* First buffer */
blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer */
wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */
if (bp == NULL || wp == NULL || blistp == NULL)
exit (1);
curbp = bp; /* Make this current */
wheadp = wp;
curwp = wp;
wp->w_wndp = NULL; /* Initialize window */
wp->w_bufp = bp;
bp->b_nwnd = 1; /* Displayed */
wp->w_linep = bp->b_linep;
wp->w_dotp = bp->b_linep;
wp->w_doto = 0;
wp->w_markp = NULL;
wp->w_marko = 0;
wp->w_toprow = 0;
wp->w_ntrows = term.t_nrow - 1; /* "-1" for mode line */
wp->w_force = 0;
wp->w_flag = WFMODE | WFHARD; /* Full */
}
/*
* This is the general command execution routine. It handles the fake binding
* of all the keys to "self-insert". It also clears out the "thisflag" word,
* and arranges to move it to the "lastflag", so that the next command can
* look at it. Return the status of command.
*/
int execute(int c, int f, int n)
{
KEYTAB *ktp;
int status;
ktp = &keytab[0]; /* Look in key table */
while (ktp->k_fp != NULL)
{
if (ktp->k_code == c)
{
thisflag = 0;
status = (*ktp->k_fp) (f, n);
lastflag = thisflag;
return (status);
}
++ktp;
}
if ((c >= 0x20 && c <= 0x7E) /* Self inserting */
|| (c >= 0xA0 && c <= 0xFE))
{
if (n <= 0)
{ /* Fenceposts */
lastflag = 0;
return (n < 0 ? FALSE : TRUE);
}
thisflag = 0; /* For the future */
status = linsert(n, c);
lastflag = thisflag;
return (status);
}
mlwrite("\007[Key not bound]"); /* complain */
lastflag = 0; /* Fake last flags */
return (FALSE);
}
/*
* Read in a key. Do the standard keyboard preprocessing. Convert the keys to
* the internal character set.
*/
int getkey()
{
int c;
c = (*term.t_getchar) ();
if (c == METACH)
{ /* Apply M- prefix */
c = getctl ();
return (META | c);
}
if (c >= 0x00 && c <= 0x1F) /* C0 control -> C- */
c = CTRL | (c + '@');
return (c);
}
/*
* Get a key. Apply control modifications to the read key.
*/
int getctl()
{
int c;
c = (*term.t_getchar) ();
if (c >= 'a' && c <= 'z') /* Force to upper */
c -= 0x20;
if (c >= 0x00 && c <= 0x1F) /* C0 control -> C- */
c = CTRL | (c + '@');
return (c);
}
/*
* Fancy quit command, as implemented by Norm. If any buffer has changed
* do a write on that buffer and exit emacs, otherwise simply exit.
*/
int quickexit(int f, int n)
{
BUFFER *bp; /* scanning pointer to buffers */
bp = bheadp;
while (bp != NULL)
{
if ((bp->b_flag & BFCHG) != 0 /* Changed */
&& (bp->b_flag & BFTEMP) == 0)
{ /* Real */
curbp = bp; /* make that buffer current */
mlwrite("[Saving %s]", (int*)bp->b_fname);
filesave(f, n);
}
bp = bp->b_bufp; /* on to the next buffer */
}
return quit(f, n); /* conditionally quit */
}
/*
* Quit command. If an argument, always quit. Otherwise confirm if a buffer
* has been changed and not written out. Normally bound to "C-X C-C".
*/
int quit(int f, int n)
{
int s;
if (f != FALSE /* Argument forces it */
|| anycb () == FALSE /* All buffers clean */
|| (s = mlyesno("Modified buffers exist. Leave anyway")) == TRUE)
{
vttidy();
exit (0);
}
mlwrite("");
return (s);
}
/*
* Begin a keyboard macro. Error if not at the top level in keyboard
* processing. Set up variables and return.
*/
int ctlxlp(int f, int n)
{
if (kbdmip != NULL || kbdmop != NULL)
{
mlwrite("Not now");
return (FALSE);
}
mlwrite("[Start macro]");
kbdmip = &kbdm[0];
return (TRUE);
}
/*
* End keyboard macro. Check for the same limit conditions as the above
* routine. Set up the variables and return to the caller.
*/
int ctlxrp(int f, int n)
{
if (kbdmip == NULL)
{
mlwrite("Not now");
return (FALSE);
}
mlwrite("[End macro]");
kbdmip = NULL;
return (TRUE);
}
/*
* Execute a macro. The command argument is the number of times to loop. Quit
* as soon as a command gets an error. Return TRUE if all ok, else FALSE.
*/
int ctlxe(int f, int n)
{
int c, af, an, s;
if (kbdmip != NULL || kbdmop != NULL)
{
mlwrite("No macro defined");
return (FALSE);
}
if (n <= 0)
return (TRUE);
do
{
kbdmop = &kbdm[0];
do
{
af = FALSE;
an = 1;
if ((c = *kbdmop++) == (CTRL | 'U'))
{
af = TRUE;
an = *kbdmop++;
c = *kbdmop++;
}
s = TRUE;
}
while (c != (CTLX | ')') && (s = execute(c, af, an)) == TRUE);
kbdmop = NULL;
}
while (s == TRUE && --n);
return (s);
}
/*
* Abort. Beep the beeper. Kill off any keyboard macro, etc., that is in
* progress. Sometimes called as a routine, to do general aborting of stuff.
*/
int ctrlg(int f, int n)
{
(*term.t_beep) ();
if (kbdmip != NULL)
{
kbdm[0] = (CTLX | ')');
kbdmip = NULL;
}
mlwrite("[Aborted]");
return (ABORT);
}
/*
* Handle ANSI escape-extended commands (with "ESC [" or "ESC O" prefix)
*/
int extendedcmd(int f, int n)
{
int (*cmd)();
int c;
c = getctl();
switch (c)
{
case 'A': cmd = backline; break;
case 'B': cmd = forwline; break;
case 'C': cmd = forwchar; break;
case 'D': cmd = backchar; break;
case 'H': cmd = gotobob; break;
case 'W': cmd = gotoeob; break;
case '5': cmd = pageup; getctl(); break;
case '6': cmd = pagedown; getctl(); break;
case '7': cmd = gotobob; getctl(); break;
case '8': cmd = gotoeob; getctl(); break;
default: mlwrite("\007[Key not bound]");
return (FALSE);
}
return cmd(f, n);
}

View File

@@ -1,290 +0,0 @@
/* This file is in the public domain. */
/*
* This file contains the command processing functions for a number of random
* commands. There is no functional grouping here, for sure.
*/
#include "estruct.h"
#include "edef.h"
extern void mlwrite();
extern void lchange(int flag);
extern int lnewline();
extern int linsert(int n, int c);
extern int backchar(int f, int n);
extern void kdelete();
extern int ldelete(int f, int n);
extern int kremove(int k);
int setfillcol(int f, int n);
int getccol(int bflg);
int twiddle(int f, int n);
int quote(int f, int n);
int tab(int f, int n);
int openline(int f, int n);
int newline(int f, int n);
int forwdel(int f, int n);
int backdel(int f, int n);
int killtext(int f, int n);
int yank(int f, int n);
/*
* Set fill column to n.
*/
int setfillcol(int f, int n)
{
fillcol = n;
mlwrite("[Fill column is %d]", n);
return (TRUE);
}
/*
* Return current column. Stop at first non-blank given TRUE argument.
*/
int getccol(int bflg)
{
int c, i, col;
col = 0;
for (i = 0; i < curwp->w_doto; ++i)
{
c = lgetc(curwp->w_dotp, i);
if (c != ' ' && c != '\t' && bflg)
break;
if (c == '\t')
col |= 0x07;
else if (c < 0x20 || c == 0x7F)
++col;
++col;
}
return (col);
}
/*
* Twiddle the two characters on either side of dot. If dot is at the end of
* the line twiddle the two characters before it. Return with an error if dot
* is at the beginning of line; it seems to be a bit pointless to make this
* work. This fixes up a very common typo with a single stroke. Normally bound
* to "C-T". This always works within a line, so "WFEDIT" is good enough
*/
int twiddle(int f, int n)
{
LINE *dotp;
int doto, cl, cr;
dotp = curwp->w_dotp;
doto = curwp->w_doto;
if (doto == llength(dotp) && --doto < 0)
return (FALSE);
cr = lgetc(dotp, doto);
if (--doto < 0)
return (FALSE);
cl = lgetc(dotp, doto);
lputc(dotp, doto + 0, cr);
lputc(dotp, doto + 1, cl);
lchange(WFEDIT);
return (TRUE);
}
/*
* Quote the next character, and insert it into the buffer. All the characters
* are taken literally, with the exception of the newline, which always has
* its line splitting meaning. The character is always read, even if it is
* inserted 0 times, for regularity. Bound to "C-Q"
*/
int quote(int f, int n)
{
int s, c;
c = (*term.t_getchar) ();
if (n < 0)
return (FALSE);
if (n == 0)
return (TRUE);
if (c == '\n')
{
do
{
s = lnewline();
}
while (s == TRUE && --n);
return (s);
}
return (linsert(n, c));
}
/*
* Insert a tab into file.
* Bound to "C-I"
*/
int tab(int f, int n)
{
if (n < 0)
return (FALSE);
return (linsert(n, 9));
}
/*
* Open up some blank space. The basic plan is to insert a bunch of newlines,
* and then back up over them. Everything is done by the subcommand
* processors. They even handle the looping. Normally this is bound to "C-O"
*/
int openline(int f, int n)
{
int i, s;
if (n < 0)
return (FALSE);
if (n == 0)
return (TRUE);
i = n; /* Insert newlines */
do
{
s = lnewline();
}
while (s == TRUE && --i);
if (s == TRUE) /* Then back up overtop */
s = backchar(f, n); /* of them all */
return (s);
}
/*
* Insert a newline. Bound to "C-M".
*/
int newline(int f, int n)
{
int s;
if (n < 0)
return (FALSE);
/* insert some lines */
while (n--)
{
if ((s = lnewline()) != TRUE)
return (s);
}
return (TRUE);
}
/*
* Delete forward. This is real easy, because the basic delete routine does
* all of the work. Watches for negative arguments, and does the right thing.
* If any argument is present, it kills rather than deletes, to prevent loss
* of text if typed with a big argument. Normally bound to "C-D"
*/
int forwdel(int f, int n)
{
if (n < 0)
return (backdel(f, -n));
if (f != FALSE)
{ /* Really a kill */
if ((lastflag & CFKILL) == 0)
kdelete();
thisflag |= CFKILL;
}
return (ldelete(n, f));
}
/*
* Delete backwards. This is quite easy too, because it's all done with other
* functions. Just move the cursor back, and delete forwards. Like delete
* forward, this actually does a kill if presented with an argument. Bound to
* both "RUBOUT" and "C-H"
*/
int backdel(int f, int n)
{
int s;
if (n < 0)
return (forwdel(f, -n));
if (f != FALSE)
{ /* Really a kill */
if ((lastflag & CFKILL) == 0)
kdelete();
thisflag |= CFKILL;
}
if ((s = backchar(f, n)) == TRUE)
s = ldelete(n, f);
return (s);
}
/*
* Kill text. If called without an argument, it kills from dot to the end of
* the line, unless it is at the end of the line, when it kills the newline.
* If called with an argument of 0, it kills from the start of the line to
* dot. If called with a positive argument, it kills from dot forward over
* that number of newlines. If called with a negative argument it kills
* backwards that number of newlines. Normally bound to "C-K"
*/
int killtext(int f, int n)
{
LINE *nextp;
int chunk;
if ((lastflag & CFKILL) == 0)/* Clear kill buffer if last wasn't a kill */
kdelete();
thisflag |= CFKILL;
if (f == FALSE)
{
chunk = llength(curwp->w_dotp) - curwp->w_doto;
if (chunk == 0)
chunk = 1;
}
else if (n == 0)
{
chunk = curwp->w_doto;
curwp->w_doto = 0;
}
else if (n > 0)
{
chunk = llength(curwp->w_dotp) - curwp->w_doto + 1;
nextp = lforw(curwp->w_dotp);
while (--n)
{
if (nextp == curbp->b_linep)
return (FALSE);
chunk += llength(nextp) + 1;
nextp = lforw(nextp);
}
}
else
{
mlwrite("neg kill");
return (FALSE);
}
return (ldelete(chunk, TRUE));
}
/*
* Yank text back from the kill buffer. This is really easy. All of the work
* is done by the standard insert routines. All you do is run the loop, and
* check for errors. Bound to "C-Y"
*/
int yank(int f, int n)
{
int c, i;
if (n < 0)
return (FALSE);
while (n--)
{
i = 0;
while ((c = kremove(i)) >= 0)
{
if (c == '\n')
{
if (lnewline(FALSE, 1) == FALSE)
return (FALSE);
}
else
{
if (linsert(1, c) == FALSE)
return (FALSE);
}
++i;
}
}
return (TRUE);
}

View File

@@ -1,142 +0,0 @@
/* This file is in the public domain. */
/*
* The routines in this file deal with the region, that magic space between
* "." and mark. Some functions are commands. Some functions are just for
* internal use
*/
#include "estruct.h"
#include "edef.h"
extern void kdelete();
extern int ldelete(int f, int n);
extern int kinsert(int c);
extern void mlwrite();
int killregion(int f, int n);
int copyregion(int f, int n);
int getregion(REGION *rp);
/*
* Kill the region. Ask "getregion" to figure out the bounds of the region.
* Move "." to the start, and kill the characters. Bound to "C-W"
*/
int killregion(int f, int n)
{
REGION region;
int s;
if ((s = getregion(&region)) != TRUE)
return (s);
if ((lastflag & CFKILL) == 0) /* This is a kill type */
kdelete(); /* command, so do magic */
thisflag |= CFKILL; /* kill buffer stuff */
curwp->w_dotp = region.r_linep;
curwp->w_doto = region.r_offset;
return (ldelete(region.r_size, TRUE));
}
/*
* Copy all of the characters in the region to the kill buffer. Don't move dot
* at all. This is a bit like a kill region followed by a yank. Bound to "M-W"
*/
int copyregion(int f, int n)
{
LINE *linep;
REGION region;
int loffs, s;
if ((s = getregion(&region)) != TRUE)
return (s);
if ((lastflag & CFKILL) == 0) /* Kill type command */
kdelete();
thisflag |= CFKILL;
linep = region.r_linep; /* Current line */
loffs = region.r_offset; /* Current offset */
while (region.r_size--)
{
if (loffs == llength(linep))
{ /* End of line */
if ((s = kinsert('\n')) != TRUE)
return (s);
linep = lforw(linep);
loffs = 0;
}
else
{ /* Middle of line */
if ((s = kinsert(lgetc(linep, loffs))) != TRUE)
return (s);
++loffs;
}
}
return (TRUE);
}
/*
* This routine figures out the bounds of the region in the current window,
* and fills in the fields of the "REGION" structure pointed to by "rp".
* Because the dot and mark are usually very close together, we scan outward
* from dot looking for mark. This should save time. Return a standard code.
* Callers of this routine should be prepared to get an "ABORT" status; we
* might make this have the conform thing later
*/
int getregion(REGION *rp)
{
LINE *flp, *blp;
int fsize, bsize;
if (curwp->w_markp == (struct LINE*)0)
{
mlwrite("No mark set in this window");
return (FALSE);
}
if (curwp->w_dotp == curwp->w_markp)
{
rp->r_linep = curwp->w_dotp;
if (curwp->w_doto < curwp->w_marko)
{
rp->r_offset = curwp->w_doto;
rp->r_size = curwp->w_marko - curwp->w_doto;
}
else
{
rp->r_offset = curwp->w_marko;
rp->r_size = curwp->w_doto - curwp->w_marko;
}
return (TRUE);
}
blp = curwp->w_dotp;
bsize = curwp->w_doto;
flp = curwp->w_dotp;
fsize = llength(flp) - curwp->w_doto + 1;
while (flp != curbp->b_linep || lback(blp) != curbp->b_linep)
{
if (flp != curbp->b_linep)
{
flp = lforw(flp);
if (flp == curwp->w_markp)
{
rp->r_linep = curwp->w_dotp;
rp->r_offset = curwp->w_doto;
rp->r_size = fsize + curwp->w_marko;
return (TRUE);
}
fsize += llength(flp) + 1;
}
if (lback(blp) != curbp->b_linep)
{
blp = lback(blp);
bsize += llength(blp) + 1;
if (blp == curwp->w_markp)
{
rp->r_linep = blp;
rp->r_offset = curwp->w_marko;
rp->r_size = bsize - curwp->w_marko;
return (TRUE);
}
}
}
mlwrite("Bug: lost mark");
return (FALSE);
}

View File

@@ -1,383 +0,0 @@
/* This file is in the public domain. */
/*
* The functions in this file implement commands that search in the forward
* and backward directions. There are no special characters in the search
* strings
*/
#include <string.h> /* strncpy(3), strncat(3) */
#include "estruct.h"
#include "edef.h"
extern void mlwrite();
extern int mlreplyt(char *prompt, char *buf, int nbuf, char eolchar);
extern void update();
extern int forwchar(int f, int n);
extern int ldelete(int n, int kflag);
extern int lnewline();
extern int linsert(int n, int c);
int forwsearch(int f, int n);
int forwhunt(int f, int n);
int backsearch(int f, int n);
int backhunt(int f, int n);
int bsearch(int f, int n);
int eq(int bc, int pc);
int readpattern(char *prompt);
int forscan(char *patrn, int leavep);
void expandp(char *srcstr, char *deststr, int maxlength);
#define PTBEG 1 /* leave the point at the begining on search */
#define PTEND 2 /* leave the point at the end on search */
/*
* Search forward. Get a search string from the user, and search, beginning at
* ".", for the string. If found, reset the "." to be just after the match
* string, and [perhaps] repaint the display. Bound to "C-S"
*/
int forwsearch(int f, int n)
{
int status;
int curline = curwp->w_dotline;
if (n == 0) /* resolve the repeat count */
n = 1;
if (n < 1) /* search backwards */
return (backsearch(f, -n));
/* ask the user for the text of a pattern */
if ((status = readpattern("Search")) != TRUE)
return (status);
/* search for the pattern */
while (n-- > 0)
{
if ((status = forscan(&pat[0], PTEND)) == FALSE)
break;
}
/* and complain if not there */
if (status == FALSE) {
mlwrite("Not found");
curwp->w_dotline = curline;
}
return (status);
}
int forwhunt(int f, int n)
{
int status = 0;
int curline = curwp->w_dotline;
/* resolve the repeat count */
if (n == 0)
n = 1;
if (n < 1) /* search backwards */
return (backhunt(f, -n));
/* Make sure a pattern exists */
if (pat[0] == 0)
{
mlwrite("No pattern set");
return (FALSE);
}
/* search for the pattern */
while (n-- > 0)
{
if ((status = forscan(&pat[0], PTEND)) == FALSE)
break;
}
/* and complain if not there */
if (status == FALSE) {
mlwrite("Not found");
curwp->w_dotline = curline;
}
return (status);
}
/*
* Reverse search. Get a search string from the user, and search, starting at
* "." and proceeding toward the front of the buffer. If found "." is left
* pointing at the first character of the pattern [the last character that was
* matched]. Bound to "C-R"
*/
int backsearch(int f, int n)
{
int s;
if (n == 0) /* resolve null and negative arguments */
n = 1;
if (n < 1)
return (forwsearch(f, -n));
if ((s = readpattern("Reverse search")) != TRUE) /* get a pattern to search */
return (s);
return bsearch(f, n); /* and go search for it */
}
/* hunt backward for the last search string entered
*/
int backhunt(int f, int n)
{
if (n == 0) /* resolve null and negative arguments */
n = 1;
if (n < 1)
return (forwhunt(f, -n));
if (pat[0] == 0) /* Make sure a pattern exists */
{
mlwrite("No pattern set");
return (FALSE);
}
return bsearch(f, n); /* go search */
}
int bsearch(int f, int n)
{
LINE *clp, *tlp;
char *epp, *pp;
int cbo, tbo, c;
int curline = curwp->w_dotline;
/* find a pointer to the end of the pattern */
for (epp = &pat[0]; epp[1] != 0; ++epp)
;
/* make local copies of the starting location */
clp = curwp->w_dotp;
cbo = curwp->w_doto;
while (n-- > 0)
{
for (;;)
{
/* if we are at the begining of the line, wrap back around */
if (cbo == 0)
{
clp = lback(clp);
curwp->w_dotline--;
if (clp == curbp->b_linep)
{
mlwrite("Not found");
curwp->w_dotline = curline;
return (FALSE);
}
cbo = llength(clp) + 1;
}
/* fake the <NL> at the end of a line */
if (--cbo == llength(clp))
c = '\n';
else
c = lgetc(clp, cbo);
/* check for a match against the end of the pattern */
if (eq(c, *epp) != FALSE)
{
tlp = clp;
tbo = cbo;
pp = epp;
/* scanning backwards through the rest of the pattern
* looking for a match */
while (pp != &pat[0])
{
/* wrap across a line break */
if (tbo == 0)
{
tlp = lback(tlp);
curwp->w_dotline--;
if (tlp == curbp->b_linep)
goto fail;
tbo = llength(tlp) + 1;
}
/* fake the <NL> */
if (--tbo == llength(tlp))
c = '\n';
else
c = lgetc(tlp, tbo);
if (eq(c, *--pp) == FALSE)
goto fail;
}
/* A Match! reset the current cursor */
curwp->w_dotp = tlp;
curwp->w_doto = tbo;
curwp->w_flag |= WFMOVE;
goto next;
}
fail:;
}
next:;
}
return (TRUE);
}
/*
* Compare two characters. The "bc" comes from the buffer. It has it's case
* folded out. The "pc" is from the pattern
*/
int eq(int bc, int pc)
{
if (bc >= 'a' && bc <= 'z')
bc -= 0x20;
if (pc >= 'a' && pc <= 'z')
pc -= 0x20;
if (bc == pc)
return (TRUE);
return (FALSE);
}
/*
* Read a pattern. Stash it in the external variable "pat". The "pat" is not
* updated if the user types in an empty line. If the user typed an empty
* line, and there is no old pattern, it is an error. Display the old pattern,
* in the style of Jeff Lomicka. There is some do-it-yourself control
* expansion.
*/
int readpattern(char *prompt)
{
char tpat[NPAT + 20];
int s;
strncpy(tpat, prompt, NPAT-12); /* copy prompt to output string */
strncat(tpat, " [", 3); /* build new prompt string */
expandp(&pat[0], &tpat[strlen (tpat)], NPAT / 2); /* add old pattern */
strncat(tpat, "]: ", 4);
s = mlreplyt(tpat, tpat, NPAT, 10); /* Read pattern */
if (s == TRUE) /* Specified */
strncpy(pat, tpat, NPAT);
else if (s == FALSE && pat[0] != 0) /* CR, but old one */
s = TRUE;
return (s);
}
/* search forward for a <patrn>
*/
int forscan(char *patrn, int leavep)
{
LINE *curline; /* current line during scan */
LINE *lastline; /* last line position during scan */
LINE *matchline; /* current line during matching */
char *patptr; /* pointer into pattern */
int curoff; /* position within current line */
int lastoff; /* position within last line */
int c; /* character at current position */
int matchoff; /* position in matching line */
/* setup local scan pointers to global "." */
curline = curwp->w_dotp;
curoff = curwp->w_doto;
/* scan each character until we hit the head link record */
while (curline != curbp->b_linep)
{
/* save the current position in case we need to restore it on a match */
lastline = curline;
lastoff = curoff;
/* get the current character resolving EOLs */
if (curoff == llength(curline))
{ /* if at EOL */
curline = lforw(curline); /* skip to next line */
curwp->w_dotline++;
curoff = 0;
c = '\n'; /* and return a <NL> */
}
else
c = lgetc(curline, curoff++); /* get the char */
/* test it against first char in pattern */
if (eq(c, patrn[0]) != FALSE) /* if we find it. */
{
/* setup match pointers */
matchline = curline;
matchoff = curoff;
patptr = &patrn[0];
/* scan through patrn for a match */
while (*++patptr != 0)
{
/* advance all the pointers */
if (matchoff == llength(matchline))
{
/* advance past EOL */
matchline = lforw(matchline);
curwp->w_dotline++;
matchoff = 0;
c = '\n';
}
else
c = lgetc(matchline, matchoff++);
/* and test it against the pattern */
if (eq(*patptr, c) == FALSE)
goto fail;
}
/* A SUCCESSFULL MATCH!!! */
/* reset the global "." pointers */
if (leavep == PTEND)
{ /* at end of string */
curwp->w_dotp = matchline;
curwp->w_doto = matchoff;
}
else
{ /* at begining of string */
curwp->w_dotp = lastline;
curwp->w_doto = lastoff;
}
curwp->w_flag |= WFMOVE; /* flag that we have moved */
return (TRUE);
}
fail:; /* continue to search */
}
/* we could not find a match */
return (FALSE);
}
/* expandp: expand control key sequences for output
*/
void expandp(char *srcstr, char *deststr, int maxlength)
{
char c; /* current char to translate */
/* scan through the string */
while ((c = *srcstr++) != 0)
{
if (c < 0x20 || c == 0x7f)
{ /* control character */
*deststr++ = '^';
*deststr++ = c ^ 0x40;
maxlength -= 2;
}
else if (c == '%')
{
*deststr++ = '%';
*deststr++ = '%';
maxlength -= 2;
}
else
{ /* any other character */
*deststr++ = c;
maxlength--;
}
/* check for maxlength */
if (maxlength < 4)
{
*deststr++ = '$';
*deststr = '\0';
return;
}
}
*deststr = '\0';
return;
}

View File

@@ -1,117 +0,0 @@
/* This file is in the public domain. */
/* termios video driver */
#define termdef 1 /* don't define "term" externally */
#include <stdio.h> /* puts(3), snprintf(3) */
#include "estruct.h"
#include "edef.h"
#undef CTRL /* Needs to be done here. */
#include <sys/ioctl.h>
extern int tgetent();
extern char *tgetstr();
extern char *tgoto();
extern void tputs();
extern char *getenv();
extern void ttopen();
extern int ttgetc();
extern void ttputc();
extern void ttflush();
extern void ttclose();
extern void panic();
void getwinsize();
void tcapopen();
void tcapmove(int row, int col);
void tcapeeol();
void tcapeeop();
void tcaprev();
void tcapbeep();
#define MARGIN 8
#define SCRSIZ 64
#define BEL 0x07
#define TCAPSLEN 64
char tcapbuf[TCAPSLEN]; /* capabilities actually used */
char *CM, *CE, *CL, *SO, *SE;
TERM term = {
0, 0, MARGIN, SCRSIZ, tcapopen, ttclose, ttgetc, ttputc,
ttflush, tcapmove, tcapeeol, tcapeeop, tcapbeep, tcaprev
};
void getwinsize()
{
int cols = FORCE_COLS;
int rows = FORCE_ROWS;
/* Too small and we're out */
if ((cols < 10) || (rows < 3))
panic("Too few columns or rows");
if (FORCE_COLS > MAXCOL)
cols = MAXCOL;
if (FORCE_ROWS > MAXROW)
rows = MAXROW;
term.t_ncol = cols;
term.t_nrow = rows - 1;
}
void tcapopen()
{
char tcbuf[1024];
char *p, *tv_stype;
if ((tv_stype = getenv("TERM")) == NULL)
panic("TERM not defined");
if ((tgetent(tcbuf, tv_stype)) != 1)
panic("Unknown terminal type");
p = tcapbuf;
CL = tgetstr("cl", &p);
CM = tgetstr("cm", &p);
CE = tgetstr("ce", &p);
SE = tgetstr("se", &p);
SO = tgetstr("so", &p);
if (CE == NULL)
eolexist = FALSE;
if (SO != NULL && SE != NULL)
revexist = TRUE;
if (CL == NULL || CM == NULL)
panic("Need cl & cm abilities");
if (p >= &tcapbuf[TCAPSLEN]) /* XXX */
panic("Description too big");
ttopen ();
}
void tcaprev(int state)
{
if (revexist)
tputs((state ? SO : SE), 1, ttputc);
}
void tcapmove (int row, int col)
{
tputs(tgoto(CM, col, row), 1, ttputc);
}
void tcapeeol()
{
tputs(CE, 1, ttputc);
}
void tcapeeop()
{
tputs(CL, 1, ttputc);
}
void tcapbeep()
{
ttputc(BEL);
}

View File

@@ -1,163 +0,0 @@
/* This file is in the public domain. */
/*
* This file comes from mg1a.
* Uses the panic function from OpenBSD's mg.
*/
/*
* Ultrix-32 and Unix terminal I/O.
* The functions in this file
* negotiate with the operating system for
* keyboard characters, and write characters to
* the display in a barely buffered fashion.
*/
#include <stdio.h>
#include <sgtty.h>
#include <stdlib.h>
#include <term.h>
#include <unistd.h>
#undef CTRL
#include "estruct.h"
void ttflush(void);
void panic(char *);
extern void getwinsize();
#define NROW 66 /* Rows. */
#define NCOL 132 /* Columns. */
#define NOBUF 512 /* Output buffer size. */
char obuf[NOBUF]; /* Output buffer. */
int nobuf;
struct sgttyb oldtty; /* V6/V7 stty data. */
struct sgttyb newtty;
struct tchars oldtchars; /* V7 editing. */
struct tchars newtchars;
struct ltchars oldltchars; /* 4.2 BSD editing. */
struct ltchars newltchars;
/*
* This function gets called once, to set up
* the terminal channel.
*/
void ttopen(void) {
register char *tv_stype;
char *getenv(), *tgetstr(), tcbuf[1024];
if (ioctl(0, TIOCGETP, (char *) &oldtty) < 0)
panic("ttopen can't get sgtty");
newtty.sg_ospeed = oldtty.sg_ospeed;
newtty.sg_ispeed = oldtty.sg_ispeed;
newtty.sg_erase = oldtty.sg_erase;
newtty.sg_kill = oldtty.sg_kill;
newtty.sg_flags = oldtty.sg_flags;
newtty.sg_flags &= ~(ECHO|CRMOD); /* Kill echo, CR=>NL. */
newtty.sg_flags |= RAW|ANYP; /* raw mode for 8 bit path.*/
if (ioctl(0, TIOCSETP, (char *) &newtty) < 0)
panic("ttopen can't set sgtty");
if (ioctl(0, TIOCGETC, (char *) &oldtchars) < 0)
panic("ttopen can't get chars");
newtchars.t_intrc = 0xFF; /* Interrupt. */
newtchars.t_quitc = 0xFF; /* Quit. */
newtchars.t_startc = 0xFF; /* ^Q, for terminal. */
newtchars.t_stopc = 0xFF; /* ^S, for terminal. */
newtchars.t_eofc = 0xFF;
newtchars.t_brkc = 0xFF;
if (ioctl(0, TIOCSETC, (char *) &newtchars) < 0)
panic("ttopen can't set chars");
if (ioctl(0, TIOCGLTC, (char *) &oldltchars) < 0)
panic("ttopen can't get ltchars");
newltchars.t_suspc = 0xFF; /* Suspend #1. */
newltchars.t_dsuspc = 0xFF; /* Suspend #2. */
newltchars.t_rprntc = 0xFF;
newltchars.t_flushc = 0xFF; /* Output flush. */
newltchars.t_werasc = 0xFF;
newltchars.t_lnextc = 0xFF; /* Literal next. */
if (ioctl(0, TIOCSLTC, (char *) &newltchars) < 0)
panic("ttopen can't set ltchars");
/* do this the REAL way */
if ((tv_stype = getenv("TERM")) == NULL)
panic("TERM not defined");
if((tgetent(tcbuf, tv_stype)) != 1)
panic("Unknown terminal type");
getwinsize();
}
/*
* This function gets called just
* before we go back home to the shell. Put all of
* the terminal parameters back.
*/
void ttclose(void) {
ttflush();
if (ioctl(0, TIOCSLTC, (char *) &oldltchars) < 0)
panic("ttclose can't set ltchars");
if (ioctl(0, TIOCSETC, (char *) &oldtchars) < 0)
panic("ttclose can't set chars");
if (ioctl(0, TIOCSETP, (char *) &oldtty) < 0)
panic("ttclose can't set sgtty");
}
/*
* Write character to the display.
* Characters are buffered up, to make things
* a little bit more efficient.
*/
int ttputc(int c) {
if (nobuf >= NOBUF)
ttflush();
obuf[nobuf++] = c;
return (c);
}
/*
* Flush output.
*/
void ttflush(void) {
if (nobuf != 0) {
if (write(1, obuf, nobuf) != nobuf)
panic("ttflush write failed");
nobuf = 0;
}
}
/*
* Read character from terminal.
* All 8 bits are returned, so that you can use
* a multi-national terminal.
*/
int ttgetc(void) {
char buf[1];
while (read(0, &buf[0], 1) != 1);
return (buf[0] & 0xFF);
}
/*
* typeahead returns TRUE if there are characters available to be read
* in.
*/
int typeahead(void) {
int x;
return((ioctl(0, FIONREAD, (char *) &x) < 0) ? 0 : x);
}
/*
* panic - just exit, as quickly as we can.
* From OpenBSD's mg.
*/
void panic(char *s)
{
ttclose();
(void) fputs("panic: ", stderr);
(void) fputs(s, stderr);
(void) fputc('\n', stderr);
exit(1);
}

View File

@@ -1,336 +0,0 @@
/* This file is in the public domain. */
/*
* Window management. Some of the functions are internal, and some are
* attached to keys that the user actually types
*/
#include <stdlib.h> /* free(3), malloc(3) */
#include "estruct.h"
#include "edef.h"
extern void upmode();
extern void mlwrite();
int refresh(int f, int n);
int nextwind(int f, int n);
int prevwind(int f, int n);
int onlywind(int f, int n);
int splitwind(int f, int n);
int enlargewind(int f, int n);
int shrinkwind(int f, int n);
WINDOW* wpopup();
/*
* Refresh the screen. With no argument, it does the refresh and centers
* the cursor on the screen. With an argument it does a reposition instead.
* Bound to "C-L"
*/
int refresh(int f, int n)
{
if (n >= 0)
n++; /* adjust to screen row */
if (f == FALSE)
{
sgarbf = TRUE;
n = 0; /* Center dot */
}
curwp->w_force = n;
curwp->w_flag |= WFFORCE;
return (TRUE);
}
/*
* The command make the next window (next => down the screen) the current
* window. There are no real errors, although the command does nothing if
* there is only 1 window on the screen. Bound to "C-X C-N"
*/
int nextwind(int f, int n)
{
WINDOW *wp;
if ((wp = curwp->w_wndp) == NULL)
wp = wheadp;
curwp = wp;
curbp = wp->w_bufp;
upmode();
return (TRUE);
}
/*
* This command makes the previous window (previous => up the screen) the
* current window. There arn't any errors, although the command does not do a
* lot if there is 1 window
*/
int prevwind(int f, int n)
{
WINDOW *wp1, *wp2;
wp1 = wheadp;
wp2 = curwp;
if (wp1 == wp2)
wp2 = NULL;
while (wp1->w_wndp != wp2)
wp1 = wp1->w_wndp;
curwp = wp1;
curbp = wp1->w_bufp;
upmode();
return (TRUE);
}
/*
* This command makes the current window the only window on the screen. Bound
* to "C-X 1". Try to set the framing so that "." does not have to move on the
* display. Some care has to be taken to keep the values of dot and mark in
* the buffer structures right if the distruction of a window makes a buffer
* become undisplayed
*/
int onlywind(int f, int n)
{
WINDOW *wp;
LINE *lp;
int i;
while (wheadp != curwp)
{
wp = wheadp;
wheadp = wp->w_wndp;
if (--wp->w_bufp->b_nwnd == 0)
{
wp->w_bufp->b_dotp = wp->w_dotp;
wp->w_bufp->b_doto = wp->w_doto;
wp->w_bufp->b_markp = wp->w_markp;
wp->w_bufp->b_marko = wp->w_marko;
}
free((char *) wp);
}
while (curwp->w_wndp != NULL)
{
wp = curwp->w_wndp;
curwp->w_wndp = wp->w_wndp;
if (--wp->w_bufp->b_nwnd == 0)
{
wp->w_bufp->b_dotp = wp->w_dotp;
wp->w_bufp->b_doto = wp->w_doto;
wp->w_bufp->b_markp = wp->w_markp;
wp->w_bufp->b_marko = wp->w_marko;
}
free((char *) wp);
}
lp = curwp->w_linep;
i = curwp->w_toprow;
while (i != 0 && lback (lp) != curbp->b_linep)
{
--i;
lp = lback(lp);
}
curwp->w_toprow = 0;
curwp->w_ntrows = term.t_nrow - 1;
curwp->w_linep = lp;
curwp->w_flag |= WFMODE | WFHARD;
return (TRUE);
}
/*
* Split the current window. A window smaller than 3 lines cannot be split.
* The only other error that is possible is a "malloc" failure allocating the
* structure for the new window. Bound to "C-X 2"
*/
int splitwind(int f, int n)
{
LINE *lp;
WINDOW *wp, *wp1, *wp2;
int ntru, ntrl, ntrd;
if (curwp->w_ntrows < 3)
{
mlwrite("Cannot split a %d line window", curwp->w_ntrows);
return (FALSE);
}
if ((wp = (WINDOW *) malloc(sizeof(WINDOW))) == NULL)
{
mlwrite("Cannot allocate WINDOW block");
return (FALSE);
}
++curbp->b_nwnd; /* Displayed twice */
wp->w_bufp = curbp;
wp->w_dotp = curwp->w_dotp;
wp->w_doto = curwp->w_doto;
wp->w_markp = curwp->w_markp;
wp->w_marko = curwp->w_marko;
wp->w_flag = 0;
wp->w_force = 0;
ntru = (curwp->w_ntrows - 1) / 2; /* Upper size */
ntrl = (curwp->w_ntrows - 1) - ntru; /* Lower size */
lp = curwp->w_linep;
ntrd = 0;
while (lp != curwp->w_dotp)
{
++ntrd;
lp = lforw(lp);
}
lp = curwp->w_linep;
if (ntrd <= ntru)
{ /* Old is upper window */
if (ntrd == ntru) /* Hit mode line */
lp = lforw(lp);
curwp->w_ntrows = ntru;
wp->w_wndp = curwp->w_wndp;
curwp->w_wndp = wp;
wp->w_toprow = curwp->w_toprow + ntru + 1;
wp->w_ntrows = ntrl;
}
else
{ /* Old is lower window */
wp1 = NULL;
wp2 = wheadp;
while (wp2 != curwp)
{
wp1 = wp2;
wp2 = wp2->w_wndp;
}
if (wp1 == NULL)
wheadp = wp;
else
wp1->w_wndp = wp;
wp->w_wndp = curwp;
wp->w_toprow = curwp->w_toprow;
wp->w_ntrows = ntru;
++ntru; /* Mode line */
curwp->w_toprow += ntru;
curwp->w_ntrows = ntrl;
while (ntru--)
lp = lforw (lp);
}
curwp->w_linep = lp; /* Adjust the top lines */
wp->w_linep = lp; /* if necessary */
curwp->w_flag |= WFMODE | WFHARD;
wp->w_flag |= WFMODE | WFHARD;
return (TRUE);
}
/*
* Enlarge the current window. Find the window that loses space. Make sure it
* is big enough. If so, hack the window descriptions, and ask redisplay to do
* all the hard work. You don't just set "force reframe" because dot would
* move. Bound to "C-X Z"
*/
int enlargewind(int f, int n)
{
WINDOW *adjwp;
LINE *lp;
int i;
if (n < 0)
return (shrinkwind(f, -n));
if (wheadp->w_wndp == NULL)
{
mlwrite("Only one window");
return (FALSE);
}
if ((adjwp = curwp->w_wndp) == NULL)
{
adjwp = wheadp;
while (adjwp->w_wndp != curwp)
adjwp = adjwp->w_wndp;
}
if (adjwp->w_ntrows <= n)
{
mlwrite("Impossible change");
return (FALSE);
}
if (curwp->w_wndp == adjwp)
{ /* Shrink below */
lp = adjwp->w_linep;
for (i = 0; i < n && lp != adjwp->w_bufp->b_linep; ++i)
lp = lforw(lp);
adjwp->w_linep = lp;
adjwp->w_toprow += n;
}
else
{ /* Shrink above */
lp = curwp->w_linep;
for (i = 0; i < n && lback(lp) != curbp->b_linep; ++i)
lp = lback(lp);
curwp->w_linep = lp;
curwp->w_toprow -= n;
}
curwp->w_ntrows += n;
adjwp->w_ntrows -= n;
curwp->w_flag |= WFMODE | WFHARD;
adjwp->w_flag |= WFMODE | WFHARD;
return (TRUE);
}
/*
* Shrink the current window. Find the window that gains space. Hack at the
* window descriptions. Ask the redisplay to do all the hard work
*/
int shrinkwind(int f, int n)
{
WINDOW *adjwp;
LINE *lp;
int i;
if (n < 0)
return (enlargewind(f, -n));
if (wheadp->w_wndp == NULL)
{
mlwrite("Only one window");
return (FALSE);
}
if ((adjwp = curwp->w_wndp) == NULL)
{
adjwp = wheadp;
while (adjwp->w_wndp != curwp)
adjwp = adjwp->w_wndp;
}
if (curwp->w_ntrows <= n)
{
mlwrite("Impossible change");
return (FALSE);
}
if (curwp->w_wndp == adjwp)
{ /* Grow below */
lp = adjwp->w_linep;
for (i = 0; i < n && lback(lp) != adjwp->w_bufp->b_linep; ++i)
lp = lback(lp);
adjwp->w_linep = lp;
adjwp->w_toprow -= n;
}
else
{ /* Grow above */
lp = curwp->w_linep;
for (i = 0; i < n && lp != curbp->b_linep; ++i)
lp = lforw(lp);
curwp->w_linep = lp;
curwp->w_toprow += n;
}
curwp->w_ntrows -= n;
adjwp->w_ntrows += n;
curwp->w_flag |= WFMODE | WFHARD;
adjwp->w_flag |= WFMODE | WFHARD;
return (TRUE);
}
/*
* Pick a window for a pop-up. Split the screen if there is only one window.
* Pick the uppermost window that isn't the current window. An LRU algorithm
* might be better. Return a pointer, or NULL on error
*/
WINDOW* wpopup()
{
WINDOW *wp;
if (wheadp->w_wndp == NULL /* Only 1 window */
&& splitwind(FALSE, 0) == FALSE) /* and it won't split */
return (NULL);
wp = wheadp; /* Find window to use */
while (wp != NULL && wp == curwp)
wp = wp->w_wndp;
return (wp);
}

View File

@@ -1,90 +0,0 @@
/* This file is in the public domain. */
/*
* The routines in this file implement commands that work word at a time.
* There are all sorts of word mode commands. If I do any sentence and/or
* paragraph mode commands, they are likely to be put in this file
*/
#include "estruct.h"
#include "edef.h"
extern int backchar(int f, int n);
extern int forwchar(int f, int n);
int backword(int f, int n);
int forwword(int f, int n);
int inword(void);
/*
* Move the cursor backward by "n" words. All of the details of motion are
* performed by the "backchar" and "forwchar" routines. Error if you try to
* move beyond the buffers
*/
int backword(int f, int n)
{
if (n < 0)
return (forwword(f, -n));
if (backchar(FALSE, 1) == FALSE)
return (FALSE);
while (n--)
{
while (inword() == FALSE)
{
if (backchar(FALSE, 1) == FALSE)
return (FALSE);
}
while (inword() != FALSE)
{
if (backchar(FALSE, 1) == FALSE)
return (FALSE);
}
}
return (forwchar(FALSE, 1));
}
/*
* Move the cursor forward by the specified number of words. All of the motion
* is done by "forwchar". Error if you try and move beyond the buffer's end
*/
int forwword(int f, int n)
{
if (n < 0)
return (backword(f, -n));
while (n--)
{
while (inword() != FALSE)
{
if (forwchar(FALSE, 1) == FALSE)
return (FALSE);
}
while (inword() == FALSE)
{
if (forwchar(FALSE, 1) == FALSE)
return (FALSE);
}
}
return (TRUE);
}
/*
* Return TRUE if the character at dot is a character that is considered to be
* part of a word. The word character list is hard coded. Should be setable
*/
int inword(void)
{
int c;
if (curwp->w_doto == llength(curwp->w_dotp))
return (FALSE);
c = lgetc(curwp->w_dotp, curwp->w_doto);
if (c >= 'a' && c <= 'z')
return (TRUE);
if (c >= 'A' && c <= 'Z')
return (TRUE);
if (c >= '0' && c <= '9')
return (TRUE);
if (c == '$' || c == '_') /* For identifiers */
return (TRUE);
return (FALSE);
}

View File

@@ -32,7 +32,7 @@ depend: ${SRCS}
install: all
install -m 755 $(BIN) ${DESTDIR}/sbin
cp $(MAN) ${DESTDIR}/share/man/cat8
install -m 755 $(MAN) ${DESTDIR}/share/man/cat8
lint: ${SRCS}
lint -hax ${SRCS}

View File

@@ -1 +0,0 @@
lv

View File

@@ -1,56 +0,0 @@
#
# Public Domain. 1995/03/13 - Steven Schultz
#
TOPSRC = $(shell cd ../../..; pwd)
include $(TOPSRC)/target.mk
#CFLAGS += -Werror
LIBS += -ltermcap
OBJS = blockio.o display.o editcor.o exec.o find.o \
unixcall.o globals.o insert.o main.o misc.o \
modify.o move.o ucsd.o undo.o wildargs.o \
version.o
MAN = lv.0
all: lv ${MAN}
lv: ${OBJS}
${CC} ${LDFLAGS} -o lv.elf ${OBJS} ${LIBS}
${OBJDUMP} -S lv.elf > lv.dis
${SIZE} lv.elf
${ELF2AOUT} lv.elf $@ && rm lv.elf
version.o: version.c VERSION
$(CC) $(CFLAGS) -c -DVERSION=\"`cat VERSION`\" version.c
.SUFFIXES: .0 .1
.1.0:
${MANROFF} $*.1 > $@
clean:
rm -f *.o *.elf ${MAN} lv *.elf *.dis tags *~
install: all
install lv ${DESTDIR}/bin/
cp lv.0 ${DESTDIR}/share/man/cat1/
# Dependencies
blockio.o : levee.h extern.h blockio.c config.h
display.o : levee.h extern.h termcap.i display.c config.h
editcor.o : levee.h extern.h editcor.c config.h
exec.o : levee.h extern.h exec.c config.h
find.o : levee.h extern.h grep.h find.c config.h
globals.o : levee.h globals.c config.h
insert.o : levee.h extern.h insert.c config.h
main.o : levee.h extern.h main.c config.h
misc.o : levee.h extern.h misc.c config.h
modify.o : levee.h extern.h grep.h modify.c config.h
move.o : levee.h extern.h move.c config.h
rmxcall.o : levee.h rmxcall.c config.h
ucsd.o : levee.h extern.h ucsd.c config.h
undo.o : levee.h extern.h undo.c config.h
unixcall.o : levee.h extern.h unixcall.c config.h
wildargs.o : levee.h extern.h wildargs.c config.h

View File

@@ -1,56 +0,0 @@
# makefile for Levee
exedir=/usr/local/bin
mandir=/usr/local/man
CC=cc
CFLAGS=-g
LDFLAGS=-g
OBJS = blockio.o display.o editcor.o exec.o find.o \
unixcall.o globals.o insert.o main.o misc.o \
modify.o move.o ucsd.o undo.o wildargs.o \
version.o
lev: $(OBJS)
$(CC) $(LDFLAGS) -o lev $(OBJS) -lcurses
version.o: version.c VERSION
$(CC) $(CFLAGS) -c -DVERSION=\"`cat VERSION`\" version.c
clean:
rm -f *.o lev
distclean spotless: clean
rm -f Makefile config.cmd config.sub config.h config.mak config.log config.md
install: install.bin install.man
install.bin: lev
/home/sergev/Daily/workdir-2015-01-06/levee-3.5a/config.md $(PREFIX)$(exedir)
/usr/bin/install -s -m 755 lev $(PREFIX)$(exedir)/levee
/bin/ln -s -f levee $(PREFIX)$(exedir)/lv
install.man:
/home/sergev/Daily/workdir-2015-01-06/levee-3.5a/config.md $(PREFIX)$(mandir)/man1
/usr/bin/install -m 444 lv.1 $(PREFIX)$(mandir)/man1/levee.1
echo ".so man1/levee.1" > $(PREFIX)$(mandir)/man1/lv.1
# Dependencies
blockio.o : levee.h extern.h blockio.c config.h
display.o : levee.h extern.h termcap.i display.c config.h
editcor.o : levee.h extern.h editcor.c config.h
exec.o : levee.h extern.h exec.c config.h
find.o : levee.h extern.h grep.h find.c config.h
globals.o : levee.h globals.c config.h
insert.o : levee.h extern.h insert.c config.h
main.o : levee.h extern.h main.c config.h
misc.o : levee.h extern.h misc.c config.h
modify.o : levee.h extern.h grep.h modify.c config.h
move.o : levee.h extern.h move.c config.h
rmxcall.o : levee.h rmxcall.c config.h
ucsd.o : levee.h extern.h ucsd.c config.h
undo.o : levee.h extern.h undo.c config.h
unixcall.o : levee.h extern.h unixcall.c config.h
wildargs.o : levee.h extern.h wildargs.c config.h

View File

@@ -1,56 +0,0 @@
# makefile for Levee
exedir=@exedir@
mandir=@mandir@
CC=@CC@
CFLAGS=@CFLAGS@
LDFLAGS=@LDFLAGS@
OBJS = blockio.o display.o editcor.o exec.o find.o \
unixcall.o globals.o insert.o main.o misc.o \
modify.o move.o ucsd.o undo.o wildargs.o \
version.o
lev: $(OBJS)
$(CC) $(LDFLAGS) -o lev $(OBJS) @LIBS@
version.o: version.c VERSION
$(CC) $(CFLAGS) -c -DVERSION=\"`cat VERSION`\" version.c
clean:
rm -f *.o lev
distclean spotless: clean
rm -f @GENERATED_FILES@ @CONFIGURE_FILES@
install: install.bin install.man
install.bin: lev
@INSTALL_DIR@ $(PREFIX)$(exedir)
@INSTALL_PROGRAM@ lev $(PREFIX)$(exedir)/levee
@NOMK@@LN_S@ -f levee $(PREFIX)$(exedir)/lv
install.man:
@INSTALL_DIR@ $(PREFIX)$(mandir)/man1
@INSTALL_DATA@ lv.1 $(PREFIX)$(mandir)/man1/levee.1
@NOMK@echo ".so man1/levee.1" > $(PREFIX)$(mandir)/man1/lv.1
# Dependencies
blockio.o : levee.h extern.h blockio.c config.h
display.o : levee.h extern.h termcap.i display.c config.h
editcor.o : levee.h extern.h editcor.c config.h
exec.o : levee.h extern.h exec.c config.h
find.o : levee.h extern.h grep.h find.c config.h
globals.o : levee.h globals.c config.h
insert.o : levee.h extern.h insert.c config.h
main.o : levee.h extern.h main.c config.h
misc.o : levee.h extern.h misc.c config.h
modify.o : levee.h extern.h grep.h modify.c config.h
move.o : levee.h extern.h move.c config.h
rmxcall.o : levee.h rmxcall.c config.h
ucsd.o : levee.h extern.h ucsd.c config.h
undo.o : levee.h extern.h undo.c config.h
unixcall.o : levee.h extern.h unixcall.c config.h
wildargs.o : levee.h extern.h wildargs.c config.h

View File

@@ -1 +0,0 @@
3.5a

View File

@@ -1,48 +0,0 @@
/*
* LEVEE, or Captain Video; A vi clone
*
* Copyright (c) 1982-2007 David L Parsons
* All rights reserved.
*
* Redistribution and use in source and binary forms, without or
* without modification, are permitted provided that the above
* copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and
* other materials related to such distribution and use acknowledge
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
* My name may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
#include "levee.h"
#if OS_ATARI
#include <atari\osbind.h>
char sound[] = {
0xA8,0x01,0xA9,0x01,0xAA,0x01,0x00,
0xF8,0x10,0x10,0x10,0x00,0x20,0x03
};
#define SADDR 0xFF8800L
typedef char srdef[4];
srdef *SOUND = (srdef *)SADDR;
main()
{
register i;
long ssp;
ssp = Super(0L);
for (i=0; i<sizeof(sound); i++) {
(*SOUND)[0] = i;
(*SOUND)[2] = sound[i];
}
Super(ssp);
}
#endif /*OS_ATARI*/

View File

@@ -1,50 +0,0 @@
/*
* LEVEE, or Captain Video; A vi clone
*
* Copyright (c) 1982-2007 David L Parsons
* All rights reserved.
*
* Redistribution and use in source and binary forms, without or
* without modification, are permitted provided that the above
* copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and
* other materials related to such distribution and use acknowledge
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
* My name may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
#include "levee.h"
#include "extern.h"
/* read in a file -- return TRUE -- read file
FALSE-- file too big
*/
int PROC
addfile(f, start, endd, size)
FILE *f;
int start;
int endd, *size;
{
register int chunk;
chunk = read(fileno(f), core+start, (endd-start)-1);
*size = chunk;
return chunk < (endd-start)-1;
}
/* write out a file -- return TRUE if ok. */
bool PROC
putfile(f, start, endd)
register FILE *f;
register int start, endd;
{
return write(fileno(f), core+start, endd-start) == (endd-start);
}

View File

@@ -1,26 +0,0 @@
/*
* configuration for levee, generated Tue Jan 6 12:41:26 PST 2015
* by sergev@ubuntu-sergev
*/
#ifndef __AC_LEVEE_D
#define __AC_LEVEE_D 1
// Size of editor data buffer.
#define SIZE 16000
#define OS_UNIX 1
#define HAVE_STRING_H 1
#define HAVE_MEMSET 1
#define HAVE_STRCHR 1
#define HAVE_BASENAME 1
#define HAVE_SIGNAL_H 1
#define HAVE_SIGNAL 1
#define HAVE_TGETENT 1
#define USE_TERMCAP 1
#define HAVE_MVCUR 1
#define mvcur __mvcur
#define HAVE_TCGETATTR 1
#define PATH_FIND "/bin/find"
#define PATH_SED "/bin/sed"
#endif/* __AC_LEVEE_D */

File diff suppressed because it is too large Load Diff

View File

@@ -1,112 +0,0 @@
#! /bin/sh
# local options: ac_help is the help message that describes them
# and LOCAL_AC_OPTIONS is the script that interprets them. LOCAL_AC_OPTIONS
# is a script that's processed with eval, so you need to be very careful to
# make certain that what you quote is what you want to quote.
ac_help="
--use-termcap Link with termcap instead of curses, if possible
--partial-install Don\'t install the lv, lv(1) name links
--size=NNN Use a NNN-byte edit buffer
--dos compile for ms-dos or microsoft windows
--tos compile for the Atari ST
--rmx compile for RMX
--flexos compile for FlexOS"
LOCAL_AC_OPTIONS='
case Z$1 in
Z--partial-install)
missing_lv=1;;
Z--dos) ac_os=DOS;;
Z--tos) ac_os=ATARI=1;;
Z--flexos) ac_os=FLEXOS=1;;
Z--rmx) ac_os=RMX;;
Z--size=*) SIZE=$(echo Z$1 | sed -e 's/^Z--size=//') ;;
*) ac_error=1;;
esac;shift'
# load in the configuration file
#
TARGET=levee
. ./configure.inc
AC_INIT $TARGET
# validate --size=
#
case X"${SIZE}" in
X[0-9][0-9]*) ;;
X[0-9][0-9]*[Ll]);;
X) ;;
X*) AC_FAIL "--size=$SIZE is not a valid number" ;;
esac
AC_PROG_CC
if [ "$OS_DOS" ]; then
AC_DEFINE SIZE ${SIZE:-32000}
AC_DEFINE PROC _fastcall
AC_DEFINE TTY_ANSI 1
AC_CHECK_FUNCS basename
elif [ "$OS_ATARI" ]; then
AC_DEFINE SIZE ${SIZE:-32000}
AC_DEFINE TTY_VT52 1
AC_DEFINE HAVE_BLKFILL 1
AC_CHECK_FUNCS basename
elif [ "$OS_FLEXOS" ]; then
AC_DEFINE SIZE ${SIZE:-256000}
AC_CHECK_FUNCS basename
else
AC_DEFINE SIZE ${SIZE:-256000}
AC_DEFINE OS_UNIX 1
if AC_CHECK_HEADERS string.h; then
# Assume a mainly ANSI-compliant world, where the
# existance of string.h implies a memset() and strchr()
AC_DEFINE HAVE_MEMSET 1
AC_DEFINE HAVE_STRCHR 1
else
AC_CHECK_FUNCS memset
AC_CHECK_FUNCS strchr
fi
# for basename
if AC_CHECK_FUNCS basename; then
AC_CHECK_HEADERS libgen.h
fi
if AC_CHECK_HEADERS signal.h; then
# Assume a mainly sane world where the existance
# of signal.h means that signal() exists
AC_DEFINE HAVE_SIGNAL 1
fi
if [ "$USE_TERMCAP" ]; then
LIBORDER="-ltermcap -lcurses -lncurses"
else
LIBORDER="-lcurses -lncurses -ltermcap"
fi
if AC_LIBRARY tgetent $LIBORDER; then
AC_CHECK_HEADERS termcap.h || AC_FAIL "levee needs <termcap.h>"
AC_DEFINE USE_TERMCAP 1
# our -libtermcap might be (n)curses in disguise. If so,
# it might have a colliding mvcur() that we need to define
# ourselves out from.
AC_QUIET AC_CHECK_FUNCS mvcur && AC_DEFINE mvcur __mvcur
else
# have to use a local termcap
AC_DEFINE TERMCAP_EMULATION 1
AC_DEFINE USE_TERMCAP 1
fi
AC_CHECK_HEADERS termios.h && AC_CHECK_FUNCS tcgetattr
fi
if AC_PROG_LN_S && test -z "$missing_lv"; then
AC_SUB NOMK ''
else
AC_SUB NOMK '@#'
fi
AC_OUTPUT Makefile

View File

@@ -1,349 +0,0 @@
/*
* LEVEE, or Captain Video; A vi clone
*
* Copyright (c) 1982-2007 David L Parsons
* All rights reserved.
*
* Redistribution and use in source and binary forms, without or
* without modification, are permitted provided that the above
* copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and
* other materials related to such distribution and use acknowledge
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
* My name may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
#include "levee.h"
#include "extern.h"
/* do a gotoXY -- allowing -1 for same row/column */
#if USE_TERMCAP | OS_ATARI
#define MAXCOLS 160
#if USE_TERMCAP
#include "termcap.i"
#endif
#else /*!(USE_TERMCAP | OS_ATARI)*/
#define MAXCOLS COLS
#endif
VOID PROC
mvcur(y,x)
int y,x;
{
#if TERMCAP_EMULATION || TTY_ANSI
static char gt[30];
#endif
if (y == -1)
y = curpos.y;
else
curpos.y = y;
if (y >= LINES)
y = LINES-1;
if (x == -1)
x = curpos.x;
else
curpos.x = x;
if (x >= COLS)
x = COLS-1;
#if TERMCAP_EMULATION
tgoto(gt,y,x);
strput(gt);
#elif USE_TERMCAP
strput( tgoto(CM, x, y) );
#elif TTY_ZTERM
zgoto(x,y);
#elif TTY_ANSI
{ register char *p = gt; /* make a ansi gotoXY string */
*p++ = 033;
*p++ = '[';
numtoa(p,1+y); p += strlen(p);
*p++ = ';';
numtoa(p,1+x); p += strlen(p);
*p++ = 'H';
WRITE_TEXT(1, gt, (p-gt));
}
#elif TTY_VT52
CM[2] = y+32;
CM[3] = x+32;
strput(CM);
#endif
}
VOID PROC
numtoa(str,num)
char *str;
int num;
{
int i = 10; /* I sure hope that str is 10 bytes long... */
bool neg = (num < 0);
if (neg)
num = -num;
str[--i] = 0;
do{
str[--i] = (num%10)+'0';
num /= 10;
}while (num > 0);
if (neg)
str[--i] = '-';
moveleft(&str[i], str, 10-i);
}
VOID PROC
printi(num)
int num;
{
char nb[10];
register int size;
numtoa(nb,num);
size = min(strlen(nb),COLS-curpos.x);
if (size > 0) {
nb[size] = 0;
zwrite(nb, size);
curpos.x += size;
}
}
VOID PROC
println()
{
zwrite("\r\n", 2);
curpos.x = 0;
curpos.y = min(curpos.y+1, LINES-1);
}
/* print a character out in a readable form --
* ^<x> for control-<x>
* spaces for <tab>
* normal for everything else
*/
static char hexdig[] = "0123456789ABCDEF";
int PROC
format(out,c)
/* format: put a displayable version of c into out */
register char *out;
register unsigned c;
{
if (c >= ' ' && c < '') {
out[0] = c;
return 1;
}
else if (c == '\t' && !list) {
register int i;
int size;
for (i = size = tabsize - (curpos.x % tabsize);i > 0;)
out[--i] = ' ';
return size;
}
else if (c < 128) {
out[0] = '^';
out[1] = c^64;
return 2;
}
else {
#if OS_DOS
out[0] = c;
return 1;
#else
out[0] = '\\';
out[1] = hexdig[(c>>4)&017];
out[2] = hexdig[c&017];
return 3;
#endif
}
}
VOID PROC
printch(c)
char c;
{
register int size;
char buf[MAXCOLS];
size = min(format(buf,c),COLS-curpos.x);
if (size > 0) {
buf[size] = 0;
zwrite(buf, size);
curpos.x += size;
}
}
VOID PROC
prints(s)
char *s;
{
int size,oxp = curpos.x;
char buf[MAXCOLS+1];
register int bi = 0;
while (*s && curpos.x < COLS) {
size = format(&buf[bi],*s++);
bi += size;
curpos.x += size;
}
size = min(bi,COLS-oxp);
if (size > 0) {
buf[size] = 0;
zwrite(buf, size);
}
}
VOID PROC
writeline(y,x,start)
int y,x,start;
{
int endd,oxp;
register int size;
char buf[MAXCOLS+1];
register int bi = 0;
endd = fseekeol(start);
if (start==0 || core[start-1] == EOL)
mvcur(y, 0);
else
mvcur(y, x);
oxp = curpos.x;
while (start < endd && curpos.x < COLS) {
size = format(&buf[bi],core[start++]);
bi += size;
curpos.x += size;
}
if (list) {
buf[bi++] = '$';
curpos.x++;
}
size = min(bi,COLS-oxp);
if (size > 0) {
buf[size] = 0;
zwrite(buf, size);
}
if (curpos.x < COLS)
strput(CE);
}
/* redraw && refresh the screen */
VOID PROC
refresh(y,x,start,endd,rest)
int y,x,start,endd;
bool rest;
{
int sp;
#if OS_ATARI
/* turn the cursor off */
asm(" clr.l -(sp) ");
asm(" move.w #21,-(sp) ");
asm(" trap #14 ");
asm(" addq.l #6,sp ");
#endif
sp = start;
while (sp <= endd) {
writeline(y, x, sp);
sp = 1+fseekeol(sp);
y++;
x = 0;
}
if (rest && sp >= bufmax)
while (y<LINES-1) { /* fill screen with ~ */
mvcur(y, 0);
printch('~'); strput(CE);
y++;
}
#if OS_ATARI
/* turn the cursor back on */
asm(" clr.w -(sp) ");
asm(" move.w #1,-(sp) ");
asm(" move.w #21,-(sp) ");
asm(" trap #14 ");
asm(" addq.l #6,sp ");
#endif
}
/* redraw everything */
VOID PROC
redisplay(flag)
bool flag;
{
if (flag)
clrprompt();
refresh(0, 0, ptop, pend, TRUE);
}
VOID PROC
scrollback(curr)
int curr;
{
mvcur(0,0); /* move to the top line */
do {
ptop = bseekeol(ptop-1);
strput(UpS);
writeline(0, 0, ptop);
} while (ptop > curr);
setend();
}
VOID PROC
scrollforward(curr)
int curr;
{
do {
writeline(LINES-1, 0, pend+1);
zwrite("\n", 1);
pend = fseekeol(pend+1);
ptop = fseekeol(ptop)+1;
} while (pend < curr);
}
/* find if the number of lines between top && bottom is less than dofscroll */
bool PROC
ok_to_scroll(top,bottom)
int top,bottom;
{
int nl, i;
nl = dofscroll;
i = top;
do
i += 1+scan(bufmax-i,'=',EOL, &core[i]);
while (--nl > 0 && i < bottom);
return(nl>0);
}
VOID PROC
clrprompt()
{
mvcur(LINES-1,0);
strput(CE);
}
VOID PROC
prompt(toot,s)
bool toot;
char *s;
{
if (toot)
error();
clrprompt();
prints(s);
}

View File

@@ -1,50 +0,0 @@
name dos
page 55,80
title 'DOS.ASM -- assembly routines for the teeny-shell under DOS'
_TEXT segment byte public 'CODE'
assume cs:_TEXT
public _fail_criterr
;
; If we get a critical error, just fail it - dos 3.0 and up only, please!
;
_fail_criterr proc far
mov al, 3
iret
_fail_criterr endp
public _ignore_ctrlc
;
; If the user presses ^C, don't do any special handling of it.
;
_ignore_ctrlc proc far
iret
_ignore_ctrlc endp
_pexec endp
public _intr_on_ctrlc
;
; If the user presses ^C, terminate the current process.
;
_intr_on_ctrlc proc far
mov ah, 4ch
mov al, 0ffh
int 21h
_intr_on_ctrlc endp
public _crawcin
;
; get a character from standard input without any sort of magical
; processing.
;
_crawcin proc far
mov ah, 07h
int 21h
ret
_crawcin endp
_TEXT ends
end

View File

@@ -1,200 +0,0 @@
/*
* LEVEE, or Captain Video; A vi clone
*
* Copyright (c) 1982-2007 David L Parsons
* All rights reserved.
*
* Redistribution and use in source and binary forms, without or
* without modification, are permitted provided that the above
* copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and
* other materials related to such distribution and use acknowledge
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
* My name may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/*
* dos interface for levee (Microsoft C)
*/
#include "levee.h"
#if OS_DOS
#include <glob.h>
#include <dos.h>
int PROC
min(a,b)
int a,b;
{
return (a>b) ? b : a;
}
int PROC
max(a,b)
int a,b;
{
return (a<b) ? b : a;
}
PROC
strput(s)
char *s;
{
write(1, s, strlen(s));
}
/* get a key, mapping certain control sequences
*/
PROC
getKey()
{
register c;
extern char _far crawcin();
c = crawcin();
if (c == 0 || c == 0xe0)
switch (c=crawcin()) {
case 'K': return LTARROW;
case 'M': return RTARROW;
case 'H': return UPARROW;
case 'P': return DNARROW;
case 'I': return 'U'-'@'; /* page-up */
case 'Q': return 'D'-'@'; /* page-down */
default : return 0;
}
return c;
}
/* don't allow interruptions to happen
*/
PROC
nointr()
{
extern void _cdecl _interrupt _far ignore_ctrlc();
_dos_setvect(0x23, ignore_ctrlc);
} /* nointr */
/* have ^C do what it usually does
*/
PROC
allowintr()
{
extern void _cdecl _interrupt _far intr_on_ctrlc();
_dos_setvect(0x23, intr_on_ctrlc);
} /* allowintr */
/*
* basename() returns the filename part of a pathname
*/
char *
basename(s)
register char *s;
{
register char *p = s;
for (p = s+strlen(s); p > s; --p)
if (p[-1] == '/' || p[-1] == '\\' || p[-1] == ':')
return p;
return s;
} /* basename */
/*
* glob() expands a wildcard, via calls to _dos_findfirst/_next()
* and pathname retention.
*/
char *
glob(path, dta)
char *path;
struct glob_t *dta;
{
static char path_bfr[256]; /* full pathname to return */
static char *file_part; /* points at file - for filling */
static char isdotpattern; /* looking for files starting with . */
static char isdotordotdot; /* special case . or .. */
static struct glob_t *dta_bfr; /* pointer to desired dta */
static struct find_t dird; /* DOS dta */
register st; /* status from _dos_findxxx */
if (path) {
/* when we start searching, save the path part of the filename in
* a safe place.
*/
strcpy(path_bfr, path);
file_part = basename(path_bfr);
/* set up initial parameters for DosFindFirst()
*/
dta_bfr = dta;
if (isdotpattern = (*file_part == '.'))
/* _dos_findfirst() magically expands . and .. into their
* directory names. Admittedly, there are cases where
* this can be useful, but this is not one of them. So,
* if we find that we're matching . and .., we just
* special-case ourselves into oblivion to get around
* this particular bit of DOS silliness.
*/
isdotordotdot = (file_part[1] == 0 || file_part[1] == '.');
else
isdotordotdot = 0;
st = _dos_findfirst(path, 0x16, &dird);
}
else
st = _dos_findnext(&dird);
while (st == 0) {
/* Unless the pattern has a leading ., don't include any file
* that starts with .
*/
if (dird.name[0] == '.' && !isdotpattern)
st = _dos_findnext(&dird);
else {
/* found a file - affix the path leading to it, then return
* a pointer to the (static) buffer holding the path+the name.
*/
strlwr(dird.name); /* DOS & OS/2 are case-insensitive */
if (dta_bfr) {
dta_bfr->wr_time = dird.wr_time;
dta_bfr->wr_date = dird.wr_date;
if (isdotordotdot)
strcpy(dta_bfr->name, file_part);
else {
strncpy(dta_bfr->name, dird.name, sizeof(dta_bfr->name)-1);
dta_bfr->name[sizeof(dta_bfr->name)-1] = 0;
}
dta_bfr->size = dird.size;
dta_bfr->attrib = dird.attrib;
}
if (!isdotordotdot)
strcpy(file_part, dird.name);
return path_bfr;
}
}
/* nothing matched
*/
if (path && isdotordotdot) {
/* must be at root, so statting dot will most likely fail. Fake a
* dta.
*/
if (dta_bfr) {
memset(dta_bfr, 0, sizeof *dta_bfr);
dta_bfr->attrib = 0x10;
dta_bfr->name[0] = '.';
}
return path_bfr;
}
return (char*)0;
} /* glob */
#endif /*OS_DOS*/

View File

@@ -1,644 +0,0 @@
/*
* LEVEE, or Captain Video; A vi clone
*
* Copyright (c) 1982-2008 David L Parsons
* All rights reserved.
*
* Redistribution and use in source and binary forms, without or
* without modification, are permitted provided that the above
* copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and
* other materials related to such distribution and use acknowledge
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
* My name may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
#include "levee.h"
#include "extern.h"
#include <stdlib.h>
/* do some undoable modification */
/* These variables make docommand nonrecursive */
bool ok;
int newend, /* end position after change */
disp, /* start redisplay here */
newc, /* new cursor position for wierd cmds */
endY; /* final yp for endp */
/* move a line of text right || left */
VOID PROC
adjuster(sleft, endd, sw)
bool sleft;
int endd, sw;
{
bool noerror;
int np, ts,
ip,
ss, adjp,
DLEnum;
if (sw == -1)
sw = shiftwidth;
if (sleft)
sw = -sw;
curr = bseekeol(curr);
ip = curr;
noerror = TRUE;
do {
DLEnum = sw + findDLE(ip, &np, bufmax,0);
if (DLEnum >= 0 && DLEnum <= COLS && core[np] != EOL && np < bufmax) {
ts = DLEnum / tabsize;
ss = DLEnum % tabsize;
adjp = ts+ss+ip;
if (np-adjp < 0) { /* expand the buf */
moveright(&core[np], &core[adjp], bufmax-np);
insert_to_undo(&undo, adjp, adjp - np);
}
else
delete_to_undo(&undo, adjp, np - adjp);
endd += (adjp-np);
noerror = move_to_undo(&undo, ip, ts+ss);
fillchar(&core[ip], ts, TAB);
fillchar(&core[ip+ts], ss, 32);
}
else if (np > ip) { /* remove the indent code */
noerror = delete_to_undo(&undo, ip, np-ip);
endd += (ip - np);
}
ip = 1 + fseekeol(ip);
} while (noerror && ip < endd);
if (!noerror)
error();
newc = skipws(curr);
disp = curr;
newend = endd;
endY = setY(min(newend, pend));
}
/* join <count> lines together */
VOID PROC
join(count)
int count;
{
bool ok;
int lp, first;
if (lend < bufmax) { /* are we in the buffer? */
disp = lend; /* start redraw here */
newc = lend;
do { /* join until.. */
first = lend;
lp = skipws(1+first);
ok = delete_to_undo(&undo, 1+first, lp-(1+first));
if (ok) {
ok = move_to_undo(&undo, first, 1);
core[first] = ' '; /* spaces between lines */
}
count--;
lend = fseekeol(first);
} while (ok && count > 0);
endY = MAGICNUMBER;
newend = lend;
if (!ok)
error();
}
else
error();
}
VOID PROC
squiggle(endp, c, dorepl)
int endp;
char c;
bool dorepl;
{
int i;
if (endp >= curr) {
ok = move_to_undo(&undo,curr,endp-curr+1);
if (ok) {
for (i = curr;i<=endp;i++) {
if (!dorepl) { /* squiggle it to uc - lc */
if (core[i] >='A' && core[i] <='Z')
core[i] += 32;
else if (core[i]>='a' && core[i]<='z')
core[i] -= 32;
}
else
core[i] = c;
}
newend = min(endp+1,lend);
}
}
}
VOID PROC
bigreplace()
{
int len, tsiz;
tsiz = lend-curr;
if (move_to_undo(&undo, curr, tsiz))
if (SIZE - bufmax > tsiz) { /* enough room for temp copy? */
moveleft(&core[curr], &core[bufmax],lend-curr);
if (line(core, curr, lend, &len) != ESC)
error();
newend = curr+len;
moveright(&core[bufmax+len], &core[newend], lend-newend);
}
}
bool PROC
put(before)
bool before;
{
endY = setY(curr);
if (!before)
if (yank.lines)
curr = min(lend+1,bufmax);
else
curr = min(curr+1, lend);
else if (yank.lines)
curr = lstart;
newc = disp = curr;
return(putback(curr, &newend));
}
bool PROC
execute(start, end)
{
int tf;
FILE *f;
char scratch[20];
bool ret = FALSE;
int size;
strcpy(scratch, "/tmp/lv.XXXXXX");
clrprompt();
printch('!');
if ( !getlin(instring) )
return FALSE;
if ( (tf = mkstemp(scratch)) < 0 ) {
prints("[tempfile error]");
return FALSE;
}
strcat(instring, " 2>&1 <");
strcat(instring, scratch);
if ( (size = write(tf, core+start, end-start)) == (end-start) ) {
if ( (f=popen(instring, "r")) ) {
if ( deletion(start, end) && (insertfile(f, 1, start, &size) > 0) )
ret = TRUE;
pclose(f);
}
else
error();
}
close(tf);
unlink(scratch);
return ret;
}
VOID PROC
gcount()
{
do {
count = (count*10) + (ch-'0');
readchar(); /* get a char to replace the one we dumped */
} while ( count >= 0 && isdigit(ch) );
}
VOID PROC
docommand(cmd)
cmdtype cmd;
{
cmdtype movecmd; /* movement command for y, d, c */
char cmdch;
int oldc; /* old count */
int endp; /* end position before change */
extern bool s_wrapped;
resetX(); /* un-derange the cursor */
oldc = newc = -1;
endY = yp;
newend = disp = curr;
ok = TRUE; /* so far everything is working */
cmdch = ch;
if (cmd != UNDO_C && cmd != YANK_C) {
if (macro<0)
zerostack(&undo);
if (redoing != TRUE) {
rcp = rcb; /* point at start of redo buffer */
if (count > 1) { /* put in a count? */
numtoa(rcb,count);
rcp += strlen(rcb);
}
*rcp++ = cmdch; /* the command char goes in... */
xerox = TRUE; /* hoist the magical flags */
}
}
if (cmd <= YANK_C) {
readchar();
if ( isdigit(ch) && ch != '0' ) {
oldc = count;
count = 0;
gcount(); /* get a new count */
if (cmd == ADJUST_C) /* special for >>,<< wierdness */
swap(&count, &oldc); /* reverse sw & count */
else
count = count*max(oldc,1); /* combine them */
}
if (ch == cmdch) { /* diddle lines */
yank.lines = TRUE;
endp = nextline(TRUE, curr, count);
curr = bseekeol(curr);
disp = curr;
}
else { /* diddle 'things' */
yank.lines = FALSE;
movecmd = movemap[(unsigned int)ch];
if ( (ok = (findCP(curr,&endp,movecmd) == LEGALMOVE)) ) {
if (curr > endp) {
swap(&curr,&endp);
ok = (cmd != CHANGE_C);
}
if (adjcurr[(unsigned int)movecmd])
curr++;
if (adjendp[(unsigned int)movecmd])
endp++;
}
if (!ok) {
if (ch != ESC)
error();
goto killredo;
}
}
endY = setY(endp);
newend = curr;
disp = curr;
switch (cmd) {
case EXEC_C:
ok = execute(curr, endp);
break;
case DELETE_C:
ok = deletion(curr, endp);
break;
case ADJUST_C:
adjuster((cmdch == '<'), endp-1, oldc);
break;
case CHANGE_C:
if (endp <= pend+1) {
mvcur(setY(endp-1), setX(endp-1));
printch('$');
mvcur(yp, xp);
}
if (deletion(curr, endp))
ok = ((newend = insertion(1, 0, &disp, &endY, TRUE)) >= 0);
else
ok = FALSE;
break;
case YANK_C:
if (!doyank(curr, endp))
error();
return; /* xerox will not be true, nor will redoing */
}
}
else {
endp = curr;
endY = yp;
switch (cmd) {
case I_AT_NONWHITE:
case A_AT_END:
case APPEND_C:
case INSERT_C: /* variations on insert */
if (cmd != INSERT_C) {
if (cmd == APPEND_C)
curr = min(curr+1, lend);
else if (cmd == A_AT_END)
curr = lend;
else /* if (cmd == I_AT_NONWHITE) */
curr = skipws(lstart);
xp = setX(curr);
mvcur(yp,xp);
}
newend = insertion(count, 0, &disp, &endY, TRUE);
ok = (newend >= 0);
break;
case OPEN_C:
case OPENUP_C:
newend = insertion(1,setstep[ (cmd==OPENUP_C)&1 ],
&disp,&endY,TRUE)-1;
ok = (newend >= 0);
break;
case REPLACE_C:
case TWIDDLE_C:
if (cmd == REPLACE_C) {
if ((cmdch = readchar()) == ESC)
goto killredo;
}
if (findCP(curr, &endp, GO_RIGHT) == LEGALMOVE)
squiggle(endp-1, cmdch, (cmd==REPLACE_C));
break;
case PUT_BEFORE:
case PUT_AFTER:
ok = put(cmd==PUT_AFTER);
break;
case BIG_REPL_C:
bigreplace();
break;
case RESUBST_C:
ok = FALSE;
if (dst[0] != 0) {
newend = chop(curr, &lend, TRUE, &ok);
if (newend >= 0) {
endY = setY(newend+strlen(dst));
ok = TRUE;
}
}
break;
case JOIN_C:
join(count); /* join lines */
break;
case UNDO_C: /* undo last modification */
ok = fixcore(&newend) >= 0;
disp = newend;
endY = MAGICNUMBER;
break;
}
}
if (ok) {
setpos((newc<0)?newend:newc);
setend();
if (curr < ptop || curr > pend) {
yp = settop(12);
redisplay(TRUE);
}
else {
yp = setY(curr);
if (endY != setY(newend)) /* shuffled lines */
refresh(setY(disp), setX(disp), disp, pend, TRUE);
else /* refresh to end position */
refresh(setY(disp), setX(disp), disp, newend, FALSE);
}
if (curr >= bufmax && bufmax > 0) { /* adjust off end of buffer */
setpos(bufmax-1);
yp = setY(curr);
}
if (s_wrapped) {
prompt(FALSE, "search wrapped around end of buffer");
s_wrapped = 0;
}
else
clrprompt();
modified = TRUE;
}
else {
error();
killredo:
rcb[0] = 0;
}
mvcur(yp, xp);
if (xerox)
*rcp = 0; /* terminate the redo */
redoing = FALSE;
xerox = FALSE;
core[bufmax] = EOL;
}
/* Initialize && execute a macro */
VOID PROC
exmacro()
{
int mp;
mp = lookup(ch);
if (mp > 0) {
if (macro<0)
zerostack(&undo);
insertmacro(mbuffer[mp].m_text, count);
}
else
error();
}
/* redraw the screen w.r.t. the cursor */
VOID PROC
zdraw(code)
unsigned char code;
{
int nl = ERR,
np = (count>0)?to_index(count):curr;
if (movemap[code] == CR_FWD)
nl = 0;
else if (movemap[code] == CR_BACK)
nl = LINES-1;
else if (code == '.')
nl = LINES / 2;
if (nl >= 0) {
curr = np;
yp = settop(nl);
redisplay(TRUE);
mvcur(yp,xp);
}
else
error();
}
/* start up a built-in macro */
VOID PROC
macrocommand()
{
if (count > 1)
numtoa(gcb,count);
else
gcb[0] = 0;
switch (ch) { /* which macro? */
case 'x': /* x out characters */
strcat(gcb,"dl"); break;
case 'X': /* ... backwards */
strcat(gcb,"dh"); break;
case 's': /* substitute over chars */
strcat(gcb,"cl"); break;
case 'D': /* delete to end of line */
strcat(gcb,"d$"); break;
case 'C': /* change ... */
strcat(gcb,"c$"); break;
case 'Y': /* yank ... */
strcat(gcb,"y$"); break;
case '': /* scroll up one page */
strcpy(gcb,"22"); break;
case '': /* ... down one page */
strcpy(gcb,"22"); break;
case '': /* scroll up one line */
strcpy(gcb,"1"); break;
case '': /* ... down one line */
strcpy(gcb,"1"); break;
default:
error();
return;
break;
}
if (macro<0)
zerostack(&undo);
insertmacro(gcb, 1);
}
/* scroll the window up || down */
VOID PROC
scroll(down)
bool down;
{
int i;
if (count <= 0)
count = dofscroll;
strput(CURoff);
if (down) {
curr = min(bufmax-1, nextline(TRUE, curr, count));
i = min(bufmax-1, nextline(TRUE, pend, count));
if (i > pend)
scrollforward(i);
}
else {
curr = bseekeol(max(0,nextline(FALSE, curr, count)));
i = bseekeol(max(0,nextline(FALSE, ptop, count)));
if (i < ptop) {
if (canUPSCROLL)
scrollback(i);
else {
ptop = i;
setend();
redisplay(TRUE);
}
}
}
strput(CURon);
setpos(skipws(curr)); /* initialize new position - first nonwhite */
yp = setY(curr);
mvcur(yp, xp); /* go there */
}
exec_type PROC
editcore()
{
cmdtype cmd;
extern bool s_wrapped;
/* rcb[0] = 0; rcp = rcb; */
if (diddled) {
setpos(skipws(curr)); /* set cursor x position.. */
yp = settop(LINES / 2); /* Y position */
}
if (diddled || zotscreen) /* redisplay? */
redisplay(FALSE);
mvcur(yp, xp); /* and move the cursor */
for (;;) {
s_wrapped = 0;
ch = readchar(); /* get a char */
count = 0;
if (isdigit(ch) && ch != '0')
gcount(); /* ... a possible count */
switch (cmd = movemap[(unsigned int)ch]) {
case FILE_C:
wr_stat(); /* write file stats */
mvcur(yp, xp);
break;
case WINDOW_UP:
case WINDOW_DOWN:
scroll(cmd==WINDOW_UP); /* scroll the window */
break;
case REDRAW_C: /* redraw the window */
redisplay(TRUE);
mvcur(yp, xp);
break;
case MARKER_C: /* set a marker */
ch = tolower(readchar());
if (ch >= 'a' && ch <= 'z')
contexts[ch-'`'] = curr;
else if (ch != ESC)
error();
break;
case REDO_C:
if (rcb[0] != 0) {
zerostack(&undo);
insertmacro(rcb, 1);
redoing = TRUE;
}
break;
case REWINDOW:
zdraw(readchar()); /* shift the window */
break;
case DEBUG_C: /* debugging stuff -- unused */
break;
case ZZ_C: /* shortcut for :xit */
ch = readchar();
if (ch == 'Z')
insertmacro(":x\r", 1);
else if (ch != ESC)
error();
break;
case EDIT_C: /* drop into line mode */
return E_EDIT;
case COLIN_C: /* do one exec mode command */
return E_VISUAL;
case HARDMACRO:
macrocommand(); /* 'hard-wired' macros */
break;
case SOFTMACRO:
exmacro(); /* run a macro */
break;
case INSMACRO: /* macro for insert mode */
case BAD_COMMAND:
error();
break;
default:
if (cmd < DELETE_C)
movearound(cmd);
else /*if (cmd < HARDMACRO)*/
docommand(cmd);
break;
}
lastexec = 0;
}
/* never exits here */
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,237 +0,0 @@
/*
* LEVEE, or Captain Video; A vi clone
*
* Copyright (c) 1982-2007 David L Parsons
* All rights reserved.
*
* Redistribution and use in source and binary forms, without or
* without modification, are permitted provided that the above
* copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and
* other materials related to such distribution and use acknowledge
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
* My name may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
#ifndef GLOBALS_D
#define GLOBALS_D
extern
char lastchar, /* Last character read via peekc */
ch; /* Global command char */
extern
exec_type mode; /* editor init state */
extern
int lastexec; /* last exec mode command */
extern
int contexts['z'-'`'+1]; /* Labels */
/* C O N S T A N T S */
extern
bool adjcurr[PARA_BACK+1],
adjendp[PARA_BACK+1];
/* A R G U M E N T S */
extern
char startcmd[]; /* initial command after read */
extern
char **argv; /* Arguments */
extern
int argc, /* # arguments */
pc; /* Index into arguments */
/* M A C R O S T U F F */
extern
struct macrecord mbuffer[];
extern
struct tmacro mcr[]; /* A place for executing macros */
/* S E A R C H S T U F F */
extern
char dst[], /* last replacement pattern */
lastpatt[], /* last search pattern */
pattern[];
extern
int RE_start[9], /* start of substitute argument */
RE_size [9], /* size of substitute argument */
lastp; /* last character matched in search */
extern
struct undostack undo; /* To undo a command */
/* R A N D O M S T R I N G S */
extern
char instring[], /* Latest input */
filenm[], /* Filename */
altnm[], /* Alternate filename */
gcb[]; /* Command buffer for mutations of insert */
extern
char undobuf[],
undotmp[],
yankbuf[];
extern
int uread, /* reading from the undo stack */
uwrite; /* writing to the undo stack */
/* B U F F E R S */
extern
char rcb[], *rcp, /* last modification command */
core[]; /* data space */
extern
struct ybuf yank; /* last deleted/yanked text */
/* STATIC INITIALIZATIONS: */
/* ttydef stuff */
#if OS_ATARI | USE_TERMCAP
extern int LINES, COLS;
#endif
#if USE_TERMCAP
extern bool CA, canUPSCROLL;
extern char FkL,
CurRT,
CurLT,
CurDN,
CurUP;
#endif /*USE_TERMCAP*/
extern char *TERMNAME,
*HO,
*UP,
*CE,
*CL,
*OL,
*BELL,
*CM,
*UpS,
*CURoff,
*CURon;
extern
char Erasechar,
eraseline;
extern
char codeversion[], /* Editor version */
fismod[], /* File is modified message */
fisro[]; /* permission denied message */
extern
char *excmds[],
wordset[],
spaces[];
extern
struct variable vars[];
extern
int autowrite,
autocopy,
overwrite,
beautify,
autoindent,
dofscroll,
shiftwidth,
tabsize,
list,
wrapscan,
bell,
magic;
/*extern
char *suffix; */
/* For movement routines */
extern
int setstep[];
/* Where the last diddling left us */
extern
struct coord curpos;
/* initialize the buffer */
extern
int curr, /* Global cursor pos */
lstart, lend, /* Start & end of current line */
count, /* Latest count */
xp, yp, /* Cursor window position */
bufmax, /* End of file here */
ptop, pend; /* Top & bottom of CRT window */
extern
bool modified, /* File has been modified */
readonly, /* is this file readonly? */
needchar, /* Peekc flag */
deranged, /* Up-arrow || down-arrow left xpos in Oz. */
indirect, /* Reading from an indirect file?? */
redoing, /* doing a redo? */
xerox, /* making a redo buffer? */
newfile, /* Editing a new file? */
newline, /* Last insert/delete included a EOL */
lineonly, /* Dumb terminal? */
zotscreen, /* do more after command in execmode */
diddled; /* force redraw when I enter editcore */
extern
int macro; /* Index into MCR macro execution stack */
extern
char lsearch;
/* movement, command codes */
extern
cmdtype movemap[];
#endif /*GLOBALS_D*/
#ifndef EXTERN_D
#define EXTERN_D
#define wc(ch) (scan(65,'=',(ch),wordset)<65)
#if HAVE_STRING_H
#include <string.h>
#endif
#if HAVE_MEMSET
#define fillchar(p,l,c) memset((p),(c),(l))
#elif HAVE_BLKFILL
#define fillchar(p,l,c) blkfill((p),(c),(l))
#endif
#if HAVE_STRCHR
#define index(s,c) strchr((s),(c))
#endif
extern findstates PROC findCP();
extern exec_type PROC editcore();
extern char PROC line(), peekc(), readchar();
extern char PROC *findparse(),*makepat();
extern bool PROC getlin();
extern bool PROC putfile();
extern bool PROC doyank(), deletion(), putback();
extern bool PROC pushb(),pushi(),pushmem(),uputcmd(), delete_to_undo();
extern bool PROC ok_to_scroll(), move_to_undo();
extern int PROC min(), max(), fseekeol(), bseekeol(), settop();
extern int PROC scan(), findDLE(), setY(), skipws(), nextline(), setX();
extern int PROC insertion(), chop(), fixcore(), lookup(), to_index();
extern int PROC doaddwork(), addfile(), expandargs(), to_line();
extern int PROC findfwd(), findback(), getcontext(), getKey();
extern int PROC cclass();
extern int PROC insertfile();
extern VOID PROC strput(), numtoa(), clrprompt(), setend(), error();
extern VOID PROC insert_to_undo(), resetX(), zerostack(), swap();
extern VOID PROC mvcur(), printch(), prints(), writeline(), refresh();
extern VOID PROC redisplay(), scrollback(), scrollforward(), prompt();
extern VOID PROC setpos(), resetX(), insertmacro(), wr_stat();
extern VOID PROC movearound(), printi(), println(), killargs();
extern VOID PROC exec(), initcon(), fixcon(), version(), setcmd();
extern VOID PROC toedit(), inputf(), fixmarkers(), errmsg();
#ifndef moveleft
extern VOID PROC moveleft();
#endif
#ifndef moveright
extern VOID PROC moveright();
#endif
#ifndef fillchar
extern VOID PROC fillchar();
#endif
#if USE_TERMCAP
extern void tc_init();
#endif
#endif /*EXTERN_D*/

View File

@@ -1,514 +0,0 @@
/*
* LEVEE, or Captain Video; A vi clone
*
* Copyright (c) 1982-2007 David L Parsons
* All rights reserved.
*
* Redistribution and use in source and binary forms, without or
* without modification, are permitted provided that the above
* copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and
* other materials related to such distribution and use acknowledge
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
* My name may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
#include "levee.h"
#include "extern.h"
#include "grep.h"
#include <ctype.h>
int PROC amatch();
int PROC locate();
VOID PROC patsize();
static int arg; /* arguments inside of a RE */
int PROC
REmatch(pattern, start, end)
char *pattern;
int start,end;
{
char *endp = &core[end];
if (!*pattern)
return -1;
arg = 0;
while (start <= end && !amatch(pattern, &core[start], endp))
start++;
return start;
}
int PROC
omatch(pattern, cp, endp)
char *pattern, **cp, *endp;
{
register int flag;
extern int ignorecase;
switch (*pattern) {
case LEND:
return (**cp == EOL);
case LSTART:
return (*cp == core) || (*(*cp-1) == EOL);
case TOKENB:
return (*cp == core) || !isalnum(*(*cp-1));
case TOKENE:
return !isalnum(**cp);
case LITCHAR:
if (ignorecase)
flag = (toupper(**cp) == toupper(*(pattern+1)));
else
flag = (**cp == *(pattern+1));
break;
case ANY:
flag = (**cp != EOL);
break;
case CCL:
flag = locate(pattern,*cp);
break;
case NCCL:
flag = !locate(pattern,*cp);
break;
case ARGSTART:
RE_start[arg] = (*cp)-core;
return TRUE;
case ARGEND:
RE_size[arg] = ((*cp)-core) - RE_start[arg];
++arg;
return TRUE;
default:
return TRUE;
}
if (*cp <= endp && flag) {
(*cp)++;
return TRUE;
}
return FALSE;
}
int PROC
amatch(pattern,start,endp)
char *pattern, *endp, *start;
{
int sarg = arg; /* save old arg match count for errors */
while (*pattern) {
if (*pattern == CLOSURE) {
/* Find the longest closure possible and work backwards trying
* to match the rest of the pattern.
*/
char *oldstart = start;
++pattern; /* skip over the closure token */
while (start <= endp && omatch(pattern,&start,endp))
;
/* start points at the character that failed the search.
* Try to match the rest of the pattern against it, working
* back down the line if failure
*/
patsize(&pattern);
while (start >= oldstart)
if (amatch(pattern,start--,endp))
return TRUE;
arg = sarg;
return FALSE;
}
else {
if (!omatch(pattern,&start,endp)) {
arg = sarg;
return FALSE;
}
patsize(&pattern);
}
}
lastp = start-core;
return TRUE;
}
/* increment pattern by the size of the token being scanned
*/
VOID PROC
patsize(pattern)
register char **pattern;
{
register int count;
switch (**pattern) {
case LITCHAR:
*pattern += 2;
break;
case CCL:
case NCCL:
count = *(++*pattern) & 0xff;
*pattern += 1+count;
break;
default:
(*pattern)++;
break;
}
}
int PROC
locate(pattern,linep)
/* locate: find a character in a closure */
char *pattern;
register char *linep;
{
register char *p = 1+pattern;
register int count;
if ((count = (*p++)&0xff) == 0)
return FALSE;
while (count--)
if (*p++ == *linep)
return TRUE;
return FALSE;
}
char *p;
VOID PROC
concatch(c)
/* add a character to the pattern */
char c;
{
if (p < &pattern[MAXPAT-1])
*p++ = c;
}
char PROC
esc(s)
char **s;
{
if (**s != ESCAPE || *(1+*s) == 0)
return **s;
++(*s);
switch (**s) {
case 't': return TAB;
case 'n': return EOL;
}
return **s;
}
char * PROC
dodash(src)
/* parse the innards of a [] */
char *src;
{
int k;
char *start = src;
char cs[128];
fillchar(cs,sizeof(cs),FALSE);
while (*src && *src != CCLEND) {
if (*src == DASH && src>start && src[1] != CCLEND && src[-1]<src[1]) {
for ( k = src[-1]; k <= src[1]; k++)
cs[k] = TRUE;
src++;
}
else
cs[(unsigned int)esc(&src)] = TRUE;
src++;
}
for (k=0; k < sizeof(cs); k++)
if (cs[k])
concatch((char)k);
return src;
}
char * PROC
badccl(src)
/* a [] was encountered. is it a CCL (match one of the included
* characters); or is it a NCCL (match all but the included characters)?
*/
char *src;
{
char *jstart;
if (*src == NEGATE) {
concatch(NCCL);
++src;
}
else
concatch(CCL);
jstart = p;
concatch(0); /* this will be the length of the pattern */
src = dodash(src);
*jstart = (p-jstart)-1;
return src;
}
/* patterns that cannot be closed */
char badclose[] = { LSTART, LEND, CLOSURE, 0 };
char * PROC
makepat(string,delim)
char *string, delim;
/* make up the pattern string for find -- ripped from 'Software Tools' */
{
char *cp = 0, *oldcp;
char *start = string;
int inarg = FALSE;
for(arg=0;arg<9;++arg)
RE_start[arg] = RE_size[arg] = (-1);
arg = 0;
p = pattern;
while ((*string != delim) && (*string != 0)) {
oldcp = cp;
cp = p;
if (!magic) /* kludge for nonmagical patterns */
goto normal;
if (*string == ANY)
concatch(ANY);
else if ((*string == LSTART) && (string == start))
concatch(LSTART);
else if ((*string == LEND) && (string[1] == delim || string[1] == 0))
concatch(LEND);
else if (*string == CCL)
string = badccl(1+string);
else if ((*string == CLOSURE) && (p > pattern)) {
cp = oldcp;
if (strchr(badclose, *cp) || p >= &pattern[MAXPAT-1])
return NULL;
moveright(cp,1+cp,(int)(p-cp));
*cp = CLOSURE;
p++;
}
else if (*string == ESCAPE) {
if (string[1] == ARGSTART || string[1] == ARGEND) {
if (string[1] == ARGEND)
if (!inarg)
goto normal;
if (string[1] == ARGSTART) {
if (inarg)
goto normal;
if (++arg > 9)
return NULL;
}
inarg = !inarg;
}
else if (string[1] != TOKENB && string[1] != TOKENE)
goto normal;
++string;
concatch(*string);
}
else {
normal:concatch(LITCHAR);
concatch(esc(&string));
}
if (*string)
string++;
}
if (inarg)
concatch(ARGEND);
if (p > pattern) { /* new pattern was created */
strncpy(lastpatt,start,(int)(string-start));
lastpatt[string-start] = 0;
concatch(0);
if (p-pattern >= MAXPAT)
return NULL;
}
return (*string == delim)?(string+1):(string);
}
int PROC
findfwd(pattern,start,endp)
/* look for a regular expression forward */
char *pattern;
int start, endp;
{
int ep;
while (start < endp) {
ep = fseekeol(start);
if ((start = REmatch(pattern, start, ep)) <= ep)
return start;
}
return ERR;
}
int PROC
findback(pattern,start,endp)
/* look for a regular expression backwards */
char *pattern;
int start, endp;
{
int ep,i;
while (start > endp) {
ep = bseekeol(start);
if ((i = REmatch(pattern, ep, start)) <= start)
return i;
start = ep-1;
}
return ERR;
}
bool s_wrapped = 0;
char * PROC
search(pat, start)
/* get a token for find & find it in the buffer
*/
char *pat;
int *start;
{
bool forwd;
int pos;
char *p;
forwd = ((lsearch = *pat) == '/');
if ((p=makepat(pat+1,*pat)) == NULL) {
*start = ERR;
return pat;
}
do {
if (forwd) {
pos = findfwd(pattern, (*start)+1, bufmax-1);
if ((pos == ERR) && wrapscan) {
s_wrapped = 1;
pos = findfwd(pattern, 0, (*start)-1);
}
}
else {
pos = findback(pattern, (*start)-1, 0);
if ((pos == ERR) && wrapscan) {
s_wrapped = 1;
pos = findback(pattern, bufmax-1, (*start)+1);
}
}
*start = pos;
} while (--count > 0 && *start != ERR);
return p;
}
char * PROC
findparse(src,idx,start) /* driver for ?, /, && : lineranges */
char *src;
int *idx,start;
{
int addr = start;
char c;
s_wrapped = 0;
switch (*src) {
case '/':
case '?':
/* get a token for find & find it in the buffer */
src = search(src,&addr);
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
/* fabricate a count */
count = 0;
while (*src >= '0' && *src <= '9')
count = (count*10) + *(src++) - '0';
addr = to_index(count);
break;
case '$':
addr = bufmax-1;
src++;
break;
case '.' :
src++;
break;
case '`':
case '\'':
addr = getcontext(*(src+1), (*src == '\''));
src += 2;
break;
}
while (addr>=0 && (*src =='+' || *src == '-')) {
c = *(src++);
/* skip delimiter */
if (*src == '/' || *src == '?') {
count = 1;
if ((src = search(src,&addr)) == NULL)
break;
}
else {
if (*src >= '0' && *src <= '9') {
/* fabricate a count */
count = 0;
while (*src >= '0' && *src <= '9')
count = (count*10) + *(src++) - '0';
}
else
count = -1; /* for naked + & - */
if (count == 0) /* +0 goes to beginning of line */
addr = bseekeol(addr);
else {
addr = nextline((c=='+'), addr, count);
if (c=='-' && addr > 0)
addr = bseekeol(addr);
}
if (addr >= bufmax)
addr = -1;
}
}
*idx = addr;
return(src);
}
int PROC
nextline(advance,dest,count)
bool advance;
int dest,count;
{
if (advance)
do {
dest = fseekeol(dest) + 1;
count--;
} while (count>0 && dest<bufmax);
else
do {
dest = bseekeol(dest) - 1;
count--;
} while (count>0 && dest>=0);
return(dest);
}
int PROC
fseekeol(origin)
int origin;
{
return(origin + scan(bufmax-origin-1,'=',EOL,&core[origin]));
}
int PROC
bseekeol(origin)
int origin;
{
return(origin + scan(-origin,'=',EOL,&core[origin-1]));
}
/* get something from the context table */
int PROC
getcontext(c,begline)
char c;
bool begline;
{
int i;
if (c == '\'')
c = '`';
if (c >= '`' && c <= 'z')
i = contexts[c-'`'];
else
i = -1;
if (begline && i>=0)
return(bseekeol(i));
return(i);
}

View File

@@ -1,122 +0,0 @@
/*
* LEVEE, or Captain Video; A vi clone
*
* Copyright (c) 1982-2007 David L Parsons
* All rights reserved.
*
* Redistribution and use in source and binary forms, without or
* without modification, are permitted provided that the above
* copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and
* other materials related to such distribution and use acknowledge
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
* My name may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/*
* flexos interface for levee (Metaware C)
*/
#include "levee.h"
#if OS_FLEXOS
#include <flexos.h>
#include <ctype.h>
static int oldkmode;
static int oldsmode;
int
min(a,b)
{
return (a>b) ? b : a;
}
int
max(a,b)
{
return (a<b) ? b : a;
}
strput(s)
char *s;
{
s_write(0x01, 1L, s, (long)strlen(s), 0L);
}
char *
basename(s)
char *s;
{
char *strrchr();
char *p;
if ((p=strrchr(s,'/')) || (p=strrchr(s,'\\')) || (p = strrchr(s,':')))
return 1+p;
return s;
}
getKey()
{
char c;
s_read(0x0101, 0L, &c, 1L, 0L);
return c;
}
initcon()
{
CONSOLE tty;
s_get(T_CON, 1L, &tty, SSIZE(tty));
oldkmode = tty.con_kmode;
oldsmode = tty.con_smode;
tty.con_kmode = 0x0667;
tty.con_smode = 0;
s_set(T_CON, 1L, &tty, SSIZE(tty));
}
fixcon()
{
CONSOLE tty;
s_get(T_CON, 1L, &tty, SSIZE(tty));
tty.con_kmode = oldkmode;
tty.con_smode = oldsmode;
s_set(T_CON, 1L, &tty, SSIZE(tty));
}
char *
strdup(s)
char *s;
{
char *malloc();
char *p;
if (p=malloc(strlen(s)+1))
strcpy(p, s);
return p;
}
getpid()
{
PROCESS myself;
s_get(T_PDEF, 0L, &myself, SSIZE(myself));
return myself.ps_pid;
}
strlwr(s)
char *s;
{
while (*s) {
if (isupper(*s))
*s += 32;
s++;
}
}
#endif

View File

@@ -1,70 +0,0 @@
/*
* LEVEE, or Captain Video; A vi clone
*
* Copyright (c) 1982-2007 David L Parsons
* All rights reserved.
*
* Redistribution and use in source and binary forms, without or
* without modification, are permitted provided that the above
* copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and
* other materials related to such distribution and use acknowledge
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
* My name may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/*
* Gemdos (Atari ST) bindings for levee (Alcyon/Sozobon C)
*/
#include "levee.h"
#if OS_ATARI
#include <atari\osbind.h>
strput(s)
register char *s;
{
write(1, s, strlen(s));
}
zwrite(s,len)
char *s;
{
write(1, s, len);
}
min(a,b)
register int a, b;
{
return (a<b)?a:b;
}
max(a,b)
register int a, b;
{
return (a>b)?a:b;
}
unsigned
getKey()
/* get input from the keyboard. All odd keys (function keys, et al) that
* do not produce a character have their scancode orred with $80 and returned.
*/
{
unsigned c;
long key;
c = (key = Crawcin()) & 0xff;
if (!c)
c = (((unsigned)(key>>16))|0x80) & 0xff;
return c;
} /* getKey */
#endif /*OS_ATARI*/

View File

@@ -1,547 +0,0 @@
/*
* LEVEE, or Captain Video; A vi clone
*
* Copyright (c) 1982-2008 David L Parsons
* All rights reserved.
*
* Redistribution and use in source and binary forms, without or
* without modification, are permitted provided that the above
* copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and
* other materials related to such distribution and use acknowledge
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
* My name may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
/* global declarations */
#include "levee.h"
#define GLOBALS
char lastchar, /* Last character read via peekc */
ch; /* Global command char */
exec_type mode; /* editor init state */
int lastexec = 0; /* last exec command */
int contexts['z'-'`'+1]; /* Labels */
/* C O N S T A N T S */
bool adjcurr[PARA_BACK+1],
adjendp[PARA_BACK+1];
/* A R G U M E N T S */
char startcmd[80] = ""; /* initial command after read */
char **argv; /* Arguments */
int argc=0, /* # arguments */
pc=0; /* Index into arguments */
#if 0
struct stat thisfile; /* status on current file, for writeout... */
#endif
/* M A C R O S T U F F */
struct macrecord mbuffer[MAXMACROS];
struct tmacro mcr[NMACROS]; /* A place for executing macros */
/* S E A R C H S T U F F */
char dst[80] = "", /* last replacement pattern */
lastpatt[80] = "", /* last search pattern */
pattern[MAXPAT] = ""; /* encoded last pattern */
int RE_start[9], /* start of substitution arguments */
RE_size [9], /* size of substitution arguments */
lastp; /* end of last pattern */
struct undostack undo; /* To undo a command */
/* R A N D O M S T R I N G S */
char instring[200], /* Latest input */
filenm[80] = "", /* Filename */
altnm[80] = ""; /* Alternate filename */
char gcb[16]; /* Command buffer for mutations of insert */
char undobuf[40];
char undotmp[40];
char yankbuf[40];
HANDLE uread, /* reading from the undo stack */
uwrite; /* writing to the undo stack */
/* B U F F E R S */
char rcb[256]; /* last modification command */
char *rcp; /* this points at the end of the redo */
char core[SIZE+1]; /* data space */
struct ybuf yank; /* last deleted/yanked text */
/* STATIC INITIALIZATIONS: */
/* ttydef stuff */
#if OS_ATARI | USE_TERMCAP
int LINES, COLS;
#endif
#if TTY_ZTERM
char *TERMNAME = "zterm",
*HO = "\001", /* goto top of screen */
*UP = "\002", /* move up 1 line? */
*CE = "\003", /* clear to end of line */
*CL = "\004", /* clearscreen */
*OL = "\005", /* open current line down */
*UpS = "\006", /* scroll up 1 line */
*BELL= "\007", /* ring the bell */
*CM = "yes", /* cursor movement exists */
*CURoff,
*CURon;
#endif /*ZTERM*/
#if TTY_ANSI
#if OS_DOS
char *TERMNAME = "braindamaged ansi",
#else
char *TERMNAME = "hardwired ansi",
#endif
*HO = "\033[H",
*UP = "\033[A",
*CE = "\033[K",
*CL = "\033[H\033[J",
#if OS_DOS
*OL = NULL,
*UpS = NULL,
#else
*OL = "\033[L",
*UpS = "\033[L",
#endif
*BELL= "\007",
*CM = "\033[%d;%dH",
*CURoff,
*CURon;
#endif /*TTY_ANSI*/
#if TTY_VT52
#if OS_ATARI
char *TERMNAME = "Atari ST",
#else
#if OS_FLEXOS
char *TERMNAME = "Flexos console",
#else
char *TERMNAME = "hardwired vt52",
#endif /*OS_FLEXOS*/
#endif /*OS_ATARI*/
*HO = "\033H",
*UP = "\033A",
*CE = "\033K",
*CL = "\033E",
*OL = "\033L",
*BELL= "\007",
*CM = "\033Y??",
#if OS_FLEXOS
*UpS = NULL, /* Reverse scrolling is painfully slow */
#else
*UpS = "\033I",
#endif
*CURoff= "\033f",
*CURon = "\033e";
#endif /*TTY_VT52*/
#if USE_TERMCAP
bool CA, canUPSCROLL;
char FkL, CurRT, CurLT, CurUP, CurDN;
char *TERMNAME, /* will be set in termcap handling */
*HO,
*UP,
*CE,
*CL,
*OL,
*BELL,
*CM,
*UpS,
*CURoff,
*CURon;
#endif /*USE_TERMCAP*/
char Erasechar = ERASE, /* our erase character */
eraseline = 'X'-'@'; /* and line-kill character */
char fismod[] = "File is modified", /* File is modified message */
fisro[] = "File is readonly"; /* when you can't write the file */
char *excmds[] = {
"print", /* lines to screen */
"quit", /* quit editor */
"read", /* add file to buffer */
"edit", /* replace buffer with file */
"write", /* write out file */
"wq", /* write file and quit */
"next", /* make new arglist or traverse this one */
"substitute", /* pattern */
"xit", /* write changes and quit */
"file", /* show/set file name */
"set", /* options */
"rm", /* a file */
"previous", /* back up in arglist */
"delete", /* lines from buffer */
"=", /* tell line number */
"yank", /* lines from buffer */
"put", /* back yanked lines */
"visual", /* go to visual mode */
"exec", /* go to exec mode */
"insert", /* text below current line */
"open", /* insert text above current line */
"change", /* lines */
"undo", /* last change */
"!", /* shell escape */
"map", /* keyboard macro */
"unmap", /* keyboard macro */
"source", /* read commands from file */
"version", /* print version # */
"args", /* print argument list */
"rewind", /* rewind argument list */
NULL
};
char wordset[] = "0123456789$_#ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
char spaces[] = { TAB,EOL,' ',0 };
int shiftwidth = 4,
#if USE_TERMCAP | OS_ATARI
dofscroll,
#else
dofscroll = LINES/2,
#endif
tabsize = 8;
int autoindent = YES,
autocopy = NO,
autowrite = YES,
wrapscan = YES,
overwrite = YES,
beautify = YES,
list = NO,
magic = YES,
bell = YES,
#if OS_ATARI
mapslash,
#endif
ignorecase = NO;
struct variable vars[]={
{"terminal", "", VSTR, V_CONST, (void*)&TERMNAME },
{"shiftwidth","sw", VINT, 0, (void*)&shiftwidth },
{"scroll", "", VINT, 0, (void*)&dofscroll },
{"tabsize", "ts", VINT, V_DISPLAY, (void*)&tabsize },
{"autoindent","ai", VBOOL, 0, (void*)&autoindent },
{"autocopy", "ac", VBOOL, 0, (void*)&autocopy },
{"autowrite", "aw", VBOOL, 0, (void*)&autowrite },
{"wrapscan", "ws", VBOOL, 0, (void*)&wrapscan },
{"overwrite", "ow", VBOOL, 0, (void*)&overwrite },
{"beautify", "be", VBOOL, 0, (void*)&beautify },
{"list", "", VBOOL, V_DISPLAY, (void*)&list },
{"magic", "", VBOOL, 0, (void*)&magic },
{"ignorecase","ic", VBOOL, 0, (void*)&ignorecase },
{"bell", "", VBOOL, 0, (void*)&bell },
#if OS_ATARI
{"mapslash", "ms", VBOOL, 0, (void*)&mapslash },
#endif
{NULL}
};
/* For movement routines */
int setstep[2] = {-1,1};
/* Where the last diddling left us */
struct coord curpos={0, 0};
/* initialize the buffer */
int bufmax = 0, /* End of file here */
lstart = 0, lend = 0, /* Start & end of current line */
ptop = 0, pend = 0, /* Top & bottom of CRT window */
curr = 0, /* Global cursor pos */
xp = 0, yp = 0, /* Cursor window position */
count = 0; /* Latest count */
bool modified= NO, /* File has been modified */
readonly= NO, /* is this file readonly? */
needchar= YES, /* Peekc flag */
deranged= NO, /* Up-arrow || down-arrow left xpos in Oz. */
indirect= NO, /* Reading from an indirect file?? */
redoing = NO, /* doing a redo? */
xerox = NO, /* making a redo buffer? */
newfile = YES, /* Editing a new file? */
newline = NO, /* Last insert/delete included a EOL */
lineonly= NO, /* Dumb terminal? */
zotscreen=NO, /* ask for [more] in execmode */
diddled = NO; /* force new window in editcore */
int macro = -1; /* Index into MCR */
char lsearch = 0; /* for N and n'ing... */
/* movement, command codes */
cmdtype movemap[256]={
/*^@*/ BAD_COMMAND,
/*^A*/ DEBUG_C,
/*^B*/ HARDMACRO,
/*^C*/ BAD_COMMAND,
/*^D*/ WINDOW_UP,
/*^E*/ HARDMACRO,
/*^F*/ HARDMACRO,
/*^G*/ FILE_C,
/*^H*/ GO_LEFT, /* also leftarrow */
/*^I*/ REDRAW_C,
/*^J*/ GO_DOWN, /* also downarrow */
/*^K*/ GO_UP, /* also uparrow */
/*^L*/ GO_RIGHT, /* also rightarrow */
/*^M*/ CR_FWD,
/*^N*/ BAD_COMMAND,
/*^O*/ BAD_COMMAND,
/*^P*/ BAD_COMMAND,
/*^Q*/ BAD_COMMAND,
/*^R*/ BAD_COMMAND,
/*^S*/ BAD_COMMAND,
/*^T*/ BAD_COMMAND,
/*^U*/ WINDOW_DOWN,
/*^V*/ BAD_COMMAND,
/*^W*/ BAD_COMMAND,
/*^X*/ BAD_COMMAND,
/*^Y*/ HARDMACRO,
/*^Z*/ BAD_COMMAND,
/*^[*/ BAD_COMMAND,
/*^\*/ BAD_COMMAND,
/*^]*/ BAD_COMMAND,
/*^^*/ BAD_COMMAND,
/*^_*/ BAD_COMMAND,
/* */ GO_RIGHT,
/*! */ EXEC_C,
/*" */ BAD_COMMAND,
/*# */ BAD_COMMAND,
/*$ */ TO_EOL,
/*% */ MATCHEXPR,
/*& */ RESUBST_C,
/*\ */ TO_MARK_LINE,
/*( */ SENT_BACK,
/*) */ SENT_FWD,
/** */ BAD_COMMAND,
/*+ */ CR_FWD,
/*, */ BAD_COMMAND,
/*- */ CR_BACK,
/*. */ REDO_C,
/*/ */ PATT_FWD,
/*0 */ TO_COL,
/*1 */ BAD_COMMAND,
/*2 */ BAD_COMMAND,
/*3 */ BAD_COMMAND,
/*4 */ BAD_COMMAND,
/*5 */ BAD_COMMAND,
/*6 */ BAD_COMMAND,
/*7 */ BAD_COMMAND,
/*8 */ BAD_COMMAND,
/*9 */ BAD_COMMAND,
/*: */ COLIN_C,
/*; */ BAD_COMMAND,
/*< */ ADJUST_C,
/*= */ BAD_COMMAND,
/*> */ ADJUST_C,
/*? */ PATT_BACK,
/*@ */ BAD_COMMAND,
/*A */ A_AT_END,
/*B */ BACK_WD,
/*C */ HARDMACRO,
/*D */ HARDMACRO,
/*E */ BAD_COMMAND,
/*F */ BACK_CHAR,
/*G */ GLOBAL_LINE,
/*H */ PAGE_BEGIN,
/*I */ I_AT_NONWHITE,
/*J */ JOIN_C,
/*K */ BAD_COMMAND,
/*L */ PAGE_END,
/*M */ PAGE_MIDDLE,
/*N */ BSEARCH,
/*O */ OPENUP_C,
/*P */ PUT_AFTER,
/*Q */ EDIT_C,
/*R */ BIG_REPL_C,
/*S */ BAD_COMMAND,
/*T */ BACKTO_CHAR,
/*U */ BAD_COMMAND,
/*V */ BAD_COMMAND,
/*W */ FORWD,
/*X */ HARDMACRO,
/*Y */ HARDMACRO,
/*Z */ ZZ_C,
/*[ */ BAD_COMMAND,
/*\ */ BAD_COMMAND,
/*] */ BAD_COMMAND,
/*^ */ NOTWHITE,
/*_ */ BAD_COMMAND,
/*` */ TO_MARK,
/*a */ APPEND_C,
/*b */ BACK_WD,
/*c */ CHANGE_C,
/*d */ DELETE_C,
/*e */ FORWD,
/*f */ TO_CHAR,
/*g */ BAD_COMMAND,
/*h */ GO_LEFT,
/*i */ INSERT_C,
/*j */ GO_DOWN,
/*k */ GO_UP,
/*l */ GO_RIGHT,
/*m */ MARKER_C,
/*n */ FSEARCH,
/*o */ OPEN_C,
/*p */ PUT_BEFORE,
/*q */ BAD_COMMAND,
/*r */ REPLACE_C,
/*s */ HARDMACRO,
/*t */ UPTO_CHAR,
/*u */ UNDO_C,
/*v */ BTO_WD,
/*w */ TO_WD,
/*x */ HARDMACRO,
/*y */ YANK_C,
/*z */ REWINDOW,
/*{ */ PARA_BACK,
/*| */ TO_COL,
/*} */ PARA_FWD,
/*~ */ TWIDDLE_C,
/*^?*/ BAD_COMMAND,
/*80*/ BAD_COMMAND,
/*81*/ BAD_COMMAND,
/*82*/ BAD_COMMAND,
/*83*/ BAD_COMMAND,
/*84*/ BAD_COMMAND,
/*85*/ BAD_COMMAND,
/*x6*/ BAD_COMMAND,
/*x7*/ BAD_COMMAND,
/*x8*/ BAD_COMMAND,
/*x9*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND,
/*xx*/ BAD_COMMAND
};

View File

@@ -1,36 +0,0 @@
/*
* LEVEE, or Captain Video; A vi clone
*
* Copyright (c) 1982-2007 David L Parsons
* All rights reserved.
*
* Redistribution and use in source and binary forms, without or
* without modification, are permitted provided that the above
* copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and
* other materials related to such distribution and use acknowledge
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
* My name may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
#define LEND '$'
#define LSTART '^'
#define LITCHAR 'c'
#define ANY '.'
#define CCL '['
#define NCCL '!'
#define DASH '-'
#define CCLEND ']'
#define NEGATE '^'
#define CLOSURE '*'
#define ESCAPE '\\'
#define TOKENB '<'
#define TOKENE '>'
#define ARGSTART '('
#define ARGEND ')'
#define AMPERSAND '&'

View File

@@ -1,156 +0,0 @@
/*
* LEVEE, or Captain Video; A vi clone
*
* Copyright (c) 1982-2007 David L Parsons
* All rights reserved.
*
* Redistribution and use in source and binary forms, without or
* without modification, are permitted provided that the above
* copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and
* other materials related to such distribution and use acknowledge
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
* My name may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*/
#include "levee.h"
#include "extern.h"
int PROC
insertion(count, openflag, dp, yp, visual)
int count, openflag, *dp, *yp;
bool visual;
{
char cmd, c;
int rp; /* number of spaces to diddle */
int ts, ss; /* tabs && spaces to insert */
register int cp; /* current position */
int i; /* random index */
int endd; /* last open place */
register int rsize; /* size of upper buffer */
int currDLE = 0; /* what DLE is now */
int len; /* full insert size */
bool Dflag;
if (openflag != 0) { /* opening a line above || below */
if (openflag<0 && bufmax>0 && curr<bufmax) {
curr = 1+lend;
if (visual)
zwrite("\n", 1);
}
else { /* open above current line */
(*yp)--;
curr = lstart;
}
if (autoindent)
currDLE = findDLE(lstart, &i, skipws(lstart),0);
if (visual) {
#if TTY_VT52
if (OL) {
#else
if (OL && (*yp) < LINES-2) {
#endif
strput(OL);
(*yp)++;
curpos.y = *yp;
}
else {
mvcur(1+(*yp), 0);
strput(CE);
}
}
mvcur(-1, currDLE);
}
else {
if (autoindent)
currDLE = findDLE(lstart, &i, curr, 0);
if (curr == i) {
if (!delete_to_undo(&undo, lstart, i-lstart))
return(-1);
curr = lstart;
}
}
rsize = (bufmax-curr); /* amount of stuff above curr */
endd = SIZE - rsize; /* split the buffer */
if (rsize > 0)
moveright(&core[curr], &core[endd], rsize);
cp = curr;
do { /* Insert loop */
Dflag = (cp==0 || core[cp-1]==EOL);
do {
if (Dflag)
while ((cmd=peekc()) == '' || cmd == '') {
if (readchar() == '')
currDLE = min(COLS,currDLE+shiftwidth);
else
currDLE = max(0,currDLE-shiftwidth);
mvcur(-1, currDLE);
}
} while (!(c = line(core, cp, endd-1, &len)));
if (Dflag && (len > 0 || c == ESC)) {
/* makeDLE : optimize leading whitespace for insert */
currDLE = findDLE(cp, &rp, cp+len, currDLE);
if (rp > cp) {
len -= (rp-cp);
moveleft(&core[rp], &core[cp], len); /* squash whitespace */
}
if (currDLE > 0) { /* create DLE indent */
ts = currDLE / tabsize;
ss = currDLE % tabsize;
moveright(&core[cp], &core[cp+ts+ss], len);
len += (ts+ss);
fillchar(&core[cp ], ts, TAB);
fillchar(&core[cp+ts], ss, 32);
}
}
cp += len;
if (c == EOL) { /* Diddle-Diddle */
core[cp++] = EOL; /* add in a \n */
strput(CE); /* clear this line */
println();
if (visual) {
#if OS_RMX
/* at OL at bottom kludge... */
if (OL && (*yp) < LINES-2) {
#else
if (OL) {
#endif
strput(OL);
(*yp)++;
}
else
strput(CE);
}
if (!autoindent) /* reset currDLE? */
currDLE = 0;
mvcur(-1, currDLE);
}
} while (c != ESC && cp <= endd-INSSIZE);
*dp = cp; /* start display here */
if (count > 1) { /* repeated insertion */
len = cp-curr;
if ((count-1)*len < endd-cp)
for (i = 1;i <count;i++) {
moveright(&core[cp-len], &core[cp], len);
cp += len;
}
}
if (openflag != 0 /* open or insert at end of buffer */
|| (rsize < 1 && cp > curr && core[cp-1] != EOL))
core[cp++] = EOL;
len = cp-curr;
if (rsize > 0) /* if not at end of buffer, stitch things together */
moveleft(&core[endd], &core[cp], rsize);
insert_to_undo(&undo, curr, len);
core[bufmax] = EOL;
return(cp);
}

View File

@@ -1,386 +0,0 @@
/*
* LEVEE, or Captain Video; A vi clone
*
* Copyright (c) 1980-2008 David L Parsons
* All rights reserved.
*
* Redistribution and use in source and binary forms, without or
* without modification, are permitted provided that the above
* copyright notice and this paragraph are duplicated in all such
* forms and that any documentation, advertising materials, and
* other materials related to such distribution and use acknowledge
* that the software was developed by David L Parsons (orc@pell.chi.il.us).
* My name may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
* PURPOSE.
*
* Levee v3.C
* C version for Unix/Atari ST/MS-DOS/OS-2/FlexOs/iRMX/etc
* Pascal version for UCSD Pascal 4.X
*
* written fall 82' - now (approx) by David L. Parsons.
*
* many patches, suggestions,
* and impractical design goals by:
* Jim Bolland,
* John Plocher,
* John Tainter
*/
#ifndef LEVEE_D
#define LEVEE_D
#include "config.h"
#ifndef TRUE
#define TRUE (1) /* Nobody defines TRUE & FALSE, so I will do */
#define FALSE (0) /* it myself */
#endif
#define HANDLE int /* default file handle type */
#define PROC /* for magic function types (MSDOS) */
#define VOID void /* ancient creaking C compilers won't understand void */
/*
* Compilation defines for different systems.
*/
#if OS_ATARI
#include <stdio.h>
#define void int /* Alcyon C don't know void */
/* extractions from osbind.h */
#define OPEN_OLD(n) gemdos(0x3d,n,/*open mode*/0)
#define OPEN_NEW(n) gemdos(0x3c,n,/*permissions*/0)
#define CLOSE_FILE(f) gemdos(0x3e,f)
#define SEEK_POSITION(f,o,m) gemdos(0x42,(long)(o),f,m)
#define READ_TEXT(f,b,c) gemdos(0x3f,f,(long)(c),b)
#define WRITE_TEXT(f,b,c) gemdos(0x40,f,(long)(c),b)
extern char *malloc();
extern long gemdos();
#endif /*OS_ATARI*/
#if OS_RMX
#include <:inc:stdio.h>
#include <:inc:udi.h>
#define OPEN_OLD(n) open(n, /*open mode*/0)
#define OPEN_NEW(n) creat(n,/*permissions*/0)
#define CLOSE_FILE(f) close(f)
#define SEEK_POSITION(f,o,m) lseek((f),(long)(o),(m))
#define READ_TEXT(f,p,c) read((f),(p),(unsigned)(c))
#define WRITE_TEXT(f,p,c) write((f),(p),(unsigned)(c))
#define zwrite(p,s) write(1,(p), (unsigned)(s))
#endif /*OS_RMX*/
#if OS_DOS
#include <stdio.h>
#include <fcntl.h>
#define OPEN_OLD(n) open(n, O_RDONLY|O_BINARY)
#define OPEN_NEW(n) open(n, O_WRONLY|O_CREAT|O_TRUNC|O_BINARY, 0666)
#define CLOSE_FILE(f) close(f)
#define SEEK_POSITION(f,o,m) lseek(f, (long)(o), (m))
#define READ_TEXT(f,p,c) read(f, p, (int)(c))
#define WRITE_TEXT(f,p,c) write(f, p, (int)(c))
#define zwrite(p,s) WRITE_TEXT(fileno(stdout), p, s)
#undef PROC
#define PROC _fastcall
#include "proto.h"
#endif /*OS_DOS*/
#if OS_UNIX
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
#include <ctype.h>
#define OPEN_OLD(n) open(n, O_RDONLY)
#define OPEN_NEW(n) open(n, O_WRONLY|O_CREAT|O_TRUNC, 0666)
#define CLOSE_FILE(f) close(f)
#define SEEK_POSITION(f,o,m) lseek(f, (long)(o), (m))
#define READ_TEXT(f,p,c) read(f, p, (int)(c))
#define WRITE_TEXT(f,p,c) write(f, p, (int)(c))
#define zwrite(p,s) fwrite(p, 1, s, stdout)
#endif /*OS_UNIX*/
#if OS_FLEXOS
#include <stdio.h>
#define OPEN_OLD(n) s_open(m,0x08) /* note reversed parameters! */
#define OPEN_NEW(n) s_create(0,0,n,0,0/*mode*/,0)
#define CLOSE_FILE(f) s_close(0,f) /* Full close on handle */
#define SEEK_POSITION(f,o,m) s_seek((m&03)<<9, f, o)
#define READ_TEXT(f,p,c) s_read(0x0100,(long)(f),p,(long)(c),0L)
#define WRITE_TEXT(f,p,c) s_write(0x0101,(long)(f),p,(long)(c),0L)
#define zwrite(p,s) s_write(0x0101, 1L, p, (long)(s),0L)
#define unlink(n) s_delete(0, n)
#define rename(a,b) s_rename(0, a, b)
/* OPEN_OLD mode flags */
#undef HANDLE
#define HANDLE long
#endif /*OS_FLEXOS*/
#define bool int
/* ttydef stuff */
#if !(OS_ATARI | USE_TERMCAP)
#ifndef LINES
#define LINES 25
#endif /*LINES*/
#define COLS 79
#endif
#define YES 1
#define NO 0
#define UPARROW 11
#define DNARROW 10
#define LTARROW erase
#define RTARROW 12
#if !USE_TERMCAP
#define CA TRUE
#if !(OS_DOS||OS_FLEXOS)
#define canUPSCROLL 1
#endif
#endif
/* nospecific stuff */
#define MAGICNUMBER 42
#define hell_freezes_over FALSE
#define BUGS 7 /* sometime when you least expect it.. */
#define DW 23 /* Delete Word */
#define EOL 10 /* End Of Line */
#define DLE 16 /* Space compression lead-in */
#define ESC 27 /* Escape */
/* hardwired line kill and erase character for non-unix machines */
#define DEL 21 /* ^U */
#if RMX
#define ERASE 127
#else
#define ERASE 8 /* ^H */
#endif
#define TAB 9
/* variable types */
#define VBOOL 0
#define VINT 1
#define VSTR 2
#define ERR (-1)
/* Undostack commands */
#define U_ADDC 'A'
#define U_MOVEC 'M'
#define U_DELC 'D'
/* magic things for find */
#define MAXPAT ((int)300)
/* exec mode commands */
#define EX_CR (ERR-1)
#define EX_PR 0
#define EX_QUIT 1
#define EX_READ 2
#define EX_EDIT 3
#define EX_WRITE 4
#define EX_WQ 5
#define EX_NEXT 6
#define EX_SUBS 7
#define EX_XIT 8
#define EX_FILE 9
#define EX_SET 10
#define EX_RM 11
#define EX_PREV 12
#define EX_DELETE 13
#define EX_LINE 14
#define EX_YANK 15
#define EX_PUT 16
#define EX_VI 17
#define EX_EX 18
#define EX_INSERT 19
#define EX_OPEN 20
#define EX_CHANGE 21
#define EX_UNDO 22
#define EX_ESCAPE 23
#define EX_MAP 24
#define EX_UNMAP 25
#define EX_SOURCE 26
#define EX_VERSION 27
#define EX_ARGS 28
#define EX_REWIND 29
/* movement return states */
#define LEGALMOVE 0
#define BADMOVE 1
#define ESCAPED 2
#define findstates char
/* command codes */
#define BAD_COMMAND 0
/*visual movement*/
#define GO_RIGHT 1
#define GO_LEFT 2
#define GO_UP 3
#define GO_DOWN 4
#define FORWD 5
#define TO_WD 6
#define BACK_WD 7
#define BTO_WD 8
#define NOTWHITE 9
#define TO_COL 10
#define TO_EOL 11
#define MATCHEXPR 12
#define TO_CHAR 13
#define UPTO_CHAR 14
#define BACK_CHAR 15
#define BACKTO_CHAR 16
#define SENT_FWD 17
#define SENT_BACK 18
#define PAGE_BEGIN 19
#define PAGE_END 20
#define PAGE_MIDDLE 21
#define CR_FWD 22
#define CR_BACK 23
#define PATT_FWD 24
#define PATT_BACK 25
#define FSEARCH 26
#define BSEARCH 27
#define GLOBAL_LINE 28
#define TO_MARK 29
#define TO_MARK_LINE 30
#define PARA_FWD 31
#define PARA_BACK 32
/*modifications*/
#define DELETE_C 39
#define EXEC_C 40
#define ADJUST_C 41
#define CHANGE_C 42
#define YANK_C 43
#define INSERT_C 44
#define APPEND_C 45
#define I_AT_NONWHITE 46
#define A_AT_END 47
#define OPEN_C 48
#define OPENUP_C 49
#define REPLACE_C 50
#define TWIDDLE_C 51
#define RESUBST_C 52
#define JOIN_C 53
#define UNDO_C 54
#define BIG_REPL_C 55
#define PUT_BEFORE 56
#define PUT_AFTER 57
/*everything else*/
#define HARDMACRO 70
#define REWINDOW 71
#define ZZ_C 72
#define DEBUG_C 73
#define FILE_C 74
#define WINDOW_UP 75
#define WINDOW_DOWN 76
#define REDRAW_C 77
#define MARKER_C 78
#define REDO_C 79
#define EDIT_C 80
#define COLIN_C 81
/*macros*/
#define SOFTMACRO 100
#define INSMACRO 101
#define cmdtype char
/* exec mode states */
#define E_VISUAL 0
#define E_INIT 1
#define E_EDIT 2
#define exec_type char
/* various sizes */
#define INSSIZE ((int)80) /* Insert string size */
#define FSIZE ((int)39) /* File string size */
#ifndef SIZE
# define SIZE ((int)32760) /* Edit buffer size */
#endif
#define SBUFSIZE ((int)4096) /* Incore yank buffer size */
#define MAXMACROS 32 /* Maximum # of macros */
#define NMACROS 9 /* Nexting level for macros */
#define PAGESIZE ((int)1024) /* Bytes per block */
struct coord { /* Screen Coordinate */
int x,y;
};
struct ybuf { /* Yank Buffer */
int size; /* Bytes yanked */
bool lines, /* Yanked whole lines? */
has_eol; /* Yanked a EOL? */
char stuff[SBUFSIZE]; /* The stuff */
};
struct undostack { /* Undo Stack Descriptor */
int blockp, /* block address of core block */
ptr; /* offset within coreblock */
int coreblock[PAGESIZE]; /* core block */
};
union optionrec { /* Black Magic Option Structure */
int valu; /* if integer, the value */
char *strp; /* or if string, a pointer to it */
};
struct macrecord { /* Macro Descriptor */
char token; /* Character mapped */
cmdtype oldmap; /* Old value in movemap */
char *m_text; /* Replacement text */
};
struct tmacro { /* For running a macro */
char *mtext, /* Pointer to macro text */
*ip; /* Pointer into macro text */
int m_iter; /* Number of times to execute */
};
#define V_CONST 1 /* this option cannot be modified */
#define V_DISPLAY 2 /* this option affects the display */
struct variable { /* Settable Variable Record */
char *v_name; /* full name */
char *v_abbr; /* abbreviated name */
int v_tipe; /* what kind of variable */
int v_flags; /* special attributes... */
union optionrec *u; /* pointer to it */
};
#endif /*LEVEE_D*/

View File

@@ -1,955 +0,0 @@
.TH LEVEE 1 "29 August 1998" "Mastodon Linux"
.SH NAME
.B levee
\-
A Screen Oriented Editor.
.SH SYNOPSIS
.B levee
[\fI+address\fR] [\fIfile \fB...\fR]
.SH DESCRIPTION
Levee is a screen oriented editor based on the Unix editor
"vi". It provides a terse, powerful way to enter and edit text
(however, if you want a word-processor, you're better off with
WordStar.)
Levee is a moded editor. It operates in 3 modes -- visual,
command, and insert. Most of the editing work is done is visual
mode, file reading and writing is done in command mode, and
insert mode does what you would expect.
.PP
When you enter Levee, you may specify an address to start
editing at. These addresses are in the same format as command
mode addresses, except that a naked + will put you at the very
end of the file.
.PP
Levee is copyright (c) 1982-2008 by David L. Parsons. (see
the notice at the end of this document for distribution terms)
.SH "COMMAND MODE COMMANDS"
These commands are used for editing new files, writing
modified files, changing options, doing substitutions, and
a subset of the visual commands. They take as input whole
lines, terminated by return (to execute), or escape (to
abort.)
Command mode is reached by typing ":" or "Q" from visual
mode. If you enter command mode by typing ":", Levee will
execute one command, then return to visual mode after
prompting you with "[more]". If you type anything except
a space or return, Levee will accept another command, and so
forth. If, however, you enter command mode via "Q", Levee
will remain in command mode until you enter the "visual"
command.
.SS "A NOTE ON COMMAND SYNTAX"
.PP
A command may be preceded by an optional line-range. If
you do not provide a line-range, Levee will use the default
line-range shown by the command. A line-range is one or two
address specifications in the following format:
.RS
(\fB.\fR|\fB$\fR|\fB'x\fR|\fB#\fR) [ (\fB+\fR|\fB-\fR) (\fB/\fIpatt\fB\fB/\fR|\fB?\fIpatt\fB?\fR|\fB#\fR) ]
.TP
.B \.
current line.
.TP
.B $
last line.
.TP
.B 'x
the line with mark x on it.
.TP
.B #
line #.
.RE
.PP
For example, ".-5,.+5p" will print every line within ten
lines of the current line. "$-5" is the fifth line from the
end of the file, and "/end/+2" is the second line past the
next occurrence of the pattern "end". Patterns may be
regular expressions (see below.)
Also, a naked line-range will set the current line to
the first line in the range and print all the lines in that
range. "1,10" sets the current line to 1, then prints lines
1 to 10.
If you specify a non-existent line in a range, the command
will abort and Levee will tell you "bad address".
.SS "Command mode commands"
.TP
.B args
show the current argument list, if one exists. The file that you
are currently editing will be framed by '[' and ']'.
.TP
.IB (.,.) change
delete lines, then enter insert mode.
.TP
.IB (.,.) delete
delete lines. Deleted lines are stored in a Yank Buffer for
later putback with "put".
.TP
.B "edit[!] [file]"
Discard the current file and start editing a new one. If
changes were made to the current file, you must enter "edit!"
to force Levee to discard the changes. If you do not specify
a filename, Levee will try to reedit the current filename.
When Levee reads in a new file, it will tell you how many
bytes it read in, or [overflow] if the file is larger than the
internal buffer (256000 bytes on most platforms; 20k on USCD
Pascal.)
.TP
.B execmode
Remain in command mode until you use the "visual" command.
.TP
.BI file [name]
Echo what the current filename is, its status, and the current
line. If you provide it with a name, it will change the filename
to that.
.TP
.IB (.) insert
Insert text above the current line. If you specify a line number,
Levee will make that the current line, then insert above it.
.RS
.SS "Insert mode commands"
.TP
.B ^W
back over the last word you entered.
.TP
.B ^H
back over one character.
.TP
.B ^U
back over all input on this line.
.TP
.B ^V
escape the next character typed. (For example,
.B ^V^H
will put a ^H into the file.)
.TP
.B ESC
exit insert mode.
.TP
.B ^D
If at start of line, reduce indentation 'shiftwidth' columns.
.TP
.B ^T
If at start of line, increase indentation 'shiftwidth' columns.
.RE
.PP
When in insert mode, Levee will not allow you to enter any control
characters except return and tab. Return ends input on this line and
opens a new line for input.
.TP
.BI map[!] [key [text]]
Define/list macros. There are 3 forms of map:
.TP
.I map.
This lists all the active macros.
.TP
.IR map (key).
This shows the macro associated with (key), if any.
.TP
.IR map "(key) (text)"
This maps (key) to (text). You may map any
key except ":" and escape. In the normal
form (map), the macro will be effective
in visual mode, but in the alternate form,
(map!), the macro will be effective in
insert and command modes.
.PP
For example, if you map!ped return to "hello world", every time
you entered a return in command or visual mode, the string "hello
world" would pop up.
.TP
.BI next [file ...]
Edit the next file in the arglist, or edit a new arglist. Levee
takes its initial arglist off the command line when you execute it.
If "autowrite" is set, Levee will write out the changes to the
current file before editing the next one.
.TP
.IB (.) open
Insert below the current line. Otherwise just like insert.
.TP
.B previous
Edit the previous file in the arglist. Otherwise, like next.
.TP
.IB (.,.) print
Display lines without changing the current line.
.TP
.IB (.) put
Put the contents of the yank buffer back on the line below
the current line. If you specify a line, it resets the current
line, then puts the yank buffer back. The yank buffer is filled
by the delete, change, or yank commands. Put does not destroy
the yank buffer, so you may put back text multiple times.
.TP
.B quit[!]
Exit Levee. If you want to discard changes, use "quit!"
.TP
.IB (.) read [file]
put the contents of 'file' after the current line.
.TP
.BI rm file
Delete 'file' from disk.
.TP
.BI set [option=value]
Set a tunable variable. Levee has a dozen or so user-definable
variables which you can twiddle via this command. There are boolean,
integer, and string variables that you can set. A string or integer
variable is set by 'set xxx=yyy', a boolean variable is set via
'set xxx' or 'set noxxx'.
Here are the settable variables (and abbreviations):
.TP
.BI tabsize (ts)
tab stop.
.TP
.BI shiftwidth (sw)
columns to shift on ^D, ^T, >>, or <<
.TP
.B scroll
number of lines to scroll on ^D, ^U
.TP
.BI autoindent (ai)
supply indentation during insert mode.
.TP
.BI autowrite (aw)
write out changes before :next, :prev
.TP
.BI autocopy (ac)
make backup copies before writing changes.
.TP
.B list
display tabs as ^I, end of line as $.
.TP
.B magic
use regular expressions in searches.
.TP
.B suffix
if the filename does not have a . in
it, supply the suffix. (this is the
only string variable.)
.TP
.BI overwrite (ow)
destroy old file first, then write.
.TP
.BI beautify (be)
When set, Levee will not allow insert
of any control character except tab
and return unless you escape it with
ctrl-V.
.TP
.B wrapscan
searches wrap around end of buffer.
.TP
.BI ignorecase (ic)
Ignore the case of alphabetic characters
during searches.
.TP
.B "mapslash"
(ST version only) Map '/' in filenames to
'\\'. If the environment contains `mapslash'
when levee is called, this variable will
default to true, otherwise it defaults to
false. (See the documentation for the
Teeny-shell on how the teeny-shell interprets
`mapslash')
.TP
.BI lines (li)
(ST version only) How many lines on the display.
This is primarily for running levee through
the serial port - put set li=xx into your
LVRC for a xx line terminal.
.TP
.BI cols (co)
(ST version only) How many columns on the
display. Like the lines variable, it's for
running levee through the serial port.
.PP
You may set multiple variables on one line, as in 'set ws noai'.
To see the current settings of these variables, :set -- without any
arguments -- will show the current settings.
At startup, Levee looks in the environment variable LVRC for
a list of variables to set (GEMDOS/MS-DOS). LVRC is one line
of the form 'option=value ...'. If you have a LVRC defined that
is 'ts=4 ow nows', Levee will set tabsize to 4, turn on overwrite,
and turn off wrapscan.
If you are using RMX, Levee looks in the file ":home:r?lvrc"
for initialization. If you are using Osy/SWOs, Levee looks in the
file "*.lvrc". The format of these files are different from the
LVRC variable -- see "source" for more information.
.TP
.BI source file
Take command mode commands from 'file'. These commands can be
any legal command, except "visual". If a error happens during
execution of 'file', Levee abandons that level of source'ing.
In Osy/SWOs, there are a few differences in insert mode from
within a sourced file. No character has special meaning except a
line containing nothing but a period, which terminates insert mode.
For example:
.RS
:commands
.br
.
.br
.
.br
:insert
.br
blah blah blah blah blah blah
.br
blah blah blah blah blah blah
.br
blah blah blah blah blah blah
.br
.
.br
:more commands
.RE
If you are running Levee under any other operating system,
you cannot do a insert from a :source file.
.TP
.B (.,.)substitute(delim)patt(delim)repl(delim)[qcpg]
.TP
.B (.,.)substitute&
Search for patt and replace it with repl. Levee will look for
patt once on each line and replace it with repl. The delimiter
may be any ascii character.
The pattern is a regular expression, just like a search pattern.
You may include parts of the pattern in the replacement string;
A '&' in the replacement pattern copies in the whole source pattern,
so if you do a 'sub/this/& and that/g', every instance of 'this'
will be replaced with 'this and that'. Also, you may pull parts of
the pattern out by using the \\( and \\) argument meta-characters.
Arguments gotten by \\( & \\) are put into the replacement string
everywhere you do a \\1..\\9 [ \\1 is the first argument you set up
with \\( & \\) ]. So, if you want to reverse the order of two substrings,
you can do 'sub/\\(string1\\)\\(string2\\)/\\2\\1/'.
substitute& redoes the last substitution.
Options:
.TP
.B q,c
before doing the substitute, display the affected
line and wait for you to type a character. If you
type 'y', it will do the substitution. 'q' aborts
the substitute, 'a' does the rest of the change
without prompting, and 'n' does not do it.
.TP
.B p
print the affected lines after the change.
.TP
.B g
do the change globally. That is, do it for every
occurence of patt on a line, rather than just
once.
.PP
.TP
.B undo
Undo the last modification to the file (except :edit, :next, :rm,
or :write.) You can only undo the last change to a file -- undo counts
as a change. :undo followed by :undo does nothing to the file.
.TP
.BI unmap (key)
Undefine a macro (see map).
.TP
.BI visual [list]
If you entered command mode by "Q" or "execmode", return to
visual mode. If you provide an argument list, it also does a
`:next' on that list.
.TP
.B version
Show which version of levee this is.
.TP
.IB (.,.) "write \fI[file]"
Write lines to a file. If you write the everything to 'file',
the filename is set to 'file', and if you do not specify a file,
Levee will write to the filename.
.TP
.IB (.,.) "wq \fI[file]"
Write to a file, then quit.
.TP
.IB (.,.) yank
Yank lines from the file into the yank buffer, for later
putback with "put".
.TP
.B xit[!]
Write changes to the current file, then exit. If there are
more files in the arglist, use "xit!"
.TP
.B ![command]
Execute command.
Example:
.RS
!ls => does a 'ls'.
.RE
This command is available only under GEMDOS, MSDOS, RMX, and
Unix.
.TP
.B ($)=
Give the line number of the addressed line. /end/= gives you
the line number of the next line with a 'end' on it.
.SH "VISUAL MODE COMMANDS"
Visual mode commands move you around and modify the file.
There are movement commands to move the cursor by a variety of
objects.
In the description, a (#) means a optional count. If a
command has a optional count, it will tell you what the count
does in parenthesis. A (*) means that the command can be used
in the delete, yank, and change commands.
Counts are made up by entering digits. If you type '45',
the count will be set to 45. To cancel a count, type ESC.
This section discusses 'whitespace' occasionally.
Whitespace is tabs, spaces, and end of line.
.SS "How the display works"
Characters are displayed on the screen as you would
expect, except that nonprinting characters are shown as ^x,
and tabs expand to spaces ( unless you set the option list,
then they show as ^I.) When sitting on a control character or
tab, the cursor is placed on the FIRST character displayed. If
you move the cursor to any other part of them ( via j or k --
see below), any changes will start at the next character.
Levee does not display a end of file marker, but lines
past the end of the file are denoted by ~ lines.
If list is set, tabs display as ^I, and the end of line
displays as $.
If a line is too long for the screen, it will just disappear off the end of the screen.
Levee will handle any screen resolution and any monospaced
font you hand it ( if you are running in low resolution, Levee
will give you a 25x40 window, for example.)
.SS "Visual mode commands"
.TP
.B ^A
Show a debugging message at the bottom of the screen. This is not at
all useful unless you are debugging the editor. Ignore it.
.TP
.B (#)^D
Scroll the screen down a half screen. If a count is specified, scroll
down the specified number of lines.
.TP
.B ^E
Scroll down 1 line (shorthand for 1^D )
.TP
.B ^G
Show file statistics. Exactly like ':file'.
.TP
.IB (*) (#)^H
Move the cursor left one (count) chars.
.TP
.B ^I
Redraw the screen.
.TP
.IB (*) (#)^J
Move down one (count) lines. When you use ^J and ^K (below) to move
up or down lines, the cursor will remain in the same column, even if
it is in the middle of a tabstop or past the end of a line.
.TP
.IB (*) (#)^K
Move up one (count) lines.
.TP
.IB (*) (#)^L
Move right one (count) characters.
.TP
.IB (*) (#)^M
Move to the first nonwhite space on the next line. If a count is specified,
move to the first nonwhite count lines down.
.TP
.B (#)^U
Scroll the screen up a half page. If a count is specified, scroll up
count lines.
.TP
.B ^Y
Scroll the screen up 1 line (shorthand for 1^U.)
.TP
.B (#)a
Insert text AFTER the cursor. If you give a count, the insertion will
be repeated count times ( 40i-ESC will give you a line of 40 dashes).
The commands in insert mode are the same for visual and command mode.
.TP
.IB (*) (#)b
Move to the beginning of the last word (the count'th word back).
A word is a collection of alphanumeric characters (a-z0-9$_#) or
any other nonwhite character (i.e. anything but space, tab, eoln).
.TP
.B c
Change a object. Change deletes an object, then enters insert mode without
redrawing the screen. When you tell it the object to be changed, Levee
puts a '$' on the last character of the object. You cannot change
backwards.
The object may be any visual mode command marked with a '(*) '. For
example, 'c4l' will change the next 4 characters on the line to something
else. (4cl does the same thing -- 4c4l changes the next 16 characters on
this line.)
'cc' will change whole lines.
When changing, deleting, or yanking a object, it will be placed into
a yank buffer, where it can be retrieved by the 'p' or 'P' commands.
.TP
.B (#)d
Delete an object. Like 'cc', 'dd' affects whole lines.
.TP
.IB (*) (#)e
Move to the end of the current word.
.TP
.IB (*) (#)f(x)
Find the next (count'th) occurance of a character on the current line.
For example, if the cursor is sitting on the first character of the
line 'abcdef', typing "ff" will put the cursor on the 'f'.
.TP
.IB (*) (#)h
Move left one (count) characters. Exactly like ^H.
.TP
.B (#)i
Start inserting characters at the cursor. If you specify a count,
the insertion will be duplicated count times.
.TP
.IB (*) (#)j
Move down one (count) lines. Exactly like ^J.
.TP
.IB (*) (#)k
Move up one (count) lines. Exactly like ^K.
.TP
,B (*) (#)l
Move right one (count) character. Exactly like ^L.
.TP
.B m(x)
Set the marker (x). There are 26 markers available (a-z). You may
move to a marker by use of the ' or ` commands.
.TP
.IB (*) n
Find the next occurance of a search pattern. When you do a search with
a / or ? command, Levee will remember the pattern and the direction you
searched in. 'n' will search in the same direction for the pattern, 'N'
searches in the opposite direction.
.TP
.B o
Open a line below the current line for insertion.
.TP
.B p
Put yanked/deleted text back after the cursor. Text is yanked
by the delete (d,x,X,D), change (c,C,s,S), and yank (y,Y) commands.
.TP
.B (#)r(x)
Replace characters (up to end of line) with (x). '4ra' will change the
next 4 characters after the cursor into 'aaaa'.
.TP
.B (#)s
change one (count) characters. Shorthand for (#)cl.
.TP
.IB (*) (#)t(x)
Move up to a character on the current line. If you are on the first
character of the line 'abcdef' and you type 'tf', you will end up sitting
on the 'e'.
.TP
.B u
Undo last modification. You can undo ANY modification command except
:edit, :next, :rm, or :write. (Just like :undo).
.TP
.IB (*) (#)v
Move back to the very end of the previous (count'th) word.
See 'b' for the definition of a word.
.TP
.IB (*) (#)w
Move up to the very beginning of the next (count'th) word.
.TP
.B (#)x
Delete one (count) characters forward. Shorthand for (#)dl.
.TP
.B y
Yank an object for later use by put. 'yy' yanks whole lines.
.TP
.B A
Append text at the end of the line. Shorthand for $a.
.TP
.IB (*) (#)B
Move to the beginning of the current word. Exactly like 'b'.
.B NOTE:
this is incorrect. the capitalized word movement commands should,
and will in the future, be used for movement by space-delimited words.
.TP
.B C
Change to the end of the line. Shorthand for c$.
.TP
.B D
Delete to the end of the line. Shorthand for d$.
.TP
.IB (*) (#)F(x)
Move to the first (count'th) previous occurance of a character on the
current line. If you are sitting at the end of the line 'abcdef', typing
"Fa" will move you back to the 'a' at the start of the line.
.TP
.IB (*) (#)G
Goto line. If you specify a count, Levee will move to that line, and if
there is no count, Levee moves to the absolute end of the file.
To get to the start of the file, type "1G". To the end, just "G".
.TP
.IB (*) H
Move to the first nonwhite character at the top of the screen.
.TP
.B I
Insert at the end of the current line. Shorthand for $i.
.TP
.B (#)J
Join two (count+1) lines together. Joining appends the second line at
the end of the first, putting a space between them. If the first line
ends in whitespace, Levee will not put in a space.
.TP
.IB (*) L
Move to the last nonwhite character on the last line of the screen.
.TP
.IB (*) M
Move to the first nonwhite character in the middle of the screen.
.TP
.B O
Open a line above the current line. Otherwise works just like 'o'.
.TP
.B P
Put back the yank buffer at the cursor. Otherwise works just like 'p'.
.TP
.B Q
Enter and remain in command mode. Just like the command :exec. To get
back to visual mode, you must enter the command ':visual'.
.TP
.B R
Replace mode. A limited subset of insert mode that overwrites characters
up to end of line. All of the normal insert mode commands apply.
If you overwrite a character, then back over it with ^H,^U, or ^W, it
will reappear after you exit Replace mode.
Escape exits replace mode.
.B NOTE:
due to a bug, entering a <return> in Replace mode will drop you
back into visual mode with an error. The replacements you have made
will remain.
.TP
.B S
Change characters backwards. Shorthand for (#)ch.
.TP
.IB (*) (#)T(x)
Move back to character on current line. If you are on the last character
of the line 'abcdef', typing "Ta" will move you back to the 'b'.
.TP
.IB (*) (#)W
Move to end of word. Exactly like 'e'.
.TP
.B (#)X
Delete characters backwards. Shorthand for (#)dh.
.TP
.B Y
Yank to end of line. Shorthand for y$.
.TP
.B ZZ
Write changes to current file and exit if last file in arglist.
Exactly like :xit.
.TP
.IB (*) (#)$
Move to end of line. If you give a count, move to the end of the (count-1)
line down (so 2$ moves you to the end of the next line.).
.TP
.B 0
Move to the beginning of the current line. Shorthand for 0|.
.TP
.B (#)!
Pipe an object through an external program. Like 'cc', '!!' affects whole lines.
.TP
.IB (*) %
Find matching bracket, parenthesis, or squiggly bracket. If you are not
sitting on a '[]{}()', Levee will search forward for one of them on the
current line, then match whatever it finds.
.TP
.B [space]
Move to the first nonwhite character on the current line.
.TP
.B &
Redo last substitution command.
.TP
.IB (*) (#){
Move to the beginning of the count'th paragraph back. A paragraph is
delimited by a blank line.
.TP
.IB (*) (#)}
Move to the end of the count'th paragraph forward.
.TP
.IB (*) (#)(
Move to the beginning of the count'th sentence back. A sentence is
delimited by a ., a !, or a ? followed by a space, a tab, or end of line.
.TP
.IB (*) (#))
Move to the end of the count'th sentence forward.
.TP
.IB (*) (#)-
Move to the (count'th) previous line, first nonwhite.
.TP
.IB (*) (#)+
Move to the (count'th) next line, first nonwhite.
.TP
.B (#)~
Change the case of the next count characters. Upper case becomes lowercase,
lowercase becomes uppercase.
.TP
.IB (*) `(x)
Move to the exact position of mark (x). There is a special mark for some
of the visual mode move ment commands -- '' will move you to where you
were before the last (,),',`,G,/,?,n,N command.
.TP
.B :
Execute one command mode command. When the command is done, it will return
to visual mode if it produces one line of output, but if it scrolls the
screen, Levee will prompt [more] before returning to visual mode. If you
type a : in response to the [more] prompt, Levee will remain in command
mode for one more command.
.TP
.B (#)<(#)
Shift one (count) objects left. If you specify a second count, Levee will
shift the object left that many columns -- if you do not, they will be sh
shifted shiftwidth columns.
This is a nondestructive shift. If the shift would carry past the left
margin, the objects will be moved up to the left margin but no farther.
Like the other object movement commands, '<<' will affect whole lines.
.TP
.B (#)>(#)
Shift one (count) objects right. Just like <, except it will not shift
objects past the right margin of the screen. If you do shift an object
past the right margin of the screen, all of its indent will be removed
and it will end up by the left margin.
.TP
.B \.
Repeat last modification command. (except undo)
.TP
.IB (*) ?
Search for pattern backwards. Escape aborts the search pattern, and a
empty pattern means search for the last pattern again.
.TP
.IB (*) /
Search for pattern forwards. Otherwise like ?.
.TP
.B (#)|
Move to specified column. If you don't have a count, move to column 0.
.SH "REGULAR EXPRESSIONS"
Levee gives special meanings to some characters during
a pattern match. The character "." will match any one char,
the character "*" will match zero or more occurances of the
previous char ( so, a* will match 'a','aa','aaa', etc, or it
will match nothing at all). If a pattern begins with "^", it
will only match at the beginning of a line, and patterns
ending with a "$" will only match at the end of a line.
Brackets ('[]') have special meaning as well. They mean
match any one of the characters inside the brackets. '[abc]'
will match 'a', 'b', or 'c'. You may specify a range of
characters inside brackets by using a dash (-). '[a-z]' will
match any lowercase alphabetic character. If ^ is the first
character in the bracket, it means match any character
except those in the brackets. '[^abc]' will match anything
except 'a','b', or 'c'.
Backslash takes away special meaning for these chars,
but '\\t' specifies a tab, and \\( & \\) delimit arguments
inside a pattern (used only by :substitute.) The patterns
\\< and \\> have special meaning, too; they match the start
and end of alpha-numeric tokens.
If you turn off the editor variable 'magic', none of
the above characters will have special meaning inside of
a pattern (see 'set').
Some example patterns:
.TP
.B ^end$
Find a line that is just 'end'.
.TP
.B [Ee][Nn][Dd]
Find a 'end', ignoring case.
.TP
.B [A-Za-z][A-Za-z0-9]*
Find the next identifier.
.TP
.B (\\*.*\\*)
Find the next one-line pascal comment.
.TP
.B \<the\>
Find the next occurance of `the'.
.SH LIMITATIONS
Levee can only edit files up to 256000 characters long. ^M is used
as its internal line separator, so inserting ^M will have interesting
consequences.
.SH BUGS
Probably infinite.
.SH AUTHOR
.B "David L. Parsons"
.I (orc@pell.chi.il.us)
.br
Testing, suggestions, and impractical design goals by:
Jim Bolland. John Tainter. John Plocher.
.SH COPYRIGHT
Copyright (c) 1982-2007 David L Parsons
.br
All rights reserved.
.br
Redistribution and use in source and binary forms, without or
without modification, are permitted provided that the above
copyright notice and this paragraph are duplicated in all such
forms and that any documentation, advertising materials, and
other materials related to such distribution and use acknowledge
that the software was developed by David L Parsons (orc@pell.chi.il.us).
My name may not be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
PURPOSE.

Some files were not shown because too many files have changed in this diff Show More