[BACK]Return to xlint.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.bin / xlint / xlint

Annotation of src/usr.bin/xlint/xlint/xlint.c, Revision 1.25

1.25    ! tv          1: /* $NetBSD: xlint.c,v 1.24 2001/10/24 02:31:10 thorpej Exp $ */
1.2       cgd         2:
1.1       cgd         3: /*
1.4       cgd         4:  * Copyright (c) 1996 Christopher G. Demetriou.  All Rights Reserved.
1.1       cgd         5:  * Copyright (c) 1994, 1995 Jochen Pohl
                      6:  * All Rights Reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *      This product includes software developed by Jochen Pohl for
                     19:  *     The NetBSD Project.
                     20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
1.6       christos   35: #include <sys/cdefs.h>
1.1       cgd        36: #ifndef lint
1.25    ! tv         37: __RCSID("$NetBSD: xlint.c,v 1.24 2001/10/24 02:31:10 thorpej Exp $");
1.1       cgd        38: #endif
                     39:
1.3       jpo        40: #include <sys/param.h>
1.1       cgd        41: #include <sys/wait.h>
                     42: #include <sys/stat.h>
1.3       jpo        43: #include <sys/utsname.h>
1.25    ! tv         44: #include <errno.h>
        !            45: #include <fcntl.h>
        !            46: #include <paths.h>
        !            47: #include <signal.h>
1.1       cgd        48: #include <stdio.h>
                     49: #include <stdlib.h>
                     50: #include <string.h>
                     51: #include <unistd.h>
                     52:
                     53: #include "lint.h"
                     54: #include "pathnames.h"
                     55:
1.23      lukem      56: int main(int, char *[]);
1.6       christos   57:
1.1       cgd        58: /* directory for temporary files */
                     59: static const   char *tmpdir;
                     60:
                     61: /* path name for cpp output */
                     62: static char    *cppout;
                     63:
1.10      mrg        64: /* file descriptor for cpp output */
                     65: static int     cppoutfd = -1;
                     66:
1.1       cgd        67: /* files created by 1st pass */
                     68: static char    **p1out;
                     69:
                     70: /* input files for 2nd pass (without libraries) */
                     71: static char    **p2in;
                     72:
                     73: /* library which will be created by 2nd pass */
                     74: static char    *p2out;
                     75:
1.10      mrg        76: /* flags always passed to cc(1) */
                     77: static char    **cflags;
1.1       cgd        78:
1.10      mrg        79: /* flags for cc(1), controled by sflag/tflag */
                     80: static char    **lcflags;
1.1       cgd        81:
                     82: /* flags for lint1 */
                     83: static char    **l1flags;
                     84:
                     85: /* flags for lint2 */
                     86: static char    **l2flags;
                     87:
                     88: /* libraries for lint2 */
                     89: static char    **l2libs;
                     90:
                     91: /* default libraries */
                     92: static char    **deflibs;
                     93:
                     94: /* additional libraries */
                     95: static char    **libs;
                     96:
                     97: /* search path for libraries */
                     98: static char    **libsrchpath;
                     99:
1.17      garbled   100: static  char   *libexec_path;
                    101:
1.1       cgd       102: /* flags */
1.17      garbled   103: static int     iflag, oflag, Cflag, sflag, tflag, Fflag, dflag, Bflag;
1.1       cgd       104:
                    105: /* print the commands executed to run the stages of compilation */
                    106: static int     Vflag;
                    107:
                    108: /* filename for oflag */
                    109: static char    *outputfn;
                    110:
                    111: /* reset after first .c source has been processed */
                    112: static int     first = 1;
                    113:
                    114: /*
                    115:  * name of a file which is currently written by a child and should
                    116:  * be removed after abnormal termination of the child
                    117:  */
                    118: static const   char *currfn;
                    119:
1.24      thorpej   120: #if !defined(TARGET_PREFIX)
                    121: #define        TARGET_PREFIX   ""
                    122: #endif
                    123: static const char target_prefix[] = TARGET_PREFIX;
1.1       cgd       124:
1.23      lukem     125: static void    appstrg(char ***, char *);
                    126: static void    appcstrg(char ***, const char *);
                    127: static void    applst(char ***, char *const *);
                    128: static void    freelst(char ***);
                    129: static char    *concat2(const char *, const char *);
                    130: static char    *concat3(const char *, const char *, const char *);
                    131: static void    terminate(int) __attribute__((__noreturn__));
1.25    ! tv        132: static const   char *lbasename(const char *, int);
1.23      lukem     133: static void    appdef(char ***, const char *);
                    134: static void    usage(void);
                    135: static void    fname(const char *, int);
                    136: static void    runchild(const char *, char *const *, const char *, int);
                    137: static void    findlibs(char *const *);
                    138: static int     rdok(const char *);
                    139: static void    lint2(void);
                    140: static void    cat(char *const *, const char *);
1.1       cgd       141:
                    142: /*
                    143:  * Some functions to deal with lists of strings.
                    144:  * Take care that we get no surprises in case of asyncron signals.
                    145:  */
                    146: static void
1.23      lukem     147: appstrg(char ***lstp, char *s)
1.1       cgd       148: {
                    149:        char    **lst, **olst;
                    150:        int     i;
                    151:
                    152:        olst = *lstp;
1.23      lukem     153:        for (i = 0; olst[i] != NULL; i++)
                    154:                continue;
1.8       itohy     155:        lst = xrealloc(olst, (i + 2) * sizeof (char *));
1.3       jpo       156:        lst[i] = s;
1.1       cgd       157:        lst[i + 1] = NULL;
                    158:        *lstp = lst;
1.23      lukem     159: }
1.1       cgd       160:
                    161: static void
1.23      lukem     162: appcstrg(char ***lstp, const char *s)
1.1       cgd       163: {
1.23      lukem     164:
1.3       jpo       165:        appstrg(lstp, xstrdup(s));
1.1       cgd       166: }
                    167:
                    168: static void
1.23      lukem     169: applst(char ***destp, char *const *src)
1.1       cgd       170: {
                    171:        int     i, k;
                    172:        char    **dest, **odest;
                    173:
                    174:        odest = *destp;
1.23      lukem     175:        for (i = 0; odest[i] != NULL; i++)
                    176:                continue;
                    177:        for (k = 0; src[k] != NULL; k++)
                    178:                continue;
1.8       itohy     179:        dest = xrealloc(odest, (i + k + 1) * sizeof (char *));
1.1       cgd       180:        for (k = 0; src[k] != NULL; k++)
                    181:                dest[i + k] = xstrdup(src[k]);
                    182:        dest[i + k] = NULL;
                    183:        *destp = dest;
                    184: }
                    185:
                    186: static void
1.23      lukem     187: freelst(char ***lstp)
1.1       cgd       188: {
                    189:        char    *s;
                    190:        int     i;
                    191:
1.23      lukem     192:        for (i = 0; (*lstp)[i] != NULL; i++)
                    193:                continue;
1.1       cgd       194:        while (i-- > 0) {
                    195:                s = (*lstp)[i];
                    196:                (*lstp)[i] = NULL;
                    197:                free(s);
                    198:        }
                    199: }
                    200:
1.3       jpo       201: static char *
1.23      lukem     202: concat2(const char *s1, const char *s2)
1.3       jpo       203: {
                    204:        char    *s;
                    205:
                    206:        s = xmalloc(strlen(s1) + strlen(s2) + 1);
                    207:        (void)strcpy(s, s1);
                    208:        (void)strcat(s, s2);
                    209:
                    210:        return (s);
                    211: }
                    212:
                    213: static char *
1.23      lukem     214: concat3(const char *s1, const char *s2, const char *s3)
1.3       jpo       215: {
                    216:        char    *s;
                    217:
                    218:        s = xmalloc(strlen(s1) + strlen(s2) + strlen(s3) + 1);
                    219:        (void)strcpy(s, s1);
                    220:        (void)strcat(s, s2);
                    221:        (void)strcat(s, s3);
                    222:
                    223:        return (s);
                    224: }
                    225:
1.1       cgd       226: /*
                    227:  * Clean up after a signal.
                    228:  */
                    229: static void
1.23      lukem     230: terminate(int signo)
1.1       cgd       231: {
                    232:        int     i;
                    233:
1.10      mrg       234:        if (cppoutfd != -1)
                    235:                (void)close(cppoutfd);
1.1       cgd       236:        if (cppout != NULL)
                    237:                (void)remove(cppout);
                    238:
                    239:        if (p1out != NULL) {
                    240:                for (i = 0; p1out[i] != NULL; i++)
                    241:                        (void)remove(p1out[i]);
                    242:        }
                    243:
                    244:        if (p2out != NULL)
                    245:                (void)remove(p2out);
                    246:
                    247:        if (currfn != NULL)
                    248:                (void)remove(currfn);
                    249:
                    250:        exit(signo != 0 ? 1 : 0);
                    251: }
                    252:
                    253: /*
                    254:  * Returns a pointer to the last component of strg after delim.
                    255:  * Returns strg if the string does not contain delim.
                    256:  */
                    257: static const char *
1.25    ! tv        258: lbasename(const char *strg, int delim)
1.1       cgd       259: {
                    260:        const   char *cp, *cp1, *cp2;
                    261:
                    262:        cp = cp1 = cp2 = strg;
                    263:        while (*cp != '\0') {
                    264:                if (*cp++ == delim) {
                    265:                        cp2 = cp1;
                    266:                        cp1 = cp;
                    267:                }
                    268:        }
                    269:        return (*cp1 == '\0' ? cp2 : cp1);
                    270: }
                    271:
                    272: static void
1.23      lukem     273: appdef(char ***lstp, const char *def)
1.3       jpo       274: {
1.23      lukem     275:
1.3       jpo       276:        appstrg(lstp, concat2("-D__", def));
                    277:        appstrg(lstp, concat3("-D__", def, "__"));
                    278: }
                    279:
                    280: static void
1.23      lukem     281: usage(void)
1.1       cgd       282: {
1.22      cgd       283:
1.12      christos  284:        (void)fprintf(stderr,
1.20      christos  285:            "Usage: %s [-abceghprvwxzHF] [-s|-t] [-i|-nu] [-Dname[=def]]"
1.22      cgd       286:            " [-Uname] [-X <id>[,<id>]...\n", getprogname());
1.23      lukem     287:        (void)fprintf(stderr,
1.20      christos  288:            "\t[-Idirectory] [-Ldirectory] [-llibrary] [-ooutputfile]"
                    289:            " file...\n");
1.12      christos  290:        (void)fprintf(stderr,
1.20      christos  291:            "       %s [-abceghprvwzHF] [-s|-t] -Clibrary [-Dname[=def]]\n"
1.22      cgd       292:            " [-X <id>[,<id>]...\n", getprogname());
1.20      christos  293:        (void)fprintf(stderr, "\t[-Idirectory] [-Uname] [-Bpath] file"
                    294:            " ...\n");
1.1       cgd       295:        terminate(-1);
                    296: }
1.6       christos  297:
1.1       cgd       298:
                    299: int
1.23      lukem     300: main(int argc, char *argv[])
1.1       cgd       301: {
                    302:        int     c;
                    303:        char    flgbuf[3], *tmp, *s;
                    304:        size_t  len;
                    305:
                    306:        if ((tmp = getenv("TMPDIR")) == NULL || (len = strlen(tmp)) == 0) {
                    307:                tmpdir = xstrdup(_PATH_TMP);
                    308:        } else {
                    309:                s = xmalloc(len + 2);
                    310:                (void)sprintf(s, "%s%s", tmp, tmp[len - 1] == '/' ? "" : "/");
                    311:                tmpdir = s;
                    312:        }
                    313:
                    314:        cppout = xmalloc(strlen(tmpdir) + sizeof ("lint0.XXXXXX"));
                    315:        (void)sprintf(cppout, "%slint0.XXXXXX", tmpdir);
1.10      mrg       316:        cppoutfd = mkstemp(cppout);
                    317:        if (cppoutfd == -1) {
1.1       cgd       318:                warn("can't make temp");
                    319:                terminate(-1);
                    320:        }
                    321:
                    322:        p1out = xcalloc(1, sizeof (char *));
                    323:        p2in = xcalloc(1, sizeof (char *));
1.10      mrg       324:        cflags = xcalloc(1, sizeof (char *));
                    325:        lcflags = xcalloc(1, sizeof (char *));
1.1       cgd       326:        l1flags = xcalloc(1, sizeof (char *));
                    327:        l2flags = xcalloc(1, sizeof (char *));
                    328:        l2libs = xcalloc(1, sizeof (char *));
                    329:        deflibs = xcalloc(1, sizeof (char *));
                    330:        libs = xcalloc(1, sizeof (char *));
                    331:        libsrchpath = xcalloc(1, sizeof (char *));
                    332:
1.10      mrg       333:        appcstrg(&cflags, "-E");
                    334:        appcstrg(&cflags, "-x");
                    335:        appcstrg(&cflags, "c");
1.12      christos  336: #if 0
1.10      mrg       337:        appcstrg(&cflags, "-D__attribute__(x)=");
1.11      christos  338:        appcstrg(&cflags, "-D__extension__(x)=/*NOSTRICT*/0");
1.12      christos  339: #else
                    340:        appcstrg(&cflags, "-U__GNUC__");
                    341: #endif
1.10      mrg       342:        appcstrg(&cflags, "-Wp,-$");
                    343:        appcstrg(&cflags, "-Wp,-CC");
                    344:        appcstrg(&cflags, "-Wcomment");
1.16      kleink    345:        appcstrg(&cflags, "-D__LINT__");
1.10      mrg       346:        appcstrg(&cflags, "-Dlint");            /* XXX don't def. with -s */
                    347:
                    348:        appdef(&cflags, "lint");
                    349:
                    350:        appcstrg(&lcflags, "-Wtraditional");
                    351:
1.3       jpo       352:        appcstrg(&deflibs, "c");
1.1       cgd       353:
                    354:        if (signal(SIGHUP, terminate) == SIG_IGN)
                    355:                (void)signal(SIGHUP, SIG_IGN);
                    356:        (void)signal(SIGINT, terminate);
                    357:        (void)signal(SIGQUIT, terminate);
                    358:        (void)signal(SIGTERM, terminate);
                    359:
                    360:        while (argc > optind) {
                    361:
                    362:
1.20      christos  363:                c = getopt(argc, argv, "abcd:eghil:no:prstuvwxzB:C:D:FHI:L:U:VX:");
1.1       cgd       364:
                    365:                switch (c) {
                    366:
                    367:                case 'a':
                    368:                case 'b':
                    369:                case 'c':
                    370:                case 'e':
                    371:                case 'g':
                    372:                case 'r':
                    373:                case 'v':
1.20      christos  374:                case 'w':
1.1       cgd       375:                case 'z':
                    376:                        (void)sprintf(flgbuf, "-%c", c);
1.3       jpo       377:                        appcstrg(&l1flags, flgbuf);
1.1       cgd       378:                        break;
                    379:
                    380:                case 'F':
                    381:                        Fflag = 1;
                    382:                        /* FALLTHROUGH */
                    383:                case 'u':
                    384:                case 'h':
                    385:                        (void)sprintf(flgbuf, "-%c", c);
1.3       jpo       386:                        appcstrg(&l1flags, flgbuf);
                    387:                        appcstrg(&l2flags, flgbuf);
1.20      christos  388:                        break;
                    389:
                    390:                case 'X':
                    391:                        (void)sprintf(flgbuf, "-%c", c);
                    392:                        appcstrg(&l1flags, flgbuf);
                    393:                        appcstrg(&l1flags, optarg);
1.1       cgd       394:                        break;
                    395:
                    396:                case 'i':
                    397:                        if (Cflag)
                    398:                                usage();
                    399:                        iflag = 1;
                    400:                        break;
                    401:
                    402:                case 'n':
                    403:                        freelst(&deflibs);
                    404:                        break;
                    405:
                    406:                case 'p':
1.3       jpo       407:                        appcstrg(&l1flags, "-p");
                    408:                        appcstrg(&l2flags, "-p");
1.1       cgd       409:                        if (*deflibs != NULL) {
                    410:                                freelst(&deflibs);
1.3       jpo       411:                                appcstrg(&deflibs, "c");
1.1       cgd       412:                        }
                    413:                        break;
                    414:
                    415:                case 's':
                    416:                        if (tflag)
                    417:                                usage();
1.10      mrg       418:                        freelst(&lcflags);
                    419:                        appcstrg(&lcflags, "-trigraphs");
                    420:                        appcstrg(&lcflags, "-Wtrigraphs");
                    421:                        appcstrg(&lcflags, "-pedantic");
                    422:                        appcstrg(&lcflags, "-D__STRICT_ANSI__");
1.3       jpo       423:                        appcstrg(&l1flags, "-s");
                    424:                        appcstrg(&l2flags, "-s");
1.1       cgd       425:                        sflag = 1;
                    426:                        break;
                    427:
1.25    ! tv        428: #if !HAVE_CONFIG_H
1.1       cgd       429:                case 't':
                    430:                        if (sflag)
                    431:                                usage();
1.10      mrg       432:                        freelst(&lcflags);
                    433:                        appcstrg(&lcflags, "-traditional");
                    434:                        appstrg(&lcflags, concat2("-D", MACHINE));
                    435:                        appstrg(&lcflags, concat2("-D", MACHINE_ARCH));
1.3       jpo       436:                        appcstrg(&l1flags, "-t");
                    437:                        appcstrg(&l2flags, "-t");
1.1       cgd       438:                        tflag = 1;
                    439:                        break;
1.25    ! tv        440: #endif
1.1       cgd       441:
                    442:                case 'x':
1.3       jpo       443:                        appcstrg(&l2flags, "-x");
1.1       cgd       444:                        break;
                    445:
                    446:                case 'C':
                    447:                        if (Cflag || oflag || iflag)
                    448:                                usage();
                    449:                        Cflag = 1;
1.3       jpo       450:                        appstrg(&l2flags, concat2("-C", optarg));
1.1       cgd       451:                        p2out = xmalloc(sizeof ("llib-l.ln") + strlen(optarg));
                    452:                        (void)sprintf(p2out, "llib-l%s.ln", optarg);
                    453:                        freelst(&deflibs);
                    454:                        break;
                    455:
1.7       sommerfe  456:                case 'd':
                    457:                        if (dflag)
                    458:                                usage();
                    459:                        dflag = 1;
1.10      mrg       460:                        appcstrg(&cflags, "-nostdinc");
                    461:                        appcstrg(&cflags, "-idirafter");
                    462:                        appcstrg(&cflags, optarg);
1.7       sommerfe  463:                        break;
1.23      lukem     464:
1.1       cgd       465:                case 'D':
                    466:                case 'I':
                    467:                case 'U':
                    468:                        (void)sprintf(flgbuf, "-%c", c);
1.10      mrg       469:                        appstrg(&cflags, concat2(flgbuf, optarg));
1.1       cgd       470:                        break;
                    471:
                    472:                case 'l':
1.3       jpo       473:                        appcstrg(&libs, optarg);
1.1       cgd       474:                        break;
                    475:
                    476:                case 'o':
                    477:                        if (Cflag || oflag)
                    478:                                usage();
                    479:                        oflag = 1;
                    480:                        outputfn = xstrdup(optarg);
                    481:                        break;
                    482:
                    483:                case 'L':
1.3       jpo       484:                        appcstrg(&libsrchpath, optarg);
1.1       cgd       485:                        break;
                    486:
                    487:                case 'H':
1.3       jpo       488:                        appcstrg(&l2flags, "-H");
1.1       cgd       489:                        break;
                    490:
1.17      garbled   491:                case 'B':
                    492:                        Bflag = 1;
                    493:                        libexec_path = xstrdup(optarg);
                    494:                        break;
                    495:
1.1       cgd       496:                case 'V':
                    497:                        Vflag = 1;
                    498:                        break;
                    499:
                    500:                case -1:
                    501:                        /* filename */
1.21      wiz       502:                        fname(argv[optind], argc == optind+1);
1.1       cgd       503:                        first = 0;
1.21      wiz       504:                        optind++;
1.25    ! tv        505:
        !           506:                default:
        !           507:                        usage();
        !           508:                        /* NOTREACHED */
1.1       cgd       509:                }
                    510:
                    511:        }
1.21      wiz       512:        argc -= optind;
                    513:        argv += optind;
1.1       cgd       514:
                    515:        if (first)
                    516:                usage();
                    517:
                    518:        if (iflag)
                    519:                terminate(0);
                    520:
                    521:        if (!oflag) {
                    522:                if ((s = getenv("LIBDIR")) == NULL || strlen(s) == 0)
                    523:                        s = PATH_LINTLIB;
1.3       jpo       524:                appcstrg(&libsrchpath, s);
1.1       cgd       525:                findlibs(libs);
                    526:                findlibs(deflibs);
                    527:        }
                    528:
                    529:        (void)printf("Lint pass2:\n");
                    530:        lint2();
                    531:
                    532:        if (oflag)
                    533:                cat(p2in, outputfn);
                    534:
                    535:        if (Cflag)
                    536:                p2out = NULL;
                    537:
                    538:        terminate(0);
                    539:        /* NOTREACHED */
                    540: }
                    541:
                    542: /*
                    543:  * Read a file name from the command line
                    544:  * and pass it through lint1 if it is a C source.
                    545:  */
                    546: static void
1.23      lukem     547: fname(const char *name, int last)
1.1       cgd       548: {
                    549:        const   char *bn, *suff;
                    550:        char    **args, *ofn, *path;
                    551:        size_t  len;
1.4       cgd       552:        int is_stdin;
1.10      mrg       553:        int     fd;
1.1       cgd       554:
1.4       cgd       555:        is_stdin = (strcmp(name, "-") == 0);
1.25    ! tv        556:        bn = lbasename(name, '/');
        !           557:        suff = lbasename(bn, '.');
1.1       cgd       558:
                    559:        if (strcmp(suff, "ln") == 0) {
                    560:                /* only for lint2 */
                    561:                if (!iflag)
1.3       jpo       562:                        appcstrg(&p2in, name);
1.1       cgd       563:                return;
                    564:        }
                    565:
1.4       cgd       566:        if (!is_stdin && strcmp(suff, "c") != 0 &&
1.1       cgd       567:            (strncmp(bn, "llib-l", 6) != 0 || bn != suff)) {
                    568:                warnx("unknown file type: %s\n", name);
                    569:                return;
                    570:        }
                    571:
                    572:        if (!iflag || !first || !last)
1.4       cgd       573:                (void)printf("%s:\n",
                    574:                    is_stdin ? "{standard input}" : Fflag ? name : bn);
1.1       cgd       575:
                    576:        /* build the name of the output file of lint1 */
                    577:        if (oflag) {
                    578:                ofn = outputfn;
                    579:                outputfn = NULL;
                    580:                oflag = 0;
                    581:        } else if (iflag) {
1.4       cgd       582:                if (is_stdin) {
                    583:                        warnx("-i not supported without -o for standard input");
                    584:                        return;
                    585:                }
1.1       cgd       586:                ofn = xmalloc(strlen(bn) + (bn == suff ? 4 : 2));
                    587:                len = bn == suff ? strlen(bn) : (suff - 1) - bn;
                    588:                (void)sprintf(ofn, "%.*s", (int)len, bn);
                    589:                (void)strcat(ofn, ".ln");
                    590:        } else {
                    591:                ofn = xmalloc(strlen(tmpdir) + sizeof ("lint1.XXXXXX"));
                    592:                (void)sprintf(ofn, "%slint1.XXXXXX", tmpdir);
1.10      mrg       593:                fd = mkstemp(ofn);
                    594:                if (fd == -1) {
1.1       cgd       595:                        warn("can't make temp");
                    596:                        terminate(-1);
                    597:                }
1.10      mrg       598:                close(fd);
1.1       cgd       599:        }
                    600:        if (!iflag)
1.3       jpo       601:                appcstrg(&p1out, ofn);
1.1       cgd       602:
                    603:        args = xcalloc(1, sizeof (char *));
                    604:
1.10      mrg       605:        /* run cc */
1.1       cgd       606:
1.17      garbled   607:        if (getenv("CC") == NULL) {
                    608:                path = xmalloc(strlen(PATH_USRBIN) + sizeof ("/cc"));
                    609:                (void)sprintf(path, "%s/cc", PATH_USRBIN);
                    610:        } else {
                    611:                path = strdup(getenv("CC"));
                    612:        }
1.1       cgd       613:
1.3       jpo       614:        appcstrg(&args, path);
1.10      mrg       615:        applst(&args, cflags);
                    616:        applst(&args, lcflags);
1.3       jpo       617:        appcstrg(&args, name);
1.1       cgd       618:
1.15      jwise     619:        /* we reuse the same tmp file for cpp output, so rewind and truncate */
                    620:        if (lseek(cppoutfd, SEEK_SET, (off_t)0) != 0) {
                    621:                warn("lseek");
                    622:                terminate(-1);
                    623:        }
                    624:        if (ftruncate(cppoutfd, (off_t)0) != 0) {
                    625:                warn("ftruncate");
                    626:                terminate(-1);
                    627:        }
1.23      lukem     628:
1.10      mrg       629:        runchild(path, args, cppout, cppoutfd);
1.1       cgd       630:        free(path);
                    631:        freelst(&args);
                    632:
                    633:        /* run lint1 */
                    634:
1.17      garbled   635:        if (!Bflag) {
1.24      thorpej   636:                path = xmalloc(strlen(PATH_LIBEXEC) + sizeof ("/lint1") +
                    637:                    strlen(target_prefix));
                    638:                (void)sprintf(path, "%s/%slint1", PATH_LIBEXEC,
                    639:                    target_prefix);
1.17      garbled   640:        } else {
1.24      thorpej   641:                /*
                    642:                 * XXX Unclear whether we should be using target_prefix
                    643:                 * XXX here.  --thorpej@wasabisystems.com
                    644:                 */
1.17      garbled   645:                path = xmalloc(strlen(libexec_path) + sizeof ("/lint1"));
                    646:                (void)sprintf(path, "%s/lint1", libexec_path);
                    647:        }
1.1       cgd       648:
1.3       jpo       649:        appcstrg(&args, path);
1.1       cgd       650:        applst(&args, l1flags);
1.3       jpo       651:        appcstrg(&args, cppout);
                    652:        appcstrg(&args, ofn);
1.1       cgd       653:
1.10      mrg       654:        runchild(path, args, ofn, -1);
1.1       cgd       655:        free(path);
                    656:        freelst(&args);
                    657:
1.3       jpo       658:        appcstrg(&p2in, ofn);
1.1       cgd       659:        free(ofn);
                    660:
                    661:        free(args);
                    662: }
                    663:
                    664: static void
1.23      lukem     665: runchild(const char *path, char *const *args, const char *crfn, int fdout)
1.1       cgd       666: {
                    667:        int     status, rv, signo, i;
                    668:
                    669:        if (Vflag) {
                    670:                for (i = 0; args[i] != NULL; i++)
                    671:                        (void)printf("%s ", args[i]);
                    672:                (void)printf("\n");
                    673:        }
                    674:
                    675:        currfn = crfn;
                    676:
                    677:        (void)fflush(stdout);
                    678:
1.15      jwise     679:        switch (vfork()) {
1.1       cgd       680:        case -1:
                    681:                warn("cannot fork");
                    682:                terminate(-1);
                    683:                /* NOTREACHED */
                    684:        default:
                    685:                /* parent */
                    686:                break;
                    687:        case 0:
                    688:                /* child */
1.10      mrg       689:
                    690:                /* setup the standard output if necessary */
                    691:                if (fdout != -1) {
                    692:                        dup2(fdout, STDOUT_FILENO);
                    693:                        close(fdout);
                    694:                }
1.19      wrstuden  695:                (void)execvp(path, args);
1.1       cgd       696:                warn("cannot exec %s", path);
1.15      jwise     697:                _exit(1);
1.1       cgd       698:                /* NOTREACHED */
                    699:        }
                    700:
                    701:        while ((rv = wait(&status)) == -1 && errno == EINTR) ;
                    702:        if (rv == -1) {
                    703:                warn("wait");
                    704:                terminate(-1);
                    705:        }
                    706:        if (WIFSIGNALED(status)) {
                    707:                signo = WTERMSIG(status);
1.25    ! tv        708: #if HAVE_DECL_SYS_SIGNAME
1.1       cgd       709:                warnx("%s got SIG%s", path, sys_signame[signo]);
1.25    ! tv        710: #else
        !           711:                warnx("%s got signal %d", path, signo);
        !           712: #endif
1.1       cgd       713:                terminate(-1);
                    714:        }
                    715:        if (WEXITSTATUS(status) != 0)
                    716:                terminate(-1);
                    717:        currfn = NULL;
                    718: }
                    719:
                    720: static void
1.23      lukem     721: findlibs(char *const *liblst)
1.1       cgd       722: {
                    723:        int     i, k;
                    724:        const   char *lib, *path;
                    725:        char    *lfn;
                    726:        size_t  len;
                    727:
                    728:        lfn = NULL;
                    729:
                    730:        for (i = 0; (lib = liblst[i]) != NULL; i++) {
                    731:                for (k = 0; (path = libsrchpath[k]) != NULL; k++) {
                    732:                        len = strlen(path) + strlen(lib);
                    733:                        lfn = xrealloc(lfn, len + sizeof ("/llib-l.ln"));
                    734:                        (void)sprintf(lfn, "%s/llib-l%s.ln", path, lib);
                    735:                        if (rdok(lfn))
                    736:                                break;
                    737:                        lfn = xrealloc(lfn, len + sizeof ("/lint/llib-l.ln"));
                    738:                        (void)sprintf(lfn, "%s/lint/llib-l%s.ln", path, lib);
                    739:                        if (rdok(lfn))
                    740:                                break;
                    741:                }
                    742:                if (path != NULL) {
1.3       jpo       743:                        appstrg(&l2libs, concat2("-l", lfn));
1.1       cgd       744:                } else {
                    745:                        warnx("cannot find llib-l%s.ln", lib);
                    746:                }
                    747:        }
                    748:
                    749:        free(lfn);
                    750: }
                    751:
                    752: static int
1.23      lukem     753: rdok(const char *path)
1.1       cgd       754: {
                    755:        struct  stat sbuf;
                    756:
                    757:        if (stat(path, &sbuf) == -1)
                    758:                return (0);
1.5       mycroft   759:        if (!S_ISREG(sbuf.st_mode))
1.1       cgd       760:                return (0);
                    761:        if (access(path, R_OK) == -1)
                    762:                return (0);
                    763:        return (1);
                    764: }
                    765:
                    766: static void
1.23      lukem     767: lint2(void)
1.1       cgd       768: {
                    769:        char    *path, **args;
                    770:
                    771:        args = xcalloc(1, sizeof (char *));
                    772:
1.17      garbled   773:        if (!Bflag) {
1.24      thorpej   774:                path = xmalloc(strlen(PATH_LIBEXEC) + sizeof ("/lint2") +
                    775:                    strlen(target_prefix));
                    776:                (void)sprintf(path, "%s/%slint2", PATH_LIBEXEC,
                    777:                    target_prefix);
1.17      garbled   778:        } else {
1.24      thorpej   779:                /*
                    780:                 * XXX Unclear whether we should be using target_prefix
                    781:                 * XXX here.  --thorpej@wasabisystems.com
                    782:                 */
1.17      garbled   783:                path = xmalloc(strlen(libexec_path) + sizeof ("/lint2"));
                    784:                (void)sprintf(path, "%s/lint2", libexec_path);
1.23      lukem     785:        }
                    786:
1.3       jpo       787:        appcstrg(&args, path);
1.1       cgd       788:        applst(&args, l2flags);
                    789:        applst(&args, l2libs);
                    790:        applst(&args, p2in);
                    791:
1.10      mrg       792:        runchild(path, args, p2out, -1);
1.1       cgd       793:        free(path);
                    794:        freelst(&args);
                    795:        free(args);
                    796: }
                    797:
                    798: static void
1.23      lukem     799: cat(char *const *srcs, const char *dest)
1.1       cgd       800: {
                    801:        int     ifd, ofd, i;
                    802:        char    *src, *buf;
                    803:        ssize_t rlen;
                    804:
                    805:        if ((ofd = open(dest, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1) {
                    806:                warn("cannot open %s", dest);
                    807:                terminate(-1);
                    808:        }
                    809:
                    810:        buf = xmalloc(MBLKSIZ);
                    811:
                    812:        for (i = 0; (src = srcs[i]) != NULL; i++) {
                    813:                if ((ifd = open(src, O_RDONLY)) == -1) {
                    814:                        free(buf);
                    815:                        warn("cannot open %s", src);
                    816:                        terminate(-1);
                    817:                }
                    818:                do {
                    819:                        if ((rlen = read(ifd, buf, MBLKSIZ)) == -1) {
                    820:                                free(buf);
                    821:                                warn("read error on %s", src);
                    822:                                terminate(-1);
                    823:                        }
                    824:                        if (write(ofd, buf, (size_t)rlen) == -1) {
                    825:                                free(buf);
                    826:                                warn("write error on %s", dest);
                    827:                                terminate(-1);
                    828:                        }
                    829:                } while (rlen == MBLKSIZ);
                    830:                (void)close(ifd);
                    831:        }
                    832:        (void)close(ofd);
                    833:        free(buf);
                    834: }

CVSweb <webmaster@jp.NetBSD.org>