📄 cc.c
字号:
static
int
cfile (char *arg)
{
int mainflg; /* Set if module contains "main" */
int asmdflg = -2; /* Set to result of assembly attempt */
clock_t startime;
extern
int nsert_file (char *f, int insert_flag);
int save_fline;
int save_tline;
if (!vrbsta)
startime = clock(); /* Mark cpu time */
/* 11/91 added nwarns */
nerrors = nwarns = err_waiting = 0; /* KAR added err_waiting init */
if (!files(arg)) /* If couldn't open or file is .REL, */
return asmdflg; /* just return. */
if (mlist) /* set up output file with page hdr */
{
opage = 0;
outpghdr();
}
module_loop:
save_fline = fline;
save_tline = tline;
if (!prepf)
{
fprintf (outmsgs, "KCC: %s\n", (module_pragma) ? title : inpfmodule);
if (outmsgs == stdout)
fprintf (stderr, "KCC: %s\n",
(module_pragma) ? title : inpfmodule);
}
syminit (); /* Set up symbol tables */
ppinit (); /* Initialize the input preprocessor */
ppdefine (npreundef,preundefs, /* then can do initial -U undefs */
npredef, predefs); /* and initial -D definitions */
if (module_pragma)
{
fline = save_fline; /* ppinit() reset fline */
tline = save_tline;
module_pragma = 0;
lexinit ();
module_pragma = 1;
}
else
lexinit (); /* Initialize the input lexer */
initpar (); /* Initialize the input parser */
/* KAR-6/92, moved reset of -i here to handle multiple files as well */
nsert_file (NULL,0); /* turn off "-i" command line switch */
dbginit (); /* Initialize src debugger output */
if (prepf) /* If only preprocessor output (-E) */
{
passthru (stdout); /* send it through specially */
fclose (in); /* and then close input */
#if DEBUG_KCC /* 5/91 KCC size */
if (debsym)
{
symdump (minsym->Snext, "external"); /* symbol table dump */
typedump ();
fclose (fsym);
}
#endif
}
else /* Normal compilation processing */
{
NODE* n;
/* if (module_pragma) outinit() puts title in *.mac outpreamble()*/
outinit (); /* Initialize assembler code output */
module_pragma = 0;
if (eof)
{
if (clevel >= CLEV_STRICT)
error ("File must contain at least one external definition");
else
warn ("Null source file");
}
while (!eof) /* Process each external definition */
{
savelits = 0; /* Reset string literal pool */
nodeinit (); /* Reset parse-tree node table */
curfn = NULL; /* Not in any function */
n = extdef (); /* parse one external definition */
/* 2/92 may turn on module_pragma */
#if DEBUG_KCC /* 5/91 KCC size */
if (debpar)
nodedump (n); /* Dump parse tree if debugging */
#endif
gencode (n); /* Call code generator on parse tree */
}
if (!module_pragma)
{
fclose (in); /* Done with input stream, close it. */
curfn = NULL; /* Not in any function */
fline = 0; /* Avoid context on errs after this */
}
while ((n = tntdef ()) != NULL) /* Output remaining tentative defs */
{
#if DEBUG_KCC /* 5/91 KCC size */
if (debpar)
nodedump (n);
#endif
gencode (n);
nodeinit (); /* Reset node table after each */
}
if ((mainflg = mainsymp ()) != 0) /* Is "main" defined in module? */
strcpy (mainname, inpfmodule); /* Yes, save module name! */
switch (abs (debcsi))
{
case KCC_DBG_SDBG :
case KCC_DBG_FDBG :
savesymtab (minsym->Snext); /* generate debug symtab */
break;
default:
break;
}
outdone (mainflg); /* Output assembler postamble stuff */
if (module_pragma)
goto module_loop;
fclose (out); /* and close assembler output file. */
#if DEBUG_KCC /* 5/91 KCC size */
if (debsym)
{
symdump (minsym->Snext, "external"); /* symbol table dump */
typedump ();
fclose (fsym);
}
if (debpar)
fclose (fdeb); /* Close parse tree debug file */
if (debpho)
fclose (fpho); /* Close peephole debug file */
#endif
if (!nerrors && assemble)
asmdflg = asmb ((savofnam ? savofnam : inpfmodule),
(char *) NULL, outfname); /* and this. */
if ((delete && asmdflg != 0) && (!mlist))
remove (outfname);
}
if (outmsgs == stdout)
fprintf (outmsgs, "%% KCC - %d warning%s detected\n", nwarns,
nwarns == 1 ? "" : "s" );
if (nwarns) /* Report warnings */
fprintf (stderr, "%% KCC - %d warning%s detected\n", nwarns,
nwarns == 1 ? "" : "s" );
if (nerrors) /* Report errors */
jmsg ("%d error%s detected", nerrors, nerrors == 1 ? "" : "s" );
else if (!vrbsta)
showcpu (startime); /* or say how much cpu we used */
return asmdflg; /* Return assembly result */
}
/* Auxiliary - returns true if main() was defined in this module */
static
int
mainsymp (void)
{
SYMBOL* s;
return ((s = symfidstr ("main")) != NULL && s->Sclass == SC_EXTDEF);
}
/*
* FILES - parse a filename argument and set up I/O streams.
*
* Note that "prefname" is set up here, but not opened.
* This is because we may not need to use it; the call to
* "makprefile()" will do so if necessary.
*/
static
int
files (char *fname)
{
int cextf;
char* cp;
char cname[FNAMESIZE]; /* Name of .C source file */
char rname[FNAMESIZE]; /* Name of .REL binary file */
char ext[FNAMESIZE]; /* Temp to hold parsed extension */
/*
** Parse filename into its various pieces, mainly to get module name.
** As a special case, it will work to specify a device (logical) name
** with no filename, e.g. you can say
** @CC FOO:
** where FOO: => <DIR>NAME.C, and the module name will be FOO.
*/
/* in __MSDOS__ fnparse() calls fnsplit() */
if ((cp = fnparse (fname, inpfdir, inpfmodule, ext, inpfsuf)) != NULL)
{
jerr ("Bad filename arg (%s): \"%s\"", cp, fname); /* Ugh */
return 0; /* and don't try to compile */
}
if (fnxisrel(ext)) /* .obj for DOS */
return 0;
/* Check for .C or .H extensions. "cextf" is set if we have it. */
cextf = (ext[0] == '.'
&& (toupper(ext[1]) == 'C' || toupper(ext[1]) == 'H') && !ext[2]);
/* Now compose source filename with ".C" appended if necessary */
if (cextf)
strcpy (cname, fname); /* Found .C, just copy filename */
else
{
#if __MSDOS__
estrcpy (estrcpy (estrcpy (estrcpy (cname, /* Rebuild filename */
inpfsuf), inpfdir), inpfmodule), ".c");
#else
estrcpy (estrcpy (estrcpy (estrcpy (cname, /* Rebuild filename */
inpfdir), inpfmodule), ".c"), inpfsuf);
#endif
}
if (mlist)
{
int i;
for (i = 0; cname[i] != '\0'; i++)
dspfname[i] = toupper(cname[i]);
dspfname[i] = '\0';
getimestr(cname);
}
/*
* If the -q conditional compile flag was
* set, we assume that we are to check the .C and .REL extensions of
* this file to determine whether compilation is necessary.
*/
if (condccf)
{
strcpy (rname, inpfmodule); /* Make the .REL filename */
strcat (rname, ".rel");
if (!needcomp (cname, rname))
return 0; /* Doesn't need to be compiled! */
}
/*
* Now that we've figured out what the name of the file is, we can try
* to open it. First we try the filename as given, and if that doesn't
* work (most likely because no .C was specified) then we try the
* one we constructed by adding .C.
*/
strcpy (inpfname, fname); /* Try filename as given */
#if __MSDOS__ /* FW 2A(47) */
in = fopen (inpfname, "r");
#else
switch (sourcebytewidth) /* FW 2A(47) */
{
case 8 :
in = fopen (inpfname, "r8");
break;
case 9 :
in = fopen (inpfname, "r9");
break;
default :
in = fopen (inpfname, "r");
break;
}
#endif
if (in == NULL)
{
strcpy (inpfname, cname); /* then constructed filename */
#if __MSDOS__ /* FW 2A(47) */
in = fopen (inpfname, "r");
#else
switch (sourcebytewidth) /* FW 2A(47) */
{
case 8 :
in = fopen (inpfname, "r8");
break;
case 9 :
in = fopen (inpfname, "r9");
break;
default :
in = fopen (inpfname, "r");
break;
}
#endif
if (in == NULL)
{
errfopen("input", inpfname);
return 0;
}
}
#if DEBUG_KCC /* 5/91 KCC size */
/* Compose symbol table dump output filename, if desired */
if (debsym)
{
strcpy (symfname, inpfmodule);
strcat (symfname, ".cym");
if ((fsym = fopen(symfname, "w")) == NULL)
{
errfopen("symbol table", symfname);
return 0;
}
}
#endif
/* If we are only doing pre-processing, then no other filenames are
** needed, and we can return now.
*/
if (prepf)
return 1;
/*
** The output file is merely ".mac" etc concatenated to the stripped
** filename we calculated above, in the current directory.
*/
cp = ".mac";
if (savofnam != NULL)
{
char *tfnam, *ptr;
tfnam = (char *) calloc (strlen (savofnam), sizeof(char *));
if (tfnam == NULL)
jerr("Out of memory for .REL filenames\n");
strcpy (tfnam, savofnam);
ptr = strchr(tfnam, '.');
if (ptr == NULL)
strcat (strcpy(outfname, savofnam), cp);
else
{
*ptr = '\0';
strcat (strcpy(outfname, tfnam), cp);
}
free (tfnam);
}
else
strcat(strcpy(outfname, inpfmodule), cp); /* Compose output filename */
if ((out = fopen(outfname, "w")) == NULL)
{
errfopen("output", outfname);
return 0;
}
/* Now open various other debugging output files */
if (debpar) /* debugging output goes here */
{
strcpy(debfname, inpfmodule);
strcat(debfname, ".deb");
if ((fdeb = fopen(debfname, "w")) == NULL)
{
errfopen("parser debugging output", debfname);
return 0;
}
}
#if DEBUG_KCC /* 5/91 KCC size */
if (debpho) /* Peephole debugging output goes here */
{
strcpy(phofname, inpfmodule);
strcat(phofname, ".pho");
if ((fpho = fopen(phofname, "w")) == NULL)
{
errfopen("peephole debugging output", phofname);
return 0;
}
}
#endif
return 1;
}
/*
* NEEDCOMP - Auxiliary for above.
* Takes source and binary filenames, returns TRUE if
* source needs compiling (is newer than binary).
*/
#if __MSDOS__ /* 4/92 avoid non-ANSI stat() */
#define stats stat /* just use stat() */
#else
extern
int stats (char *source_fname, struct stat* statb);
#endif
static
int
needcomp (char* src, char* rel)
{
struct
stat sbuf,
rbuf;
if (stats(src, &sbuf) < 0)
return 1;
/* No source?? Try compiling anyway */
if (stats(rel, &rbuf) < 0)
return 1; /* No .REL, so must compile */
return (sbuf.st_mtime > rbuf.st_mtime); /* Compare last mod times */
}
/*
* GETIMESTR - Builds time strings for mixed listing --KAR 8/90
*/
static
void
getimestr (char* src_fname)
{
time_t curtime;
time_t* ctptr = &curtime;
char* tptr;
struct
stat sbuf;
stats (src_fname, &sbuf);
curtime = time (NULL);
tptr = ctime (ctptr);
strcpy (comptime, tptr);
#if 0
tptr = ctime(&sbuf.st_mtime);
strcpy (creatime, tptr);
#endif
strtok (comptime, "\n");
strtok (creatime, "\n");
}
/*
* show how much cpu we used
*/
static
void
showcpu (clock_t otim)
{
float secs;
secs = (float) (clock() - otim) / CLOCKS_PER_SEC; /* Find # secs used */
if (outmsgs == stdout) /* 8/91 -s PPS 4298 */
fprintf (outmsgs, "Processed %d lines in %.2f CPU seconds "
"(%ld lines/min)\n", (int) tline, secs,
(INT)((tline*60.0)/secs));
fprintf (stderr,"Processed %d lines in %.2f CPU seconds (%ld lines/min)\n",
(int) tline, secs, (INT)((tline*60.0)/secs));
}
#if !__MSDOS__
/*
* KAR-8/92, added to check the current level KCC is running on
* and use the leveled header file directories. (PPS 4516)
*/
static
int
set_level (int level)
{
long ac = level;
long ret_val;
asm("\tSEARCH CSISYM\n");
if (ICSIUUO_ACVAL("STLEV$", ac, ret_val))
return (int) ret_val;
else
return STLEV_FAILURE;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -