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 void notifyf(void*, char*); 277 void panic(char*); 278 void printposn(File*, int); 279 void print_ss(char*, String*, String*); 280 void print_s(char*, String*); 281 int rcv(void); 282 Range rdata(List*, Posn, Posn); 283 Posn readio(File*, int*, int, int); 284 void rescue(void); 285 void resetcmd(void); 286 void resetsys(void); 287 void resetxec(void); 288 void rgrow(List*, Posn, Posn); 289 void samerr(char*); 290 void settempfile(void); 291 int skipbl(void); 292 void snarf(File*, Posn, Posn, Buffer*, int); 293 void sortname(File*); 294 void startup(char*, int, char**, char**); 295 void state(File*, int); 296 int statfd(int, ulong*, uvlong*, long*, long*, long*); 297 int statfile(char*, ulong*, uvlong*, long*, long*, long*); 298 void Straddc(String*, int); 299 void Strclose(String*); 300 int Strcmp(String*, String*); 301 void Strdelete(String*, Posn, Posn); 302 void Strdupl(String*, Rune*); 303 void Strduplstr(String*, String*); 304 void Strinit(String*); 305 void Strinit0(String*); 306 void Strinsert(String*, String*, Posn); 307 void Strinsure(String*, ulong); 308 int Strispre(String*, String*); 309 void Strzero(String*); 310 int Strlen(Rune*); 311 char *Strtoc(String*); 312 void syserror(char*); 313 void telldot(File*); 314 void tellpat(void); 315 String *tmpcstr(char*); 316 String *tmprstr(Rune*, int); 317 void freetmpstr(String*); 318 void termcommand(void); 319 void termwrite(char*); 320 File *tofile(String*); 321 void trytoclose(File*); 322 void trytoquit(void); 323 int undo(int); 324 void update(void); 325 char *waitfor(int); 326 void warn(Warn); 327 void warn_s(Warn, char*); 328 void warn_SS(Warn, String*, String*); 329 void warn_S(Warn, String*); 330 int whichmenu(File*); 331 void writef(File*); 332 Posn writeio(File*); 333 Discdesc *Dstart(void); 334 335 extern Rune samname[]; /* compiler dependent */ 336 extern Rune *left[]; 337 extern Rune *right[]; 338 339 extern char RSAM[]; /* system dependent */ 340 extern char SAMTERM[]; 341 extern char HOME[]; 342 extern char TMPDIR[]; 343 extern char SH[]; 344 extern char SHPATH[]; 345 extern char RX[]; 346 extern char RXPATH[]; 347 extern char SAMSAVECMD[]; 348 349 /* 350 * acme globals 351 */ 352 extern long seq; 353 extern Disk *disk; 354 355 extern char *rsamname; /* globals */ 356 extern char *samterm; 357 extern Rune genbuf[]; 358 extern char *genc; 359 extern int io; 360 extern int patset; 361 extern int quitok; 362 extern Address addr; 363 extern Buffer snarfbuf; 364 extern Buffer plan9buf; 365 extern List file; 366 extern List tempfile; 367 extern File *cmd; 368 extern File *curfile; 369 extern File *lastfile; 370 extern Mod modnum; 371 extern Posn cmdpt; 372 extern Posn cmdptadv; 373 extern Rangeset sel; 374 extern String curwd; 375 extern String cmdstr; 376 extern String genstr; 377 extern String lastpat; 378 extern String lastregexp; 379 extern String plan9cmd; 380 extern int downloaded; 381 extern int eof; 382 extern int bpipeok; 383 extern int panicking; 384 extern Rune empty[]; 385 extern int termlocked; 386 extern int noflush; 387 388 #include "mesg.h" 389 390 void outTs(Hmesg, int); 391 void outT0(Hmesg); 392 void outTl(Hmesg, long); 393 void outTslS(Hmesg, int, long, String*); 394 void outTS(Hmesg, String*); 395 void outTsS(Hmesg, int, String*); 396 void outTsllS(Hmesg, int, long, long, String*); 397 void outTsll(Hmesg, int, long, long); 398 void outTsl(Hmesg, int, long); 399 void outTsv(Hmesg, int, long); 400 void outstart(Hmesg); 401 void outcopy(int, void*); 402 void outshort(int); 403 void outlong(long); 404 void outvlong(void*); 405 void outsend(void); 406 void outflush(void); 407