home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / shell / ncd-0.000 / ncd-0 / ncd-0.9.8 / nodeops.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-04  |  7.7 KB  |  402 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. #include "ncd.h"
  5.  
  6. /*************************************************************************/
  7. /* given a starting node in {baseNode}, a base directory in {baseDir},
  8.    where {baseDir} corresponds to {baseNode}, and a directory {dir} to
  9.    locate in the node tree, the function {returns} the node for {dir} or
  10.    NULL if not found */
  11.  
  12. DirNode *searchNodeForDir(DirNode * baseNode, char *baseDir, char *dir)
  13. {
  14.     char *s;
  15.     DirNode *dn, *son;
  16.  
  17.     if (baseNode == NULL)
  18.         return NULL;
  19.  
  20.     if (strstr(dir, baseDir) != dir)
  21.         return NULL;
  22.  
  23.     s = dir + strlen(baseDir);
  24.     if (*s == '/')
  25.         s++;
  26.     if (*s == '\0')
  27.         return baseNode;
  28.  
  29.     son = baseNode->right;
  30.     
  31.     while (son != NULL) {
  32.         dn = searchNodeForDir(son, son->name, s);
  33.         if (dn)
  34.             return dn;
  35.         son = son->down;
  36.     }
  37.     return NULL;
  38. }
  39.  
  40. /*************************************************************************/
  41.  
  42. DirNode *getLastDescendant(DirNode * node)
  43. {
  44.     if (node == NULL)
  45.         return NULL;
  46.  
  47.     if (node->right == NULL)
  48.         return node;
  49.     node = node->right;
  50.  
  51.     while (1) {
  52.         while (node->down != NULL)
  53.             node = node->down;
  54.         if (node->right == NULL)
  55.             return node;
  56.         node = node->right;
  57.     }
  58. }
  59.  
  60. /*************************************************************************/
  61.  
  62. DirNode *getLastNodeInSameLevel(DirNode * node)
  63. {
  64.     if (node == NULL)
  65.         return NULL;
  66.  
  67.     while (node->right != NULL)
  68.         node = node->right;
  69.  
  70.     return node;
  71. }
  72.  
  73. /*************************************************************************/
  74.  
  75. DirNode *getFirstNodeInSameLevel(DirNode * node)
  76. {
  77.     if (node == NULL)
  78.         return NULL;
  79.  
  80.     while ((node->left != NULL) && (node->left->right == node))
  81.         node = node->left;
  82.  
  83.     return node;
  84. }
  85.  
  86. /*************************************************************************/
  87.  
  88. DirNode *getAnyNodeInLevel(DirNode * node, int level)
  89. {
  90.  
  91.     while (1) {
  92.         if (node == NULL)
  93.             return NULL;
  94.  
  95.         while ((node->down != NULL) && (node->down->y <= level))
  96.             node = node->down;
  97.  
  98.         if (node->y == level)
  99.             return node;
  100.  
  101.         node = node->right;
  102.     }
  103. }
  104.  
  105. /*************************************************************************/
  106.  
  107. DirNode *getLastNodeInLevel(DirNode * node, int level)
  108. {
  109.     return getLastNodeInSameLevel(getAnyNodeInLevel(node, level));
  110. }
  111.  
  112. /*************************************************************************/
  113.  
  114. DirNode *getFirstNodeInLevel(DirNode * node, int level)
  115. {
  116.     return getFirstNodeInSameLevel(getAnyNodeInLevel(node, level));
  117. }
  118.  
  119. /*************************************************************************/
  120.  
  121. DirNode *getNodeCursUp(DirNode * curNode)
  122. {
  123.     if (curNode->up)
  124.         return curNode->up;
  125.     if (curNode->left)
  126.         return curNode->left;
  127.  
  128.     return curNode;
  129. }
  130.  
  131. /*************************************************************************/
  132.  
  133. DirNode *getNodeLnUp(DirNode * curNode)
  134. {
  135.     DirNode * dn;
  136.     
  137.     if (curNode->y>0) 
  138.         dn = getLastNodeInLevel(_rootNode, curNode->y-1);
  139.     else    
  140.         dn = NULL;
  141.  
  142.     if (dn!=NULL)
  143.         return dn;
  144.     else
  145.         return curNode;
  146. }
  147.  
  148. /*************************************************************************/
  149.  
  150. DirNode *getNodeLnDn(DirNode * curNode)
  151. {
  152.     DirNode * dn;
  153.     
  154.     dn = getFirstNodeInLevel(_rootNode, curNode->y+1);
  155.  
  156.     if (dn!=NULL)
  157.         return dn;
  158.     else
  159.         return curNode;
  160. }
  161.  
  162. /*************************************************************************/
  163.  
  164. DirNode *getNodePrev( DirNode * curNode )
  165. {
  166.     if (curNode==NULL)
  167.         return NULL;
  168.  
  169.     if ((curNode->left!=NULL)&&(curNode->left->right==curNode))
  170.         return curNode->left;
  171.         
  172.     return getNodeLnUp(curNode);
  173. }
  174.  
  175. /*************************************************************************/
  176.  
  177. DirNode *getNodeCursDown(DirNode * curNode)
  178. {
  179.     DirNode *node;
  180.  
  181.     if (curNode->down != NULL)
  182.         return curNode->down;
  183.     if (curNode->right != NULL)
  184.         return curNode->right;
  185.  
  186.     node = getFirstNodeInLevel(_rootNode, curNode->y + 1);
  187.  
  188.     if (node != NULL)
  189.         return node;
  190.     else
  191.         return curNode;
  192. }
  193.  
  194. /*************************************************************************/
  195.  
  196. DirNode *getNodeCursLeft(DirNode * curNode)
  197. {
  198.     if (curNode->left != NULL)
  199.         return curNode->left;
  200.     else
  201.         return curNode;
  202. }
  203.  
  204. /*************************************************************************/
  205.  
  206. DirNode *getNodeCursRight(DirNode * curNode)
  207. {
  208.     DirNode *node;
  209.  
  210.     if (curNode->right != NULL)
  211.         return curNode->right;
  212.     if (curNode->down != NULL)
  213.         return curNode->down;
  214.  
  215.     node = curNode->left;
  216.  
  217.     while (node != NULL) {
  218.         if (node->down != NULL)
  219.             return node->down;
  220.         else
  221.             node = node->left;
  222.     }
  223.  
  224.     return curNode;
  225. }
  226.  
  227. /*************************************************************************/
  228.  
  229. DirNode *locatePathOrSo( char * path, char * *rest )
  230. {
  231.     char dir[PATH_MAX];
  232.     char *s;
  233.     DirNode *dn;
  234.  
  235.     strcpy(dir, path);
  236.     s = dir+strlen(dir);
  237.  
  238.     while ((dn = searchNodeForDir(_rootNode, _xroot, dir)) == NULL) {
  239.         s = strrchr(dir, '/');
  240.         if (s != NULL)
  241.             *s = '\0';
  242.         else {
  243.             if (rest!=NULL)
  244.                 *rest = path;
  245.             return _rootNode;
  246.         }
  247.     }
  248.     if (rest!=NULL)
  249.         *rest = path + (s-dir);
  250.     return dn;
  251. }
  252.  
  253. /*************************************************************************/
  254.  
  255. DirNode *nextNodeCiclic(DirNode * rootNode, DirNode * curNode)
  256. {
  257.     if ((rootNode == NULL) || (curNode == NULL))
  258.         return rootNode;
  259.  
  260.     if (curNode->right != NULL)
  261.         return curNode->right;
  262.  
  263.     if (curNode->down != NULL)
  264.         return curNode->down;
  265.  
  266.     curNode = curNode->left;
  267.     while (curNode != NULL) {
  268.         if (curNode->down != NULL)
  269.             return curNode->down;
  270.         curNode = curNode->left;
  271.     }
  272.  
  273.     if (curNode == NULL)
  274.         return rootNode;
  275.     else
  276.         return curNode;
  277. }
  278.  
  279. /*************************************************************************/
  280.  
  281. int validSearchDir( char * fullDir, char * fullDirLink, char * searchDir )
  282. {
  283.     char *s;
  284.     int len;
  285.     char *min;
  286.     
  287.     if (fullDir==NULL)
  288.         return 0;
  289.         
  290.     if (searchDir[0]=='/') {
  291.         if (searchDir[1]=='\0')
  292.             return ((fullDir[0]=='/')&&(fullDir[1]=='\0'));
  293.         min = fullDir;
  294.     }
  295.     else {
  296.         stripSlash(fullDir);
  297.         min = strrchr(fullDir, '/');
  298.         if (min==NULL)
  299.             min = fullDir;
  300.         else
  301.             min++;
  302.     }
  303.     if (fullDirLink!=NULL) {
  304.         strcat(fullDir," -> ");
  305.         strcat(fullDir,fullDirLink);
  306.         strcat(fullDir,"/");
  307.     } 
  308.     else
  309.         addSlash(fullDir);
  310.     
  311.     len = strlen(searchDir);
  312.     if (len<strlen(min))
  313.         s = min;
  314.     else
  315.         s = fullDir+(strlen(fullDir)-len);
  316.     
  317.     while ((s>=fullDir)&&(s+len>min)) {
  318.         if ((strncmp(s,searchDir,len)==0)&&((s[0]=='/')||(s==fullDir)||(s[-1]=='/')))
  319.             return 1;
  320.         
  321.         s--;
  322.     }
  323.  
  324.     return 0;
  325. }
  326.  
  327. /*************************************************************************/
  328.  
  329. DirNode *findDirInCicle(DirNode * rootNode, DirNode * curNode, char *dir)
  330. {
  331.     DirNode *node;
  332.     char *s;
  333.     int valid;
  334.  
  335.     node = curNode;
  336.     do {
  337.         s = getNodeFullPath(node, (_showlink?0:-1), 1, NULL, 0);
  338.         valid = validSearchDir(s,node->lname, dir);
  339.  
  340.         if (!valid) 
  341.             node = nextNodeCiclic(rootNode, node);
  342.     } while ((!valid) && (node != curNode));
  343.  
  344.     if (valid)
  345.         return node;
  346.     else
  347.         return NULL;
  348. }
  349.  
  350. /*************************************************************************/
  351.  
  352. DirNode *findDirSegInCicle(DirNode * rootNode, DirNode * curNode, char *dir)
  353. {
  354.     DirNode *dn;
  355.     char s[PATH_MAX];
  356.  
  357.     strcpy(s, dir);
  358.     dn = NULL;
  359.  
  360.     if (dir[0] != '\0') {
  361.         addSlash(dir);
  362.         dn = findDirInCicle(rootNode, curNode, dir);
  363.         if (dn!=NULL)
  364.             return dn;
  365.     }
  366.  
  367.     strcpy(s,dir);
  368.  
  369.     while ((s[0] != '\0') && (dn == NULL)) {
  370.         dn = findDirInCicle(rootNode, curNode, s);
  371.         s[strlen(s) - 1] = '\0';
  372.     }
  373.  
  374.     return dn;
  375. }
  376.  
  377. /*************************************************************************/
  378.  
  379. DirNode *directSelectANode( void )
  380. {
  381.     DirNode * dn;
  382.  
  383.     _curNode = locatePathOrSo(_cwd, NULL);
  384.     dn = findDirSegInCicle(_rootNode, nextNodeCiclic(_rootNode,_curNode), _argumentDir);
  385.     return dn;
  386. }
  387.  
  388. /*************************************************************************/
  389.  
  390. void showTree(DirNode * rootNode)
  391. {
  392.     if (rootNode->right != NULL)
  393.         showTree(rootNode->right);
  394.     else {
  395.         fprintf(stdout, "%s\n", getTreeLine(rootNode, 0, 0));
  396.     }
  397.     if (rootNode->down != NULL)
  398.         showTree(rootNode->down);
  399. }
  400.  
  401. /*************************************************************************/
  402.