⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccasmb.c

📁 KCC , a good c compiler, write by Ken Harrenstien
💻 C
📖 第 1 页 / 共 3 页
字号:
register char *str;
{
    register char i = 6, c;
    register unsigned INT val = 0;

    --str;
    while (i-- > 0 && (c = *++str) != '\0')
	val = val * 050 + torad50 (c);

    return val;
}

/* SYMVAL - Implements _KCCsymval ("filename", "symbol").
**	Called by CCPP to evaluate as a macro expansion.
**	Returns the value of the symbol as looked up in "filename".
**	May encounter an error, in which case a value of 0 is returned.
** If "valf" is zero, we are just seeing whether it is defined or not,
** and only problems with loading the file cause errors.
*/

#define WORD INT
#define WDSIZ (sizeof (INT))
#define RNDUP(a) ((((a)+WDSIZ-1)/WDSIZ)*WDSIZ)	/* Round up # bytes */

#define SF_UNVTYP 0			/* Only .UNV format understood */

struct symfile
    {
    struct symfile
    *sf_next;	/* Ptr to next sym file in chain */
    int sf_type;			/* Type of file (UNV, etc) */
    int sf_ents;			/* # entries in table */
    struct sfent			/*	Format of a table entry */
	{
	INT se_sym;		/*		SIXBIT symbol name */
	INT se_val;		/*		symbol value */
	}
    *sf_entp;			/* Location of table array */
    char sf_fname[1];		/* Name of this file */
    };	/* Filename string is stored immediately following struct */

static struct symfile
*sfhead = NULL;	/* Initially no files loaded */


int
symval (char *fnam, char *sym, int valf)	/* valf=true if want symbol's value */
{
    register struct symfile
    *sf;
    register struct sfent
    *ep;
    register int cnt;
    INT sym6;			/* Symbol name in sixbit */

    /* First search existing loaded files to find right one */
    for (sf = sfhead; sf; sf = sf->sf_next)
	if (strcmp (fnam, sf->sf_fname)==0)	/* Must be exact match */
	    break;

    /* If not already loaded, try to load it. */
    if (!sf)
	{
	if (!ldsymfile (fnam))	/* Load up a symbol file */
	    return 0;		/* If failed, just return now */
	sf = sfhead;		/* else 1st symfile block is right one! */
	}

    /* Now have sf pointing to right symfile block. */
    if (sf->sf_type < 0 || (cnt = sf->sf_ents) <= 0)
	{
	if (valf)
	    error ("No symbols for \"%s\"", fnam);
	return 0;
	}

    sym6 = sixbit (sym);		/* Get sixbit for symbol */
    ep = sf->sf_entp;
    for (; --cnt >= 0; ++ep)	/* Scan thru table looking for sym match */
	{
	if (ep->se_sym == sym6)
	    return (int) (valf ? ep->se_val : 1);	/* Found it! */
	}

    if (valf)
	error ("Symbol lookup failed for \"%s\" in \"%s\"", sym, fnam);
    return 0;			/* Failed, just return zero. */
}

/* LDSYMFILE - Auxiliary for SYMVAL, loads a symbol def file.
**	Returns 0 if error, but new symfile struct is always added to
**	list.
*/
static int
ldsymfile (fnam)
char *fnam;
{
    register struct symfile
    *sf;
    char *tabp;
    struct stat statb;
    int typ, nsyms, sts;
    long flen;
    FILE *fp;


    /* Allocate a symfile struct, plus room for filename after it */
    sf = (struct symfile
    *)calloc (1,sizeof (struct symfile
    ) + strlen (fnam)+1);
    if (sf == NULL)
	{
	error ("Out of memory for symfile \"%s\"", fnam);
	return 0;
	}
    strcpy (sf->sf_fname, fnam);		/* Copy filename into block */
    sf->sf_type = -1;			/* Say no contents yet */
    sf->sf_next = sfhead;		/* Link onto start of list */
    sfhead = sf;


    if ( (sts = stats (fnam, &statb) != 0)
      || (fp = fopen (fnam, "rb")) == NULL)
	{
#if 0 /* kar */
	fprintf (stderr, "sts: %d fp: %o, %s\n", sts, fp, fnam);
#endif
	error ("Could not open symbol file \"%s\": %s",
		    fnam, strerror (_ERRNO_LASTSYSERR));

	if (fp == NULL)
	    fclose (fp);
	return 0;
	}
    flen = statb.st_size;		/* Get file length in bytes */

    /* Find initial size to allocate for contents, and read it in. */
    
    if ((tabp = (char *) calloc (1, (size_t) (RNDUP (flen)))) == NULL)
	error ("Out of memory for symbol file \"%s\"", fnam);

    else if ((long) (fread (tabp, 1, flen, fp)) != flen)
	{
	error ("Could not read symbol file \"%s\": %s",
			    fnam, strerror (_ERRNO_LASTSYSERR));
	free (tabp);
	tabp = NULL;
	}

    fclose (fp);

    if (!tabp)
	return 0;

    /* Now grovel over the contents, turning it into a simple array
    ** of "sfent" symbol entries.
    */
    switch (typ = SF_UNVTYP)		/* May someday have other types */
	{
	case SF_UNVTYP:
	    nsyms = crsfunv (tabp, flen);
	    if (nsyms < 0)
		{
		error ("Symbol file \"%s\" not in UNV format", fnam);
		nsyms = 0;
		}
	    break;
	default:
	    nsyms = 0;
	    break;
	}

    /* Done crunching file into table, now reallocate storage so as to
    ** free up the space we don't need.
    */
    if (nsyms == 0)
	{
	free (tabp);
	tabp = NULL;
	}
    else if ( (tabp = realloc (tabp, nsyms*sizeof (struct sfent
    ))) == NULL)
	int_warn ("Couldn't trim mem for symbol file \"%s\"", fnam);

    sf->sf_entp = (struct sfent
    *)tabp;
    sf->sf_ents = nsyms;
    sf->sf_type = typ;		/* Store type to say now OK */
    return 1;
}


#if !__MSDOS__	/* 4/92 avoid non-ANSI stat () (use LIBCA) */

static void ppnprs (struct _filespec
*f, char *beg, char *end);

int
stats (char *source_fname, struct stat
*statb)
{
    int ret;
    struct _filespec fs = {0};
    struct _filehack ff, *f = &ff;
    MON_MJD	mtime;
    char nname[64];		/* KAR-5/92, added to hold name w/o ppn */
    char *beg, *end;		/* and added these to marc beg & end of PPN */
    char dev[7], fname[7], ext[5], suffix[5];

    if ( (beg = strchr (source_fname, '[')) != NULL)
	{
	if ( (end = strchr (beg, ']')) == NULL)
	    return -1;					/* invalid PPN */
	else
	    ppnprs (&fs, beg, end);

	strncpy (nname, source_fname, (beg - source_fname));
	strcat (nname, (end + 1));
	f->lerppn = fs.fs_path.p_path.ppn;
	}
    else
	{
	strcpy (nname, source_fname);
	f->lerppn = 0;
	}

#if 0
    fprintf (stderr, "nname=%s\n", nname);
#endif

    stats_parse = 1;
    fnparse (nname, dev, fname, ext, suffix);
    stats_parse = 0;
    fs.fs_dev = to_sixbit (dev);
    fs.fs_nam = to_sixbit (fname);
    fs.fs_ext = to_sixbit (&ext[1]);	/* want C not .C */
#if 0 /* kar */
    fprintf (stderr, "%s=0%o %s=0%o %s=0%o, ppn=0%o\n", dev, fs.fs_dev, fname,
	fs.fs_nam, ext, fs.fs_ext, f->lerppn);
#endif
    ff.fs = fs;	/* Copy filespec into big hack struct */

    if (!fs.fs_dev)
	fs.fs_dev = _SIXWRD ("DSK");/*supply default device*/

#if 0 /* KAR-5/92, removed DEVCHR call because it's result wasn't used */
    MUUO_ACVAL ("DEVCHR", fs.fs_dev, &ret);
    if (!ret)
	return -1;
#endif

    f->filop.fo_ios = 0;		/* Simply zap all flags & mode */
    f->filop.fo_brh = 0;		/* Use no buffering */
    f->filop.fo_dev = fs.fs_dev;
    f->xrb.s.rb_cnt = uuosym (".RBTIM");        /* # wds following */
    
    /* KAR-5/92, changed assignment from f->lerppn to 0, lerppn was undef */
    f->xrb.s.rb_ppn = f->lerppn;
    f->xrb.s.rb_nam = fs.fs_nam;
    f->xrb.s.rb_ext.wd = fs.fs_ext;
    f->xrb.s.rb_prv.wd = 0;
    f->filop.fo_chn = uuosym ("FO.ASC") >> 18;
    f->filop.fo_fnc = uuosym (".FORED");
    f->filop.fo_nbf = 0;
    f->filop.fo_leb = XWD (0, (int)&f->xrb);
    f->error = -1;
    if (!MUUO_ACVAL ("FILOP.", XWD (6, (int)&f->filop), &ret))
	f->error = ret;
    if (f->error != -1)
	return -1;

    /* KAR-5/92, added MON_ calls to get correct times */
    if (MON_Get_File_Times (f->filop.fo_chn, &mtime, 0))
	return -1;

    statb->st_mtime = MON_MJD_To_Time (mtime);

    ret = XWD (f->filop.fo_chn, uuosym (".FOREL"));
    MUUO_AC ("FILOP.", XWD (1, (int)&ret));
    statb->st_size = 4 * f->xrb.s.rb_siz;

#if 0 /* KAR-5/92, replaced with MON_ calls, this needs another call; see stat.c */
    statb->st_mtime = (XWD (
	 (f->xrb.s.rb_ext.rb.crx << 12) | f->xrb.s.rb_prv.rb.crd,
	f->xrb.s.rb_prv.rb.crt * 60));
#endif
    return 0;
}

static long
to_sixbit (char *str)
{
    long    tmp, sbit_val = 0;
    short    cnt = 36;

    while (*str != NULL)
	{
	tmp = toupper (*str) - 040;
	cnt -= 06;
	sbit_val |= tmp << cnt;
	str++;
	} /* while */

    return sbit_val;
}

#define _LHALF 0777777000000	/* Left half mask */
#define _RHALF 0777777		/* Right half mask */

/* FLDGET (wd,mask)     - Get right-justified value from field in word */
#define FLDGET(wd,mask) ( ( (unsigned) (wd)& (mask))/ ( (mask)& (- (mask))))

/* KAR-5/92, added to allow stats () to parse PPN numbers */
/* beg pts to '[' and end ptrs to ']' */
static void
ppnprs (struct _filespec* f, char *beg, char *end)
    {
    int lh = 0, rh = 0, defppn = 0;
    char tmp[16];

    strncpy (tmp, beg, (end - beg) - 1); /* get P,PN into tmp */

    sscanf (tmp, "%o,%o", &lh, &rh);	 /* get P into lh and PN into rh */

    if (!lh || !rh)			 /* get default PPN if not specifed */
	MUUO_VAL ("GETPPN", &defppn);

    if (!lh)
	lh = FLDGET (defppn, _LHALF);

    if (!rh)
	rh = FLDGET (defppn, _RHALF);

    f->fs_path.p_path.ppn = XWD (lh,rh);
    f->fs_nfds = 1;
    f->fs_path.p_arg = 0;
    }
#endif

/* UNV format symbol file cruncher.
**	Argument is char ptr to file in memory, plus length.
**	Returns # of symbol def entries (sfent) that were made;
**	array starts in same location as file.
*/

/* From MACRO source:

The first word of a .UNV file must be:
777,,<UNV version stuff>	= <UNVF_xxx flags>

If the UNVF_MACV flag is set, the next word will be:
<.JBVER of the MACRO that produced this UNV>

The next word is:
<# symbols>

Followed by the symbol table definitions, which are all at least
2 words long:
<SIXBIT symbol name>
<flags or value>

*/

#define UNVF_MACV 020	/* Has MACRO .JBVER in 2nd word */
#define UNVF_SYN 010	/* "New SYN handling in universal" */
#define UNVF_BAS 004	/* Must always have this bit on for compatibility */
#define UNVF_POL 002	/* Polish fixups included */
#define UNVF_MAD 001	/* "macro arg default value bug fixed" */

/* Symbol table flags */
#define USF_SYMF (0400000L <<18) /* Symbol */
#define	USF_TAGF (0200000L <<18) /* Tag */
#define USF_NOUT (0100000<<18)	/* No DDT output */
#define USF_SYNF  (040000<<18)	/* Synonym */
#define	USF_MACF  (020000<<18)	/* Macro */
#define USF_OPDF  (010000<<18)	/* Opdef */
#define	USF_PNTF   (04000<<18)	/* Symtab "val" points to real 36-bit val */
#define	USF_UNDF   (02000<<18)	/* Undefined */
#define	USF_EXTF   (01000<<18)	/* External */
#define	USF_INTF    (0400<<18)	/* Internal */
#define	USF_ENTF    (0200<<18)	/* Entry */
#define USF_VARF    (0100<<18)	/* Variable */
#define USF_NCRF     (040<<18)	/* Don't cref this sym */
#define	USF_MDFF     (020<<18)	/* multiply defined */
#define	USF_SPTR     (010<<18)	/* special external pointer */
#define USF_SUPR      (04<<18)	/* Suppress output to .REL and .LST */
#define	USF_LELF      (02<<18)	/* LH relocatable */
#define	USF_RELF      (01<<18)	/* RH relocatable */

#define	SYM6_SYMTAB	0166371556441L	/* .SYMTAB in sixbit */
#define	SYM6_UNVEND	0373737373737L

static int
crsfunv (tabp, flen)
char *tabp;			/* Location of file in memory */
long flen;			/* # bytes in file */
{
    register INT *rp;
    register INT cnt;
    register struct sfent
    *ep;
    INT wd, flags;

    cnt = flen/WDSIZ;		/* Get # words in file (round down) */
    rp = (INT *)tabp;		/* Set up word pointers to start */
    ep = (struct sfent
    *)rp;

#define nextwd() (--cnt >= 0 ? *++rp : 0)
#define skipwd(n) ( (void) (cnt -= n, rp += n))

    if ( (*rp&LH) != (0777<<18))	/* Is it really a UNV file? */
	{
	return -1;		/* No, say bad format. */
	}
    if (*rp&UNVF_MACV)		/* If has MACRO version word, */
	skipwd (1);		/* skip it. */
    skipwd (1);			/* Skip # of symbols for now */
    skipwd (2);			/* Also skip 1st symbol def (why??) */
    while (cnt > 0)
	{
	if (nextwd () == 0)	/* Get next word, */
	    continue;		/* ignoring zero words. */
	if (*rp == SYM6_UNVEND)	/* End of UNV file contents? */
	    break;
	flags = nextwd ();	/* Next word is flags or value */

	/* Quick check for any bad bits. */
	if ( (flags & (USF_MACF|USF_TAGF|USF_UNDF|USF_EXTF
		|USF_ENTF|USF_MDFF|USF_SPTR|USF_LELF|USF_RELF))==0)
	    {
	    ep->se_sym = rp[-1];	/* Hurray, set symbol name in entry */
	    ep->se_val = (flags & USF_PNTF)	/* 36-bit value? */
			? nextwd () : (*rp&RH);	/* If not, just use RH */

	    if (ep->se_sym != SYM6_SYMTAB)/* Unless sym we don't want, */
		++ep;			/* make it part of table. */
	    continue;			/* Won, back to start of loop */
	    }

	/* Not a constant symbol def, so we have to flush it. */
	if (flags & USF_MACF)		/* Macro? */
	    {
	    do
		{
		wd = nextwd ();
		skipwd (3);
		}
	    while (wd & LH)
		;
	    wd = nextwd ();
	    if (wd & 0770000000000L)	/* possible sixbit sym? */
		{
		++cnt, --rp;		/* Yes, assume no macro args */
		continue;		/* Back up one and continue */
		}
	    wd = (wd >> 18) & RH;
	    while (wd-- >= 0)		/* Flush macro args */
		skipwd (5);
	    continue;
	    }

	/* Special external pointer?  Relocatable or polish fixup */
	if (flags & USF_SPTR)
	    {
	    skipwd (1);		/* Flush value */
	    if ( (wd = nextwd ()) >= 0)	/* Get relocation word */
		{
		if (wd&RH)
		    skipwd (2);	/* Flush any right-half relocation */
		if (wd&LH)
		    skipwd (2);	/* Ditto for left-half reloc */
		continue;
		}
	    /* Ugh, polish.  Val plus <polish expression> */
	    while (cnt > 0)		/* Ensure don't run off */
		{
		while (nextwd ())
		    ;	/* Flush links */
		wd = nextwd ();		/* Hit zero word, get next */
		if (wd < 0 || wd >= 14)
		    break;
		else
		    skipwd (6);		/* Flush 6 wds */
		}
	    }
	else if (flags & USF_EXTF)	/* simple external? */
	    {
	    skipwd (2);			/* 2 wds, <value> + <symbol> */
	    }
	else if (flags & USF_PNTF)	/* Simple full-word value? */
	    {
	    skipwd (1);			/* 1 wd, <value> */
	    }
	}	/* Loop til all symbols scanned */

    return ep - ( (struct sfent
    *)tabp); /* Return # entries we got */
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -