Annotation of 43BSDTahoe/new/spms/src/bin/pexec/pdset.c, revision 1.1.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.