Subject: rc on unix, part 2

From: Geoff Collyer <[email-masked]>
Date: Thu, 18 Dec 2003 22:23:21 -0800

These are the include files I used to emulate plan 9's include
files on Unix (APE).

# To unbundle, run this file
mkdir include
echo include/bio.h
sed 's/^X//' >include/bio.h <<'!'
X#ifndef _BIOH_
X#define _BIOH_ 1

X#include <sys/types.h>	/* for off_t */
X#include <fcntl.h>	/* for O_RDONLY, O_WRONLY */

typedef	struct	Biobuf	Biobuf;

enum
X{
X	Bsize		= 8*1024,
X	Bungetsize	= 4,		/* space for ungetc */
X	Bmagic		= 0x314159,
X	Beof		= -1,
X	Bbad		= -2,

X	Binactive	= 0,		/* states */
X	Bractive,
X	Bwactive,
X	Bracteof,

X	Bend
X};

struct	Biobuf
X{
X	int	icount;		/* neg num of bytes at eob */
X	int	ocount;		/* num of bytes at bob */
X	int	rdline;		/* num of bytes after rdline */
X	int	runesize;		/* num of bytes of last getrune */
X	int	state;		/* r/w/inactive */
X	int	fid;		/* open file */
X	int	flag;		/* magic if malloc'ed */
X	off_t	offset;		/* offset of buffer in file */
X	int	bsize;		/* size of buffer */
X	unsigned char*	bbuf;		/* pointer to beginning of buffer */
X	unsigned char*	ebuf;		/* pointer to end of buffer */
X	unsigned char*	gbuf;		/* pointer to good data in buf */
X	unsigned char	b[Bungetsize+Bsize];
X};

X#define	BGETC(bp)\
X	((bp)->icount?(bp)->bbuf[(bp)->bsize+(bp)->icount++]:Bgetc((bp)))
X#define	BPUTC(bp,c)\
X	((bp)->ocount?(bp)->bbuf[(bp)->bsize+(bp)->ocount++]=(c),0:Bputc((bp),(c)))
X#define	BOFFSET(bp)\
X	(((bp)->state==Bractive)?\
X		(bp)->offset + (bp)->icount:\
X	(((bp)->state==Bwactive)?\
X		(bp)->offset + ((bp)->bsize + (bp)->ocount):\
X		-1))
X#define	BLINELEN(bp)\
X	(bp)->rdline
X#define	BFILDES(bp)\
X	(bp)->fid

int	Bbuffered(Biobuf*);
int	Bfildes(Biobuf*);
int	Bflush(Biobuf*);
int	Bgetc(Biobuf*);
int	Bgetd(Biobuf*, double*);
int	Binit(Biobuf*, int, int);
int	Binits(Biobuf*, int, int, unsigned char*, int);
int	Blinelen(Biobuf*);
off_t	Boffset(Biobuf*);
Biobuf*	Bopen(char*, int);
int	Bprint(Biobuf*, char*, ...);
int	Bputc(Biobuf*, int);
void*	Brdline(Biobuf*, int);
long	Bread(Biobuf*, void*, long);
off_t	Bseek(Biobuf*, off_t, int);
int	Bterm(Biobuf*);
int	Bungetc(Biobuf*);
long	Bwrite(Biobuf*, void*, long);

long	Bgetrune(Biobuf*);
int	Bputrune(Biobuf*, long);
int	Bungetrune(Biobuf*);

X#endif
!
echo include/fmt.h
sed 's/^X//' >include/fmt.h <<'!'

X/*
X * The authors of this software are Rob Pike and Ken Thompson.
X *              Copyright (c) 2002 by Lucent Technologies.
X * Permission to use, copy, modify, and distribute this software for any
X * purpose without fee is hereby granted, provided that this entire notice
X * is included in all copies of any software which is or includes a copy
X * or modification of this software and in all copies of the supporting
X * documentation for such software.
X * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
X * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES MAKE ANY
X * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
X * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
X */

X#ifndef _FMTH_
X#define _FMTH_ 1

X#include <stdarg.h>

X#ifndef _UTFH_
X#include <utf.h>
X#endif

typedef struct Fmt	Fmt;
struct Fmt{
X	unsigned char	runes;		/* output buffer is runes or chars? */
X	void	*start;			/* of buffer */
X	void	*to;			/* current place in the buffer */
X	void	*stop;			/* end of the buffer; overwritten if flush fails */
X	int	(*flush)(Fmt *);	/* called when to == stop */
X	void	*farg;			/* to make flush a closure */
X	int	nfmt;			/* num chars formatted so far */
X	va_list	args;			/* args passed to dofmt */
X	int	r;			/* % format Rune */
X	int	width;
X	int	prec;
X	unsigned long	flags;
X};

enum{
X	FmtWidth	= 1,
X	FmtLeft		= FmtWidth << 1,
X	FmtPrec		= FmtLeft << 1,
X	FmtSharp	= FmtPrec << 1,
X	FmtSpace	= FmtSharp << 1,
X	FmtSign		= FmtSpace << 1,
X	FmtZero		= FmtSign << 1,
X	FmtUnsigned	= FmtZero << 1,
X	FmtShort	= FmtUnsigned << 1,
X	FmtLong		= FmtShort << 1,
X	FmtVLong	= FmtLong << 1,
X	FmtComma	= FmtVLong << 1,
X	FmtByte		= FmtComma << 1,
X	FmtLDouble	= FmtByte << 1,

X	FmtFlag		= FmtLDouble << 1
X};

extern	int	print(char*, ...);
extern	char*	seprint(char*, char*, char*, ...);
extern	char*	vseprint(char*, char*, char*, va_list);
extern	int	snprint(char*, int, char*, ...);
extern	int	vsnprint(char*, int, char*, va_list);
extern	char*	smprint(char*, ...);
extern	char*	vsmprint(char*, va_list);
extern	int	sprint(char*, char*, ...);
extern	int	fprint(int, char*, ...);
extern	int	vfprint(int, char*, va_list);

extern	int	runesprint(Rune*, char*, ...);
extern	int	runesnprint(Rune*, int, char*, ...);
extern	int	runevsnprint(Rune*, int, char*, va_list);
extern	Rune*	runeseprint(Rune*, Rune*, char*, ...);
extern	Rune*	runevseprint(Rune*, Rune*, char*, va_list);
extern	Rune*	runesmprint(char*, ...);
extern	Rune*	runevsmprint(char*, va_list);

extern	int	fmtfdinit(Fmt*, int, char*, int);
extern	int	fmtfdflush(Fmt*);
extern	int	fmtstrinit(Fmt*);
extern	char*	fmtstrflush(Fmt*);

extern	int	quotestrfmt(Fmt *f);
extern	void	quotefmtinstall(void);
extern	int	(*fmtdoquote)(int);

extern	int	fmtinstall(int, int (*)(Fmt*));
extern	int	dofmt(Fmt*, char*);
extern	int	fmtprint(Fmt*, char*, ...);
extern	int	fmtvprint(Fmt*, char*, va_list);
extern	int	fmtrune(Fmt*, int);
extern	int	fmtstrcpy(Fmt*, char*);

extern	double	fmtstrtod(const char *, char **);
extern	double	fmtcharstod(int(*)(void*), void*);

X#endif
!
echo include/lib9.h
sed 's/^X//' >include/lib9.h <<'!'
X#include <string.h>
X#include "utf.h"

X#define nil ((void*)0)

X#define uchar _fmtuchar
X#define ushort _fmtushort
X#define uint _fmtuint
X#define ulong _fmtulong
X#define vlong _fmtvlong
X#define uvlong _fmtuvlong

typedef unsigned char		uchar;
typedef unsigned short		ushort;
typedef unsigned int		uint;
typedef unsigned long		ulong;

X#define OREAD O_RDONLY
X#define OWRITE O_WRONLY
X#define ORDWR O_RDWR
X#define OCEXEC 0
!
echo include/regexp9.h
sed 's/^X//' >include/regexp9.h <<'!'
X#ifndef _REGEXP9H_

X#define _REGEXP9H_ 1
X#include <utf.h>

typedef struct Resub		Resub;
typedef struct Reclass		Reclass;
typedef struct Reinst		Reinst;
typedef struct Reprog		Reprog;

X/*
X *	Sub expression matches
X */
struct Resub{
X	union
X	{
X		char *sp;
X		Rune *rsp;
X	}s;
X	union
X	{
X		char *ep;
X		Rune *rep;
X	}e;
X};

X/*
X *	character class, each pair of rune's defines a range
X */
struct Reclass{
X	Rune	*end;
X	Rune	spans[64];
X};

X/*
X *	Machine instructions
X */
struct Reinst{
X	int	type;
X	union	{
X		Reclass	*cp;		/* class pointer */
X		Rune	r;		/* character */
X		int	subid;		/* sub-expression id for RBRA and LBRA */
X		Reinst	*right;		/* right child of OR */
X	}u1;
X	union {	/* regexp relies on these two being in the same union */
X		Reinst *left;		/* left child of OR */
X		Reinst *next;		/* next instruction for CAT & LBRA */
X	}u2;
X};

X/*
X *	Reprogram definition
X */
struct Reprog{
X	Reinst	*startinst;	/* start pc */
X	Reclass	class[16];	/* .data */
X	Reinst	firstinst[5];	/* .text */
X};

extern Reprog	*regcomp(char*);
extern Reprog	*regcomplit(char*);
extern Reprog	*regcompnl(char*);
extern void	regerror(char*);
extern int	regexec(Reprog*, char*, Resub*, int);
extern void	regsub(char*, char*, int, Resub*, int);

extern int	rregexec(Reprog*, Rune*, Resub*, int);
extern void	rregsub(Rune*, Rune*, Resub*, int);

X#endif
!
echo include/utf.h
sed 's/^X//' >include/utf.h <<'!'
X#ifndef _UTFH_
X#define _UTFH_ 1

typedef unsigned short Rune;	/* 16 bits */

enum
X{
X	UTFmax		= 3,		/* maximum bytes per rune */
X	Runesync	= 0x80,		/* cannot represent part of a UTF sequence (<) */
X	Runeself	= 0x80,		/* rune and UTF sequences are the same (<) */
X	Runeerror	= 0x80,		/* decoding error in UTF */
X};

X/*
X * rune routines
X */
extern	int	runetochar(char*, Rune*);
extern	int	chartorune(Rune*, char*);
extern	int	runelen(long);
extern	int	runenlen(Rune*, int);
extern	int	fullrune(char*, int);
extern	int	utflen(char*);
extern	int	utfnlen(char*, long);
extern	char*	utfrune(char*, long);
extern	char*	utfrrune(char*, long);
extern	char*	utfutf(char*, char*);
extern	char*	utfecpy(char*, char*, char*);

extern	Rune*	runestrcat(Rune*, Rune*);
extern	Rune*	runestrchr(Rune*, Rune);
extern	int	runestrcmp(Rune*, Rune*);
extern	Rune*	runestrcpy(Rune*, Rune*);
extern	Rune*	runestrncpy(Rune*, Rune*, long);
extern	Rune*	runestrecpy(Rune*, Rune*, Rune*);
extern	Rune*	runestrdup(Rune*);
extern	Rune*	runestrncat(Rune*, Rune*, long);
extern	int	runestrncmp(Rune*, Rune*, long);
extern	Rune*	runestrrchr(Rune*, Rune);
extern	long	runestrlen(Rune*);
extern	Rune*	runestrstr(Rune*, Rune*);

extern	Rune	tolowerrune(Rune);
extern	Rune	totitlerune(Rune);
extern	Rune	toupperrune(Rune);
extern	int	isalpharune(Rune);
extern	int	islowerrune(Rune);
extern	int	isspacerune(Rune);
extern	int	istitlerune(Rune);
extern	int	isupperrune(Rune);

X#endif
!