30 Commits

Author SHA1 Message Date
Matt Jenkins
5da189ad36 Changed %2 to %s in string format 2014-04-19 13:37:15 +01:00
Matt Jenkins
de9ae5c603 Merge branch 'master' into double_precision 2014-04-19 12:42:19 +01:00
Matt Jenkins
9cf1805a1d Added double precision test programs 2014-04-19 10:31:33 +01:00
Matt Jenkins
4e2777e9fb Added double precision test programs 2014-04-19 10:31:25 +01:00
Matt Jenkins
6316b05ec3 Added gccdump.s to gitignore 2014-04-19 10:26:30 +01:00
Matt Jenkins
738874016f Merge github.com:igor-m/retrobsd-1 into double_precision 2014-04-19 10:04:52 +01:00
igor-m
6ce8e28a85 Fix of 16byte stack alignment, doprnt.c does not require va_arg fix now 2014-04-19 09:50:04 +02:00
igor-m
4783836659 New SPI IOCTL modi - R,W,RB,WB,RWB 2014-04-17 19:49:40 +02:00
igor-m
249b5716bb Original spi.c and spi.h 2014-04-17 01:17:06 +02:00
igor-m
1d1151403b Revert "Added comment to spi.c"
This reverts commit 28aae2c427.
2014-04-17 01:06:49 +02:00
igor-m
54a771c6f0 Revert "Added comment to spi.c"
This reverts commit 28aae2c427.
2014-04-17 00:53:24 +02:00
igor-m
eddfd51e51 Fix of vaarg alignment addr calc 2014-04-17 00:14:41 +02:00
igor-m
d9033fbf2d target.mk back with -fno-short-double 2014-04-17 00:07:00 +02:00
igor-m
28aae2c427 Added comment to spi.c 2014-04-16 15:24:09 +02:00
igor-m
6d689c335c Added SPI modes R,W,RB,WB,RWB 2014-04-16 15:03:35 +02:00
igor-m
bad98ad239 Single -fno-short-double in target.mk 2014-04-14 13:30:22 +02:00
igor-m
c04495837f Fix of the vaarg fix 2014-04-13 09:34:13 +02:00
igor-m
297b14aa0c Fixes with aliasing - using ieee.h 2014-04-12 13:39:05 +02:00
igor-m
190aa1e633 Fixes with aliasing 2014-04-12 12:51:40 +02:00
igor-m
0220852a66 Fix of va_arg aliasing in doprnt.c 2014-04-12 01:25:31 +02:00
igor-m
2afff6f8aa Fix to doprnt.c and moded modff, modf etc 2014-04-12 01:14:47 +02:00
igor-m
5b1496e5c3 Fix6 2014-04-11 22:55:29 +02:00
igor-m
bcff791a3c Fix5 2014-04-11 22:45:22 +02:00
igor-m
98d034efe1 Fix4 2014-04-11 22:24:56 +02:00
igor-m
0f6e23c2fe Fix 3 2014-04-11 21:55:53 +02:00
igor-m
af3db0bcd2 Another attempt to fix isinff.c, grrh 2014-04-11 21:51:23 +02:00
igor-m
b73ccfb9dc Attempt to fix isinff.c 2014-04-11 21:23:23 +02:00
igor-m
c31e4fa1e8 Was within untracked files ?? 2014-04-11 20:13:51 +02:00
igor-m
16e7b63b48 Fix the Double Precision changes 2014-04-11 19:35:55 +02:00
igor-m
16214d4557 Double Precision Floating Math implementation 2014-04-11 13:36:20 +02:00
1159 changed files with 14503 additions and 153905 deletions

149
Makefile
View File

@@ -12,7 +12,6 @@
# Supported boards
#
MAX32 = sys/pic32/max32/MAX32
MAX32-ETH = sys/pic32/max32-eth/MAX32-ETH
UBW32 = sys/pic32/ubw32/UBW32
UBW32UART = sys/pic32/ubw32-uart/UBW32-UART
UBW32UARTSDRAM = sys/pic32/ubw32-uart-sdram/UBW32-UART-SDRAM
@@ -24,23 +23,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 +59,107 @@ 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 \
$(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 +173,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
installflash:
sudo pic32prog sys/pic32/fubarino/unix.hex
# TODO: make it relative to Target
installboot:
sudo pic32prog sys/pic32/fubarino/bootloader.hex
installboot:
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:
@@ -48,11 +40,12 @@ TARGET = $(MAXCOLOR) # for the Colour Maximite board
TARGET = $(EXPLORER16) # for the Explorer 16 board
TARGET = $(STARTERKIT) # for the PIC32 USB or Ethernet Starter Kit
TARGET = $(MAX32) # default
TARGET = $(MAX32-ETH) # for the chipKIT MAX32 board with Arduino Ethernet shield
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 +64,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 +75,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).
@@ -96,7 +89,7 @@ on a board used.
#### Max32 board:
```shell
$ cd sys/pic32/ubw32
$ AVRTOOLS=/Applications/Mpide.app/Contents/Resources/Java/hardware/tools/avr
$ AVRTOOLS=/Applications/Mpide.app/Contents/Resources/Java/hardware/tools
$AVRTOOLS/bin/avrdude -C$AVRTOOLS/etc/avrdude.conf -c stk500v2 -p pic32 \
-P /dev/tty.usbserial-* -b 115200 -v -U flash:w:unix.hex:i
```
@@ -160,3 +153,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
```

2
cross.mk Normal file → Executable file
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

@@ -33,7 +33,29 @@
#ifndef _AOUT_H_
#define _AOUT_H_
#include <sys/exec_aout.h>
#include <sys/exec.h>
/* Valid magic number check. */
#define N_BADMAG(x) (((x).a_magic) != RMAGIC && \
((x).a_magic) != OMAGIC && \
((x).a_magic) != NMAGIC)
/* Text segment offset. */
#define N_TXTOFF(x) sizeof(struct exec)
/* Data segment offset. */
#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
/* Text relocation table offset. */
#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
/* Data relocation table offset. */
#define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_reltext)
/* Symbol table offset. */
#define N_SYMOFF(x) ((x).a_magic == RMAGIC ? \
N_DRELOFF(x) + (x).a_reldata : \
N_DATOFF(x) + (x).a_data)
#define _AOUT_INCLUDE_
#include <nlist.h>

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.

47
include/ieee.h Normal file
View File

@@ -0,0 +1,47 @@
typedef union // LITTLE ENDIAN
{
double value;
struct
{
unsigned long lsw;
unsigned long msw;
} parts;
} ieee_double_shape_type;
/* Get two 32 bit ints from a double. */
#define EXTRACT_WORDS(ix0,ix1,d) \
do { \
ieee_double_shape_type ew_u; \
ew_u.value = (d); \
(ix0) = ew_u.parts.msw; \
(ix1) = ew_u.parts.lsw; \
} while (0)
/* Get the more significant 32 bit int from a double. */
#define GET_HIGH_WORD(i,d) \
do { \
ieee_double_shape_type gh_u; \
gh_u.value = (d); \
(i) = gh_u.parts.msw; \
} while (0)
/* Set a double from two 32 bit ints. */
#define INSERT_WORDS(d,ix0,ix1) \
do { \
ieee_double_shape_type iw_u; \
iw_u.parts.msw = (ix0); \
iw_u.parts.lsw = (ix1); \
(d) = iw_u.value; \
} while (0)
#define SET_HIGH_WORD(d,v) \
do { \
ieee_double_shape_type sh_u; \
sh_u.value = (d); \
sh_u.parts.msw = (v); \
(d) = sh_u.value; \
} while (0)

View File

@@ -12,8 +12,9 @@ extern double sinh(), cosh(), tanh();
extern double gamma();
extern double j0(), j1(), jn(), y0(), y1(), yn();
#define HUGE 1.701411733192644270e38
#define LOGHUGE 39
// ###PITO #define HUGE 1.701411733192644270e38
#define HUGE 1.79769313486231570000e+308
#define LOGHUGE 307
int isnanf(float x);
int isnan(double x);

View File

@@ -4,49 +4,32 @@
#ifndef _STDARG_H
#define _STDARG_H
/*
* Define va_start, va_arg, va_end, va_copy.
*/
#if defined(__GNUC__) /* Gnu C */
# define va_start(ap, last) __builtin_va_start((ap), last)
# define va_arg(ap, type) __builtin_va_arg((ap), type)
# define va_end(ap) __builtin_va_end((ap))
# define va_copy(dest, src) __builtin_va_copy((dest), (src))
/* Define __gnuc_va_list. */
#elif defined(__PCC__) /* PCC */
# define va_start(ap, last) __builtin_stdarg_start((ap), last)
# define va_arg(ap, type) __builtin_va_arg((ap), type)
# define va_end(ap) __builtin_va_end((ap))
# define va_copy(dest, src) __builtin_va_copy((dest), (src))
#else /* SmallerC, LCC */
# define va_start(ap, last) (ap = ((char*)&(last) + \
(((sizeof(last) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))))
# define va_arg(ap, type) ((type*)(ap += \
sizeof(type) == sizeof(int) ? sizeof(type) : \
(-(int)(ap) & (sizeof(type) - 1)) + sizeof(type)))[-1]
# define va_end(ap)
# define va_copy(dest, src) (dest = (src))
#ifdef __GNUC__
# ifndef __GNUC_VA_LIST
# define __GNUC_VA_LIST
typedef __builtin_va_list __gnuc_va_list;
# endif
# define va_start(ap, last) __builtin_va_start((ap), last)
#endif
#ifdef __PCC__
# define va_start(ap, last) __builtin_stdarg_start((ap), last)
#endif
#define va_arg(ap, type) __builtin_va_arg((ap), type)
#define va_end(ap) __builtin_va_end((ap))
#define va_copy(dest, src) __builtin_va_copy((dest), (src))
/*
* Define va_list.
*/
#ifndef _VA_LIST_T
# define _VA_LIST_T
# if defined(__GNUC__) || defined(__PCC__)
#ifndef _VA_LIST
#define _VA_LIST
#ifdef __GNUC__
typedef __builtin_va_list va_list;
# else
typedef char *va_list;
# endif
#endif
/*
* Define __gnuc_va_list.
*/
#if defined(__GNUC__) && !defined(__GNUC_VA_LIST)
# define __GNUC_VA_LIST
typedef __builtin_va_list __gnuc_va_list;
#ifdef __SMALLER_C__
typedef int *va_list;
#endif
#endif
#endif /* not _STDARG_H */

View File

@@ -110,12 +110,7 @@ int scanf (const char *, ...);
int sscanf (const char *, const char *, ...);
#ifndef _VA_LIST_
# ifdef __GNUC__
# define va_list __builtin_va_list /* For Gnu C */
# endif
# ifdef __SMALLER_C__
# define va_list char * /* For Smaller C */
# endif
#define va_list __builtin_va_list /* For GCC */
#endif
int vfprintf (FILE *, const char *, va_list);
@@ -131,7 +126,7 @@ int _doprnt (const char *, va_list, FILE *);
int _doscan (FILE *, const char *, va_list);
#ifndef _VA_LIST_
# undef va_list
#undef va_list
#endif
void perror (const char *);

View File

@@ -54,51 +54,49 @@
#define RAND_MAX 0x7fff
void abort (void);
void abort();
int abs (int);
int atexit (void (*)(void));
int atoi (const char *);
long atol (const char *);
double atof();
int atoi();
long atol();
void *calloc (size_t, size_t);
void exit (int);
void free (void *);
char *getenv (const char *);
char *getenv();
long labs (long);
void *malloc (size_t);
char *mktemp (char *);
int mkstemp (char *);
void qsort (void *, size_t, size_t, int (*)(const void *, const void *));
int rand (void);
void qsort();
int rand();
void *realloc (void*, size_t);
void srand (unsigned);
long strtol (const char *, char **, int);
unsigned long strtoul (const char *, char **, int);
int system (const char *);
void srand();
double strtod();
long strtol();
unsigned long strtoul();
int system();
int putenv (char *string);
int setenv (const char *name, const char *value, int overwrite);
int unsetenv (const char *name);
char *_findenv (const char *name, int *offset);
void *alloca (size_t size);
void *alloca();
int daemon (int, int);
char *devname (dev_t dev, mode_t type);
int getloadavg (unsigned loadavg[], int nelem);
int daemon();
char *devname();
int getloadavg(unsigned loadavg[], int nelem);
extern char *suboptarg; /* getsubopt(3) external variable */
int getsubopt (char **, char **, char **);
int getsubopt();
long random (void);
char *setstate (char *);
void srandom (unsigned);
#ifndef __SMALLER_C__
double atof (const char *);
double strtod (const char *, char **);
char *ecvt (double, int, int *, int *);
char *fcvt (double, int, int *, int *);
char *gcvt (double, int, char *);
#endif
char *ecvt (double, int, int *, int *);
char *fcvt (double, int, int *, int *);
char *gcvt (double, int, char *);
#endif /* _STDLIB_H_ */

View File

@@ -143,12 +143,7 @@ extern char *optarg; /* getopt(3) external variables */
extern int opterr, optind, optopt;
#ifndef _VA_LIST_
# ifdef __GNUC__
# define va_list __builtin_va_list /* For Gnu C */
# endif
# ifdef __SMALLER_C__
# define va_list char * /* For Smaller C */
# endif
#define va_list __builtin_va_list /* For GCC */
#endif
void err (int eval, const char *fmt, ...);
@@ -161,6 +156,6 @@ void vwarn (const char *fmt, va_list ap);
void vwarnx (const char *fmt, va_list ap);
#ifndef _VA_LIST_
# undef va_list
#undef va_list
#endif
#endif /* !_UNISTD_H_ */

5
lib/Makefile Normal file → Executable file
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
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 *.dis *~

View File

@@ -5,13 +5,13 @@ CFLAGS += -Werror
ASFLAGS += -DCROSS
ASLDFLAGS = --oformat=elf32-tradlittlemips -N -nostartfiles -T $(TOPSRC)/src/elf32-mips.ld
all: chello cplus echo stdarg
all: hello cplus
chello: chello.o
${CC} ${LDFLAGS} -o chello.elf chello.o ${LIBS}
${OBJDUMP} -S chello.elf > chello.dis
${SIZE} chello.elf
${ELF2AOUT} chello.elf $@
hello: hello.o
${CC} ${LDFLAGS} -o hello.elf hello.o ${LIBS}
${OBJDUMP} -S hello.elf > hello.dis
${SIZE} hello.elf
${ELF2AOUT} hello.elf $@
cplus: cplus.o
${CXX} ${LDFLAGS} -nostdlib -o cplus.elf cplus.o ${LIBS}
@@ -24,6 +24,7 @@ echo: echo.o
${OBJDUMP} -S $@.elf > $@.dis
${SIZE} $@.elf
${ELF2AOUT} $@.elf $@
./aout $@ > $@.dis
clean:
rm -f *.o *.elf ${MAN} chello cplus echo stdarg *.elf *.dis tags *~
rm -f *.o *.elf ${MAN} hello cplus *.elf *.dis tags *~

View File

@@ -2,6 +2,6 @@
int main()
{
printf ("Hello, C World!\n");
return 0;
printf ("Hello, C World!\n");
return 0;
}

View File

@@ -1,92 +0,0 @@
/*
* Generic skeleton for a C program.
* When you create your own program based on this skeleton,
* you can replace the author's name and copyright with
* whatever your want. When you redistribute this skeleton or
* enhance it, please leave my name and copyright on it.
*
* Copyright (C) 1993-2014 Serge Vakulenko, <vak@cronyx.ru>
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for any purpose and without fee is hereby
* granted, provided that the above copyright notice appear in all
* copies and that both that the copyright notice and this
* permission notice and warranty disclaimer appear in supporting
* documentation, and that the name of the author not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
*
* The author disclaim 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, 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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
const char version[] = "1.0";
const char copyright[] = "Copyright (C) 1993-2014 Serge Vakulenko";
char *progname; /* Name of the current program (argv[0]) */
int verbose; /* Option -v */
int trace; /* Option -t */
int debug; /* Option -d */
void usage ()
{
fprintf (stderr, "Generic C skeleton, Version %s, %s\n", version, copyright);
fprintf (stderr, "Usage:\n\t%s [-vtd] [-r count] file...\n", progname);
fprintf (stderr, "Options:\n");
fprintf (stderr, "\t-v\tverbose mode\n");
fprintf (stderr, "\t-t\ttrace mode\n");
fprintf (stderr, "\t-d\tdebug\n");
fprintf (stderr, "\t-r #\trepeat count\n");
exit (-1);
}
int main (int argc, char **argv)
{
int count = 1; /* Option -r # */
progname = *argv;
for (;;) {
switch (getopt (argc, argv, "vtdr:")) {
case EOF:
break;
case 'v':
++verbose;
continue;
case 't':
++trace;
continue;
case 'd':
++debug;
continue;
case 'r':
count = strtol (optarg, 0, 0);
continue;
default:
usage ();
}
break;
}
argc -= optind;
argv += optind;
if (argc < 1)
usage ();
while (count-- > 0) {
int i;
for (i=0; i<argc; ++i)
printf ("%s ", argv[i]);
printf ("\n");
}
return (0);
}

View File

@@ -1,34 +0,0 @@
#include <stdio.h>
#include <stdarg.h>
void print(char *fmt, ...)
{
va_list ap;
int d;
char c, *s;
va_start(ap, fmt);
while (*fmt) {
switch (*fmt++) {
case 's': /* string */
s = va_arg(ap, char*);
printf("string %s\n", s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("int %d\n", d);
break;
case 'c': /* char */
c = va_arg(ap, int);
printf("char %c\n", c);
break;
}
}
va_end(ap);
}
int main()
{
print("sdcsdc", "abracadabra", 12345, 'Z', "foo", 365, '%');
return 0;
}

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)

57
src/cmd/9degree/9degree.c Normal file
View File

@@ -0,0 +1,57 @@
#include <stdio.h>
#include <math.h>
#include <sys/time.h>
void print64x( double x ) {
char* p;
int j;
p = (char *) &x;
for( j=0; j< sizeof(x); j++) {
printf("%02X", p[(sizeof(x)-1)-j]&0xFF);
}
}
void print32x( float x ) {
char* p;
int j;
p = (char *) &x;
for( j=0; j< sizeof(x); j++) {
printf("%02X", p[(sizeof(x)-1)-j]&0xFF);
}
}
int main() {
struct timeval start, stop;
volatile double _p64, q64, r64, e64;
long i;
unsigned long elapsed;
_p64 = 3.1415926535897932384626433832795;
for(i=0;i<100;i++) {
// 64bit test
// 9 degree test input
q64 = i;
// Convert to radians
q64 = q64 * _p64 / 180.0;
// Make the test
gettimeofday(&start, NULL);
r64 = (asin(acos(atan(tan(cos(sin(q64)))))));
gettimeofday(&stop, NULL);
// Convert to degree
r64 = r64 * 180.0 / _p64;
elapsed = stop.tv_usec - start.tv_usec;
printf("%ld degree 64bit test result= %1.15e time= %lu " , i, r64, elapsed );
printf("= 0x");
print64x( r64 );
printf("\n");
}
return 0;
}

1
src/cmd/9degree/Makefile Symbolic link
View File

@@ -0,0 +1 @@
../generic.mk

View File

@@ -10,14 +10,14 @@ 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 \
zmodem gtest msec unixbench cron compress date2 tip \
talloc devupdate uucp smux
talloc devupdate uucp smux 9degree mathtest scantest
# /sbin
SUBDIR += chown chroot disktool fsck getty init \

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

@@ -55,7 +55,7 @@ int fgethdr (text, h)
register FILE *text;
register struct exec *h;
{
h->a_midmag = fgetword (text);
h->a_magic = fgetword (text);
h->a_text = fgetword (text);
h->a_data = fgetword (text);
h->a_bss = fgetword (text);
@@ -235,7 +235,7 @@ void disasm (fname)
return;
}
if (rflag) {
if (N_GETMAGIC(hdr) != RMAGIC) {
if (hdr.a_magic != RMAGIC) {
fprintf (stderr, "aout: %s is not relocatable\n",
fname);
rflag = 0;
@@ -250,9 +250,9 @@ void disasm (fname)
}
printf ("File %s:\n", fname);
printf (" a_magic = %08x (%s)\n", hdr.a_magic,
N_GETMAGIC(hdr) == RMAGIC ? "relocatable" :
N_GETMAGIC(hdr) == OMAGIC ? "OMAGIC" :
N_GETMAGIC(hdr) == NMAGIC ? "NMAGIC" : "unknown");
hdr.a_magic == RMAGIC ? "relocatable" :
hdr.a_magic == OMAGIC ? "OMAGIC" :
hdr.a_magic == NMAGIC ? "NMAGIC" : "unknown");
printf (" a_text = %08x (%u bytes)\n", hdr.a_text, hdr.a_text);
printf (" a_data = %08x (%u bytes)\n", hdr.a_data, hdr.a_data);
printf (" a_bss = %08x (%u bytes)\n", hdr.a_bss, hdr.a_bss);
@@ -261,7 +261,7 @@ void disasm (fname)
printf (" a_syms = %08x (%u bytes)\n", hdr.a_syms, hdr.a_syms);
printf (" a_entry = %08x\n", hdr.a_entry);
addr = ((hdr.a_magic) == RMAGIC) ? 0 : USER_CODE_START;
addr = (hdr.a_magic == RMAGIC) ? 0 : USER_CODE_START;
if (hdr.a_text > 0) {
printf ("\nSection .text:\n");

View File

@@ -83,7 +83,6 @@ enum {
LIDENT, /* .ident */
LWEAK, /* .weak */
LLOCAL, /* .local */
LNAN, /* .nan */
};
/*
@@ -216,8 +215,7 @@ const struct optable optable [] = {
{ 0x04110000, "bal", FAOFF18 | FDSLOT },
{ 0x10000000, "beq", FRS1 | FRT2 | FOFF18 | FDSLOT },
{ 0x50000000, "beql", FRS1 | FRT2 | FOFF18 | FDSLOT },
{ 0x10000000, "beqz", FRS1 | FOFF18 | FDSLOT },
{ 0x50000000, "beqzl", FRS1 | FOFF18 | FDSLOT },
{ 0x50000000, "beqz", FRS1 | FOFF18 | FDSLOT },
{ 0x04010000, "bgez", FRS1 | FOFF18 | FDSLOT },
{ 0x04110000, "bgezal", FRS1 | FOFF18 | FDSLOT },
{ 0x04130000, "bgezall", FRS1 | FOFF18 | FDSLOT },
@@ -232,8 +230,7 @@ const struct optable optable [] = {
{ 0x04020000, "bltzl", FRS1 | FOFF18 | FDSLOT },
{ 0x14000000, "bne", FRS1 | FRT2 | FOFF18 | FDSLOT },
{ 0x54000000, "bnel", FRS1 | FRT2 | FOFF18 | FDSLOT },
{ 0x14000000, "bnez", FRS1 | FOFF18 | FDSLOT },
{ 0x54000000, "bnezl", FRS1 | FOFF18 | FDSLOT },
{ 0x54000000, "bnez", FRS1 | FOFF18 | FDSLOT },
{ 0x0000000d, "break", FCODE16 },
{ 0x70000021, "clo", FRD1 | FRS2 | FRTD | FMOD },
{ 0x70000020, "clz", FRD1 | FRS2 | FRTD | FMOD },
@@ -375,7 +372,7 @@ int mode_reorder = 1; /* .set reorder option (default) */
int mode_macro; /* .set macro option */
int mode_mips16; /* .set mips16 option */
int mode_micromips; /* .set micromips option */
int mode_at = 1; /* .set at option */
int mode_at; /* .set at option */
int reorder_full; /* instruction buffered for reorder */
unsigned reorder_word; /* buffered instruction... */
unsigned reorder_clobber; /* ...modified this register */
@@ -734,9 +731,6 @@ int lookacmd ()
case 'm':
if (! strcmp (".mask", name)) return (LMASK);
break;
case 'n':
if (! strcmp (".nan", name)) return (LNAN);
break;
case 'p':
if (! strcmp (".previous", name)) return (LPREVIOUS);
break;
@@ -1244,7 +1238,7 @@ void emitword (w, r, clobber_reg)
reorder_word = w;
reorder_rel = *r;
reorder_full = 1;
reorder_clobber = clobber_reg & 15;
reorder_clobber = clobber_reg;
} else {
fputword (w, sfile[segm]);
fputrel (r, rfile[segm]);
@@ -1273,9 +1267,6 @@ void emit_li (opcode, relinfo)
} else if (value >= -0x8000) {
/* addiu d, $zero, value */
opcode |= 0x24000000 | (value & 0xffff);
} else if ((value & 0xffff) == 0) {
/* lui d, value[31:16] */
opcode |= 0x3c000000 | (value >> 16);
} else {
/* lui d, value[31:16]
* ori d, d, value[15:0]) */
@@ -1326,9 +1317,10 @@ void makecmd (opcode, type, emitfunc)
unsigned opcode;
void (*emitfunc) (unsigned, struct reloc*);
{
unsigned offset, orig_opcode = 0;
register int clex;
register unsigned offset;
struct reloc relinfo;
int clex, cval, segment, clobber_reg, negate_literal;
int cval, segment, clobber_reg, negate_literal;
offset = 0;
relinfo.flags = RABS;
@@ -1488,7 +1480,6 @@ frs1: clex = getlex (&cval);
cval = (opcode >> 11) & 31; /* get 1-st register */
newop |= cval << 16; /* set 1-st register */
newop |= opcode & (31 << 21); /* set 2-nd register */
orig_opcode = opcode;
opcode = newop;
type = FRT1 | FRS2 | FOFF16 | FMOD;
goto foff16;
@@ -1581,79 +1572,33 @@ fsa: offset = getexpr (&segment);
}
} else if (type & (FOFF16 | FOFF18 | FAOFF18 | FAOFF28 | FHIGH16)) {
/* Relocatable offset */
int valid_range;
if ((type & (FOFF16 | FOFF18 | FHIGH16)) && getlex (&cval) != ',')
uerror ("comma expected");
foff16: expr_flags = 0;
offset = getexpr (&segment);
relinfo.flags = segmrel [segment];
if (negate_literal) {
// Negate literal arg for sub and subu
offset = -offset;
if (relinfo.flags != RABS)
uerror ("cannot negate relocatable literal");
}
if (relinfo.flags == REXT)
relinfo.index = extref;
if (expr_flags & EXPR_GPREL)
relinfo.flags |= RGPREL;
switch (type & (FOFF16 | FOFF18 | FAOFF18 | FAOFF28 | FHIGH16)) {
case FOFF16: /* low 16-bit byte address */
/* Test whether the immediate is in valid range
* for the opcode. */
if (negate_literal) {
// Negate literal arg for sub and subu
offset = -offset;
if (relinfo.flags != RABS)
uerror ("cannot negate relocatable literal");
}
switch (opcode & 0xfc000000) {
default: /* addi, addiu, slti, sltiu, lw, sw */
/* 16-bit signed value. */
valid_range = (offset >= -0x8000) || (offset <= 0x7fff);
break;
case 0x30000000: /* andi */
case 0x34000000: /* ori */
case 0x38000000: /* xori */
/* 16-bit unsigned value. */
valid_range = (offset <= 0xffff);
break;
}
if (valid_range) {
opcode |= offset & 0xffff;
} else if (orig_opcode == 0 || ! mode_at) {
uerror ("value out of range");
} else {
/* Convert back to 3-reg opcode.
* Insert an extra LI instruction. */
if (segment != SABS)
uerror ("absolute value required");
if (negate_literal)
offset = -offset;
if (offset <= 0xffff) {
/* ori $1, $zero, value */
emitword (0x34010000 | offset, &relabs, 1);
} else if (offset >= -0x8000) {
/* addiu $1, $zero, value */
emitword (0x24010000 | (offset & 0xffff), &relabs, 1);
} else if ((offset & 0xffff) == 0) {
/* lui $1, value[31:16] */
emitword (0x3c010000 | (offset >> 16), &relabs, 1);
} else {
/* lui $1, value[31:16]
* ori $1, $1, value[15:0]) */
emitword (0x3c010000 | (offset >> 16), &relabs, 1);
emitword (0x34210000 | (offset & 0xffff), &relabs, 1);
}
opcode = orig_opcode | 0x10000;
}
opcode |= offset & 0xffff;
break;
case FHIGH16: /* high 16-bit byte address */
if (expr_flags & EXPR_HI) {
if (relinfo.flags != RABS) {
/* %hi function - assume signed offset */
relinfo.flags |= RHIGH16S;
relinfo.flags |= (expr_flags & EXPR_HI) ? RHIGH16S : RHIGH16;
relinfo.offset = offset & 0xffff;
offset += 0x8000;
opcode |= offset >> 16;
} else {
opcode |= offset & 0xffff;
}
opcode |= offset >> 16;
break;
case FOFF18: /* 18-bit PC-relative word address */
case FAOFF18:
@@ -2166,7 +2111,7 @@ void pass1 ()
}
break;
case LCOMM:
/* .comm name,len[,alignment] */
/* .comm name,len */
if (getlex (&cval) != LNAME)
uerror ("bad parameter of .comm");
cval = lookname();
@@ -2210,7 +2155,7 @@ void pass1 ()
case LSECTION:
/* .section name[,"flags"[,type[,entsize]]] */
clex = getlex (&cval);
if (clex != LNAME && clex != LBSS && clex != LTEXT && clex != LDATA)
if (clex != LNAME && clex != LBSS)
uerror ("bad name of .section");
setsection();
clex = getlex (&cval);
@@ -2218,12 +2163,7 @@ void pass1 ()
ungetlex (clex, cval);
break;
}
clex = getlex (&cval);
if (clex == '"') {
ungetlex (clex, cval);
skipstring();
} else if (clex != LNAME)
uerror ("bad type of .section");
skipstring();
clex = getlex (&cval);
if (clex != ',') {
ungetlex (clex, cval);
@@ -2270,12 +2210,6 @@ void pass1 ()
uerror ("bad parameter of .end");
cval = lookname();
break;
case LNAN:
/* .nan name */
clex = getlex (&cval);
if (clex != LNAME)
uerror ("bad parameter of .nan");
break;
case LTYPE:
/* .type name,type */
if (getlex (&cval) != LNAME)
@@ -2377,28 +2311,18 @@ int findlabel (int addr, int sym)
void middle ()
{
register int i, snum, nbytes;
register int i, snum;
stlength = 0;
for (snum=0, i=0; i<stabfree; i++) {
switch (stab[i].n_type) {
case N_UNDF:
/* Without -u option, undefined symbol is considered external */
/* Without -u option, undefined symbol is considered external */
if (stab[i].n_type == N_UNDF) {
if (uflag)
uerror ("name undefined", stab[i].n_name);
stab[i].n_type |= N_EXT;
break;
case N_COMM:
/* Allocate a local common block */
nbytes = stab[i].n_value;
stab[i].n_value = count[SBSS];
stab[i].n_type = N_BSS;
count[SBSS] += nbytes;
break;
}
if (xflags)
newindex[i] = snum;
if (! xflags || (stab[i].n_type & N_EXT) ||
(Xflag && ! IS_LOCAL(&stab[i])))
{
@@ -2415,7 +2339,7 @@ void makeheader (rtsize, rdsize)
{
struct exec hdr;
hdr.a_midmag = RMAGIC;
hdr.a_magic = RMAGIC;
hdr.a_text = count [STEXT];
hdr.a_data = count [SDATA] + count [SSTRNG];
hdr.a_bss = count [SBSS];
@@ -2735,12 +2659,8 @@ int main (argc, argv)
break;
case 'I': /* include dir */
// TODO
if (cp[1] == 0) {
i++;
} else {
while (*++cp);
--cp;
}
while (*++cp);
--cp;
break;
case 'O': /* optimization level */
// TODO

View File

@@ -226,7 +226,7 @@ RDHWR Read Hardware Register Allows unprivileged acce
RDPGPR Read GPR from Previous Shadow Set Rt = SGPR[SRSCtl.PSS, Rd]
RESTORE Restore registers and deallocate stack See Architecture Reference Manual
frame (MIPS16e only)
frame (MIPS16eª only)
ROTR Rotate Word Right Rd = Rt[sa-1..0] || Rt[31..sa]

View File

@@ -1534,7 +1534,7 @@ int get_value()
value = get_num();
else {
++cmdptr;
switch ((int)c) {
switch (c) {
case '(': /* nesting */
value = eval_sub();
break;

View File

@@ -26,4 +26,4 @@ clean:
install: all
install cc $(DESTDIR)/bin/
install cc $(DESTDIR)/bin/scc
install cc $(DESTDIR)/bin/lcc
install cc $(DESTDIR)/bin/srcc

View File

@@ -449,16 +449,17 @@ main(int argc, char *argv[])
pass0 = LIBEXECDIR "/smallc";
incdir = STDINC "/smallc";
} else if (strcmp ("lcc", progname) == 0) {
/* LCC: retargetable C compiler. */
mode = MODE_LCC;
cppadd[0] = "-D__LCC__";
pass0 = LIBEXECDIR "/lccom";
} else {
} else if (strcmp ("srcc", progname) == 0) {
/* Smaller C. */
mode = MODE_SMALLERC;
cppadd[0] = "-D__SMALLER_C__";
pass0 = LIBEXECDIR "/smlrc";
incdir = STDINC "/smallerc";
} else {
/* LCC: retargetable C compiler. */
mode = MODE_LCC;
cppadd[0] = "-D__LCC__";
pass0 = LIBEXECDIR "/lccom";
}
if (argc == 1)

View File

@@ -3,15 +3,14 @@ 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
MAN = cpp.0
MANSRC = cpp.1
LDFLAGS += -g
CFLAGS += -Werror -Wall -Os
#CFLAGS += -DCPP_DEBUG -DGCC_COMPAT -DHAVE_CPP_VARARG_MACRO_GCC
CFLAGS += -DGCC_COMPAT -DHAVE_CPP_VARARG_MACRO_GCC
CFLAGS += -DCPP_DEBUG -DGCC_COMPAT -DHAVE_CPP_VARARG_MACRO_GCC
all: cpp $(MAN)
@@ -25,13 +24,13 @@ $(MAN): ${MANSRC}
${MANROFF} $< > $@
clean:
rm -f *.o *.0 *.elf cpp *.dis tags *~ lex.yy.c y.tab.[ch] tests/run*
rm -f *.o *.0 *.elf cpp *.elf *.dis tags *~ lex.yy.c y.tab.[ch] tests/run*
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) $<
@@ -42,29 +41,23 @@ cpy.o y.tab.h: cpy.y
$(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS) -c -o cpy.o y.tab.c
test:
./cpp < tests/test1 > tests/run1
./cpp.elf < tests/test1 > tests/run1
cmp tests/run1 tests/res1
./cpp < tests/test2 > tests/run2
./cpp.elf < tests/test2 > tests/run2
cmp tests/run2 tests/res2
./cpp < tests/test3 > tests/run3
./cpp.elf < tests/test3 > tests/run3
cmp tests/run3 tests/res3
./cpp < tests/test4 > tests/run4
./cpp.elf < tests/test4 > tests/run4
cmp tests/run4 tests/res4
./cpp < tests/test5 > tests/run5
./cpp.elf < tests/test5 > tests/run5
cmp tests/run5 tests/res5
./cpp < tests/test6 > tests/run6
./cpp.elf < tests/test6 > tests/run6
cmp tests/run6 tests/res6
./cpp < tests/test7 > tests/run7
./cpp.elf < tests/test7 > tests/run7
cmp tests/run7 tests/res7
./cpp < tests/test8 > tests/run8
./cpp.elf < tests/test8 > tests/run8
cmp tests/run8 tests/res8
./cpp < tests/test9 > tests/run9
./cpp.elf < tests/test9 > tests/run9
cmp tests/run9 tests/res9
./cpp < tests/test10 > tests/run10
./cpp.elf < 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 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,16 +128,16 @@ 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 *);
uchar *sheap(const char *fmt, ...);
void xwarning(uchar *);
void xerror(uchar *);
#ifdef HAVE_CPP_VARARG_MACRO_GCC
#define warning(...) xwarning(sheap(__VA_ARGS__))
#define error(...) xerror(sheap(__VA_ARGS__))
@@ -182,5 +145,6 @@ void xerror(usch *);
#define warning printf
#define error printf
#endif
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,203 +0,0 @@
/*
Copyright (c) 2013, Alexey Frunze
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.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
int _doprnt (char const *fmt, va_list pp, FILE *stream)
{
int cnt = 0;
const char* p;
const char* phex = "0123456789abcdef";
char s[1/*sign*/+10/*magnitude*/+1/*\0*/]; // up to 11 octal digits in 32-bit numbers
char* pc;
int n, sign, msign;
int minlen = 0, len;
int leadchar;
for (p = fmt; *p != '\0'; p++)
{
if (*p != '%' || p[1] == '%')
{
fputc(*p, stream);
p = p + (*p == '%');
cnt++;
continue;
}
p++;
minlen = 0;
msign = 0;
if (*p == '+') { msign = 1; p++; }
else if (*p == '-') { msign = -1; p++; }
leadchar = ' ';
if (*p >= '0' && *p <= '9')
{
if (*p == '0')
leadchar = '0';
while (*p >= '0' && *p <= '9')
minlen = minlen * 10 + *p++ - '0';
if (msign < 0)
minlen = -minlen;
msign = 0;
}
if (!msign)
{
if (*p == '+') { msign = 1; p++; }
else if (*p == '-') { msign = -1; p++; }
}
switch (*p)
{
case 'c':
while (minlen > 1) { fputc(' ', stream); cnt++; minlen--; }
fputc(va_arg(pp, int), stream);
while (-minlen > 1) { fputc(' ', stream); cnt++; minlen++; }
cnt++;
break;
case 's':
pc = va_arg(pp, char*);
len = 0;
if (pc)
len = strlen(pc);
while (minlen > len) { fputc(' ', stream); cnt++; minlen--; }
if (len)
while (*pc != '\0')
{
fputc(*pc++, stream);
cnt++;
}
while (-minlen > len) { fputc(' ', stream); cnt++; minlen++; }
break;
case 'i':
case 'd':
pc = &s[sizeof s - 1];
*pc = '\0';
len = 0;
n = va_arg(pp, int);
sign = 1 - 2 * (n < 0);
do
{
*--pc = '0' + (n - n / 10 * 10) * sign;
n = n / 10;
len++;
} while (n);
if (sign < 0)
{
*--pc = '-';
len++;
}
else if (msign > 0)
{
*--pc = '+';
len++;
msign = 0;
}
while (minlen > len) { fputc(leadchar, stream); cnt++; minlen--; }
while (*pc != '\0')
{
fputc(*pc++, stream);
cnt++;
}
while (-minlen > len) { fputc(' ', stream); cnt++; minlen++; }
break;
case 'u':
pc = &s[sizeof s - 1];
*pc = '\0';
len = 0;
n = va_arg(pp, int);
do
{
unsigned nn = n;
*--pc = '0' + nn % 10;
n = nn / 10;
len++;
} while (n);
if (msign > 0)
{
*--pc = '+';
len++;
msign = 0;
}
while (minlen > len) { fputc(leadchar, stream); cnt++; minlen--; }
while (*pc != '\0')
{
fputc(*pc++, stream);
cnt++;
}
while (-minlen > len) { fputc(' ', stream); cnt++; minlen++; }
break;
case 'X':
phex = "0123456789ABCDEF";
// fallthrough
case 'p':
case 'x':
pc = &s[sizeof s - 1];
*pc = '\0';
len = 0;
n = va_arg(pp, int);
do
{
*--pc = phex[n & 0xF];
n = (n >> 4) & ((1 << (8 * sizeof n - 4)) - 1); // drop sign-extended bits
len++;
} while (n);
while (minlen > len) { fputc(leadchar, stream); cnt++; minlen--; }
while (*pc != '\0')
{
fputc(*pc++, stream);
cnt++;
}
while (-minlen > len) { fputc(' ', stream); cnt++; minlen++; }
break;
case 'o':
pc = &s[sizeof s - 1];
*pc = '\0';
len = 0;
n = va_arg(pp, int);
do
{
*--pc = '0' + (n & 7);
n = (n >> 3) & ((1 << (8 * sizeof n - 3)) - 1); // drop sign-extended bits
len++;
} while (n);
while (minlen > len) { fputc(leadchar, stream); cnt++; minlen--; }
while (*pc != '\0')
{
fputc(*pc++, stream);
cnt++;
}
while (-minlen > len) { fputc(' ', stream); cnt++; minlen++; }
break;
default:
return -1;
}
}
return cnt;
}

View File

@@ -1,6 +1,4 @@
%{
/* $Id: scanner.l,v 1.49 2009/02/14 09:23:55 ragge Exp $ */
/*
* Copyright (c) 2004 Anders Magnusson. All rights reserved.
*
@@ -26,15 +24,10 @@
* (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>
@@ -45,7 +38,7 @@
%{
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);
@@ -93,7 +86,7 @@ yyinput(char *b, int m)
#ifdef HAVE_CPP_VARARG_MACRO_GCC
#define fprintf(x, ...) error(__VA_ARGS__)
#endif
#define ECHO putstr((usch *)yytext)
#define ECHO putstr((uchar *)yytext)
#undef fileno
#define fileno(x) 0
@@ -115,7 +108,7 @@ int yylex_destroy (void);
#define input() inch()
#define unput(ch) unch(ch)
#endif
#define PRTOUT(x) if (YYSTATE || slow) return x; if (!flslvl) putstr((usch *)yytext);
#define PRTOUT(x) if (YYSTATE || slow) return x; if (!flslvl) putstr((uchar *)yytext);
/* protection against recursion in #include */
#define MAX_INCLEVEL 100
static int inclevel;
@@ -176,7 +169,7 @@ WS [\t ]
yylval.node.op = NUMBER;
if (gotdef) {
yylval.node.nd_val
= lookup((usch *)yytext, FIND) != 0;
= lookup((uchar *)yytext, FIND) != 0;
gotdef = 0;
return IDENT;
}
@@ -192,7 +185,7 @@ WS [\t ]
}
0[xX]{H}+{IS}? { scale = 16;
num: if (YYSTATE == IFR)
num: if (YYSTATE == IFR)
cvtdig(scale);
PRTOUT(NUMBER);
}
@@ -201,13 +194,13 @@ WS [\t ]
'(\\.|[^\\'])+' {
if (YYSTATE || slow) {
yylval.node.op = NUMBER;
yylval.node.nd_val = charcon((usch *)yytext);
yylval.node.nd_val = charcon((uchar *)yytext);
return (NUMBER);
}
if (tflag)
yyless(1);
if (!flslvl)
putstr((usch *)yytext);
putstr((uchar *)yytext);
}
<IFR>. { return yytext[0]; }
@@ -243,7 +236,7 @@ WS [\t ]
"//".*$ { /* if (tflag) yyless(..) */
if (Cflag && !flslvl && !slow)
putstr((usch *)yytext);
putstr((uchar *)yytext);
else if (!flslvl)
putch(' ');
}
@@ -255,7 +248,7 @@ WS [\t ]
return CMNT;
if (prtcm)
putstr((usch *)yytext);
putstr((uchar *)yytext);
wrn = 0;
more: while ((c = input()) && c != '*') {
if (c == '\n')
@@ -308,12 +301,12 @@ L?\"(\\.|[^\\"])*\" { PRTOUT(STRING); }
if (flslvl) {
; /* do nothing */
} else if (isdigit((int)yytext[0]) == 0 &&
(nl = lookup((usch *)yytext, FIND)) != 0) {
usch *op = stringbuf;
(nl = lookup((uchar *)yytext, FIND)) != 0) {
uchar *op = stringbuf;
putstr(gotident(nl));
stringbuf = op;
} else
putstr((usch *)yytext);
putstr((uchar *)yytext);
xx: ;
}
@@ -329,8 +322,8 @@ L?\"(\\.|[^\\"])*\" { PRTOUT(STRING); }
if (YYSTATE || slow)
return yytext[0];
if (yytext[0] == 6) { /* PRAGS */
usch *obp = stringbuf;
extern usch *prtprag(usch *);
uchar *obp = stringbuf;
extern uchar *prtprag(uchar *);
*stringbuf++ = yytext[0];
do {
*stringbuf = input();
@@ -345,7 +338,7 @@ L?\"(\\.|[^\\"])*\" { PRTOUT(STRING); }
%%
usch *yyp, yybuf[CPPBUF];
uchar *yyp, yybuf[CPPBUF];
int yylex(void);
int yywrap(void);
@@ -458,7 +451,7 @@ prinit(struct initar *it, struct includ *ic)
* Return 0 on success, -1 if file to be included is not found.
*/
int
pushfile(usch *file)
pushfile(uchar *file)
{
extern struct initar *initar;
struct includ ibuf;
@@ -477,7 +470,7 @@ pushfile(usch *file)
error("Limit for nested includes exceeded");
} else {
ic->infil = 0;
ic->orgfn = ic->fname = (usch *)"<stdin>";
ic->orgfn = ic->fname = (uchar *)"<stdin>";
}
ic->buffer = ic->bbuf+NAMEMAX;
ic->curptr = ic->buffer;
@@ -513,7 +506,7 @@ pushfile(usch *file)
void
prtline()
{
usch *s, *os = stringbuf;
uchar *s, *os = stringbuf;
if (Mflag) {
if (dMflag)
@@ -586,7 +579,7 @@ cvtdig(int rad)
}
static int
charcon(usch *p)
charcon(uchar *p)
{
int val, c;
@@ -671,8 +664,8 @@ elsestmt(void)
}
static void
ifdefstmt(void)
{
ifdefstmt(void)
{
int t;
if (flslvl) {
@@ -691,7 +684,7 @@ ifdefstmt(void)
if (t != IDENT)
error("bad ifdef");
slow = 0;
if (flslvl == 0 && lookup((usch *)yytext, FIND) != 0)
if (flslvl == 0 && lookup((uchar *)yytext, FIND) != 0)
trulvl++;
else
flslvl++;
@@ -699,8 +692,8 @@ ifdefstmt(void)
}
static void
ifndefstmt(void)
{
ifndefstmt(void)
{
int t;
slow = 1;
@@ -710,7 +703,7 @@ ifndefstmt(void)
if (t != IDENT)
error("bad ifndef");
slow = 0;
if (flslvl == 0 && lookup((usch *)yytext, FIND) == 0)
if (flslvl == 0 && lookup((uchar *)yytext, FIND) == 0)
trulvl++;
else
flslvl++;
@@ -718,7 +711,7 @@ ifndefstmt(void)
}
static void
endifstmt(void)
endifstmt(void)
{
if (flslvl) {
flslvl--;
@@ -736,13 +729,13 @@ endifstmt(void)
/*
* Note! Ugly!
* Walk over the string s and search for defined, and replace it with
* spaces and a 1 or 0.
* Walk over the string s and search for defined, and replace it with
* spaces and a 1 or 0.
*/
static void
fixdefined(usch *s)
fixdefined(uchar *s)
{
usch *bc, oc;
uchar *bc, oc;
for (; *s; s++) {
if (*s != 'd')
@@ -785,14 +778,14 @@ fixdefined(usch *s)
static void
storepb(void)
{
usch *opb = stringbuf;
uchar *opb = stringbuf;
int c;
while ((c = input()) != '\n') {
if (c == '/') {
if ((c = input()) == '*') {
/* ignore comments here whatsoever */
usch *g = stringbuf;
uchar *g = stringbuf;
getcmnt();
stringbuf = g;
continue;
@@ -860,11 +853,11 @@ elifstmt(void)
error("If-less elif");
}
static usch *
static uchar *
svinp(void)
{
int c;
usch *cp = stringbuf;
uchar *cp = stringbuf;
while ((c = input()) && c != '\n')
savch(c);
@@ -877,7 +870,7 @@ svinp(void)
static void
cpperror(void)
{
usch *cp;
uchar *cp;
int c;
if (flslvl)
@@ -900,7 +893,7 @@ undefstmt(void)
slow = 1;
if (yylex() != WSPACE || yylex() != IDENT)
error("bad undef");
if (flslvl == 0 && (np = lookup((usch *)yytext, FIND)))
if (flslvl == 0 && (np = lookup((uchar *)yytext, FIND)))
np->value = 0;
slow = 0;
chknl(0);
@@ -915,7 +908,7 @@ pragmastmt(void)
if (yylex() != WSPACE)
error("bad pragma");
if (!flslvl)
putstr((usch *)"#pragma ");
putstr((uchar *)"#pragma ");
do {
c = input();
if (!flslvl)

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,28 @@ 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)
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 +792,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 +806,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 +819,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 +838,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 +871,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 +898,7 @@ cvtdig(int rad)
}
static int
charcon(usch *p)
charcon(uchar *p)
{
int val, c;
@@ -1020,8 +991,8 @@ skpln(void)
}
static void
ifdefstmt(void)
{
ifdefstmt(void)
{
int t;
if (flslvl) {
@@ -1033,7 +1004,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 +1013,8 @@ ifdefstmt(void)
}
static void
ifndefstmt(void)
{
ifndefstmt(void)
{
int t;
if (flslvl) {
@@ -1055,7 +1026,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 +1035,7 @@ ifndefstmt(void)
}
static void
endifstmt(void)
endifstmt(void)
{
if (flslvl) {
flslvl--;
@@ -1121,11 +1092,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 +1108,7 @@ svinp(void)
static void
cpperror(void)
{
usch *cp;
uchar *cp;
int c;
if (flslvl)
@@ -1155,7 +1126,7 @@ cpperror(void)
static void
cppwarning(void)
{
usch *cp;
uchar *cp;
int c;
if (flslvl)
@@ -1185,7 +1156,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 +1169,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 +1263,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}

31
src/cmd/generic.mk Normal file
View File

@@ -0,0 +1,31 @@
#==========================================
# Makefile: makefile for adc-demo
# Copyright 2012 Majenko Technolohies
# (matt@majenko.co.uk
# Last Modified: 29/01/2012
#==========================================
TOPSRC = $(shell cd ../../..; pwd)
include $(TOPSRC)/target.mk
PWD = $(shell pwd)
PROG = $(shell basename "$(PWD)")
OBJS = $(PROG).o
SRCS = $(PROG).c
all: $(PROG)
-include Makefile.app
$(PROG): ${OBJS}
${CC} ${LDFLAGS} -o $(PROG).elf ${OBJS} ${LIBS}
${OBJDUMP} -S $(PROG).elf > $(PROG).dis
${SIZE} $(PROG).elf
${ELF2AOUT} $(PROG).elf $@
clean:
-rm -f $(PROG) ${OBJS} $(PROG).elf $(PROG).dis
install: all
install $(PROG) $(DESTDIR)/bin/

View File

@@ -61,7 +61,7 @@ $Binits.o: inits.c; $(CC) $(CFLAGS) -c -I. -o $@ $<
$Binput.o: input.c; $(CC) $(CFLAGS) -c -I. -o $@ $<
$Blex.o: lex.c; $(CC) $(CFLAGS) -c -I. -o $@ $<
$Blist.o: list.c; $(CC) $(CFLAGS) -c -I. -o $@ $<
$Bmain.o: main.c; $(CC) $(CFLAGS) -DVERSION=\"$(VERSION)\" -c -I. -o $@ $<
$Bmain.o: main.c; $(CC) $(CFLAGS) -DVERSION=\"`svnversion`\" -c -I. -o $@ $<
$Bnull.o: null.c; $(CC) $(CFLAGS) -c -I. -o $@ $<
$Boutput.o: output.c; $(CC) $(CFLAGS) -c -I. -o $@ $<
$Bprof.o: prof.c; $(CC) $(CFLAGS) -c -I. -o $@ $<

View File

@@ -172,7 +172,7 @@ int fgethdr (text, h)
register FILE *text;
register struct exec *h;
{
h->a_midmag = fgetword (text);
h->a_magic = fgetword (text);
h->a_text = fgetword (text);
h->a_data = fgetword (text);
h->a_bss = fgetword (text);
@@ -860,7 +860,7 @@ void readhdr (loc)
fseek (text, loc, 0);
if (! fgethdr (text, &filhdr))
error (2, "bad format");
if (N_GETMAGIC(filhdr) != RMAGIC)
if (filhdr.a_magic != RMAGIC)
error (2, "bad magic");
if (filhdr.a_text % W)
error (2, "bad length of text");
@@ -880,7 +880,7 @@ int load1 (loc, libflg, nloc)
int savindex, ndef, type, symlen, nsymbol;
readhdr (loc);
if (N_GETMAGIC(filhdr) != RMAGIC) {
if (filhdr.a_magic != RMAGIC) {
error (1, "file not relocatable");
return (0);
}
@@ -1293,7 +1293,7 @@ void setupout ()
} else {
close(fd);
}
tcreat (&toutb, 1);
tcreat (&doutb, 1);
@@ -1494,7 +1494,7 @@ void finishout ()
while (ssize++ % W)
putc (0, outb);
}
filhdr.a_midmag = output_relinfo ? RMAGIC : OMAGIC;
filhdr.a_magic = output_relinfo ? RMAGIC : OMAGIC;
filhdr.a_text = tsize;
filhdr.a_data = dsize;
filhdr.a_bss = bsize;

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

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