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