Annotation of 43BSDTahoe/new/spms/src/bin/pdiff/pdiff.c, revision 1.1.1.1

1.1       root        1: static char *rcsid = "$Header$";
                      2: /*
                      3:  * pdiff - differential project comparator
                      4:  *
                      5:  * Author: Peter J. Nicklin
                      6:  */
                      7: #include <stdio.h>
                      8: #include "getarg.h"
                      9: #include "macro.h"
                     10: #include "null.h"
                     11: #include "path.h"
                     12: #include "pdb.h"
                     13: #include "pdtyp.h"
                     14: #include "pld.h"
                     15: #include "ptree.h"
                     16: #include "spms.h"
                     17: #include "yesno.h"
                     18: 
                     19: char **NARGV;                          /* new argument list */
                     20: char *PGN = "pdiff";                   /* program name */
                     21: int EXECUTE = YES;                     /* execute command? */
                     22: int NARGI = 0;                         /* new argument list index */
                     23: int RECURSIVE = 0;                     /* recursively compare projects */
                     24: PDTYP PDIRTYP;                         /* project directory type labels list */
                     25: 
                     26: main(argc, argv)
                     27:        int argc;
                     28:        char **argv;
                     29: {
                     30:        extern int PPDEBUG;             /* project pathname debug flag */
                     31:        char p1[PPATHSIZE];             /* project pathname buffer */
                     32:        char p2[PPATHSIZE];             /* project pathname buffer */
                     33:        char *strcpy();                 /* string copy */
                     34:        int balance();                  /* balance PDIR structs */
                     35:        int diffdir();                  /* compare directories or files */
                     36:        int diffproject();              /* compare projects */
                     37:        int pdtparse();                 /* parse boolean type label expr */
                     38:        int read_path();                /* read project or regular pathname */
                     39:        int status = 0;                 /* exit status */
                     40:        PATH pb1;                       /* pathname struct buffer 1 */
                     41:        PATH pb2;                       /* pathname struct buffer 2 */
                     42:        unsigned long pathtyp1;         /* type of pathname 1 */
                     43:        unsigned long pathtyp2;         /* type of pathname 2 */
                     44: 
                     45:        NARGV = argv;
                     46:        NARGV[NARGI++] = "diff";
                     47: 
                     48:        {
                     49:        register char *s;               /* option pointer */
                     50:        while (--argc > 0 && **++argv == '-')
                     51:                {
                     52:                for (s = argv[0]+1; *s != '\0'; s++)
                     53:                        switch (*s)
                     54:                                {
                     55:                                case 'D':
                     56:                                        PPDEBUG = YES;
                     57:                                        break;
                     58:                                case 'T':
                     59:                                        if (pdtparse(GETARG(s), &PDIRTYP) == NO)
                     60:                                                status = 1;
                     61:                                        goto endfor;
                     62:                                case 'r':
                     63:                                        RECURSIVE++;
                     64:                                        break;
                     65:                                case 'x':
                     66:                                        EXECUTE = NO;
                     67:                                        break;
                     68:                                default:
                     69:                                        NARGV[NARGI++] = *argv;
                     70:                                        break;
                     71:                                }
                     72:                endfor: continue;
                     73:                }
                     74:        }
                     75:        if (status == 1 || argc < 2)
                     76:                {
                     77:                warn("usage: pdiff [-rx] [-T typexpr] [diff options] p1 p2");
                     78:                exit(2);
                     79:                }
                     80:        
                     81:        strcpy(p1, argv[0]);
                     82:        strcpy(p2, argv[1]);
                     83:        NARGV[NARGI+2] = NULL;
                     84: 
                     85:        if (read_path(p1, &pb1) == NO || read_path(p2, &pb2) == NO)
                     86:                exit(2);
                     87:        
                     88:        pathtyp1 = (pb1.p_mode & P_IFMT);
                     89:        pathtyp2 = (pb2.p_mode & P_IFMT);
                     90: 
                     91:        if (pathtyp1 == P_IFPROOT || pathtyp1 == P_IFHOME)
                     92:                {
                     93:                if (pathtyp2 == P_IFPROOT || pathtyp2 == P_IFHOME)
                     94:                        status = diffproject(p1, pb1.p_path, p2, pb2.p_path);
                     95:                else if (balance(p1, &pb1, &pb2) == NO)
                     96:                        exit(2);
                     97:                else
                     98:                        status = diffdir(p1, pb1.p_path, p2, pb2.p_path);
                     99:                }
                    100:        else if (pathtyp2 == P_IFPROOT || pathtyp2 == P_IFHOME)
                    101:                {
                    102:                if (balance(p2, &pb2, &pb1) == NO)
                    103:                        exit(2);
                    104:                else
                    105:                        status = diffdir(p1, pb1.p_path, p2, pb2.p_path);
                    106:                }
                    107:        else    {
                    108:                status = diffdir(p1, pb1.p_path, p2, pb2.p_path);
                    109:                }
                    110: 
                    111:        if (status > 1)
                    112:                status = 2;
                    113:        exit(status);
                    114: }
                    115: 
                    116: 
                    117: 
                    118: /*
                    119:  * balance() balances a PATH struct given a project and a directory or file.
                    120:  * If a regular directory or file, then it is assumed to be relative to the
                    121:  * current working project directory. Returns NO if balancing fails, otherwise
                    122:  * YES. The project pathname p1 is updated to reflect the balancing.
                    123:  */
                    124: balance(p1, pb1, pb2)
                    125:        char *p1;                       /* we know this is a project root dir */
                    126:        PATH *pb1;                      /* project root directory buffer */
                    127:        PATH *pb2;                      /* (project) directory or file buffer */
                    128: {
                    129:        char *pathcat();                /* regular pathname concatenation */
                    130:        char *ppathcat();               /* project pathname concatenation */
                    131:        int getcpd();                   /* get current working project dir */
                    132:        int read_path();                /* read project or regular pathname */
                    133:        PATH cpathbuf;                  /* current pathname struct buffer */
                    134: 
                    135:        if ((pb2->p_mode&P_IFMT) == P_IFPDIR)
                    136:                {
                    137:                ppathcat(p1, p1, pb2->p_alias);
                    138:                return(read_path(p1, pb1));
                    139:                }
                    140:        else if (*pb2->p_path == _RDIRC || getcpd(&cpathbuf) != 1)
                    141:                {
                    142:                warn("don't know which project directory to use in %s", p1);
                    143:                return(NO);
                    144:                }
                    145:        else    {
                    146:                ppathcat(p1, p1, cpathbuf.p_alias);
                    147:                pathcat(p1, p1, pb2->p_path);
                    148:                return(read_path(p1, pb1));
                    149:                }
                    150: }
                    151: 
                    152: 
                    153: 
                    154: /*
                    155:  * diffdir() compares two directories or files. Returns whatever diff()
                    156:  * returns.
                    157:  */
                    158: diffdir(pp1, d1, pp2, d2)
                    159:        char *pp1;                      /* project pathname */
                    160:        char *d1;                       /* directory or file pathname */
                    161:        char *pp2;                      /* project pathname */
                    162:        char *d2;                       /* directory or file pathname */
                    163: {
                    164:        static int have_printed;        /* has printing already been done? */
                    165:        int diff();                     /* fork diff program */
                    166:        int iargi;                      /* argument index */
                    167: 
                    168:        if (have_printed)
                    169:                putchar('\n');
                    170:        have_printed = 1;
                    171:        printf("==> ");
                    172:        for (iargi = 0; iargi < NARGI; iargi++)
                    173:                printf("%s ", NARGV[iargi]);
                    174:        printf("%s %s <==\n", pp1, pp2);
                    175:        fflush(stdout);
                    176: 
                    177:        if (EXECUTE == NO)
                    178:                return(0);
                    179: 
                    180:        NARGV[NARGI] = d1;
                    181:        NARGV[NARGI+1] = d2;
                    182:        return(diff(NARGV));
                    183: }
                    184: 
                    185: 
                    186: 
                    187: /*
                    188:  * diffproject() compares two projects, recursively if necessary. Returns
                    189:  * 0 if no differences, 1 if some, 2 if trouble.
                    190:  */
                    191: diffproject(pp1, p1, pp2, p2)
                    192:        char *pp1;                      /* project pathname */
                    193:        char *p1;                       /* project root directory pathname */
                    194:        char *pp2;                      /* project pathname */
                    195:        char *p2;                       /* project root directory pathname */
                    196: {
                    197:        int closepdb();                 /* close database */
                    198:        int diffpdtree();               /* diff project directory tree */
                    199:        int diffptree();                /* diff tree of projects */
                    200:        int errpdb();                   /* print database error message */
                    201:        int pdtmatch();                 /* match project dir type label expr */
                    202:        int status = 0;                 /* return status */
                    203:        PATH *pd;                       /* pathname struct pointer */
                    204:        PATH *readpld();                /* read project link directory entry */
                    205:        PDB *openpdb();                 /* open database */
                    206:        PDB *pldp;                      /* project link directory stream */
                    207:        PTREE *proot;                   /* root of project tree */
                    208:        PTREE *pdroot;                  /* root of project directory tree */
                    209:        PTREE *ptree();                 /* search and insert in proj dir tree */
                    210:        void ptreerm();                 /* remove project directory tree */
                    211: 
                    212:        proot = NULL;
                    213:        pdroot = NULL;
                    214: 
                    215:        /* read PLDNAME project link directory belonging to p1 */
                    216:        if ((pldp = openpdb(PLDNAME, p1, "r")) == NULL)
                    217:                {
                    218:                errpdb((PDB *) NULL);
                    219:                return(2);
                    220:                }
                    221:        while ((pd = readpld(pldp)) != NULL)
                    222:                {
                    223:                if (EQUAL(pd->p_alias, PARENTPROJECT))
                    224:                        continue;
                    225:                else if (EQUAL(pd->p_alias, CURPROJECT))
                    226:                        {
                    227:                        if (PDIRTYP.pfxsize==0 || pdtmatch(&PDIRTYP,pd->p_type)==YES)
                    228:                                pdroot = ptree(pdroot, "", pd->p_path, CNULL);
                    229:                        }
                    230:                else if (pd->p_mode == P_IFPROOT)
                    231:                        {
                    232:                        if (RECURSIVE)
                    233:                                proot = ptree(proot, pd->p_alias, pd->p_path, CNULL);
                    234:                        }
                    235:                else if (PDIRTYP.pfxsize==0 || pdtmatch(&PDIRTYP,pd->p_type)==YES)
                    236:                        pdroot = ptree(pdroot, pd->p_alias, pd->p_path, CNULL);
                    237:                }
                    238:        closepdb(pldp);
                    239: 
                    240:        /* read PLDNAME project link directory belonging to p2 */
                    241:        if ((pldp = openpdb(PLDNAME, p2, "r")) == NULL)
                    242:                {
                    243:                errpdb((PDB *) NULL);
                    244:                return(2);
                    245:                }
                    246:        while ((pd = readpld(pldp)) != NULL)
                    247:                {
                    248:                if (EQUAL(pd->p_alias, PARENTPROJECT))
                    249:                        continue;
                    250:                else if (EQUAL(pd->p_alias, CURPROJECT))
                    251:                        {
                    252:                        if (PDIRTYP.pfxsize==0 || pdtmatch(&PDIRTYP,pd->p_type)==YES)
                    253:                                pdroot = ptree(pdroot, "", CNULL, pd->p_path);
                    254:                        }
                    255:                else if (pd->p_mode == P_IFPROOT)
                    256:                        {
                    257:                        if (RECURSIVE)
                    258:                                proot = ptree(proot, pd->p_alias, CNULL, pd->p_path);
                    259:                        }
                    260:                else if (PDIRTYP.pfxsize==0 || pdtmatch(&PDIRTYP,pd->p_type)==YES)
                    261:                        pdroot = ptree(pdroot, pd->p_alias, CNULL, pd->p_path);
                    262:                }
                    263:        closepdb(pldp);
                    264: 
                    265:        /* diff project directory tree */
                    266:        status |= diffpdtree(pdroot, pp1, pp2);
                    267:        ptreerm(pdroot);
                    268: 
                    269:        /* diff subprojects */
                    270:        status |= diffptree(proot, pp1, pp2);
                    271:        ptreerm(proot);
                    272: 
                    273:        return(status);
                    274: }
                    275: 
                    276: 
                    277: 
                    278: /*
                    279:  * diffpdtree() compares project directories in a project directory tree.
                    280:  */
                    281: diffpdtree(p, pp1, pp2)
                    282:        PTREE *p;                       /* current node in project dir tree */
                    283:        char *pp1;                      /* project pathname */
                    284:        char *pp2;                      /* project pathname */
                    285: {
                    286:        char ppathbuf1[PPATHSIZE];      /* project pathname buffer */
                    287:        char ppathbuf2[PPATHSIZE];      /* project pathname buffer */
                    288:        char *ppathcat();               /* project pathname concantenation */
                    289:        int diffdir();                  /* compare directories or files */
                    290:        int status = 0;                 /* return status */
                    291:        void printonly();               /* print "only in project ..." mesg */
                    292: 
                    293:        if (p == NULL)
                    294:                return(0);
                    295:        status |= diffpdtree(p->left, pp1, pp2);
                    296:        if (p->pd1 == NULL)
                    297:                printonly(pp2, p->alias);
                    298:        else if (p->pd2 == NULL)
                    299:                printonly(pp1, p->alias);
                    300:        else    {
                    301:                ppathcat(ppathbuf1, pp1, p->alias);
                    302:                ppathcat(ppathbuf2, pp2, p->alias);
                    303:                status |= diffdir(ppathbuf1, p->pd1, ppathbuf2, p->pd2);
                    304:                }
                    305:        status |= diffpdtree(p->right, pp1, pp2);
                    306:        return(status);
                    307: }
                    308: 
                    309: 
                    310: 
                    311: /*
                    312:  * diffptree() compares projects in a project tree.
                    313:  */
                    314: diffptree(p, pp1, pp2)
                    315:        PTREE *p;                       /* current node in project tree */
                    316:        char *pp1;                      /* project pathname */
                    317:        char *pp2;                      /* project pathname */
                    318: {
                    319:        char ppathbuf1[PPATHSIZE];      /* project pathname buffer */
                    320:        char ppathbuf2[PPATHSIZE];      /* project pathname buffer */
                    321:        char *ppathcat();               /* project pathname concantenation */
                    322:        int diffproject();              /* compare projects */
                    323:        int status = 0;                 /* return status */
                    324:        void printonly();               /* print "only in project ..." mesg */
                    325: 
                    326:        if (p == NULL)
                    327:                return(0);
                    328:        status |= diffptree(p->left, pp1, pp2);
                    329:        if (p->pd1 == NULL)
                    330:                printonly(pp2, p->alias);
                    331:        else if (p->pd2 == NULL)
                    332:                printonly(pp1, p->alias);
                    333:        else    {
                    334:                ppathcat(ppathbuf1, pp1, p->alias);
                    335:                ppathcat(ppathbuf2, pp2, p->alias);
                    336:                status |= diffproject(ppathbuf1, p->pd1, ppathbuf2, p->pd2);
                    337:                }
                    338:        status |= diffptree(p->right, pp1, pp2);
                    339:        return(status);
                    340: }
                    341: 
                    342: 
                    343: 
                    344: /*
                    345:  * printonly() prints "only in project ..." message.
                    346:  */
                    347: void
                    348: printonly(project, pdirname)
                    349:        char *project;                  /* project pathname */
                    350:        char *pdirname;                 /* unique project directory */
                    351: {
                    352:        printf("Only in project %s: %s\n", project,
                    353:              (*pdirname == '\0') ? CURPROJECT : pdirname);
                    354:        fflush(stdout);
                    355: }
                    356: 
                    357: 
                    358: 
                    359: /*
                    360:  * read_path() loads a PATH struct given a regular or project pathname.
                    361:  * Returns integer NO if an invalid pathname or non-existent target,
                    362:  * otherwise YES.
                    363:  */
                    364: read_path(pathname, pb)
                    365:        char *pathname;                 /* regular or project pathname */
                    366:        PATH *pb;                       /* pathname struct buffer */
                    367: {
                    368:        int readpath();                 /* read project or regular pathname */
                    369: 
                    370:        if (readpath(pathname, pb) == -1 || (pb->p_mode & P_IFMT) == P_IFNEW)
                    371:                {
                    372:                patherr(pathname);
                    373:                return(NO);
                    374:                }
                    375:        return(YES);
                    376: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.