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: }

Defined functions

balance defined in line 124; used 3 times
diffdir defined in line 158; used 6 times
diffpdtree defined in line 281; used 4 times
diffproject defined in line 191; used 4 times
diffptree defined in line 314; used 4 times
main defined in line 26; never used
printonly defined in line 347; used 6 times
read_path defined in line 364; used 6 times

Defined variables

EXECUTE defined in line 21; used 2 times
NARGI defined in line 22; used 6 times
NARGV defined in line 19; used 8 times
PGN defined in line 20; never used
RECURSIVE defined in line 23; used 3 times
rcsid defined in line 1; never used
Last modified: 1985-07-03
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1587
Valid CSS Valid XHTML 1.0 Strict