Annotation of os2sdk/demos/apps/ds/tree.c, revision 1.1

1.1     ! root        1: /*  tree.c - build and maintain directory tree */
        !             2: 
        !             3: #include <malloc.h>
        !             4: #include <memory.h>
        !             5: #include <stdio.h>
        !             6: 
        !             7: #include "ds.h"
        !             8: #include "vars.h"
        !             9: 
        !            10: /*  Local variables */
        !            11: 
        !            12: static int ImageExists=FALSE;          /* TRUE if image has been created */
        !            13: 
        !            14: 
        !            15: /***   decorateTree - Decorate directory tree and build screen image
        !            16: *
        !            17: *
        !            18: */
        !            19: decorateTree (root)
        !            20: Directory *root;
        !            21: {
        !            22:     LastRow = -1;
        !            23:     newLine ();
        !            24:     decorateSubTree (root, 0);
        !            25:     ImageExists = TRUE;                /* Set flag for newLine() */
        !            26: }   /* decorateTree */
        !            27: 
        !            28: 
        !            29: /***   decorateSubTree - Recursive portion called by decorateTree
        !            30: *
        !            31: *
        !            32: */
        !            33: decorateSubTree (par, level)
        !            34: Directory *par;
        !            35: int level;
        !            36: {
        !            37:     Directory *p;
        !            38:     int col,first;
        !            39: 
        !            40:     first = TRUE;
        !            41:     col = level*D_INDENT;
        !            42:     p = par->d_child;
        !            43:     while (p) {
        !            44:        if (first)                  /* First subdir at this level */
        !            45:            first = FALSE;          /* show on same row as parent */
        !            46:        else                        /* Not first at this level */
        !            47:            newLine();              /* Show underneath previous one */
        !            48:        p->d_row = LastRow;
        !            49:        p->d_col = col;
        !            50:        addImage (p,level);         /* Add image for this directory */
        !            51:        decorateSubTree (p, level+1);  /* Process subtree */
        !            52:        p = p->d_next;
        !            53:     }  /* while */
        !            54: }   /* decorateSubTree */
        !            55: 
        !            56: 
        !            57: /***   addImage - add image of one directory into screen image
        !            58: *
        !            59: *
        !            60: */
        !            61: addImage (p,level)
        !            62: Directory *p;
        !            63: int level;
        !            64: {
        !            65:     Directory *par;
        !            66:     int pLen,bLen,bCol;
        !            67:     char buf[MAX_COLS+1];
        !            68:     int parRow;
        !            69:     int row;
        !            70:     int col;
        !            71:     int distance;
        !            72:     cellType *c;
        !            73: 
        !            74:     par = p->d_parent;                     /* Get parent pointer */
        !            75:     modLine (p->d_col, p->d_name, color[nameC]); /* Put directory name in image */
        !            76:     if (level > 0)  {                      /* Draw line to parent */
        !            77:        distance = p->d_row - par->d_row;
        !            78:        if (distance == 0) {                /* Parent on same row */
        !            79:            pLen = strlen (par->d_name);
        !            80:            bLen = D_INDENT - pLen;         /* Length of bar */
        !            81:            bCol = par->d_col+pLen;
        !            82:            buf[bLen] = '\0';               /* Store string terminator */
        !            83:            memset (buf,LR_CHAR,bLen);      /* Store bar in buffer */
        !            84:            modLine (bCol, buf, color[barC]);      /* Put bar in image */
        !            85:        }
        !            86:        else {                              /* Parent is above */
        !            87:            bLen = D_INDENT;
        !            88:            bCol = par->d_col;
        !            89:            buf[bLen] = '\0';               /* Store string terminator */
        !            90:            memset (buf,LR_CHAR,bLen);      /* Store bar in buffer */
        !            91:            buf[0] = RT_CHAR;               /* Store angle char */
        !            92:            modLine (bCol, buf, color[barC]);      /* Put bar in image */
        !            93:            row = LastRow-1;
        !            94:            col = par->d_col;
        !            95:            parRow = par->d_row;
        !            96:            while (row > parRow) {          /* Finish path */
        !            97:                c = &DisplayRow[row][col];
        !            98:                switch (c->theChar) {
        !            99:                    case ' ':
        !           100:                        c->theChar = BT_CHAR;
        !           101:                        c->theAttr = color[barC];
        !           102:                        row--;
        !           103:                        break;
        !           104: 
        !           105:                    case RT_CHAR:
        !           106:                        c->theChar = BRT_CHAR;
        !           107:                        row = 0;
        !           108:                        break;
        !           109: 
        !           110:                    default:
        !           111:                        row = 0;
        !           112:                        break;
        !           113:                }   /* switch */
        !           114:            }   /* while */
        !           115:        }   /* else (distance != 0) */
        !           116:     }  /* if (level > 0) */
        !           117: }   /* addImage */
        !           118: 
        !           119: 
        !           120: /***   newLine - add a new line to the scree image
        !           121: *
        !           122: *
        !           123: */
        !           124: newLine ()
        !           125: {
        !           126:     cellType *p;
        !           127:     int i;
        !           128: 
        !           129:     if (++LastRow >= MAX_IMAGE_ROWS) {     /* Too many image rows */
        !           130:        fprintf (stderr, "\nDirectory image too large - Internal error.\n");
        !           131:        exitError (2);
        !           132:     }
        !           133:     if (ImageExists)                       /* Get image row pointer */
        !           134:        p = DisplayRow[LastRow];
        !           135:     else                                   /* Make new image row */
        !           136:        p = 0;
        !           137:     if (!p) {                              /* Have to make new image row */
        !           138:        p = (cellType *) calloc(N_of_Cols,sizeof(cellType));
        !           139:        if (!p) {
        !           140:            fprintf (stderr, "\nOut of memory - Allocating image line\n");
        !           141:            exitError (2);
        !           142:        }
        !           143:        DisplayRow[LastRow] = p;            /* Store pointer to image row */
        !           144:     }  /* if */
        !           145:     for (i=0; i<N_of_Cols; i++) {          /* Blank out row */
        !           146:        p->theChar = ' ';
        !           147:        p->theAttr = color[blankC];
        !           148:        p++;
        !           149:     }
        !           150: }   /* newLine */
        !           151: 
        !           152: 
        !           153: /***   modLine - store string with color in current line
        !           154: *
        !           155: *
        !           156: */
        !           157: modLine (col, str, color)
        !           158: int col;
        !           159: char *str;
        !           160: int color;
        !           161: {
        !           162:     cellType *p;
        !           163:     char *s;
        !           164: 
        !           165:     s = str;
        !           166:     p = &DisplayRow[LastRow][col];
        !           167:     while (*s) {
        !           168:        p->theChar = *s++;
        !           169:        p->theAttr = color;
        !           170:        p++;
        !           171:     }  /* while */
        !           172: }   /* modLine */
        !           173: 
        !           174: 
        !           175: Canonicalize (fullPath, p, headPath)
        !           176: char *fullPath;
        !           177: Directory *p;
        !           178: char *headPath;
        !           179: {
        !           180:     if (p->d_parent)
        !           181:        Canonicalize (fullPath, p->d_parent, headPath);
        !           182:     else
        !           183:        strcat (fullPath, headPath);
        !           184:     if (fullPath[strlen(fullPath)-1] != '\\')
        !           185:        strcat (fullPath, "\\");
        !           186:     strcat (fullPath, p->d_name);
        !           187: }
        !           188: 
        !           189: 
        !           190: /***   buildTree - scan directories breadth-first to build tree
        !           191: *
        !           192: *
        !           193: */
        !           194: buildTree (par,parPath)
        !           195: Directory *par;
        !           196: char *parPath;
        !           197: {
        !           198:     char        sName[MAX_PATH_LEN];       /* Search path name */
        !           199:     Directory  *child;
        !           200:     int         errCode;
        !           201:     int         sLen;
        !           202:     Attr        a;
        !           203:     Cell        c;
        !           204:     Directory  *bfsHead;
        !           205:     Directory  *bfsTail;
        !           206:     FileSearch  sBuf;                /* Find First/Next buffer */
        !           207:     unsigned    sCount;              /* Number of entries to search for */
        !           208:     unsigned    sHandle;             /* Search Handle */
        !           209: 
        !           210:     bfsHead = par;
        !           211:     bfsTail = par;
        !           212:     c.ch = ' ';
        !           213:     c.at = color[blankC];
        !           214:     a = color[statusC];
        !           215: 
        !           216:     while (bfsHead) {
        !           217:        sName[0] = '\0';
        !           218:        Canonicalize (sName, bfsHead, parPath);
        !           219: 
        !           220:        sLen = strlen(sName);
        !           221:        VIOWRTCHARSTRATT (chfs(sName), sLen, WINDOW_TOP,0, afs(&a), VioHandle);
        !           222:        VIOWRTNCELL (cefs(&c), N_of_Cols-sLen, WINDOW_TOP,sLen, VioHandle);
        !           223: 
        !           224:        if (sName[sLen-1] == '\\')
        !           225:            strcat (sName, "*.*");
        !           226:        else
        !           227:            strcat (sName, "\\*.*");
        !           228:        sHandle = -1;                   /* Family API only has one handle */
        !           229:        sCount = 1;                     /* Search for one at a time */
        !           230:        errCode = DOSFINDFIRST (chfs(sName),
        !           231:                                ufs(&sHandle),
        !           232:                                DosAttrSubDir,
        !           233:                                (FileSearch far *) &sBuf,
        !           234:                                sizeof(sBuf),
        !           235:                                ufs(&sCount),
        !           236:                                0L);
        !           237:        while (!errCode) {
        !           238:            if (sBuf.file_name[0] != '.') { /* Not a back link */
        !           239:                if (sBuf.attributes & DosAttrSubDir) {  /* A subdirectory */
        !           240:                    newDir (&child, sBuf.file_name, bfsHead);
        !           241:                    insDir (bfsHead, child, &bfsTail);
        !           242:                    bfsTail->d_link = child;
        !           243:                    bfsTail = child;
        !           244:                }
        !           245:            }
        !           246:            errCode = DOSFINDNEXT (sHandle,
        !           247:                                   (FileSearch far *) &sBuf,
        !           248:                                   sizeof(sBuf),
        !           249:                                   ufs(&sCount));
        !           250:        }
        !           251:        DOSFINDCLOSE (sHandle);
        !           252:        bfsHead = bfsHead->d_link;
        !           253:     }
        !           254: }   /* buildTree */
        !           255: 
        !           256: 
        !           257: /***   insDir - insert child directory into tree in alphabetical order
        !           258: *
        !           259: *
        !           260: */
        !           261: insDir (par,child)
        !           262: Directory  *par;
        !           263: Directory  *child;
        !           264: {
        !           265:     Directory *p,*q;
        !           266: 
        !           267:     p = par->d_child;                  /* p = first child */
        !           268:     q = 0;                             /* q = previous pointer */
        !           269:     while (p && (strcmp(child->d_name,p->d_name) > 0)) {
        !           270:        q = p;                          /* q = previous node */
        !           271:        p = p->d_next;                  /* p = next node */
        !           272:     }
        !           273:     if (!q)                            /* Insert at front of list */
        !           274:        par->d_child = child;
        !           275:     else                               /* Insert at middle or end of list */
        !           276:        q->d_next = child;
        !           277: 
        !           278:     child->d_prev = q;
        !           279:     child->d_next = p;
        !           280: 
        !           281:     if (p)                             /* Not inserting at end of list */
        !           282:        p->d_prev = child;
        !           283: }   /* insDir */
        !           284: 
        !           285: 
        !           286: /***   newDir - create a new directory entry for tree
        !           287: *
        !           288: *
        !           289: */
        !           290: newDir (dir,name,par)
        !           291: Directory **dir;
        !           292: char *name;
        !           293: Directory *par;
        !           294: {
        !           295:     Directory *p;
        !           296: 
        !           297:     p = (Directory *) malloc (sizeof(Directory));
        !           298:     if (!p) {
        !           299:        fprintf (stderr, "\nOut of memory - Allocating directory node\n");
        !           300:        exitError (2);
        !           301:     }
        !           302:     p->d_name[0]   = '\0';
        !           303:     strcpy (p->d_name,name);
        !           304:     p->d_parent    = par;
        !           305:     p->d_prev     = 0;
        !           306:     p->d_next     = 0;
        !           307:     p->d_child    = 0;
        !           308:     p->d_link     = 0;
        !           309: 
        !           310:     *dir = p;                      /* Return address of new dir node */
        !           311: }   /* newDir */
        !           312: 
        !           313: 
        !           314: /***   pruneTree - prune subtree that has been deleted
        !           315: *
        !           316: *      Called when we discover that a directory no longer exists.
        !           317: *
        !           318: *      ENTRY:  root = address of pointer to directory node that has evaporated.
        !           319: *
        !           320: *      EXIT:   root = address of pointer to some other node that is "close"
        !           321: *                     to the evaporated node.  Choose previous, next, or
        !           322: *                     parent, in that order.
        !           323: */
        !           324: pruneTree (curDir)
        !           325: Directory **curDir;
        !           326: {
        !           327:     Directory *p;                      /* Used to traverse tree */
        !           328:     Directory *q;                      /* Used to traverse tree */
        !           329:     Directory *n;                      /* Node to return */
        !           330: 
        !           331:     p = *curDir;                       /* p = node to delete */
        !           332:     if (n = p->d_prev) {               /* n = previous sibling */
        !           333:        q = p->d_next;                  /* q = next for n */
        !           334:        n->d_next = q;                  /* Point new node to new next */
        !           335:        if (q)                          /* Not last sibling */
        !           336:            q->d_prev = n;              /* Point next back to new node */
        !           337:     }
        !           338:     else                               /* No previous sibling */
        !           339:        if (n = p->d_next) {            /* n = next sibling */
        !           340:            n->d_prev = 0;              /* Next sibling is now first */
        !           341:            q = n->d_parent;            /* q = parent */
        !           342:            q->d_child = n;             /* Point parent to new first child */
        !           343:        }
        !           344:        else
        !           345:            if (n = p->d_parent)        /* n = parent */
        !           346:                if (n->d_parent)        /* n is not root */
        !           347:                    n->d_child = 0;     /* Deleted only child of parent */
        !           348:                else {
        !           349:                    fprintf (stderr, "directory tree is empty\n");
        !           350:                    exit (2);
        !           351:                }
        !           352:            else {
        !           353:                fprintf (stderr, "directory tree is empty\n");
        !           354:                exit (2);
        !           355:            };
        !           356: 
        !           357:     delDir (p);                        /* Delete subtree */
        !           358:     decorateTree (root);               /* Re-build tree image */
        !           359:     stateModified = TRUE;              /* Tree is modified */
        !           360:     *curDir = n;                       /* Return new node */
        !           361: 
        !           362: }   /* pruneTree */
        !           363: 
        !           364: 
        !           365: /***   delDir - Delete directory subtree
        !           366: *
        !           367: *
        !           368: */
        !           369: delDir (root)
        !           370: Directory *root;
        !           371: {
        !           372:     Directory *p;
        !           373:     Directory *q;
        !           374: 
        !           375:     p = root->d_child;                 /* p = first child */
        !           376:     while (p) {                        /* Still children to delete */
        !           377:        q = p;
        !           378:        p = p->d_next;
        !           379:        delDir (q);
        !           380:     }
        !           381: 
        !           382:     free ( (char *) root);
        !           383: 
        !           384: }   /* delDir */

unix.superglobalmegacorp.com

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