📄 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 + -