📄 ccasmb.c
字号:
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 + -