📄 cc.c
字号:
return 1; /* so don't use as switches */
case 'E': /* -E Run through preproc. only */
prepf = 1;
delete = assemble = link = 0;
break;
case 'g': /* -g Debugging: */
if (s[1] == '=') /* -g=[ddt,debug,fnprof,sprof,bprof] */
{
++s;
csidebug(++s); /* go parse rest of arg string */
ldddtf = 1; /* do load DDT in any case */
return 1;
}
else /* -g all by itself */
ldddtf = 1; /* added 09/15/89 by MVS: link DDT */
break;
case 'H': /* -H<path> Specify #include <> path */
if (nhfpaths < MAXINCDIR-1)
hfpaths[nhfpaths++] = ++s; /* Remember the search path */
else
jerr("More than %d -H paths", MAXINCDIR);
return 1;
case 'h': /* -h<path> Specify <sys/ > path */
if (nhfsypaths < MAXINCDIR-1)
hfsypaths[nhfsypaths++] = ++s; /* Remember search path */
else
jerr("More than %d -h paths", MAXINCDIR);
return 1;
case 'i': /* -i #incs all files only once each */
insert_all_files = (char) ~0; // FW KCC-NT
return 1;
case 'I': /* -I<path> Add an #include "" path */
if (nincpaths < MAXINCDIR-1)
incpaths[nincpaths++] = ++s; /* Remember the search path */
else
jerr("More than %d -I paths", MAXINCDIR);
return 1;
case 'k': /* FW 2A(51) */
longidents = 1;
break;
case 'l': /* -lxxx Loader: Search library */
return 0; /* Just skip over this switch */
case 'L': /* -L<path> Specify library path */
/* -L=<string> Specify LINK cmds */
if (s[1] == '=')
return 0; /* Just skip over -L= for now */
libpath = ++s; /* Set library path */
t = (char *) calloc(1, (strlen(libpath) + 9));
if (t == NULL)
jerr("Out of memory for -L= library path\n");
strcpy(t, libpath);
strcat(t, "LIB+.REL");
libpath = t;
return 1;
case 'n': /* -n No optimize */
coptimize(""); /* Turn off all optimizations */
break; /* just as if -O= given. */
case 'N': /* -Nxx specify Runtime Stack Size */
stksz = atoi(++s);
return 1;
case 'o': /* -o=<filename> Loader: output file */
if (s[1] == '=')
s += 2; /* -o <filename> Permit old syntax */
else
{
**aav = NULL; /* Flush this arg */
++(*aav); /* Point to next one */
if (--(*aac) <= 0 || (s = **aav) == 0)
jerr("No filename arg for -o");
}
savname = s;
return 1; /* Can flush arg from switch list */
case 'P': /* -P Port level (same as -P=) */
if (s[1] == '=') /* -P=<flags> If extended syntax, */
{
++s;
cportlev(++s); /* go hack rest of arg string. */
return(1);
}
else
cportlev(""); /* Else just use basic level */
break;
case 'p': /* -p Bliss Profiler (link locals)*/
csidebug("bprof"); /* changed 9/8/90 MVS */
break;
case 'q': /* -q Conditional compilation */
condccf = 1;
break;
case 'R': /* -R=<filename> .REL file */
if (s[1] == '=')
s += 2; /* -R <filename> Permit old syntax */
else
{
**aav = NULL; /* Flush this arg */
++(*aav); /* Point to next one */
if ((--(*aac) <= 0) || ((s = **aav) == 0))
jerr ("No filename arg for -R");
}
savofnam = s;
return 1;
case 'r':
#if REGISTER_VARIABLES
use_registers = 0;
#else /* FW 2A(47) */
r_maxnopreserve = atoi (++s);
if ((r_maxnopreserve < R_MAX_NOPRESERVE)
|| (r_maxnopreserve > 12))
{
jwarn ("register count out of range, using default = %d",
R_MAX_NOPRESERVE);
r_maxnopreserve = R_MAX_NOPRESERVE;
}
#endif
return 1;
case 's':
outmsgs = stdout;
break;
case 'S': /* -S Do not delete asm source */
delete = 0;
link = assemble = 0; /* don't link or assemble either */
break;
case 'U': /* -U<ident> Undefine macro */
if (!chkmacname(s)) /* Check out identifier syntax */
return 1;
if (npreundef < MAXPREDEF)
preundefs[npreundef++] = ++s;
else
jerr("More than %d -U macro undefinitions", MAXPREDEF);
return 1;
case 'v': /* -v Verbosity level (same as -v=) */
if (s[1] == '=') /* -v=<flags> If extended syntax, */
{
++s;
cverbose(++s); /* go hack rest of arg string. */
return(1);
}
else
cverbose("all"); /* Else just use basic level */
break;
case 'w': /* -w Suppress warning messages */
if (s[1] == '=') /* -w=<flags> If extended syntax, */
{
++s;
cwarnlev(++s); /* go hack rest of arg string. */
return(1);
}
if (isdigit(s[1]))
wrnlev = toint(*++s);
else
cwarnlev("all"); /* Else just use basic level */
break;
case 'x': /* -x=<flags> Cross-compilation sws */
if (s[1] == '=') /* If extended syntax, */
{
++s;
ctargmach(++s); /* go hack rest of arg string. */
return 1;
}
jerr("Syntax for -x is \"-x=flag\"");
return 1;
default:
jerr("Unknown switch: \"-%c\"", *s);
return 1;
}
}
return 1;
}
/*
* Command switch auxiliary routines.
*
* The standard way for extending KCC switch capabilities is by using
* parcswi() to implement the following keyword-based syntax, as exemplified by
* the -O switch:
* -O=<flag>+<flag>+<flag>...
* The flags are handled in the order given; all are cleared
* at the start. Using a '-' instead of '+' as the separator will cause
* the next flag to be turned OFF instead of ON. Either the flag name
* "all" or just the switch "-O" will cause all flags to be turned on.
* The handling of flag keywords is governed by a table of "flagent"
* structures.
*/
/*
* PARCSWI - Parse an extended-style command switch.
* A NULL name entry marks end of table.
* An entry with a NULL flag address is the special "all" indicator.
*
* ftab points to array of flagents.
* resetf is true if want all flags cleared initially.
*/
static
void
parcswi (char *s, flagent_t *ftab, int resetf)
{
int onoff, c, i;
char *cp;
/* First turn off all flags */
if (resetf)
for (i = 0; ftab[i].name; ++i)
if (ftab[i].fladdr)
*(ftab[i].fladdr) = 0;
while ((c = *s) != '\0')
{
onoff = 1; /* First do separator */
if (c == '-')
{
onoff = 0;
++s;
}
else if (c == '+')
++s;
/* Look up switch in table */
for (i = 0; (cp = ftab[i].name) != NULL; i++)
{
cp = cmpname(s, cp);
if (*cp == '\0' || *cp == '+' || *cp == '-')
break;
}
if (cp) /* Found one? */
{
s = cp;
if (ftab[i].fladdr) /* Single flag */
*(ftab[i].fladdr) = (onoff ? (int)ftab[i].flval : 0);
else
for (i = 0; ftab[i].name; ++i) /* Hack "all" */
if (ftab[i].fladdr)
*(ftab[i].fladdr) = (onoff ? (int)ftab[i].flval : 0);
}
else /* Nope, error. Find end of flag name */
{
for (cp = s; *cp && *cp != '+' && *cp != '-'; ++cp)
;
c = *cp; /* Remember last char */
*cp = '\0'; /* and temporarily zap it */
/* Give user error message */
{
flagent_t *ftab2 = ftab;
char emsg[1000]; /* Lots of room for temp string */
char *cp = emsg;
for (; ftab2->name; ++ftab2) /* Build string of flag names */
*cp++ = ' ', cp = estrcpy(cp, ftab2->name);
jerr("Unknown flag \"%s\" (choices are:%s)", s, emsg);
}
s = cp; /* Restore zapped char */
*s = c; /* And carry on from that point */
}
}
}
/*
* CMPNAME - String comparison, returns pointer to first non-matching char
*/
static
char *
cmpname (char* str, char* tst)
{
if (*str == *tst)
{
while (*++str == *++tst)
{
if (*str == 0)
break;
}
}
return str;
}
/*
* CHKMACNAME - Verify syntax for -D and -U macro names.
*/
static
int
chkmacname (char* s)
{
char *cp = s;
int typ = *s; /* 'D' or 'U' */
if (!iscsymf(*++cp))
{
jerr("Bad syntax for -%c macro name: \"%s\"", typ, cp);
return 0;
}
while (iscsym(*++cp))
; /* Skip over ident name */
if (*cp && (typ == 'U' || (*cp != '=')))
{
jerr("Bad syntax for -%c macro name: \"%s\"", typ, s+1);
return 0;
}
return 1;
}
/* COPTIMIZE - Set -O optimization switches
** Flags are used to provide finer degrees of control over the
** optimization process instead of just turning everything on or
** off; this makes debugging easier.
*/
static flagent_t copttab[] = {
"all", NULL, 0, /* First element is special */
"parse", &optpar, 1, /* Parse tree optimization */
"gen", &optgen, 1, /* Code generator optimizations */
"object", &optobj, 1, /* Object code (peephole) optimizations */
NULL, NULL, 0 // FW KCC-NT
};
static void
coptimize(s)
char *s;
{
parcswi(s, copttab, 1); /* Reset switches and parse */
}
/* CDEBUG - Set -d debug switches.
** This is exactly like COPTIMIZE only the switches here are for
** controlling what sorts of debug checks or output are produced.
** The syntax is:
** -d=<flag>+<flag>+<flag>...
** The flags are handled in the order given; all are cleared
** at the start. Using a '-' instead of '+' as the separator will cause
** the next flag to be turned OFF instead of ON. Either the flag name
** "all" or just the switch "-d" will cause all flags to be turned on.
*/
static flagent_t cdebtab[] = {
/* FW 2A(42) SPR9986 07-Dec-92 moved "all" entry outside #if conditional */
"all", NULL, 0, /* First element is special */
#if DEBUG_KCC /* 5/91 KCC size */
"parse", &debpar, 1, /* Parse tree output */
"gen", &debgen, 1, /* Code generator output */
"pho", &debpho, 1, /* Peephole optimizer output */
"sym", &debsym, 1, /* Symbol table output */
#endif
"list", &mlist, 1, /* CSI Mixed Listing generation-KAR */
NULL, NULL, 0 // FW KCC-NT
};
static void
cdebug(s)
char *s;
{
parcswi(s, cdebtab, 1); /* Reset switches and parse */
}
/* CSIDEBUG - Set CSI -g runtime debugging switches
** Similar to COPTIMIZE or CDEBUG; the switches here control
** runtime user code debugging (where CDEBUG is mainly for compiler
** debugging). Although this function will handle the same syntax
** as COPTIMIZE or CDEBUG (-g=<flag>+<flag>+...), the currently
** implemented options would not make sense in combinations. No
** "all" option is provided. The options are:
** -g same as -g=ddt
** -g=ddt link in the DDT object level debugger
** -g=debug create code for and link in source debugger
** -g=bprof create code for and link in bliss profiler
** -g=sprof create code for and link in statement profiler
** -g=fnprof create code for and link in function profiler
** -g=nullptr add hooks for NULL poionter detection
** -g=fndbg add hooks for function-level debugging only
**
** -- added 9/8/90, MVS at CompuServe, for source debugging
*/
/* FW 2A(42) PPS4575 09-Dec-92 added "fndbg" keyword */
static
flagent_t csidebtab[] =
{
"ddt", &ldddtf, 1, /* link in DDT object debugger */
"debug", &debcsi, KCC_DBG_SDBG, /* use KCC Source Level Debugger */
"bprof", &profbliss, 1, /* use Benny Jones' Bliss Profiler */
"sprof", &debcsi, KCC_DBG_SPRF, /* use KCC Statement Profiler */
"fnprof", &debcsi, KCC_DBG_FPRF, /* use KCC Function Profiler */
"nullptr", &debcsi, KCC_DBG_NULL, /* use null pointer detection */
"fndbg", &debcsi, KCC_DBG_FDBG, /* KCCDBG function-level only */
NULL, NULL, 0 // FW KCC-NT
};
static void
csidebug (char *s)
{
parcswi (s, csidebtab, 1); /* reset switches and parse */
}
/* CWARNLEV - Set -w warning message suppression switches.
** Same syntax as for -O and -d. -w alone is same as "all".
*/
static flagent_t cwlevtab[] = {
"all", &wrnlev, WLEV_ALL, /* Suppress everything */
"note", &wrnlev, WLEV_NOTE, /* Suppress notes */
"advise", &wrnlev, WLEV_ADVISE, /* Suppress notes & advice */
"warn", &wrnlev, WLEV_WARN, /* Suppress n & a & warnings */
NULL, NULL, 0 // FW KCC-NT
};
static void
cwarnlev(s)
char *s;
{
parcswi(s, cwlevtab, 1); /* Reset switches and parse */
}
/* CTARGMACH - Set -x cross-compilation switches.
** Same syntax as for -O and -d.
** There is no "all" and no flags are reset. -x alone does nothing.
** Note that the value for the CPU type switches is not 1, so that
** we can distinguish between a default setting (1) and a switch setting (2).
*/
static flagent_t ctgmtab[] = {
"ch7", &tgcsize, 7, /* Size of chars, in bits */
NULL, NULL, 0 // FW KCC-NT
};
static void
ctargmach(s)
char *s;
{
parcswi(s, ctgmtab, 0); /* Don't reset switches; parse */
tgcpw = TGSIZ_WORD/tgcsize; /* Ensure right vars set if charsize */
tgcmask = (1<<tgcsize)-1; /* was specified. */
#ifndef __COMPILER_KCC__
tgmachuse.mapdbl = -1;
#endif
}
/* CPORTLEV - Set -P portability level switches.
** Same syntax as for -O and -d.
** There is no "all". -P alone resets everything.
*/
static flagent_t cplevtab[] = {
"kcc", &clevkcc, 1, /* Enable KCC extensions to C */
"base", &clevel, CLEV_BASE, /* Allow only very portable code */
"carm", &clevel, CLEV_CARM, /* Allow full CARM implementation */
"ansi", &clevel, CLEV_ANSI, /* Parse CARM+ANSI implementation */
"stdc", &clevel, CLEV_STDC, /* Parse full ANSI implementation */
"strict", &clevel, CLEV_STRICT, /* Unforgiving ANSI ("pedantic") */
"nocpp", &clevnocpp, 1, /* FW 2A(45) defeat C++ comments */
NULL, NULL, 0 // FW KCC-NT
};
static void
cportlev(s)
char *s;
{
parcswi(s, cplevtab, 1); /* Reset switches and parse */
}
/* CVERBOSE - Set -v verboseness switches.
** Same syntax as for -O etc.
** -v alone is same as "all".
*/
static flagent_t cverbtab[] = {
"all", NULL, 0, /* First element is special */
"fundef", &vrbfun, 1, /* Print function names as we go */
"nostats", &vrbsta, 1, /* Don't print statistics at end */
"args", &vrbarg, 1, /* Print KCC command line args */
"load", &vrbld, 1, /* Print linking loader commands */
NULL, NULL,0 // FW KCC-NT
};
static void
cverbose(s)
char *s;
{
parcswi(s, cverbtab, 1); /* Reset switches and parse */
}
/* CFILE(filename) - Compile or otherwise process a file.
** Return value indicates whether file was assembled:
** -2 No assembly attempted (may or may not be error).
** -1 Assembly failed.
** 0 Assembly deferred, must call runasmlnk() later.
** +1 Assembled into .REL file.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -