home *** CD-ROM | disk | FTP | other *** search
/ ftp.eri.u-tokyo.ac.jp / 2014.03.ftp.eri.u-tokyo.ac.jp.zip / ftp.eri.u-tokyo.ac.jp / pub / DOS / tools / kmtar.lzh / GETDIR.C < prev    next >
C/C++ Source or Header  |  1991-02-17  |  3KB  |  160 lines

  1. /*
  2.  * get_dir() - get list of directory
  3.  */
  4.  
  5. static char rcsid[] = "$Header: RCS/getdir.c 2.3 91/02/17 18:02:08 kmori Exp $";
  6.  
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #include <dos.h>
  12.  
  13. #include "defs.h"
  14. #include "misc.h"
  15. #include "getdir.h"
  16.  
  17. #ifndef global
  18.  
  19. typedef struct flist {
  20.     struct flist *next;
  21.     char name[0];
  22. } FLIST;
  23.  
  24. #endif /* global */
  25.  
  26.  
  27. /*
  28.  * list merge sorting
  29.  *    Donald E Knuth, "The Art of Computer Programming",
  30.  *    Vol.3 / Sorting & Searching, pp. 165-166, Algorithm L.
  31.  */
  32. FLIST *sort(FLIST *p)
  33. {
  34.     FLIST xh, yh, *xp, *yp, *x, *y;
  35.     unsigned int n, xn, yn;
  36.  
  37.     /* L1. Separate list p into 2 lists. */
  38.     xp = &xh;
  39.     yp = &yh;
  40.     while (p != NULL) {
  41.         xp->next = p;
  42.         xp = p;
  43.         p = p->next;
  44.         if (p == NULL)
  45.             break;
  46.         yp->next = p;
  47.         yp = p;
  48.         p = p->next;
  49.     }
  50.     xp->next = NULL;
  51.     yp->next = NULL;
  52.     for (n = 1; yh.next != NULL; n *= 2) {
  53.         /* L2. Begin new pass. */
  54.         xp = &xh;
  55.         yp = &yh;
  56.         x = xp->next;
  57.         y = yp->next;
  58.         xn = yn = n;
  59.         do {
  60.             /* L3. Compare */
  61.             if (strcmp(x->name, y->name) <= 0) {
  62.                 /* L4. Advance x. */
  63.                 xp->next = x;
  64.                 xp = x;
  65.                 x = x->next;
  66.                 if (--xn != 0 && x != NULL)
  67.                     continue;
  68.                 /* L5. Complete the sublist. */
  69.                 xp->next = y;
  70.                 xp = yp;
  71.                 do {
  72.                     yp = y;
  73.                     y = y->next;
  74.                 } while (--yn != 0 && y != NULL);
  75.             } else {
  76.                 /* L6. Advance y. */
  77.                 xp->next = y;
  78.                 xp = y;
  79.                 y = y->next;
  80.                 if (--yn != 0 && y != NULL)
  81.                     continue;
  82.                 /* L7. Complete the sublist. */
  83.                 xp->next = x;
  84.                 xp = yp;
  85.                 do {
  86.                     yp = x;
  87.                     x = x->next;
  88.                 } while (--xn != 0 && x != NULL);
  89.             }
  90.             xn = yn = n;
  91.             /* L8. End of pass? */
  92.         } while (y != NULL);
  93.         xp->next = x;
  94.         yp->next = NULL;
  95.     }
  96.     return (xh.next);
  97. }
  98.  
  99.  
  100.  
  101. /*
  102.  * Returns list of the directory 'dir'
  103.  */
  104. global FLIST *get_dir(char *dir)
  105. {
  106.     struct find_t buf;
  107.     char fn[100];
  108.     int rc;
  109.     FLIST *dp, *fp, *w;
  110.     char *s;
  111.  
  112.     strcat(addsl(strcpy(fn, dir)), "*.*");
  113.     dp = fp = NULL;
  114.     rc = _dos_findfirst(fn,
  115.         _A_NORMAL | _A_RDONLY | _A_HIDDEN | _A_SUBDIR | _A_ARCH,
  116.         &buf);
  117.     for (; rc == 0; rc = _dos_findnext(&buf)) {
  118.         w = (FLIST *)malloc(sizeof(FLIST) + strlen(buf.name) + 1);
  119.         if (w == NULL)
  120.             fatal(NULL, "Out of memory");
  121.         for (s = buf.name; *s; s++) {
  122.             if (isupper(*s))
  123.                 *s = tolower(*s);
  124.         }
  125.         strcpy(w->name, buf.name);
  126.         if (buf.attrib & _A_SUBDIR) {
  127.             w->next = dp;
  128.             dp = w;
  129.         } else {
  130.             w->next = fp;
  131.             fp = w;
  132.         }
  133.     }
  134.     dp = sort(dp);
  135.     fp = sort(fp);
  136.     if (fp == NULL)
  137.         fp = dp;
  138.     else {
  139.         for (w = fp; w->next; w = w->next)
  140.             ;
  141.         w->next = dp;
  142.     }
  143.     return (fp);
  144. }
  145.  
  146.  
  147. /*
  148.  * Free directory list p
  149.  */
  150. global void free_dir(FLIST *p)
  151. {
  152.     FLIST *q;
  153.  
  154.     while (p) {
  155.         q = p->next;
  156.         free(p);
  157.         p = q;
  158.     }
  159. }
  160.