xref: /plan9-contrib/sys/src/cmd/sam/sam.h (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include "errors.h"
4 
5 /*
6  * BLOCKSIZE is relatively small to keep memory consumption down.
7  */
8 
9 #define	BLOCKSIZE	2048
10 #define	RUNESIZE	sizeof(Rune)
11 #define	NDISC		5
12 #define	NBUFFILES	3+2*NDISC	/* plan 9+undo+snarf+NDISC*(transcript+buf) */
13 #define NSUBEXP	10
14 
15 #define	TRUE		1
16 #define	FALSE		0
17 
18 #define	INFINITY	0x7FFFFFFFL
19 #define	INCR		25
20 #define	STRSIZE		(2*BLOCKSIZE)
21 
22 typedef long		Posn;		/* file position or address */
23 typedef	ushort		Mod;		/* modification number */
24 
25 typedef struct Address	Address;
26 typedef struct Block	Block;
27 typedef struct Buffer	Buffer;
28 typedef struct Disc	Disc;
29 typedef struct Discdesc	Discdesc;
30 typedef struct File	File;
31 typedef struct List	List;
32 typedef struct Mark	Mark;
33 typedef struct Range	Range;
34 typedef struct Rangeset	Rangeset;
35 typedef struct String	String;
36 
37 enum State
38 {
39 	Clean =		' ',
40 	Dirty =		'\'',
41 	Unread =	'-',
42 	Readerr =	'~',
43 };
44 
45 struct Range
46 {
47 	Posn	p1, p2;
48 };
49 
50 struct Rangeset
51 {
52 	Range	p[NSUBEXP];
53 };
54 
55 struct Address
56 {
57 	Range	r;
58 	File	*f;
59 };
60 
61 struct List	/* code depends on a long being able to hold a pointer */
62 {
63 	int	nalloc;
64 	int	nused;
65 	union{
66 		void	*listp;
67 		Block	*blkp;
68 		long	*longp;
69 		uchar*	*ucharp;
70 		String*	*stringp;
71 		File*	*filep;
72 		long	listv;
73 	}g;
74 };
75 
76 #define	listptr		g.listp
77 #define	blkptr		g.blkp
78 #define	longptr		g.longp
79 #define	ucharpptr	g.ucharp
80 #define	stringpptr	g.stringp
81 #define	filepptr	g.filep
82 #define	listval		g.listv
83 
84 /*
85  * Block must fit in a long because the list routines manage arrays of
86  * blocks.  Two problems: some machines (e.g. Cray) can't pull this off
87  * -- on them, use bitfields -- and the ushort bnum limits temp file sizes
88  * to about 200 megabytes.  Advantages: small, simple code and small
89  * memory overhead.  If you really want to edit huge files, making BLOCKSIZE
90  * bigger is the easiest way.
91  */
92 struct Block
93 {
94 	ushort	bnum;		/* absolute number on disk */
95 	short	nrunes;		/* runes stored in this block */
96 };
97 
98 struct Discdesc
99 {
100 	int	fd;		/* plan 9 file descriptor of temp file */
101 	ulong	nbk;		/* high water mark */
102 	List	free;		/* array of free block indices */
103 };
104 
105 struct Disc
106 {
107 	Discdesc *desc;		/* descriptor of temp file */
108 	Posn	nrunes;		/* runes on disc file */
109 	List	block;		/* list of used block indices */
110 };
111 
112 struct String
113 {
114 	short	n;
115 	short	size;
116 	Rune	*s;
117 };
118 
119 struct Buffer
120 {
121 	Disc	*disc;		/* disc storage */
122 	Posn	nrunes;		/* total length of buffer */
123 	String	cache;		/* in-core storage for efficiency */
124 	Posn	c1, c2;		/* cache start and end positions in disc */
125 				/* note: if dirty, cache is really c1, c1+cache.n */
126 	int	dirty;		/* cache dirty */
127 };
128 
129 #define	NGETC	128
130 
131 struct File
132 {
133 	Buffer	*buf;		/* cached disc storage */
134 	Buffer	*transcript;	/* what's been done */
135 	Posn	markp;		/* file pointer to start of latest change */
136 	Mod	mod;		/* modification stamp */
137 	Posn	nrunes;		/* total length of file */
138 	Posn	hiposn;		/* highest address touched this Mod */
139 	Address	dot;		/* current position */
140 	Address	ndot;		/* new current position after update */
141 	Range	tdot;		/* what terminal thinks is current range */
142 	Range	mark;		/* tagged spot in text (don't confuse with Mark) */
143 	List	*rasp;		/* map of what terminal's got */
144 	String	name;		/* file name */
145 	short	tag;		/* for communicating with terminal */
146 	char	state;		/* Clean, Dirty, Unread, or Readerr*/
147 	char	closeok;	/* ok to close file? */
148 	char	deleted;	/* delete at completion of command */
149 	char	marked;		/* file has been Fmarked at least once; once
150 				 * set, this will never go off as undo doesn't
151 				 * revert to the dawn of time */
152 	long	dev;		/* file system from which it was read */
153 	long	qid;		/* file from which it was read */
154 	long	date;		/* time stamp of plan9 file */
155 	Posn	cp1, cp2;	/* Write-behind cache positions and */
156 	String	cache;		/* string */
157 	Rune	getcbuf[NGETC];
158 	int	ngetc;
159 	int	getci;
160 	Posn	getcp;
161 };
162 
163 struct Mark
164 {
165 	Posn	p;
166 	Range	dot;
167 	Range	mark;
168 	Mod	m;
169 	short	s1;
170 };
171 
172 /*
173  * The precedent to any message in the transcript.
174  * The component structures must be an integral number of Runes long.
175  */
176 union Hdr
177 {
178 	struct _csl
179 	{
180 		short	c;
181 		short	s;
182 		long	l;
183 	}csl;
184 	struct _cs
185 	{
186 		short	c;
187 		short	s;
188 	}cs;
189 	struct _cll
190 	{
191 		short	c;
192 		long	l;
193 		long	l1;
194 	}cll;
195 	Mark	mark;
196 };
197 
198 #define	Fgetc(f)  ((--(f)->ngetc<0)? Fgetcload(f, (f)->getcp) : (f)->getcbuf[(f)->getcp++, (f)->getci++])
199 #define	Fbgetc(f) (((f)->getci<=0)? Fbgetcload(f, (f)->getcp) : (f)->getcbuf[--(f)->getcp, --(f)->getci])
200 
201 int	alnum(int);
202 void	Bclean(Buffer*);
203 void	Bterm(Buffer*);
204 void	Bdelete(Buffer*, Posn, Posn);
205 void	Bflush(Buffer*);
206 void	Binsert(Buffer*, String*, Posn);
207 Buffer	*Bopen(Discdesc*);
208 int	Bread(Buffer*, Rune*, int, Posn);
209 void	Dclose(Disc*);
210 void	Ddelete(Disc*, Posn, Posn);
211 void	Dinsert(Disc*, Rune*, int, Posn);
212 Disc	*Dopen(Discdesc*);
213 int	Dread(Disc*, Rune*, int, Posn);
214 void	Dreplace(Disc*, Posn, Posn, Rune*, int);
215 int	Fbgetcload(File*, Posn);
216 int	Fbgetcset(File*, Posn);
217 long	Fchars(File*, Rune*, Posn, Posn);
218 void	Fclose(File*);
219 void	Fdelete(File*, Posn, Posn);
220 int	Fgetcload(File*, Posn);
221 int	Fgetcset(File*, Posn);
222 void	Finsert(File*, String*, Posn);
223 File	*Fopen(void);
224 void	Fsetname(File*, String*);
225 void	Fstart(void);
226 int	Fupdate(File*, int, int);
227 int	Read(int, void*, int);
228 void	Seek(int, long, int);
229 int	plan9(File*, int, String*, int);
230 int	Write(int, void*, int);
231 int	bexecute(File*, Posn);
232 void	cd(String*);
233 void	closefiles(File*, String*);
234 void	closeio(Posn);
235 void	cmdloop(void);
236 void	cmdupdate(void);
237 void	compile(String*);
238 void	copy(File*, Address);
239 File	*current(File*);
240 void	delete(File*);
241 void	delfile(File*);
242 void	dellist(List*, int);
243 void	doubleclick(File*, Posn);
244 void	dprint(char*, ...);
245 void	edit(File*, int);
246 void	*emalloc(ulong);
247 void	*erealloc(void*, ulong);
248 void	error(Err);
249 void	error_c(Err, int);
250 void	error_s(Err, char*);
251 int	execute(File*, Posn, Posn);
252 int	filematch(File*, String*);
253 void	filename(File*);
254 File	*getfile(String*);
255 int	getname(File*, String*, int);
256 long	getnum(void);
257 void	hiccough(char*);
258 void	inslist(List*, int, long);
259 Address	lineaddr(Posn, Address, int);
260 void	listfree(List*);
261 void	load(File*);
262 File	*lookfile(String*);
263 void	lookorigin(File*, Posn, Posn);
264 int	lookup(int);
265 void	move(File*, Address);
266 void	moveto(File*, Range);
267 File	*newfile(void);
268 void	nextmatch(File*, String*, Posn, int);
269 int	newtmp(int);
270 void	notifyf(void*, char*);
271 void	panic(char*);
272 void	printposn(File*, int);
273 void	print_ss(char*, String*, String*);
274 void	print_s(char*, String*);
275 int	rcv(void);
276 Range	rdata(List*, Posn, Posn);
277 Posn	readio(File*, int*, int);
278 void	rescue(void);
279 void	resetcmd(void);
280 void	resetsys(void);
281 void	resetxec(void);
282 void	rgrow(List*, Posn, Posn);
283 void	samerr(char*);
284 void	settempfile(void);
285 int	skipbl(void);
286 void	snarf(File*, Posn, Posn, Buffer*, int);
287 void	sortname(File*);
288 void	startup(char*, int, char**, char**);
289 void	state(File*, int);
290 int	statfd(int, ulong*, ulong*, long*, long*, long*);
291 int	statfile(char*, ulong*, ulong*, long*, long*, long*);
292 void	Straddc(String*, int);
293 void	Strclose(String*);
294 int	Strcmp(String*, String*);
295 void	Strdelete(String*, Posn, Posn);
296 void	Strdupl(String*, Rune*);
297 void	Strduplstr(String*, String*);
298 void	Strinit(String*);
299 void	Strinit0(String*);
300 void	Strinsert(String*, String*, Posn);
301 void	Strinsure(String*, ulong);
302 void	Strzero(String*);
303 int	Strlen(Rune*);
304 char	*Strtoc(String*);
305 void	syserror(char*);
306 void	telldot(File*);
307 void	tellpat(void);
308 String	*tmpcstr(char*);
309 String	*tmprstr(Rune*, int);
310 void	freetmpstr(String*);
311 void	termcommand(void);
312 void	termwrite(char*);
313 File	*tofile(String*);
314 void	toterminal(File*, int);
315 void	trytoclose(File*);
316 void	trytoquit(void);
317 int	undo(void);
318 void	update(void);
319 int	waitfor(int);
320 void	warn(Warn);
321 void	warn_s(Warn, char*);
322 void	warn_SS(Warn, String*, String*);
323 void	warn_S(Warn, String*);
324 int	whichmenu(File*);
325 void	writef(File*);
326 Posn	writeio(File*);
327 Discdesc *Dstart(void);
328 
329 extern Rune	samname[];	/* compiler dependent */
330 extern Rune	*left[];
331 extern Rune	*right[];
332 
333 extern char	RSAM[];		/* system dependent */
334 extern char	SAMTERM[];
335 extern char	HOME[];
336 extern char	TMPDIR[];
337 extern char	SH[];
338 extern char	SHPATH[];
339 extern char	RX[];
340 extern char	RXPATH[];
341 extern char	SAMSAVECMD[];
342 
343 extern char	*rsamname;	/* globals */
344 extern char	*samterm;
345 extern Rune	genbuf[];
346 extern char	*genc;
347 extern int	io;
348 extern int	patset;
349 extern int	quitok;
350 extern Address	addr;
351 extern Buffer	*undobuf;
352 extern Buffer	*snarfbuf;
353 extern Buffer	*plan9buf;
354 extern List	file;
355 extern List	tempfile;
356 extern File	*cmd;
357 extern File	*curfile;
358 extern File	*lastfile;
359 extern Mod	modnum;
360 extern Posn	cmdpt;
361 extern Posn	cmdptadv;
362 extern Rangeset	sel;
363 extern String	cmdstr;
364 extern String	genstr;
365 extern String	lastpat;
366 extern String	lastregexp;
367 extern String	plan9cmd;
368 extern int	downloaded;
369 extern int	eof;
370 extern int	bpipeok;
371 extern int	panicking;
372 extern Rune	empty[];
373 extern int	termlocked;
374 extern int	noflush;
375 
376 #include "mesg.h"
377 
378 void	outTs(Hmesg, int);
379 void	outT0(Hmesg);
380 void	outTl(Hmesg, long);
381 void	outTslS(Hmesg, int, long, String*);
382 void	outTS(Hmesg, String*);
383 void	outTsS(Hmesg, int, String*);
384 void	outTsllS(Hmesg, int, long, long, String*);
385 void	outTsll(Hmesg, int, long, long);
386 void	outTsl(Hmesg, int, long);
387 void	outTsv(Hmesg, int, long);
388 void	outstart(Hmesg);
389 void	outcopy(int, void*);
390 void	outshort(int);
391 void	outlong(long);
392 void	outvlong(void*);
393 void	outsend(void);
394 void	outflush(void);
395