use split CVS repo address, like in dietlibc
[alioth/jupp.git] / types.h
1 #ifndef _JOE_TYPES_H
2 #define _JOE_TYPES_H
3
4 #ifdef EXTERN
5 __IDSTRING(rcsid_types_h, "$MirOS: contrib/code/jupp/types.h,v 1.35 2018/02/14 17:51:49 tg Exp $");
6 #endif
7
8 /*-
9  * Copyright © 2004, 2005, 2006, 2007, 2008, 2011, 2012, 2013,
10  *             2014, 2016, 2017, 2018
11  *      Thorsten “mirabilos” Glaser <tg@mirbsd.org>
12  *
13  * Provided that these terms and disclaimer and all copyright notices
14  * are retained or reproduced in an accompanying document, permission
15  * is granted to deal in this work without restriction, including un‐
16  * limited rights to use, publicly perform, distribute, sell, modify,
17  * merge, give away, or sublicence.
18  *
19  * This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
20  * the utmost extent permitted by applicable law, neither express nor
21  * implied; without malicious intent or gross negligence. In no event
22  * may a licensor, author or contributor be held liable for indirect,
23  * direct, other damage, loss, or other issues arising in any way out
24  * of dealing in the work, even if advised of the possibility of such
25  * damage or existence of a defect, except proven that it results out
26  * of said person’s immediate fault when using the work as intended.
27  */
28
29 /* Prefix to make string constants unsigned */
30 #define UC (const unsigned char *)
31 #define US (unsigned char *)
32
33 #define LINK(type) struct { type *next; type *prev; }
34
35 #ifdef SMALL
36 #define stdsiz          4096
37 #else
38 #define stdsiz          8192
39 #endif
40 #define FITHEIGHT       4               /* Minimum text window height */
41 #define LINCOLS         6
42 #define NPROC           8               /* Number of processes we keep track of */
43 #define UNDOKEEP        100
44 #define INC             16              /* Pages to allocate each time */
45
46 #define TYPETW          0x0100
47 #define TYPEPW          0x0200
48 #define TYPEMENU        0x0800
49 #define TYPEQW          0x1000
50
51 /* polymorph function pointers, which do not use compiler type checking */
52 #ifndef GCC_Wstrict_prototypes
53 typedef int jpoly_int();
54 typedef void jpoly_void();
55 #else
56 /* same content as above, but system header */
57 #include <jupp.tmp.h>
58 #endif
59
60 struct jalloc_common {
61         /*XXX these must be size_t not int */
62         /*
63          * size part: number of elements that can be fit,
64          * not counting the terminator or space needed for the header
65          */
66         int esiz;
67         /*
68          * length part: number of elements currently in the array,
69          * not counting the terminator
70          */
71         int elen;
72 };
73
74 #ifdef MKSH_ALLOC_CATCH_UNDERRUNS
75 struct jalloc_item {
76         struct jalloc_common enfo;
77         size_t len;
78         char dummy[8192 - sizeof(struct jalloc_common) - sizeof(size_t)];
79 };
80 #define ALLOC_INFO(f)   enfo.f
81 #define ALLOC_ITEM      struct jalloc_item
82 #else
83 #define ALLOC_INFO(f)   f
84 #define ALLOC_ITEM      struct jalloc_common
85 #endif
86
87 #define jalloc_krnl(i)  ((ALLOC_ITEM *)((char *)(i) - sizeof(ALLOC_ITEM)))
88 #define jalloc_user(i)  ((void *)((char *)(i) + sizeof(ALLOC_ITEM)))
89 #define jalloc_siz(i)   (jalloc_krnl(i)->ALLOC_INFO(esiz))
90 #define jalloc_len(i)   (jalloc_krnl(i)->ALLOC_INFO(elen))
91
92 #ifdef HAVE_LIMITS_H
93 #include <limits.h>
94 #endif
95 #ifdef HAVE_STDINT_H
96 #include <stdint.h>
97 #endif
98
99 #ifndef SIZE_MAX
100 #ifdef SIZE_T_MAX
101 #define SIZE_MAX        SIZE_T_MAX
102 #else
103 #define SIZE_MAX        ((size_t)-1)
104 #endif
105 #endif
106
107 #define notok2mul(max, val, c)  (((val) != 0) && ((c) != 0) && \
108                                     (((max) / (c)) < (val)))
109 #define notok2add(max, val, c)  ((val) > ((max) - (c)))
110 #define notoktomul(val, cnst)   notok2mul(SIZE_MAX, (val), (cnst))
111 #define notoktoadd(val, cnst)   notok2add(SIZE_MAX, (val), (cnst))
112
113 void jalloc_init(void);
114 void *jalloc(void *, size_t, size_t);
115 void jfree(void *);
116
117 #define ralloc(nmemb, size)     (notoktomul(nmemb, size) ? NULL : \
118                                     malloc((nmemb) * (size)))
119
120 typedef struct header H;
121 typedef struct buffer B;
122 typedef struct point P;
123 typedef struct options OPTIONS;
124 typedef struct macro MACRO;
125 typedef struct cmd CMD;
126 typedef struct hentry HENTRY;
127 typedef struct hash HASH;
128 typedef struct kmap KMAP;
129 typedef struct kbd KBD;
130 typedef struct key KEY;
131 typedef struct watom WATOM;
132 typedef struct screen SCREEN;
133 typedef struct window W;
134 typedef struct base BASE;
135 typedef struct bw BW;
136 typedef struct menu MENU;
137 typedef struct scrn SCRN;
138 typedef struct cap CAP;
139 typedef struct pw PW;
140 typedef struct stditem STDITEM;
141 typedef struct query QW;
142 typedef struct tw TW;
143 typedef struct irec IREC;
144 typedef struct undo UNDO;
145 typedef struct undorec UNDOREC;
146 typedef struct search SRCH;
147 typedef struct srchrec SRCHREC;
148 typedef struct vpage VPAGE;
149 typedef struct vfile VFILE;
150
151 /* window.object* */
152 typedef union {
153         BASE *base;
154         MENU *menu;
155         BW *bw;
156         QW *qw;
157 } jobject;
158
159 struct header {
160         LINK(H) link;           /* LINK ??? */
161         long    seg;            /* ??? */
162         int     hole;           /* ??? */
163         int     ehole;          /* ??? */
164         int     nlines;         /* ??? */
165 };
166
167 struct point {
168         LINK(P) link;           /* ?LINK ??? */
169
170         B       *b;             /* ?B ??? */
171         int     ofst;           /* ??? */
172         unsigned char   *ptr;   /* ??? */
173         H       *hdr;           /* ?H ??? */
174
175         long    byte;           /* ??? */
176         long    line;           /* ??? */
177         long    col;            /* current column */
178         long    xcol;           /* ??? */
179         int     valcol;         /* bool: is col valid? */
180         int     end;            /* ??? */
181
182         P       **owner;        /* ??? */
183 };
184
185 struct options {
186         OPTIONS *next;
187         unsigned char   *name_regex;
188         unsigned char   *contents_regex;
189         int     overtype;
190         int     lmargin;
191         int     rmargin;
192         int     autoindent;
193         int     wordwrap;
194         int     tab;
195         int     indentc;
196         int     istep;
197         unsigned char *context;
198         const unsigned char *lmsg;
199         const unsigned char *rmsg;
200         char    *hmsg;
201         int     linums;
202         int     readonly;
203         int     french;
204         int     spaces;
205         int     crlf;
206         int     highlight;      /* Set to enable highlighting */
207         unsigned char *syntax_name;     /* Name of syntax to use */
208         struct high_syntax *syntax;     /* Syntax for highlighting (load_dfa() from syntax_name happens in setopt()) */
209         unsigned char *map_name;        /* Name of character set */
210         struct charmap *charmap;        /* Character set */
211         int     smarthome;      /* Set for smart home key */
212         int     indentfirst;    /* Smart home goes to indentation point first */
213         int     smartbacks;     /* Set for smart backspace key */
214         int     purify;         /* Purify indentation */
215         int     picture;        /* Picture mode */
216         MACRO   *mnew;          /* Macro to execute for new files */
217         MACRO   *mold;          /* Macro to execute for existing files */
218         MACRO   *msnew;         /* Macro to execute before saving new files */
219         MACRO   *msold;         /* Macro to execute before saving existing files */
220         int     vispace;        /* Set to make spaces visible */
221         int     hex;            /* Hex edit mode */
222 };
223
224 struct macro {
225         int     k;              /* Keycode */
226         int     arg;            /* Repeat argument */
227         CMD     *cmd;           /* Command address */
228         int     n;              /* Number of steps */
229         int     size;           /* Malloc size of steps */
230         MACRO   **steps;        /* Block */
231 };
232
233 struct recmac {
234         struct recmac *next;
235         int     n;
236         MACRO   *m;
237 };
238
239
240 /* Command entry */
241
242 struct cmd {
243         const unsigned char *name;      /* Command name */
244         const unsigned char *negarg;    /* Command to use if arg was negative */
245         jpoly_int *func;        /* Function bound to name */
246         MACRO   *m;             /* Macro bound to name */
247         unsigned int flag;      /* Execution flags */
248         int     arg;            /* 0= arg is meaningless, 1= ok */
249 };
250
251
252
253 struct buffer {
254         LINK(B) link;
255         P       *bof;
256         P       *eof;
257         unsigned char   *name;
258         long    mod_time;       /* Last modification time for file */
259         int     orphan;
260         int     count;
261         int     changed;
262         int     backup;
263         void    *undo;
264         P       *marks[11];     /* Bookmarks */
265         OPTIONS o;              /* Options */
266         P       *oldcur;        /* Last cursor position before orphaning */
267         P       *oldtop;        /* Last top screen position before orphaning */
268         int     rdonly;         /* Set for read-only */
269         int     internal;       /* Set for internal buffers */
270         int     scratch;        /* Set for scratch buffers */
271         int     er;             /* Error code when file was loaded */
272         pid_t   pid;            /* Process id */
273         int     out;            /* fd to write to process */
274 };
275
276
277 struct hentry {
278         const unsigned char *name;
279         HENTRY  *next;
280         void    *val;
281 };
282
283 struct hash {
284         int     len;
285         HENTRY  **tab;
286 };
287
288
289 struct help {
290         struct help     *prev;          /* previous help screen */
291         struct help     *next;          /* nex help screen */
292         unsigned char   *name;          /* context name for context sensitive help */
293         unsigned char   *text;          /* help text with attributes */
294         unsigned int    lines;          /* number of lines */
295 };
296
297 /* A key binding */
298 struct key {
299         int     k;                      /* Flag: 0=binding, 1=submap */
300         union {
301                 void    *bind;          /* What key is bound to */
302                 KMAP    *submap;        /* Sub KMAP address (for prefix keys) */
303         } value;
304 };
305
306 /* A map of keycode (octet) to command/sub-map bindings */
307 struct kmap {
308         KEY     keys[256];      /* KEYs */
309 };
310
311 /** A keyboard handler **/
312 struct kbd {
313         KMAP    *curmap;        /* Current keymap */
314         KMAP    *topmap;        /* Top-level keymap */
315         int     seq[16];        /* Current sequence of keys */
316         int     x;              /* What we're up to */
317 };
318
319
320 struct watom {
321         const unsigned char *context;   /* Context name */
322         void (*disp)(jobject, int);     /* Display window */
323         void (*follow)(jobject);        /* Display window */
324         int (*abort)(jobject);          /* Common user functions */
325         int (*rtn)(jobject);
326         int (*type)(jobject, int);
327                                         /* Called when… */
328         void (*resize)(jobject, int, int);      /* window changed size */
329         void (*move)(jobject, int, int);        /* window moved */
330         void (*ins)(BW *, B *, long, long, int);        /* on line insertions */
331         void (*del)(BW *, B *, long, long, int);        /* on line deletions */
332         int     what;           /* Type of this thing */
333 };
334
335 struct screen {
336         SCRN    *t;             /* Screen data on this screen is output to */
337
338         int     wind;           /* Number of help lines on this screen */
339
340         W       *topwin;        /* Top-most window showing on screen */
341         W       *curwin;        /* Window cursor is in */
342
343         int     w, h;           /* Width and height of this screen */
344 };
345
346 struct window {
347         LINK(W) link;           /* Linked list of windows in order they
348                                    appear on the screen */
349
350         SCREEN  *t;             /* Screen this thing is on */
351
352         int     x, y, w, h;     /* Position and size of window */
353                                 /* Currently, x = 0, w = width of screen. */
354                                 /* y == -1 if window is not on screen */
355
356         int     ny, nh;         /* Temporary values for wfit */
357
358         int     reqh;           /* Requested new height or 0 for same */
359                                 /* This is an argument for wfit */
360
361         int     fixed;          /* If this is zero, use 'hh'.  If not, this
362                                    is a fixed size window and this variable
363                                    gives its height */
364
365         int     hh;             /* Height window would be on a screen with
366                                    1000 lines.  When the screen size changes
367                                    this is used to calculate the window's
368                                    real height */
369
370         W       *win;           /* Window this one operates on */
371         W       *main;          /* Main window of this family */
372         W       *orgwin;        /* Window where space from this window came */
373         int     curx, cury;     /* Cursor position within window */
374         KBD     *kbd;           /* Keyboard handler for this window */
375         WATOM   *watom;         /* The type of this window */
376         jobject object;         /* Object which inherits this */
377
378         const unsigned char *msgt;      /* Message at top of window */
379         const unsigned char *msgb;      /* Message at bottom of window */
380         const unsigned char *huh;       /* Name of window for context sensitive hlp */
381         int     *notify;        /* Address of kill notification flag */
382 };
383
384 /* Anything which goes in window.object must start like this: */
385 struct base {
386         W       *parent;
387 };
388
389 struct bw {
390         W       *parent;
391         B       *b;
392         P       *top;
393         P       *cursor;
394         long    offset;
395         SCREEN  *t;
396         int     h, w, x, y;
397
398         OPTIONS o;
399         void    *object;
400
401         int     linums;
402         int     top_changed;    /* Top changed */
403 };
404
405 struct menu {
406         W       *parent;        /* Window we're in */
407         unsigned char   **list;         /* List of items */
408         int     top;            /* First item on screen */
409         int     cursor;         /* Item cursor is on */
410         int     width;          /* Width of widest item, up to 'w' max */
411         int     perline;        /* Number of items on each line */
412         int     nitems;         /* No. items in list */
413         int     saved_co;       /* Saved #columns of screen */
414         SCREEN  *t;             /* Screen we're on */
415         int     h, w, x, y;
416         jpoly_int *abrt;        /* Abort callback function */
417         jpoly_int *func;        /* Return callback function */
418         jpoly_int *backs;       /* Backspace callback function */
419         void    *object;
420 };
421
422 struct s_hentry {
423         int     next;
424         int     loc;
425 };
426
427 /* Each terminal has one of these */
428 struct scrn {
429         CAP     *cap;           /* Termcap/Terminfo data */
430
431         int     li;             /* Screen height */
432         int     co;             /* Screen width */
433
434         const unsigned char *ti;        /* Initialisation string */
435         const unsigned char *cl;        /* Home and clear screen... really an
436                                            init. string */
437         const unsigned char *cd;        /* Clear to end of screen */
438         const unsigned char *te;        /* Restoration string */
439
440         int     haz;            /* Terminal can't print ~s */
441         int     os;             /* Terminal overstrikes */
442         int     eo;             /* Can use blank to erase even if os */
443         int     ul;             /* _ overstrikes */
444         int     am;             /* Terminal has autowrap, but not magicwrap */
445         int     xn;             /* Terminal has magicwrap */
446
447         const unsigned char *so;        /* Enter standout (inverse) mode */
448         const unsigned char *se;        /* Exit standout mode */
449
450         const unsigned char *us;        /* Enter underline mode */
451         const unsigned char *ue;        /* Exit underline mode */
452         const unsigned char *uc;        /* Single time underline character */
453
454         int     ms;             /* Ok to move when in standout/underline mode */
455
456         const unsigned char *mb;        /* Enter blinking mode */
457         const unsigned char *md;        /* Enter bold mode */
458         const unsigned char *mh;        /* Enter dim mode */
459         const unsigned char *mr;        /* Enter inverse mode */
460         const unsigned char *me;        /* Exit above modes */
461
462         const unsigned char *Sb;        /* Set background color */
463         const unsigned char *Sf;        /* Set foregrond color */
464         int     ut;             /* Screen erases with background color */
465
466         int     da, db;         /* Extra lines exist above, below */
467         const unsigned char *al, *dl, *AL, *DL; /* Insert/delete lines */
468         const unsigned char *cs;                /* Set scrolling region */
469         int     rr;             /* Set for scrolling region relative addressing */
470         const unsigned char *sf, *SF, *sr, *SR; /* Scroll */
471
472         const unsigned char *dm, *dc, *DC, *ed; /* Delete characters */
473         const unsigned char *im, *ic, *IC, *ip, *ei;    /* Insert characters */
474         int     mi;             /* Set if ok to move while in insert mode */
475
476         const unsigned char *bs;        /* Move cursor left 1 */
477         int     cbs;
478         const unsigned char *lf;        /* Move cursor down 1 */
479         int     clf;
480         const unsigned char *up;        /* Move cursor up 1 */
481         int     cup;
482         const unsigned char *nd;        /* Move cursor right 1 */
483
484         const unsigned char *ta;        /* Move cursor to next tab stop */
485         int     cta;
486         const unsigned char *bt;        /* Move cursor to previous tab stop */
487         int     cbt;
488         int     tw;                     /* Tab width */
489
490         const unsigned char *ho;        /* Home cursor to upper left */
491         int     cho;
492         const unsigned char *ll;        /* Home cursor to lower left */
493         int     cll;
494         const unsigned char *cr;        /* Move cursor to left edge */
495         int     ccr;
496         const unsigned char *RI;        /* Move cursor right n */
497         int     cRI;
498         const unsigned char *LE;        /* Move cursor left n */
499         int     cLE;
500         const unsigned char *UP;        /* Move cursor up n */
501         int     cUP;
502         const unsigned char *DO;        /* Move cursor down n */
503         int     cDO;
504         const unsigned char *ch;        /* Set cursor column */
505         int     cch;
506         const unsigned char *cv;        /* Set cursor row */
507         int     ccv;
508         const unsigned char *cV;        /* Goto beginning of specified line */
509         int     ccV;
510         const unsigned char *cm;        /* Set cursor row and column */
511         int     ccm;
512
513         const unsigned char *ce;        /* Clear to end of line */
514         int     cce;
515
516         /* Basic abilities */
517         int     scroll;         /* Set to use scrolling */
518         int     insdel;         /* Set to use insert/delete within line */
519
520         /* Current state of terminal */
521         int     *scrn;          /* Characters on screen */
522         int     *attr;          /* Attributes on screen */
523         int     x, y;           /* Current cursor position (-1 for unknown) */
524         int     top, bot;       /* Current scrolling region */
525         int     attrib;         /* Current character attributes */
526         int     ins;            /* Set if we're in insert mode */
527
528         int     *updtab;        /* Dirty lines table */
529         int     *syntab;
530         int     avattr;         /* Bits set for available attributes */
531         int     *sary;          /* Scroll buffer array */
532
533         int     *compose;       /* Line compose buffer */
534         int     *ofst;          /* stuff for magic */
535         struct s_hentry *htab;
536         struct s_hentry *ary;
537 };
538
539
540 struct sortentry {
541         unsigned char   *name;
542         unsigned char   *value;
543 };
544
545 struct cap {
546         unsigned char   *tbuf;          /* Termcap entry loaded here */
547
548         struct sortentry *sort; /* Pointers to each capability stored in here */
549         int     sortlen;        /* Number of capabilities */
550
551         unsigned char   *abuf;          /* For terminfo compatible version */
552         unsigned char   *abufp;
553
554         int     div;            /* tenths of MS per char */
555         int     baud;           /* Baud rate */
556         const unsigned char *pad;       /* Padding string or NULL to use NUL */
557         void    (*out) (unsigned char *, unsigned char);                /* Character output routine */
558         void    *outptr;        /* First arg passed to output routine.  Second
559                                    arg is character to write */
560         int     dopadding;      /* Set if pad characters should be used */
561         const char *paste_on;   /* Enable bracketed paste mode */
562         const char *paste_off;  /* Disable bracketed paste mode */
563 };
564
565
566 struct pw {
567         jpoly_int *pfunc;       /* Func which gets called when RTN is hit */
568         jpoly_int *abrt;        /* Func which gets called when window is aborted */
569         jpoly_int *tab;         /* Func which gets called when TAB is hit */
570         unsigned char *prompt;  /* Prompt string */
571         int     promptlen;      /* Width of prompt string */
572         int     promptofst;     /* Prompt scroll offset */
573         B       *hist;          /* History buffer */
574         void    *object;        /* Object */
575 };
576
577 struct stditem {
578         LINK(STDITEM)   link;
579 };
580
581 struct query {
582         W       *parent;        /* Window we're in */
583         jpoly_int *func;        /* Func. which gets called when key is hit */
584         jpoly_int *abrt;
585         void    *object;
586         unsigned char   *prompt;        /* Prompt string */
587         int     promptlen;      /* Width of prompt string */
588         int     promptofst;     /* Prompt scroll offset */
589 };
590
591
592 typedef struct mpx MPX;
593 struct mpx {
594         int     ackfd;          /* Packetizer response descriptor */
595         int     kpid;           /* Packetizer process id */
596         int     pid;            /* Client process id */
597         jpoly_void *func;       /* Function to call when read occures */
598         void    *object;        /* First arg to pass to function */
599         jpoly_void *die;        /* Function: call when client dies or closes */
600         void    *dieobj;
601 };
602
603
604 struct tw {
605         unsigned char   *stalin;        /* Status line info */
606         unsigned char   *staright;
607         int     staon;          /* Set if status line was on */
608         long    prevline;       /* Previous cursor line number */
609         int     changed;        /* Previous changed value */
610         B       *prev_b;        /* Previous buffer (we need to update status line on nbuf/pbuf) */
611 };
612
613 struct irec {
614         LINK(IREC)      link;
615         int     what;           /* 0 repeat, >0 append n chars */
616         long    start;          /* Cursor search position */
617         long    disp;           /* Original cursor position */
618         int     wrap_flag;      /* Wrap flag */
619 };
620
621 struct isrch {
622         IREC    irecs;          /* Linked list of positions */
623         unsigned char *pattern; /* Search pattern string */
624         unsigned char *prompt;  /* Prompt (usually same as pattern unless utf-8/byte conversion) */
625         int     ofst;           /* Offset in pattern past prompt */
626         int     dir;            /* 0=fwrd, 1=bkwd */
627         int     quote;          /* Set to quote next char */
628 };
629
630
631 struct undorec {
632         LINK(UNDOREC)   link;
633         UNDOREC *unit;
634         int     min;
635         int     changed;        /* Status of modified flag before this record */
636         long    where;          /* Buffer address of this record */
637         long    len;            /* Length of insert or delete */
638         int     del;            /* Set if this is a delete */
639         B       *big;           /* Set to buffer containing a large amount of deleted data */
640         unsigned char *small;   /* Set to malloc block containg a small amount of deleted data */
641 };
642
643 struct undo {
644         LINK(UNDO)      link;
645         B       *b;
646         int     nrecs;
647         UNDOREC recs;
648         UNDOREC *ptr;
649         UNDOREC *first;
650         UNDOREC *last;
651 };
652
653 struct srchrec {
654         LINK(SRCHREC)   link;   /* Linked list of search & replace locations */
655         int     yn;             /* Did we replace? */
656         int     wrap_flag;      /* Did we wrap? */
657         long    addr;           /* Where we were */
658 };
659
660 struct search {
661         unsigned char   *pattern;       /* Search pattern */
662         unsigned char   *replacement;   /* Replacement string */
663         int     backwards;      /* Set if search should go backwards */
664         int     ignore;         /* Set if we should ignore case */
665         int     repeat;         /* Set with repeat count (or -1 for no repeat count) */
666         int     replace;        /* Set if this is search & replace */
667         int     rest;           /* Set to do remainder of search & replace w/o query */
668         unsigned char   *entire;        /* Entire matched string */
669         unsigned char   *pieces[26];    /* Pieces of the matched string */
670         int     flg;            /* Set after prompted for first replace */
671         SRCHREC recs;           /* Search & replace position history */
672         P       *markb, *markk; /* Original marks */
673         P       *wrap_p;        /* Wrap point */
674         int     wrap_flag;      /* Set if we've wrapped */
675         int     valid;          /* Set if original marks are a valid block */
676         long    addr;           /* Addr of last replacement or -1 for none */
677         int     block_restrict; /* Search restricted to marked block */
678 };
679
680
681
682 /* Page header */
683
684 struct vpage {
685         VPAGE   *next;          /* Next page with same hash value */
686         VFILE   *vfile;         /* Owner vfile */
687         long    addr;           /* Address of this page */
688         int     count;          /* Reference count */
689         int     dirty;          /* Set if page changed */
690         unsigned char   *data;          /* The data in the page */
691 };
692
693 /* File structure */
694
695 struct vfile {
696         LINK(VFILE)     link;   /* Doubly linked list of vfiles */
697         long    size;           /* Number of bytes in physical file */
698         long    alloc;          /* Number of bytes allocated to file */
699         int     fd;             /* Physical file */
700         int     writeable;      /* Set if we can write */
701         unsigned char   *name;          /* File name.  0 if unnamed */
702         int     flags;          /* Set if this is only a temporary file */
703
704         /* For array I/O */
705         unsigned char   *vpage1;        /* Page address */
706         long    addr;           /* File address of above page */
707
708         /* For stream I/O */
709         unsigned char   *bufp;          /* Buffer pointer */
710         unsigned char   *vpage;         /* Buffer pointer points in here */
711         int     left;           /* Space left in bufp */
712         int     lv;             /* Amount of append space at end of buffer */
713 };
714
715 #endif