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