📄 lcc.c
字号:
case 1: /* preprocessed source files */
if (Eflag)
break;
if (Sflag)
status = compile(name, outfile ? outfile : concat(base, first(suffixes[2])));
else if ((status = compile(name, stemp?stemp:(stemp=tempname(first(suffixes[2]))))) == 0)
return filename(stemp, base);
break;
case 2: /* assembly language files */
if (Eflag)
break;
if (!Sflag) {
char *ofile;
if (cflag && outfile)
ofile = outfile;
else if (cflag)
ofile = concat(base, first(suffixes[3]));
else
ofile = tempname(first(suffixes[3]));
compose(as, alist, append(name, 0), append(ofile, 0));
status = callsys(av);
if (!find(ofile, llist[1]))
llist[1] = append(ofile, llist[1]);
}
break;
case 3: /* object files */
if (!find(name, llist[1]))
llist[1] = append(name, llist[1]);
break;
default:
if (Eflag) {
compose(cpp, plist, append(name, 0), 0);
status = callsys(av);
}
llist[1] = append(name, llist[1]);
break;
}
if (status)
errcnt++;
return status;
}
/* find - find 1st occurrence of str in list, return list node or 0 */
static List find(char *str, List list) {
List b;
if (b = list)
do {
if (strcmp(str, b->str) == 0)
return b;
} while ((b = b->link) != list);
return 0;
}
/* help - print help message */
static void help(void) {
static char *msgs[] = {
"", " [ option | file ]...\n",
" except for -l, options are processed left-to-right before files\n",
" unrecognized options are taken to be linker options\n",
"-A warn about nonANSI usage; 2nd -A warns more\n",
"-b emit expression-level profiling code; see bprint(1)\n",
#ifdef sparc
"-Bstatic -Bdynamic specify static or dynamic libraries\n",
#endif
"-Bdir/ use the compiler named `dir/rcc'\n",
"-c compile only\n",
"-dn set switch statement density to `n'\n",
"-Dname -Dname=def define the preprocessor symbol `name'\n",
"-E run only the preprocessor on the named C programs and unsuffixed files\n",
"-g produce symbol table information for debuggers\n",
"-help or -? print this message on standard error\n",
"-Idir add `dir' to the beginning of the list of #include directories\n",
"-lx search library `x'\n",
"-M emit makefile dependencies; implies -E\n",
"-N do not search the standard directories for #include files\n",
"-n emit code to check for dereferencing zero pointers\n",
"-O is ignored\n",
"-o file leave the output in `file'\n",
"-P print ANSI-style declarations for globals on standard error\n",
"-p -pg emit profiling code; see prof(1) and gprof(1)\n",
"-S compile to assembly language\n",
"-static specify static libraries (default is dynamic)\n",
"-dynamic specify dynamically linked libraries\n",
"-t -tname emit function tracing calls to printf or to `name'\n",
"-target name is ignored\n",
"-tempdir=dir place temporary files in `dir/'", "\n"
"-Uname undefine the preprocessor symbol `name'\n",
"-v show commands as they are executed; 2nd -v suppresses execution\n",
"-w suppress warnings\n",
"-Woarg specify system-specific `arg'\n",
"-W[pfal]arg pass `arg' to the preprocessor, compiler, assembler, or linker\n",
0 };
int i;
char *s;
msgs[0] = progname;
for (i = 0; msgs[i]; i++) {
fprintf(stderr, "%s", msgs[i]);
if (strncmp("-tempdir", msgs[i], 8) == 0 && tempdir)
fprintf(stderr, "; default=%s", tempdir);
}
#define xx(v) if (s = getenv(#v)) fprintf(stderr, #v "=%s\n", s)
xx(LCCINPUTS);
xx(LCCDIR);
#ifdef WIN32
xx(include);
xx(lib);
#endif
#undef xx
}
/* initinputs - if LCCINPUTS or include is defined, use them to initialize various lists */
static void initinputs(void) {
char *s = getenv("LCCINPUTS");
List list, b;
if (s == 0 && (s = inputs)[0] == 0)
s = ".";
if (s) {
lccinputs = path2list(s);
if (b = lccinputs)
do {
b = b->link;
if (strcmp(b->str, ".") != 0) {
ilist = append(concat("-I", b->str), ilist);
if (strstr(com[1], "win32") == NULL)
llist[0] = append(concat("-L", b->str), llist[0]);
} else
b->str = "";
} while (b != lccinputs);
}
#ifdef WIN32
if (list = b = path2list(getenv("include")))
do {
int n;
b = b->link;
n = strlen(b->str);
if (b->str[n-1] == '\\')
b->str[n-1] = '/';
ilist = append(stringf("-I\"%s\"", b->str), ilist);
} while (b != list);
#endif
}
/* interrupt - catch interrupt signals */
static void interrupt(int n) {
rm(rmlist);
exit(n = 100);
}
/* opt - process option in arg */
static void opt(char *arg) {
switch (arg[1]) { /* multi-character options */
case 'W': /* -Wxarg */
if (arg[2] && arg[3])
switch (arg[2]) {
case 'o':
if (option(&arg[3]))
return;
break;
case 'p':
plist = append(&arg[3], plist);
return;
case 'f':
if (strcmp(&arg[3], "-C") == 0 && !option("-b"))
break; /* -C requires that -b is supported */
clist = append(&arg[3], clist);
if (strcmp(&arg[3], "-unsigned_char=1") == 0) {
plist = append("-D__CHAR_UNSIGNED__", plist);
plist = append("-U_CHAR_IS_SIGNED", plist);
}
#define xx(name,k) \
if (strcmp(&arg[3], "-wchar_t=" #name) == 0) \
plist = append("-D_WCHAR_T_SIZE=" #k, plist);
xx(unsigned_char,1)
xx(unsigned_short,2)
xx(unsigned_int,4)
#undef xx
return;
case 'a':
alist = append(&arg[3], alist);
return;
case 'l':
llist[0] = append(&arg[3], llist[0]);
return;
}
fprintf(stderr, "%s: %s ignored\n", progname, arg);
return;
case 'd': /* -dn -dynamic */
if (strcmp(arg, "-dynamic") == 0) {
if (!option(arg))
fprintf(stderr, "%s: %s ignored\n", progname, arg);
} else {
arg[1] = 's';
clist = append(arg, clist);
}
return;
case 't': /* -t -tname -tempdir=dir */
if (strncmp(arg, "-tempdir=", 9) == 0)
tempdir = arg + 9;
else
clist = append(arg, clist);
return;
case 'p': /* -p -pg */
if (option(arg))
clist = append(arg, clist);
else
fprintf(stderr, "%s: %s ignored\n", progname, arg);
return;
case 'D': /* -Dname -Dname=def */
case 'U': /* -Uname */
case 'I': /* -Idir */
plist = append(arg, plist);
return;
case 'B': /* -Bdir -Bstatic -Bdynamic */
#ifdef sparc
if (strcmp(arg, "-Bstatic") == 0 || strcmp(arg, "-Bdynamic") == 0)
llist[1] = append(arg, llist[1]);
else
#endif
{
static char *path;
if (path)
error("-B overwrites earlier option", 0);
path = arg + 2;
if (strstr(com[1], "win32") != NULL)
com[0] = concat(replace(path, '/', '\\'), concat("rcc", first(suffixes[4])));
else
com[0] = concat(path, "rcc");
if (path[0] == 0)
error("missing directory in -B option", 0);
}
return;
case 'h':
if (strcmp(arg, "-help") == 0) {
static int printed = 0;
case '?':
if (!printed)
help();
printed = 1;
return;
}
break;
case 's':
if (strcmp(arg, "-static") == 0) {
if (!option(arg))
fprintf(stderr, "%s: %s ignored\n", progname, arg);
return;
}
break;
}
if (arg[2] == 0)
switch (arg[1]) { /* single-character options */
case 'S':
Sflag++;
return;
case 'O':
fprintf(stderr, "%s: %s ignored\n", progname, arg);
return;
case 'A': case 'n': case 'w': case 'P':
clist = append(arg, clist);
return;
case 'g': case 'b':
if (option(arg))
clist = append(arg[1] == 'g' ? "-g2" : arg, clist);
else
fprintf(stderr, "%s: %s ignored\n", progname, arg);
return;
case 'G':
if (option(arg)) {
clist = append("-g3", clist);
llist[0] = append("-N", llist[0]);
} else
fprintf(stderr, "%s: %s ignored\n", progname, arg);
return;
case 'E':
Eflag++;
return;
case 'c':
cflag++;
return;
case 'M':
Eflag++; /* -M implies -E */
plist = append(arg, plist);
return;
case 'N':
if (strcmp(basepath(cpp[0]), "gcc-cpp") == 0)
plist = append("-nostdinc", plist);
include[0] = 0;
ilist = 0;
return;
case 'v':
if (verbose++ == 0) {
if (strcmp(basepath(cpp[0]), "gcc-cpp") == 0)
plist = append(arg, plist);
clist = append(arg, clist);
fprintf(stderr, "%s %s\n", progname, rcsid);
}
return;
}
if (cflag || Sflag || Eflag)
fprintf(stderr, "%s: %s ignored\n", progname, arg);
else
llist[1] = append(arg, llist[1]);
}
/* path2list - convert a colon- or semicolon-separated list to a list */
static List path2list(const char *path) {
List list = NULL;
char sep = ':';
if (path == NULL)
return NULL;
if (strchr(path, ';'))
sep = ';';
while (*path) {
char *p, buf[512];
if (p = strchr(path, sep)) {
assert(p - path < sizeof buf);
strncpy(buf, path, p - path);
buf[p-path] = '\0';
} else {
assert(strlen(path) < sizeof buf);
strcpy(buf, path);
}
if (!find(buf, list))
list = append(strsave(buf), list);
if (p == 0)
break;
path = p + 1;
}
return list;
}
/* replace - copy str, then replace occurrences of from with to, return the copy */
char *replace(const char *str, int from, int to) {
char *s = strsave(str), *p = s;
for ( ; (p = strchr(p, from)) != NULL; p++)
*p = to;
return s;
}
/* rm - remove files in list */
static void rm(List list) {
if (list) {
List b = list;
if (verbose)
fprintf(stderr, "rm");
do {
if (verbose)
fprintf(stderr, " %s", b->str);
if (verbose < 2)
remove(b->str);
} while ((b = b->link) != list);
if (verbose)
fprintf(stderr, "\n");
}
}
/* strsave - return a saved copy of string str */
char *strsave(const char *str) {
return strcpy(alloc(strlen(str)+1), str);
}
/* stringf - format and return a string */
char *stringf(const char *fmt, ...) {
char buf[1024];
va_list ap;
int n;
va_start(ap, fmt);
n = vsprintf(buf, fmt, ap);
va_end(ap);
return strsave(buf);
}
/* suffix - if one of tails[0..n-1] holds a proper suffix of name, return its index */
int suffix(char *name, char *tails[], int n) {
int i, len = strlen(name);
for (i = 0; i < n; i++) {
char *s = tails[i], *t;
for ( ; t = strchr(s, ';'); s = t + 1) {
int m = t - s;
if (len > m && strncmp(&name[len-m], s, m) == 0)
return i;
}
if (*s) {
int m = strlen(s);
if (len > m && strncmp(&name[len-m], s, m) == 0)
return i;
}
}
return -1;
}
/* tempname - generate a temporary file name in tempdir with given suffix */
char *tempname(char *suffix) {
static int n;
char *name = stringf("%s/lcc%d%d%s", tempdir, getpid(), n++, suffix);
if (strstr(com[1], "win32") != NULL)
name = replace(name, '/', '\\');
rmlist = append(name, rmlist);
return name;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -