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 716