Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <plumb.h>
4 #include "errors.h"
6 #undef waitfor
7 #define waitfor samwaitfor
9 #undef warn
10 #define warn samwarn
12 #undef class
13 #define class samclass
15 /*
16 * BLOCKSIZE is relatively small to keep memory consumption down.
17 */
19 #define BLOCKSIZE 2048
20 #define RUNESIZE sizeof(Rune)
21 #define NDISC 5
22 #define NBUFFILES 3+2*NDISC /* plan 9+undo+snarf+NDISC*(transcript+buf) */
23 #define NSUBEXP 10
25 #define TRUE 1
26 #define FALSE 0
28 #undef INFINITY /* Darwin declares this as HUGE_VAL */
29 #define INFINITY 0x7FFFFFFFL
30 #define INCR 25
31 #define STRSIZE (2*BLOCKSIZE)
33 typedef long Posn; /* file position or address */
34 typedef ushort Mod; /* modification number */
36 typedef struct Address Address;
37 typedef struct Block Block;
38 typedef struct Buffer Buffer;
39 typedef struct Disk Disk;
40 typedef struct File File;
41 typedef struct List List;
42 typedef struct Range Range;
43 typedef struct Rangeset Rangeset;
44 typedef struct String String;
46 enum State
47 {
48 Clean = ' ',
49 Dirty = '\'',
50 Unread = '-'
51 };
53 struct Range
54 {
55 Posn p1, p2;
56 };
58 struct Rangeset
59 {
60 Range p[NSUBEXP];
61 };
63 struct Address
64 {
65 Range r;
66 File *f;
67 };
69 struct String
70 {
71 short n;
72 short size;
73 Rune *s;
74 };
76 struct List /* code depends on a long being able to hold a pointer */
77 {
78 int type; /* 'p' for pointer, 'P' for Posn */
79 int nalloc;
80 int nused;
81 union{
82 void* listp;
83 void** voidp;
84 Posn* posnp;
85 String**stringp;
86 File** filep;
87 }g;
88 };
90 #define listptr g.listp
91 #define voidpptr g.voidp
92 #define posnptr g.posnp
93 #define stringpptr g.stringp
94 #define filepptr g.filep
96 enum
97 {
98 Blockincr = 256,
99 Maxblock = 8*1024,
101 BUFSIZE = Maxblock, /* size from fbufalloc() */
102 RBUFSIZE = BUFSIZE/sizeof(Rune)
103 };
106 enum
108 Null = '-',
109 Delete = 'd',
110 Insert = 'i',
111 Filename = 'f',
112 Dot = 'D',
113 Mark = 'm'
114 };
116 struct Block
118 vlong addr; /* disk address in bytes */
119 union {
120 uint n; /* number of used runes in block */
121 Block *next; /* pointer to next in free list */
122 } u;
123 };
125 struct Disk
127 int fd;
128 vlong addr; /* length of temp file */
129 Block *free[Maxblock/Blockincr+1];
130 };
132 Disk* diskinit(void);
133 Block* disknewblock(Disk*, uint);
134 void diskrelease(Disk*, Block*);
135 void diskread(Disk*, Block*, Rune*, uint);
136 void diskwrite(Disk*, Block**, Rune*, uint);
138 struct Buffer
140 uint nc;
141 Rune *c; /* cache */
142 uint cnc; /* bytes in cache */
143 uint cmax; /* size of allocated cache */
144 uint cq; /* position of cache */
145 int cdirty; /* cache needs to be written */
146 uint cbi; /* index of cache Block */
147 Block **bl; /* array of blocks */
148 uint nbl; /* number of blocks */
149 };
150 void bufinsert(Buffer*, uint, Rune*, uint);
151 void bufdelete(Buffer*, uint, uint);
152 uint bufload(Buffer*, uint, int, int*);
153 void bufread(Buffer*, uint, Rune*, uint);
154 void bufclose(Buffer*);
155 void bufreset(Buffer*);
157 struct File
159 Buffer b; /* the data */
160 Buffer delta; /* transcript of changes */
161 Buffer epsilon; /* inversion of delta for redo */
162 String name; /* name of associated file */
163 uvlong qidpath; /* of file when read */
164 uint mtime; /* of file when read */
165 ulong dev; /* of file when read */
166 int unread; /* file has not been read from disk */
168 long seq; /* if seq==0, File acts like Buffer */
169 long cleanseq; /* f->seq at last read/write of file */
170 int mod; /* file appears modified in menu */
171 char rescuing; /* sam exiting; this file unusable */
173 #if 0
174 // Text *curtext; /* most recently used associated text */
175 // Text **text; /* list of associated texts */
176 // int ntext;
177 // int dumpid; /* used in dumping zeroxed windows */
178 #endif
180 Posn hiposn; /* highest address touched this Mod */
181 Address dot; /* current position */
182 Address ndot; /* new current position after update */
183 Range tdot; /* what terminal thinks is current range */
184 Range mark; /* tagged spot in text (don't confuse with Mark) */
185 List *rasp; /* map of what terminal's got */
186 short tag; /* for communicating with terminal */
187 char closeok; /* ok to close file? */
188 char deleted; /* delete at completion of command */
189 Range prevdot; /* state before start of change */
190 Range prevmark;
191 long prevseq;
192 int prevmod;
193 };
194 /*File* fileaddtext(File*, Text*); */
195 void fileclose(File*);
196 void filedelete(File*, uint, uint);
197 /*void filedeltext(File*, Text*); */
198 void fileinsert(File*, uint, Rune*, uint);
199 uint fileload(File*, uint, int, int*);
200 void filemark(File*);
201 void filereset(File*);
202 void filesetname(File*, String*);
203 void fileundelete(File*, Buffer*, uint, uint);
204 void fileuninsert(File*, Buffer*, uint, uint);
205 void fileunsetname(File*, Buffer*);
206 void fileundo(File*, int, int, uint*, uint*, int);
207 int fileupdate(File*, int, int);
209 int filereadc(File*, uint);
210 File *fileopen(void);
211 void loginsert(File*, uint, Rune*, uint);
212 void logdelete(File*, uint, uint);
213 void logsetname(File*, String*);
214 int fileisdirty(File*);
215 long undoseq(File*, int);
216 long prevseq(Buffer*);
218 void raspload(File*);
219 void raspstart(File*);
220 void raspdelete(File*, uint, uint, int);
221 void raspinsert(File*, uint, Rune*, uint, int);
222 void raspdone(File*, int);
223 void raspflush(File*);
225 /*
226 * acme fns
227 */
228 void* fbufalloc(void);
229 void fbuffree(void*);
230 uint min(uint, uint);
231 void cvttorunes(char*, int, Rune*, int*, int*, int*);
233 #define runemalloc(a) (Rune*)emalloc((a)*sizeof(Rune))
234 #define runerealloc(a, b) (Rune*)realloc((a), (b)*sizeof(Rune))
235 #define runemove(a, b, c) memmove((a), (b), (c)*sizeof(Rune))
237 int alnum(int);
238 int Read(int, void*, int);
239 void Seek(int, long, int);
240 int plan9(File*, int, String*, int);
241 int Write(int, void*, int);
242 void Close(int);
243 int bexecute(File*, Posn);
244 void cd(String*);
245 void closefiles(File*, String*);
246 void closeio(Posn);
247 void cmdloop(void);
248 void cmdupdate(void);
249 void compile(String*);
250 void copy(File*, Address);
251 File *current(File*);
252 void delete(File*);
253 void delfile(File*);
254 void dellist(List*, int);
255 void doubleclick(File*, Posn);
256 void dprint(char*, ...);
257 void edit(File*, int);
258 void *emalloc(ulong);
259 void *erealloc(void*, ulong);
260 void error(Err);
261 void error_c(Err, int);
262 void error_r(Err, char*);
263 void error_s(Err, char*);
264 int execute(File*, Posn, Posn);
265 int filematch(File*, String*);
266 void filename(File*);
267 void fixname(String*);
268 void fullname(String*);
269 void getcurwd(void);
270 File *getfile(String*);
271 int getname(File*, String*, int);
272 long getnum(int);
273 void hiccough(char*);
274 void inslist(List*, int, ...);
275 Address lineaddr(Posn, Address, int);
276 List *listalloc(int);
277 void listfree(List*);
278 void load(File*);
279 File *lookfile(String*);
280 void lookorigin(File*, Posn, Posn);
281 int lookup(int);
282 void move(File*, Address);
283 void moveto(File*, Range);
284 File *newfile(void);
285 void nextmatch(File*, String*, Posn, int);
286 int newtmp(int);
287 void notifyf(void*, char*);
288 void panic(char*);
289 void printposn(File*, int);
290 void print_ss(char*, String*, String*);
291 void print_s(char*, String*);
292 int rcv(void);
293 Range rdata(List*, Posn, Posn);
294 Posn readio(File*, int*, int, int);
295 void rescue(void);
296 void resetcmd(void);
297 void resetsys(void);
298 void resetxec(void);
299 void rgrow(List*, Posn, Posn);
300 void samerr(char*);
301 void settempfile(void);
302 int skipbl(void);
303 void snarf(File*, Posn, Posn, Buffer*, int);
304 void sortname(File*);
305 void startup(char*, int, char**, char**);
306 void state(File*, int);
307 int statfd(int, ulong*, uvlong*, long*, long*, long*);
308 int statfile(char*, ulong*, uvlong*, long*, long*, long*);
309 void Straddc(String*, int);
310 void Strclose(String*);
311 int Strcmp(String*, String*);
312 void Strdelete(String*, Posn, Posn);
313 void Strdupl(String*, Rune*);
314 void Strduplstr(String*, String*);
315 void Strinit(String*);
316 void Strinit0(String*);
317 void Strinsert(String*, String*, Posn);
318 void Strinsure(String*, ulong);
319 int Strispre(String*, String*);
320 void Strzero(String*);
321 int Strlen(Rune*);
322 char *Strtoc(String*);
323 void syserror(char*);
324 void telldot(File*);
325 void tellpat(void);
326 String *tmpcstr(char*);
327 String *tmprstr(Rune*, int);
328 void freetmpstr(String*);
329 void termcommand(void);
330 void termwrite(char*);
331 File *tofile(String*);
332 void trytoclose(File*);
333 void trytoquit(void);
334 int undo(int);
335 void update(void);
336 int waitfor(int);
337 void warn(Warn);
338 void warn_s(Warn, char*);
339 void warn_SS(Warn, String*, String*);
340 void warn_S(Warn, String*);
341 int whichmenu(File*);
342 void writef(File*);
343 Posn writeio(File*);
345 extern Rune samname[]; /* compiler dependent */
346 extern Rune *left[];
347 extern Rune *right[];
349 extern char RSAM[]; /* system dependent */
350 extern char SAMTERM[];
351 extern char HOME[];
352 extern char TMPDIR[];
353 extern char SH[];
354 extern char SHPATH[];
355 extern char RX[];
356 extern char RXPATH[];
358 /*
359 * acme globals
360 */
361 extern long seq;
362 extern Disk *disk;
364 extern char *rsamname; /* globals */
365 extern char *samterm;
366 extern Rune genbuf[];
367 extern char *genc;
368 extern int io;
369 extern int patset;
370 extern int quitok;
371 extern Address addr;
372 extern Buffer snarfbuf;
373 extern Buffer plan9buf;
374 extern List file;
375 extern List tempfile;
376 extern File *cmd;
377 extern File *curfile;
378 extern File *lastfile;
379 extern Mod modnum;
380 extern Posn cmdpt;
381 extern Posn cmdptadv;
382 extern Rangeset sel;
383 extern String curwd;
384 extern String cmdstr;
385 extern String genstr;
386 extern String lastpat;
387 extern String lastregexp;
388 extern String plan9cmd;
389 extern int downloaded;
390 extern int eof;
391 extern int bpipeok;
392 extern int panicking;
393 extern Rune empty[];
394 extern int termlocked;
395 extern int outbuffered;
397 #include "mesg.h"
399 void outTs(Hmesg, int);
400 void outT0(Hmesg);
401 void outTl(Hmesg, long);
402 void outTslS(Hmesg, int, long, String*);
403 void outTS(Hmesg, String*);
404 void outTsS(Hmesg, int, String*);
405 void outTsllS(Hmesg, int, long, long, String*);
406 void outTsll(Hmesg, int, long, long);
407 void outTsl(Hmesg, int, long);
408 void outTsv(Hmesg, int, vlong);
409 void outflush(void);
410 int needoutflush(void);