282 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			282 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| /* SB - Copyright 1982 by Ken Harrenstien, SRI International
 | ||
|  *	This software is quasi-public; it may be used freely with
 | ||
|  *	like software, but may NOT be sold or made part of licensed
 | ||
|  *	products without permission of the author.  In all cases
 | ||
|  *	the source code and any modifications thereto must remain
 | ||
|  *	available to any user.
 | ||
|  *
 | ||
|  *	This is part of the SB library package.
 | ||
|  *	Any software using the SB library must likewise be made
 | ||
|  *	quasi-public, with freely available sources.
 | ||
|  */
 | ||
| 
 | ||
| #ifdef COMMENT
 | ||
| 
 | ||
| The initials "SB" stand for "String Block" or "String Buffer".
 | ||
| 
 | ||
| SBBUFFER - A SB buffer containing a sbstring opened for editing.
 | ||
| SBFILE   - A structure holding file-specific information for all
 | ||
| 		SDBLKs pointing to that file.
 | ||
| SBSTRING - A SB string; conceptually a single string, but actually
 | ||
| 		a linked list of SDBLKs.  Unless opened by a SBBUFFER,
 | ||
| 		only a few operations are allowed on SBSTRINGs (creating,
 | ||
| 		copying, deleting).
 | ||
| SDBLK    - One of the linked nodes constituting a sbstring.  Each SDBLK
 | ||
| 		node points to a continuous string either in memory or
 | ||
| 		on disk, or both.
 | ||
| SBLK	 - Another name for SDBLK.
 | ||
| SMBLK	 - An allocated chunk of memory.  Also refers to the node structure
 | ||
| 		maintained by the SBM memory management routines, which
 | ||
| 		points to the actual chunk of memory.
 | ||
| SBM	 - Name of the memory management package.  SBM routines are used
 | ||
| 		to allocate memory in general, and are not just for
 | ||
| 		use by SB routines.
 | ||
| 
 | ||
| ************ MACHINE DEPENDENT DEFINITIONS **********
 | ||
| 
 | ||
| 	The following compile time definitions represent machine
 | ||
| dependent parameters which are intended mainly for use only by SBM and
 | ||
| SBSTR routines.  Other programs should use them with caution.  Note
 | ||
| that a great deal of code assumes that type "int" corresponds to a basic
 | ||
| machine word (as per C Reference Manual).
 | ||
| 
 | ||
| 	The current definitions will only work for machines which have
 | ||
| 1, 2, 4, or 8 "char" bytes in a machine word.  Any other size will
 | ||
| require some changes to the definitions and possibly to some places
 | ||
| using them.
 | ||
| 
 | ||
| WORD   - integer-type definition corresponding to machine word.
 | ||
| WDSIZE - # addressable char bytes in a machine word.		(1, 2, 4, 8)
 | ||
| WDBITS - # low order bits in an address, ie log2(WDSIZE).	(0, 1, 2, 3)
 | ||
| WDMASK - Mask for low order bits of address			(0, 1, 3, 7)
 | ||
| CHAR_MASK - If defined, machine does sign-extension on chars, and
 | ||
| 	they must be masked with this value.
 | ||
| 
 | ||
| 	Note that the macro for WDBITS has no mathematical significance
 | ||
| other than being an expression which happens to evaluate into the right
 | ||
| constant for the 4 allowed values of WDSIZE, and in fact it is this
 | ||
| crock which restricts WDSIZE!  If C had a base 2 logarithm expression
 | ||
| then any power of 2 could be used.
 | ||
| 
 | ||
| Values for machines
 | ||
| 				WORD	WDSIZE	WDBITS	WDMASK
 | ||
| 	PDP11, Z8000, I8086	int	2	1	01
 | ||
| 	VAX11, M68000, PDP10	int	4	2	03
 | ||
| 
 | ||
| #endif /* COMMENT */
 | ||
| 
 | ||
| /* First try to define a few things in a semi-portable way
 | ||
| */
 | ||
| #include "eesite.h"
 | ||
| #ifdef __STDC__		/* Implementation supports ANSI stuff? */
 | ||
| #include <limits.h>		/* Get sizes for char stuff */
 | ||
| #define _SBMUCHAR 1		/* Can use "unsigned char" */
 | ||
| #define _SBMCHARSIGN (CHAR_MIN < 0)	/* True if "char" is sign-extended */
 | ||
| #define CHAR_MASK (UCHAR_MAX)
 | ||
| 
 | ||
| #else	/* not ANSI */
 | ||
| #ifndef _SBMUCHAR		/* Default assumes no "unsigned char" */
 | ||
| #define _SBMUCHAR 0
 | ||
| #endif
 | ||
| #ifndef _SBMCHARSIGN		/* Default assumes "char" is sign-extended */
 | ||
| #define _SBMCHARSIGN 1
 | ||
| #endif
 | ||
| #ifndef CHAR_MASK		/* Default assumes "char" is 8 bits */
 | ||
| #define CHAR_MASK 0377
 | ||
| #endif
 | ||
| #endif	/* not ANSI */
 | ||
| 
 | ||
| /* Define "sb_uchartoint" as a macro which ensures that an unsigned
 | ||
| ** character value is converted properly to an int value.
 | ||
| */
 | ||
| #if (_SBMUCHAR || (_SBMCHARSIGN==0))
 | ||
| #define sb_uchartoint(a) (a)		/* No fear of sign extension */
 | ||
| #else
 | ||
| #define sb_uchartoint(a) ((a)&CHAR_MASK)	/* Bah, sign extension */
 | ||
| #endif
 | ||
| 
 | ||
| 
 | ||
| /* Defs for machines with a base-2 WDSIZE.  Yes, the (int) is indeed necessary
 | ||
|  * (to allow implicit conversion to long where needed - the PDP11 compiler
 | ||
|  * is known to lose without it, because sizeof is cast as "unsigned int"
 | ||
|  * which loses big in long masks!)
 | ||
|  */
 | ||
| #define WORD int
 | ||
| #define WDSIZE ((int)(sizeof(WORD)))
 | ||
| #define WDMASK (WDSIZE-1)
 | ||
| #define WDBITS ((WDSIZE>>2)+(1&WDMASK))
 | ||
| 
 | ||
| #define rnddiv(a) ((a)>>WDBITS)		/* # words, rounded down */
 | ||
| #define rndrem(a) ((a)&WDMASK)		/* # bytes remaining past wd bndary */
 | ||
| #define rnddwn(a) ((a)&~WDMASK)		/* Round down to word boundary */
 | ||
| #define rndup(a)  rnddwn((a)+WDSIZE-1)	/* Round up to word boundary */
 | ||
| 
 | ||
| #ifdef COMMENT	/* The following are for machines without a base-2 WDSIZE */
 | ||
| #define rnddiv(a) ((a)/WDSIZE)
 | ||
| #define rndrem(a) ((a)%WDSIZE)
 | ||
| #define rnddwn(a) ((a)-rndrem(a))
 | ||
| #define rndup(a)  rnddwn((a)+WDSIZE-1)
 | ||
| #undef WDMASK			/* These become meaningless and anything */
 | ||
| #undef WDBITS			/* which uses them should be changed! */
 | ||
| #endif /* COMMENT */
 | ||
| 
 | ||
| /* The following 3 definitions are somewhat machine-dependent,
 | ||
|  * but are specifically intended for general use and work for all
 | ||
|  * currently known C implementations.
 | ||
|  *	SBMO must be an integer-type object large enough to hold
 | ||
|  *	the largest difference in SBMA pointers, and must not be
 | ||
|  *	used in signed comparisons.
 | ||
|  */
 | ||
| 
 | ||
| typedef long chroff;		/* CHROFF - Char offset in disk/sbstr */
 | ||
| typedef unsigned int SBMO;	/* SBMO - Char offset in memory */
 | ||
| typedef
 | ||
| #if _SBMUCHAR
 | ||
| 	unsigned
 | ||
| #endif
 | ||
| 		char *SBMA;	/* SBMA - Pointer to char loc in memory */
 | ||
| 
 | ||
| 
 | ||
| 
 | ||
| /* The following definitions tend to be system-dependent.  Only the
 | ||
|  * SBM and SBSTR routines use them.
 | ||
|  */
 | ||
| #define SB_NFILES 32		/* # of open files we can hack.  Actually
 | ||
| 				 * this is max FD value plus 1. */
 | ||
| #define SB_BUFSIZ 512		/* Optimal buffer size (system block size) */
 | ||
| #define SB_SLOP (16*WDSIZE)	/* # slop chars to tolerate for allocations */
 | ||
| 
 | ||
| #define SMNODES (20)		/* # SM or SD nodes to create when needed */
 | ||
| #define SMCHUNKSIZ (16*512)	/* # bytes of mem to create (via sbrk) " " */
 | ||
| #define MAXSBMO ((SBMO)-1)	/* Used in SBM only */
 | ||
| 		/* MAXSBMO should be the largest possible SBMO value. */
 | ||
| 
 | ||
| #define EOF (-1)
 | ||
| #define SBFILE struct sbfile
 | ||
| #define SBBUF struct sbbuffer
 | ||
| #define SBSTR struct sdblk	/* Start of a sbstring */
 | ||
| 
 | ||
| struct sbfile {
 | ||
| 	int sfflags;		/* Various flags */
 | ||
| 	int sffd;		/* FD for file (-1 if none) */
 | ||
| 	struct sdblk *sfptr1;	/* Ptr to 1st node in phys list */
 | ||
| 	chroff sflen;		/* Original length of file FD is for */
 | ||
| };
 | ||
| 
 | ||
| 	/* Definition of SBBUF string/buffer */
 | ||
| struct sbbuffer {
 | ||
| 	SBMA sbiop;		/* I/O pointer into in-core text */
 | ||
| 	int sbrleft;		/* # chars left for reading */
 | ||
| 	int sbwleft;		/* # chars left for writing */
 | ||
| 	int sbflags;		/* Various flags */
 | ||
| 	chroff sbdot;		/* Logical pos for start of current sdblk */
 | ||
| 	chroff sboff;		/* Offset into current sdblk (if no smblk)*/
 | ||
| 	struct sdblk *sbcur;	/* Pointer to current SD block of string */
 | ||
| };
 | ||
| 	/* Flags for "sbflags" */
 | ||
| #define SB_OVW	01	/* Over-write mode */
 | ||
| #define SB_WRIT 02	/* Written; smuse needs to be updated from sbiop */
 | ||
| 
 | ||
| 	/* NOTE: An unused sbbuf structure should be completely zeroed.
 | ||
| 	 *	This will cause routines to handle it properly
 | ||
| 	 *	if they are accidentally pointed at it.
 | ||
| 	 */
 | ||
| 
 | ||
| 	/* Definition of SDBLK */
 | ||
| struct sdblk {
 | ||
| 	struct sdblk *slforw;	/* Logical sequence forward link */
 | ||
| 	struct sdblk *slback;	/* Logical sequence backward link */
 | ||
| 	int sdflags;
 | ||
| 	struct sdblk *sdforw;	/* Physical sequence (disk) */
 | ||
| 	struct sdblk *sdback;	/* ditto - backptr for easy flushing */
 | ||
| 	struct smblk *sdmem;	/* Mem pointer, 0 if no in-core version */
 | ||
| 	SBFILE *sdfile;		/* File pointer, 0 if no disk version */
 | ||
| 	chroff sdlen;		/* # chars in disk text */
 | ||
| 	chroff sdaddr;		/* Disk address of text */
 | ||
| };
 | ||
| 	/* Flags for "sdflags" */
 | ||
| #define SD_LOCK 0100000		/* Locked because opened by a SBBUF */
 | ||
| #define SD_LCK2	0040000		/* Locked for other reasons */
 | ||
| #define SD_MOD	0020000		/* Modified, mem blk is real stuff */
 | ||
| #define SD_NID	   0323		/* Node ID marks active (not on freelist) */
 | ||
| #define SD_LOCKS (SD_LOCK|SD_LCK2)
 | ||
| 
 | ||
| /* Note sdback is ONLY needed for fixing up phys list when a sdblk is
 | ||
|  * deleted (so as to find previous blk in phys list).  Perhaps it shd
 | ||
|  * be flushed (ie only use SDFORW)?  How to do deletions - use circular
 | ||
|  * list?  Sigh.
 | ||
|  */
 | ||
| 
 | ||
| 	/* Definition of SMBLK (used by SBM routines) */
 | ||
| struct smblk {
 | ||
| 	struct smblk *smforw;	/* Links to other mem blks, in phys order */
 | ||
| 	struct smblk *smback;
 | ||
| 	int smflags;		/* Type, in-use flags */
 | ||
| 	SBMA smaddr;		/* Mem address of text */
 | ||
| 	SBMO smlen;		/* # bytes in mem block */
 | ||
| 	SBMO smuse;		/* # bytes "used" in block */
 | ||
| };
 | ||
| 	/* Flags for "smflags" */
 | ||
| #define SM_USE	0100000		/* Block is in use (mem free if off) */
 | ||
| #define SM_NXM	 040000		/* Block mem is non-existent */
 | ||
| #define SM_EXT	 020000		/* Block mem owned by external (non-SBM) rtn*/
 | ||
| #define SM_MNODS 010000		/* Block holds SMBLK nodes */
 | ||
| #define SM_DNODS  04000		/* Block holds SDBLK nodes */
 | ||
| #define SM_NID	   0315		/* Node in-use identifier (low byte) */
 | ||
| 
 | ||
| /* Error handler type values */
 | ||
| #define SBMERR 0	/* Error in SBM package */
 | ||
| #define SBXERR 1	/* Error in SBSTR package */
 | ||
| #define SBFERR 2	/* "Error" - SBSTR package found a file overwritten.
 | ||
| 			 *	Non-zero return will continue normally. */
 | ||
| 
 | ||
| 
 | ||
| /* Redefine certain external symbols to be unique in the first 6 chars
 | ||
| ** to conform with ANSI requirements.
 | ||
| */
 | ||
| #define sbm_nfre sbmnfre	/* SBM stuff */
 | ||
| #define sbm_nfor sbmnfor
 | ||
| #define sbm_nmov sbmnmov
 | ||
| #define sbm_ngc  sbmngc
 | ||
| #define sbx_ndget sbxndg	/* SBSTR stuff */
 | ||
| #define sbx_ndel  sbxnde
 | ||
| #define sbx_ndfre sbxndf
 | ||
| #define sbx_sdcpy sbxsdc
 | ||
| #define sbx_sdgc  sbxsdg
 | ||
| #define sbe_sdlist sbesls	/* SBERR stuff */
 | ||
| #define sbe_sdtab  sbestb
 | ||
| #define sbe_sds    sbesds
 | ||
| #define sbe_sbvfy  sbesbv
 | ||
| #define sbe_sbs    sbesbs
 | ||
| 
 | ||
| /* Forward declarations */
 | ||
| extern SBMA sbm_lowaddr;	/* For roundoff purposes */
 | ||
| 
 | ||
| extern SBFILE sbv_tf;		/* SBFILE for temp swapout file */
 | ||
| extern int (*sbv_debug)();	/* Error handler address */
 | ||
| extern off_t lseek();		/* For sbstr code mostly */
 | ||
| extern char *mktemp();
 | ||
| extern char *malloc();
 | ||
| extern char *calloc();
 | ||
| extern SBBUF *sb_open();
 | ||
| extern SBSTR *sb_close(), *sb_fduse(), *sbs_cpy(), *sbs_app(), *sb_cpyn(),
 | ||
| 	*sb_killn();
 | ||
| extern struct sdblk *sbx_ready();
 | ||
| extern chroff sb_tell(), sb_ztell(), sbs_len();
 | ||
| 
 | ||
| /* Definition of SB_GETC, SB_PUTC, SB_BACKC macros */
 | ||
| 
 | ||
| #define sb_putc(s,c) (--((s)->sbwleft) >= 0 ? \
 | ||
| 				(*(s)->sbiop++ = c) : sb_sputc(s,c))
 | ||
| #define sb_getc(s)   (--((s)->sbrleft) >= 0 ? \
 | ||
| 				sb_uchartoint(*(s)->sbiop++) : sb_sgetc(s))
 | ||
| #define sb_peekc(s)  ((s)->sbrleft > 0 ? \
 | ||
| 				sb_uchartoint(*(s)->sbiop)   : sb_speekc(s))
 | ||
| 
 | ||
| /* WARNING - sb_backc must ONLY be used if last operation was a
 | ||
|  * successful sb_getc!!  For slow but sure invocation use sb_rgetc.
 | ||
|  */
 | ||
| #define sb_backc(s) (++(s->sbrleft), --(s->sbiop))
 | ||
| 
 | ||
| #include "sbproto.h"	/* function prototypes */
 | 
