Annotation of 43BSD/contrib/spms/src/bin/pexec/pdset.c, revision 1.1

1.1     ! root        1: /* $Header$ */
        !             2: 
        !             3: /*
        !             4:  * Author: Peter J. Nicklin
        !             5:  */
        !             6: #include <stdio.h>
        !             7: #include "hash.h"
        !             8: #include "macro.h"
        !             9: #include "null.h"
        !            10: #include "path.h"
        !            11: #include "pdb.h"
        !            12: #include "pdset.h"
        !            13: #include "pdlist.h"
        !            14: #include "pdtyp.h"
        !            15: #include "pld.h"
        !            16: #include "slist.h"
        !            17: #include "slslist.h"
        !            18: #include "spms.h"
        !            19: #include "truefalse.h"
        !            20: #include "yesno.h"
        !            21: 
        !            22: #define INCRPDIRS       50             /* amount to increase pdir ptr array */
        !            23: #define MAXPDIRS       100             /* initial size of proj dir ptr array */
        !            24: 
        !            25: extern char *PGN;                      /* program name */
        !            26: extern PDTYP PDIRTYP;                  /* project directory type labels list */
        !            27: 
        !            28: static int Ipdirs;                     /* attribute block array index */
        !            29: static int Maxpdirs = MAXPDIRS;                /* maximum no. of project dirs */
        !            30: static int Ntypes;                     /* number of unique type labels */
        !            31: static PDSET **Pdarray;                        /* project dir attribute block array */
        !            32: static short *Maptyp;                  /* unique type label mapping array */
        !            33: static TYPES *Typstat;                 /* type label statistics */
        !            34: 
        !            35: /*
        !            36:  * add_pdset() adds a project directory to the set of project directories
        !            37:  * which satisfy a boolean project directory type label expression. Only
        !            38:  * those type labels which satisfy the boolean expression are included with
        !            39:  * the project directory. To determine which type labels qualify, the
        !            40:  * postfix expression is scanned from right to left. Type labels within a
        !            41:  * negated expression are ignored. For example, in the postfix equivalent
        !            42:  * of expression "src & !(cmd | lib)" (that is: src cmd lib | ! &),
        !            43:  * even if both "src" and "cmd" are found, "src" is the only type label
        !            44:  * which could qualify.
        !            45:  */
        !            46: void
        !            47: add_pdset(postfix, ppathname, pathname, project)
        !            48:        register PDTYP *postfix;        /* postfix expression struct */
        !            49:        char *ppathname;                /* project directory project pathname */
        !            50:        char *pathname;                 /* project directory pathname */
        !            51:        char *project;                  /* project directory's project */
        !            52: {
        !            53:        register int i;                 /* postfix expression index */
        !            54:        register int opcount;           /* count of expected operands */
        !            55:        char *pdtcpy();                 /* copy project directory type label */
        !            56:        char *realloc();                /* reallocate memory block */
        !            57:        char type[TYPESIZE];            /* project dir type label buffer */
        !            58:        PDSET *savepdir();              /* save pdir attribute blk somewhere */
        !            59:        void savetype();                /* save type label */
        !            60: 
        !            61:        if (Ipdirs >= Maxpdirs)
        !            62:                {
        !            63:                Maxpdirs += INCRPDIRS;
        !            64:                if ((Pdarray = (PDSET **) realloc((char *)Pdarray,
        !            65:                               (unsigned)Maxpdirs*sizeof(PDSET *))) == NULL)
        !            66:                        nomorecore();
        !            67:                }
        !            68:        Pdarray[Ipdirs] = savepdir(ppathname, pathname, project);
        !            69: 
        !            70:        opcount = 0;
        !            71:        for (i = (postfix->pfxsize)-1; i >= 0;)
        !            72:                {
        !            73:                switch ((postfix->pfx)[i].p_class)
        !            74:                        {
        !            75:                        case B_ID:
        !            76:                                if ((postfix->pfx)[i].p_sw == TRUE)
        !            77:                                        {
        !            78:                                        pdtcpy(type, (postfix->pfx)[i].p_label);
        !            79:                                        savetype(type, i);
        !            80:                                        }
        !            81:                                break;
        !            82:                        case B_OR:
        !            83:                        case B_AND:
        !            84:                                if ((postfix->pfx)[i].p_sw == FALSE)
        !            85:                                        opcount += 2;
        !            86:                                break;
        !            87:                        case B_NOT:
        !            88:                                /* always skip !subexpr */
        !            89:                                opcount += 1;
        !            90:                                break;
        !            91:                        }
        !            92:                /* skip false subexpression */
        !            93:                for (--i; opcount > 0; i--)
        !            94:                        switch ((postfix->pfx)[i].p_class)
        !            95:                                {
        !            96:                                case B_ID:
        !            97:                                        opcount -= 1;
        !            98:                                        break;
        !            99:                                case B_OR:
        !           100:                                case B_AND:
        !           101:                                        opcount += 1;
        !           102:                                        break;
        !           103:                                case B_NOT:
        !           104:                                        break;
        !           105:                                }
        !           106:                }
        !           107:        Ipdirs++;
        !           108: }
        !           109: 
        !           110: 
        !           111: 
        !           112: /*
        !           113:  * build_pdset() builds a set of project directories which satisfy a boolean
        !           114:  * project directory type label expression.
        !           115:  */
        !           116: build_pdset(ppathname, pathname)
        !           117:        char *ppathname;                /* project root dir project pathname */
        !           118:        char *pathname;                 /* regular project root dir pathname */
        !           119: {
        !           120:        extern int ERRSTATUS;           /* pexec error status */
        !           121:        extern SLIST *ENVLIST;          /* project environment variable list */
        !           122:        char ppathbuf[PPATHSIZE];       /* project pathname buffer */
        !           123:        char *ppathcat();               /* project pathname concatenation */
        !           124:        char *pv;                       /* PROJECT environment variable */
        !           125:        char *slprepend();              /* prepend key */
        !           126:        char *slsprepend();             /* prepend key+string */
        !           127:        int closepdb();                 /* close database */
        !           128:        int errpdb();                   /* print database error message */
        !           129:        int pdtmatch();                 /* match project dir type label expr */
        !           130:        int status = 0;                 /* return status */
        !           131:        PATH *pd;                       /* pathname struct pointer */
        !           132:        PATH *readpld();                /* read project link directory entry */
        !           133:        PDB *openpdb();                 /* open database */
        !           134:        PDB *pldp;                      /* project link directory stream */
        !           135:        SLSBLK *pblk;                   /* project list block */
        !           136:        SLSLIST *plist;                 /* project list */
        !           137:        SLSLIST *slsinit();             /* initialize list */
        !           138:        void add_pdset();               /* add to set of project dirs */
        !           139:        void slsrm();                   /* remove list item */
        !           140: 
        !           141:        if ((pv = slprepend(pathname, ENVLIST)) == NULL)
        !           142:                pxexit();
        !           143:        plist = slsinit();
        !           144: 
        !           145:        /* read PLDNAME project link directory */
        !           146:        if ((pldp = openpdb(PLDNAME, pathname, "r")) == NULL)
        !           147:                return(errpdb((PDB *) NULL));
        !           148:        while ((pd = readpld(pldp)) != NULL)
        !           149:                {
        !           150:                if (EQUAL(pd->p_alias, PARENTPROJECT))
        !           151:                        continue;
        !           152: 
        !           153:                if (EQUAL(pd->p_alias, CURPROJECT))
        !           154:                        {
        !           155:                        if (pdtmatch(&PDIRTYP, pd->p_type) == YES)
        !           156:                                add_pdset(&PDIRTYP, ppathname, pd->p_path, pv);
        !           157:                        }
        !           158:                else if (pd->p_mode == P_IFPROOT)
        !           159:                        {
        !           160:                        if (slsprepend(pd->p_alias, pd->p_path, plist) == NULL)
        !           161:                                pxexit();
        !           162:                        }
        !           163:                else if (pdtmatch(&PDIRTYP, pd->p_type) == YES)
        !           164:                        {
        !           165:                        ppathcat(ppathbuf, ppathname, pd->p_alias);
        !           166:                        add_pdset(&PDIRTYP, ppathbuf, pd->p_path, pv);
        !           167:                        }
        !           168:                }
        !           169:        if (closepdb(pldp) != 0)
        !           170:                status = ERRSTATUS;
        !           171: 
        !           172:        /* build project directory type label tree for subprojects */
        !           173:        for (pblk = plist->head; pblk != NULL; pblk = pblk->next)
        !           174:                {
        !           175:                ppathcat(ppathbuf, ppathname, pblk->key);
        !           176:                status |= build_pdset(ppathbuf, pblk->string);
        !           177:                }
        !           178:        slsrm(CNULL, plist);
        !           179: 
        !           180:        return(status);
        !           181: }
        !           182: 
        !           183: 
        !           184: 
        !           185: /*
        !           186:  * check_pdset() detects conflicting type label priorities by
        !           187:  * checking that project directories are sorted into ascending
        !           188:  * order according to priority. An error message is printed and
        !           189:  * 1 returned on conflict, otherwise zero.
        !           190:  */
        !           191: check_pdset()
        !           192: {
        !           193:        register int iPd;               /* proj dir block array index */
        !           194:        register int ityp;              /* type label block index */
        !           195:        register int lastpr;            /* previous type label priority */
        !           196:        register int prior;             /* project dir type label priority */
        !           197:        register PDSET **ptrPd;         /* Pdarray block array pointer */
        !           198:        int nsortyp;                    /* no. type label categories to sort */
        !           199: 
        !           200:        nsortyp = 0;
        !           201:        for (ityp = 0; ityp < Ntypes; ityp++)
        !           202:                if (Typstat[ityp].t_sort)
        !           203:                        nsortyp++;
        !           204:        if (nsortyp < 2)
        !           205:                return(0);
        !           206: 
        !           207:        for (ityp = 0; ityp < Ntypes; ityp++)
        !           208:                if (Typstat[ityp].t_sort)
        !           209:                        {
        !           210:                        for (ptrPd=Pdarray, iPd=Ipdirs; iPd > 0; ptrPd++, iPd--)
        !           211:                                if ((*ptrPd)->typblk[ityp].t_exist)
        !           212:                                        {
        !           213:                                        lastpr = (*ptrPd)->typblk[ityp].t_prior;
        !           214:                                        break;
        !           215:                                        }
        !           216:                        for (ptrPd++, iPd--; iPd > 0; ptrPd++, iPd--)
        !           217:                                {
        !           218:                                if ((*ptrPd)->typblk[ityp].t_exist)
        !           219:                                        {
        !           220:                                        prior = (*ptrPd)->typblk[ityp].t_prior;
        !           221:                                        if (prior < lastpr)
        !           222:                                                goto conflict;
        !           223:                                        lastpr = prior;
        !           224:                                        }
        !           225:                                }
        !           226:                        }
        !           227:        return(0);
        !           228: conflict:
        !           229:        fprintf(stderr, "%s:", PGN);
        !           230:        for (ityp = Ntypes-1; ityp >= 0; ityp--)
        !           231:                if (Typstat[ityp].t_sort)
        !           232:                        fprintf(stderr, (nsortyp-- > 1) ? " %s," :
        !           233:                                " %s: conflicting type label priorities\n",
        !           234:                                Typstat[ityp].t_name);
        !           235:        return(1);
        !           236: }
        !           237: 
        !           238: 
        !           239: 
        !           240: /*
        !           241:  * debug_pdset() prints the sorted project directories together with
        !           242:  * the type labels that satisfy the boolean expression.
        !           243:  */
        !           244: void
        !           245: debug_pdset()
        !           246: {      
        !           247:        int iPd;                        /* project dir block array index */
        !           248:        int ityp;                       /* type label statistics array index */
        !           249: 
        !           250:        for (iPd = 0; iPd < Ipdirs; iPd++)
        !           251:                {
        !           252:                fprintf(stderr, "%s:", Pdarray[iPd]->ppath);
        !           253:                for (ityp = 0; ityp < Ntypes; ityp++)
        !           254:                        if (Pdarray[iPd]->typblk[ityp].t_exist)
        !           255:                                fprintf(stderr," %s.%d",Typstat[ityp].t_name,
        !           256:                                        Pdarray[iPd]->typblk[ityp].t_prior);
        !           257:                putc('\n', stderr);
        !           258:                }
        !           259: }
        !           260: 
        !           261: 
        !           262: 
        !           263: /*
        !           264:  * exec_pdset() executes a set of project directories. Returns non-zero
        !           265:  * error status if error.
        !           266:  */
        !           267: exec_pdset()
        !           268: {
        !           269:        extern int ERRSTATUS;           /* pexec error status */
        !           270:        extern int EXECUTE;             /* execute command? */
        !           271:        extern int PRINT_HEADING;       /* print headings for project dirs */
        !           272:        int ch_dir();                   /* change current working directory */
        !           273:        int execcmd();                  /* execute command in directory */
        !           274:        int iPd;                        /* project dir block array index */
        !           275:        int status = 0;                 /* return status */
        !           276:        void print_title();             /* print project directory title */
        !           277: 
        !           278:        for (iPd = 0; iPd < Ipdirs; iPd++)
        !           279:                {
        !           280:                if (PRINT_HEADING == YES)
        !           281:                        print_title(Pdarray[iPd]->ppath);
        !           282:                if (ch_dir(Pdarray[iPd]->rpath) == NO)
        !           283:                        status = ERRSTATUS;
        !           284:                else if (EXECUTE == YES)
        !           285:                        status |= execcmd(Pdarray[iPd]->project);
        !           286:                }
        !           287:        return(status);
        !           288: }
        !           289: 
        !           290: 
        !           291: 
        !           292: /*
        !           293:  * init_pdset() allocates an array of pointers (Pdarray) to project
        !           294:  * directory attribute blocks, and calculates the maximum number of type
        !           295:  * labels to be stored with each project directory based on the number of
        !           296:  * unique type labels in the boolean postfix type expression. An array
        !           297:  * (Typstat) is also created to maintain statistics on each brand of
        !           298:  * label.
        !           299:  *
        !           300:  * Hash table lookup is used in forming unique type labels and a
        !           301:  * mapping array is used to map the labels from the boolean postfix
        !           302:  * type label expression to the unique representation.
        !           303:  */
        !           304: #define UNIQTYPHASHSIZE                41
        !           305: 
        !           306: void
        !           307: init_pdset()
        !           308: {
        !           309:        register int i;                 /* postfix type expression index */
        !           310:        char *malloc();                 /* memory allocator */
        !           311:        char *pfxcpy();                 /* copy string prefix */
        !           312:        char type[TYPESIZE];            /* project dir type label buffer */
        !           313:        HASH *htinit();                 /* initialize hash table */
        !           314:        HASH *uniqtyp;                  /* hash table of unique type labels */
        !           315:        HASHBLK *htb;                   /* hash table block pointer */
        !           316:        HASHBLK *htinstall();           /* install hash table entry */
        !           317:        HASHBLK *htlookup();            /* find hash table entry */
        !           318:        int nid;                        /* no. of ids in boolean expression */
        !           319: 
        !           320:        /* project directory attribute block pointer array */
        !           321:        if ((Pdarray = (PDSET **) malloc((unsigned)Maxpdirs*sizeof(PDSET *))) == NULL)
        !           322:                nomorecore();
        !           323: 
        !           324:        /* create postfix expression -> unique type label mapping array */
        !           325:        if ((Maptyp = (short *) malloc((unsigned)PDIRTYP.pfxsize*sizeof(short))) == NULL)
        !           326:                nomorecore();
        !           327: 
        !           328:        /* create type label statistics array (estimate size first) */
        !           329:        nid = 0;
        !           330:        for (i = (PDIRTYP.pfxsize)-1; i >= 0; i--)
        !           331:                if ((PDIRTYP.pfx)[i].p_class == B_ID)
        !           332:                        nid++;
        !           333:        if ((Typstat = (TYPES *) malloc((unsigned)nid*sizeof(TYPES))) == NULL)
        !           334:                nomorecore();
        !           335: 
        !           336:        /* unique type label determination */
        !           337:        uniqtyp = htinit(UNIQTYPHASHSIZE);
        !           338:        for (i = (PDIRTYP.pfxsize)-1; i >= 0; i--)
        !           339:                {
        !           340:                if ((PDIRTYP.pfx)[i].p_class != B_ID)
        !           341:                        continue;
        !           342:                pfxcpy(type, (PDIRTYP.pfx)[i].p_id);
        !           343:                if ((htb = htlookup(type, uniqtyp)) != NULL)
        !           344:                        {
        !           345:                        Maptyp[i] = htb->h_val;
        !           346:                        }
        !           347:                else    {
        !           348:                        if ((htb = htinstall(type,"",Ntypes,uniqtyp)) == NULL)
        !           349:                                nomorecore();
        !           350:                        Maptyp[i] = Ntypes;
        !           351:                        Typstat[Ntypes].t_name = htb->h_key;
        !           352:                        Typstat[Ntypes].t_ntl = Typstat[Ntypes].t_sort = 0;
        !           353:                        Ntypes++;
        !           354:                        }
        !           355:                }
        !           356: }
        !           357: 
        !           358: 
        !           359: 
        !           360: /*
        !           361:  * pdbcmp() compares the type label priorities and project pathnames
        !           362:  * for two project directories. Type label priorities override the
        !           363:  * lexicographical relationship of the project pathnames. Conflicting
        !           364:  * priorities are not detected. For example, a conflict occurs if the
        !           365:  * first directory has type labels print.1 and update.2, whereas the
        !           366:  * second directory has type labels print.2 and update.1. Returns
        !           367:  * an integer less than, equal to, or greater than zero, depending on
        !           368:  * the relative priorities of the type labels or lexicographical ordering
        !           369:  * of the project pathnames.
        !           370:  */
        !           371: pdbcmp(b1, b2)
        !           372:        PDSET **b1;                     /* project directory block pointer */
        !           373:        PDSET **b2;                     /* project directory block pointer */
        !           374: {
        !           375:        register TYPBLK *t1;            /* type label block pointer */
        !           376:        register TYPBLK *t2;            /* type label block pointer */
        !           377:        register TYPES *ty;             /* type statistics array pointer */
        !           378:        register int comp;              /* block comparison */
        !           379:        register int ityp;              /* type label block index */
        !           380:        register int ntypes;            /* number of unique type labels */
        !           381:        int strcmp();                   /* string comparison */
        !           382: 
        !           383:        comp = 0;
        !           384:        ntypes = Ntypes;
        !           385:        t1 = (*b1)->typblk;
        !           386:        t2 = (*b2)->typblk;
        !           387:        ty = Typstat;
        !           388: 
        !           389:        for (ityp = 0; ityp < ntypes; ityp++)
        !           390:                {
        !           391:                if (ty->t_sort && t1->t_exist && t2->t_exist)
        !           392:                        if ((comp = t1->t_prior - t2->t_prior) != 0)
        !           393:                                return(comp);
        !           394:                t1++, t2++, ty++;
        !           395:                }
        !           396:        return(strcmp((*b1)->ppath, (*b2)->ppath));
        !           397: }
        !           398: 
        !           399: 
        !           400: 
        !           401: /*
        !           402:  * savepdir() saves a block of project directory attributes somewhere
        !           403:  * and returns a pointer to the somewhere, or dies if out of memory.
        !           404:  */
        !           405: PDSET *
        !           406: savepdir(ppathname, pathname, project)
        !           407:        char *ppathname;                /* project directory project pathname */
        !           408:        char *pathname;                 /* project directory regular pathname */
        !           409:        char *project;                  /* project directory's project */
        !           410: {
        !           411:        char *calloc();                 /* initialize memory to zero */
        !           412:        char *malloc();                 /* memory allocator */
        !           413:        char *strcpy();                 /* string copy */
        !           414:        int strlen();                   /* string length */
        !           415:        PDSET *pdbptr;                  /* pointer to proj directory block */
        !           416: 
        !           417:        if ((pdbptr = (PDSET *) malloc(sizeof(PDSET))) == NULL ||
        !           418:            (pdbptr->ppath = malloc((unsigned)(strlen(ppathname)+1))) == NULL ||
        !           419:            (pdbptr->rpath = malloc((unsigned)(strlen(pathname)+1))) == NULL ||
        !           420:            (pdbptr->typblk = (TYPBLK *) calloc((unsigned)Ntypes,sizeof(TYPBLK))) == NULL)
        !           421:                nomorecore();
        !           422:        strcpy(pdbptr->rpath, pathname);
        !           423:        strcpy(pdbptr->ppath, ppathname);
        !           424:        pdbptr->project = project;
        !           425:        return(pdbptr);
        !           426: }
        !           427: 
        !           428: 
        !           429: 
        !           430: /*
        !           431:  * savetype() records the priorities of the type labels attached to each
        !           432:  * directory, and also the total number of each type label.
        !           433:  */
        !           434: void
        !           435: savetype(type, idx)
        !           436:        char *type;                     /* project dir type label */
        !           437:        int idx;                        /* boolean type expression id index */
        !           438: {
        !           439:        register char *ptyptr;          /* pointer to type label priority */
        !           440:        register int priority;          /* type label priority */
        !           441:        register int uniqid;            /* unique type label number */
        !           442:        char *index();                  /* first occurrence of character */
        !           443:        int atoi();                     /* string to decimal integer */
        !           444: 
        !           445:        uniqid = Maptyp[idx];
        !           446:        ptyptr = index(type, '.');
        !           447:        priority = (ptyptr == NULL) ? 0 : atoi(++ptyptr);
        !           448:        if (Typstat[uniqid].t_ntl == 0)
        !           449:                {
        !           450:                Typstat[uniqid].t_itlp = priority;
        !           451:                }
        !           452:        else    {
        !           453:                if (priority != Typstat[uniqid].t_itlp)
        !           454:                        Typstat[uniqid].t_sort = 1;
        !           455:                }
        !           456:        Typstat[uniqid].t_ntl++;
        !           457: 
        !           458:        Pdarray[Ipdirs]->typblk[uniqid].t_exist++;
        !           459:        Pdarray[Ipdirs]->typblk[uniqid].t_prior = priority;
        !           460: }
        !           461: 
        !           462: 
        !           463: 
        !           464: /*
        !           465:  * sort_pdset() sorts the set of project directories alpahabetically
        !           466:  * and by type label priorities.
        !           467:  */
        !           468: void
        !           469: sort_pdset()
        !           470: {
        !           471:        int pdbcmp();                   /* compare project dir blocks */
        !           472: 
        !           473:        qsort((char *)Pdarray, Ipdirs, sizeof(PDSET *), pdbcmp);
        !           474: }

unix.superglobalmegacorp.com

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