blob: c2aaa07026f9ceb2c5ccbf6eabf6e9d5029f4d15 [file] [log] [blame]
#include <u.h>
#include <libc.h>
#include <plumb.h>
#include "errors.h"
#undef waitfor
#define waitfor samwaitfor
#undef warn
#define warn samwarn
/*
* BLOCKSIZE is relatively small to keep memory consumption down.
*/
#define BLOCKSIZE 2048
#define RUNESIZE sizeof(Rune)
#define NDISC 5
#define NBUFFILES 3+2*NDISC /* plan 9+undo+snarf+NDISC*(transcript+buf) */
#define NSUBEXP 10
#define TRUE 1
#define FALSE 0
#undef INFINITY /* Darwin declares this as HUGE_VAL */
#define INFINITY 0x7FFFFFFFL
#define INCR 25
#define STRSIZE (2*BLOCKSIZE)
typedef long Posn; /* file position or address */
typedef ushort Mod; /* modification number */
typedef struct Address Address;
typedef struct Block Block;
typedef struct Buffer Buffer;
typedef struct Disk Disk;
typedef struct Discdesc Discdesc;
typedef struct File File;
typedef struct List List;
typedef struct Range Range;
typedef struct Rangeset Rangeset;
typedef struct String String;
enum State
{
Clean = ' ',
Dirty = '\'',
Unread = '-'
};
struct Range
{
Posn p1, p2;
};
struct Rangeset
{
Range p[NSUBEXP];
};
struct Address
{
Range r;
File *f;
};
struct String
{
short n;
short size;
Rune *s;
};
struct List /* code depends on a long being able to hold a pointer */
{
int type; /* 'p' for pointer, 'P' for Posn */
int nalloc;
int nused;
union{
void* listp;
void** voidp;
Posn* posnp;
String**stringp;
File** filep;
}g;
};
#define listptr g.listp
#define voidpptr g.voidp
#define posnptr g.posnp
#define stringpptr g.stringp
#define filepptr g.filep
enum
{
Blockincr = 256,
Maxblock = 8*1024,
BUFSIZE = Maxblock, /* size from fbufalloc() */
RBUFSIZE = BUFSIZE/sizeof(Rune)
};
enum
{
Null = '-',
Delete = 'd',
Insert = 'i',
Filename = 'f',
Dot = 'D',
Mark = 'm'
};
struct Block
{
vlong addr; /* disk address in bytes */
union {
uint n; /* number of used runes in block */
Block *next; /* pointer to next in free list */
} u;
};
struct Disk
{
int fd;
vlong addr; /* length of temp file */
Block *free[Maxblock/Blockincr+1];
};
Disk* diskinit(void);
Block* disknewblock(Disk*, uint);
void diskrelease(Disk*, Block*);
void diskread(Disk*, Block*, Rune*, uint);
void diskwrite(Disk*, Block**, Rune*, uint);
struct Buffer
{
uint nc;
Rune *c; /* cache */
uint cnc; /* bytes in cache */
uint cmax; /* size of allocated cache */
uint cq; /* position of cache */
int cdirty; /* cache needs to be written */
uint cbi; /* index of cache Block */
Block **bl; /* array of blocks */
uint nbl; /* number of blocks */
};
void bufinsert(Buffer*, uint, Rune*, uint);
void bufdelete(Buffer*, uint, uint);
uint bufload(Buffer*, uint, int, int*);
void bufread(Buffer*, uint, Rune*, uint);
void bufclose(Buffer*);
void bufreset(Buffer*);
struct File
{
Buffer b; /* the data */
Buffer delta; /* transcript of changes */
Buffer epsilon; /* inversion of delta for redo */
String name; /* name of associated file */
uvlong qidpath; /* of file when read */
uint mtime; /* of file when read */
ulong dev; /* of file when read */
int unread; /* file has not been read from disk */
long seq; /* if seq==0, File acts like Buffer */
long cleanseq; /* f->seq at last read/write of file */
int mod; /* file appears modified in menu */
char rescuing; /* sam exiting; this file unusable */
#if 0
// Text *curtext; /* most recently used associated text */
// Text **text; /* list of associated texts */
// int ntext;
// int dumpid; /* used in dumping zeroxed windows */
#endif
Posn hiposn; /* highest address touched this Mod */
Address dot; /* current position */
Address ndot; /* new current position after update */
Range tdot; /* what terminal thinks is current range */
Range mark; /* tagged spot in text (don't confuse with Mark) */
List *rasp; /* map of what terminal's got */
short tag; /* for communicating with terminal */
char closeok; /* ok to close file? */
char deleted; /* delete at completion of command */
Range prevdot; /* state before start of change */
Range prevmark;
long prevseq;
int prevmod;
};
/*File* fileaddtext(File*, Text*); */
void fileclose(File*);
void filedelete(File*, uint, uint);
/*void filedeltext(File*, Text*); */
void fileinsert(File*, uint, Rune*, uint);
uint fileload(File*, uint, int, int*);
void filemark(File*);
void filereset(File*);
void filesetname(File*, String*);
void fileundelete(File*, Buffer*, uint, uint);
void fileuninsert(File*, Buffer*, uint, uint);
void fileunsetname(File*, Buffer*);
void fileundo(File*, int, int, uint*, uint*, int);
int fileupdate(File*, int, int);
int filereadc(File*, uint);
File *fileopen(void);
void loginsert(File*, uint, Rune*, uint);
void logdelete(File*, uint, uint);
void logsetname(File*, String*);
int fileisdirty(File*);
long undoseq(File*, int);
long prevseq(Buffer*);
void raspload(File*);
void raspstart(File*);
void raspdelete(File*, uint, uint, int);
void raspinsert(File*, uint, Rune*, uint, int);
void raspdone(File*, int);
void raspflush(File*);
/*
* acme fns
*/
void* fbufalloc(void);
void fbuffree(void*);
uint min(uint, uint);
void cvttorunes(char*, int, Rune*, int*, int*, int*);
#define runemalloc(a) (Rune*)emalloc((a)*sizeof(Rune))
#define runerealloc(a, b) (Rune*)realloc((a), (b)*sizeof(Rune))
#define runemove(a, b, c) memmove((a), (b), (c)*sizeof(Rune))
int alnum(int);
int Read(int, void*, int);
void Seek(int, long, int);
int plan9(File*, int, String*, int);
int Write(int, void*, int);
int bexecute(File*, Posn);
void cd(String*);
void closefiles(File*, String*);
void closeio(Posn);
void cmdloop(void);
void cmdupdate(void);
void compile(String*);
void copy(File*, Address);
File *current(File*);
void delete(File*);
void delfile(File*);
void dellist(List*, int);
void doubleclick(File*, Posn);
void dprint(char*, ...);
void edit(File*, int);
void *emalloc(ulong);
void *erealloc(void*, ulong);
void error(Err);
void error_c(Err, int);
void error_r(Err, char*);
void error_s(Err, char*);
int execute(File*, Posn, Posn);
int filematch(File*, String*);
void filename(File*);
void fixname(String*);
void fullname(String*);
void getcurwd(void);
File *getfile(String*);
int getname(File*, String*, int);
long getnum(int);
void hiccough(char*);
void inslist(List*, int, ...);
Address lineaddr(Posn, Address, int);
List *listalloc(int);
void listfree(List*);
void load(File*);
File *lookfile(String*);
void lookorigin(File*, Posn, Posn);
int lookup(int);
void move(File*, Address);
void moveto(File*, Range);
File *newfile(void);
void nextmatch(File*, String*, Posn, int);
int newtmp(int);
void notifyf(void*, char*);
void panic(char*);
void printposn(File*, int);
void print_ss(char*, String*, String*);
void print_s(char*, String*);
int rcv(void);
Range rdata(List*, Posn, Posn);
Posn readio(File*, int*, int, int);
void rescue(void);
void resetcmd(void);
void resetsys(void);
void resetxec(void);
void rgrow(List*, Posn, Posn);
void samerr(char*);
void settempfile(void);
int skipbl(void);
void snarf(File*, Posn, Posn, Buffer*, int);
void sortname(File*);
void startup(char*, int, char**, char**);
void state(File*, int);
int statfd(int, ulong*, uvlong*, long*, long*, long*);
int statfile(char*, ulong*, uvlong*, long*, long*, long*);
void Straddc(String*, int);
void Strclose(String*);
int Strcmp(String*, String*);
void Strdelete(String*, Posn, Posn);
void Strdupl(String*, Rune*);
void Strduplstr(String*, String*);
void Strinit(String*);
void Strinit0(String*);
void Strinsert(String*, String*, Posn);
void Strinsure(String*, ulong);
int Strispre(String*, String*);
void Strzero(String*);
int Strlen(Rune*);
char *Strtoc(String*);
void syserror(char*);
void telldot(File*);
void tellpat(void);
String *tmpcstr(char*);
String *tmprstr(Rune*, int);
void freetmpstr(String*);
void termcommand(void);
void termwrite(char*);
File *tofile(String*);
void trytoclose(File*);
void trytoquit(void);
int undo(int);
void update(void);
int waitfor(int);
void warn(Warn);
void warn_s(Warn, char*);
void warn_SS(Warn, String*, String*);
void warn_S(Warn, String*);
int whichmenu(File*);
void writef(File*);
Posn writeio(File*);
Discdesc *Dstart(void);
extern Rune samname[]; /* compiler dependent */
extern Rune *left[];
extern Rune *right[];
extern char RSAM[]; /* system dependent */
extern char SAMTERM[];
extern char HOME[];
extern char TMPDIR[];
extern char SH[];
extern char SHPATH[];
extern char RX[];
extern char RXPATH[];
/*
* acme globals
*/
extern long seq;
extern Disk *disk;
extern char *rsamname; /* globals */
extern char *samterm;
extern Rune genbuf[];
extern char *genc;
extern int io;
extern int patset;
extern int quitok;
extern Address addr;
extern Buffer snarfbuf;
extern Buffer plan9buf;
extern List file;
extern List tempfile;
extern File *cmd;
extern File *curfile;
extern File *lastfile;
extern Mod modnum;
extern Posn cmdpt;
extern Posn cmdptadv;
extern Rangeset sel;
extern String curwd;
extern String cmdstr;
extern String genstr;
extern String lastpat;
extern String lastregexp;
extern String plan9cmd;
extern int downloaded;
extern int eof;
extern int bpipeok;
extern int panicking;
extern Rune empty[];
extern int termlocked;
extern int outbuffered;
#include "mesg.h"
void outTs(Hmesg, int);
void outT0(Hmesg);
void outTl(Hmesg, long);
void outTslS(Hmesg, int, long, String*);
void outTS(Hmesg, String*);
void outTsS(Hmesg, int, String*);
void outTsllS(Hmesg, int, long, long, String*);
void outTsll(Hmesg, int, long, long);
void outTsl(Hmesg, int, long);
void outTsv(Hmesg, int, vlong);
void outflush(void);
int needoutflush(void);