home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / CLISP / CLISPSRC.TAR / clisp-1995-01-01 / src / acornaux.d < prev    next >
Encoding:
Text File  |  1994-12-20  |  4.3 KB  |  159 lines

  1. # Auxiliary functions for CLISP on Acorn RISC OS
  2. # Peter Burwood 20.12.1994
  3.  
  4. #include "lispbibl.c"
  5.  
  6. #ifdef RISCOS
  7.  
  8. # New versions of opendir(), readdir() and closedir() to replace those in
  9. # UnixLib. This is so that a wildcarded search name can be passed to readdir()
  10. # to allow the underlying RISC OS filing system to do wildcard and case
  11. # sensitivity processing of filenames.
  12. # Otherwise we would have the strange situation that in a directory
  13. # containing a file "abc", (OPEN "abc") and (OPEN "Abc") are equivalent,
  14. # however (DIRECTORY "A*") returns NIL - because RISC OS readdir() returns
  15. # "abc" and CLISP thinks it doesn't match - whereas (DIRECTORY "a*")
  16. # returns (#"abc").
  17.  
  18. # The implementation of opendir() and closedir() is exactly the same as the
  19. # UnixLib 3.6e, but to avoid future problems where opendir() could load some
  20. # filenames from the directory, they are reproduced here.
  21. # telldir() and seekdir() are not supported.
  22.  
  23. # While copying this small piece of code, I have fixed four (4) bugs in
  24. # this code. I dare not bet whether there are hundreds or thousands similar
  25. # bugs in the whole UnixLib. -- Bruno
  26.  
  27. #include <string.h>
  28. #include <stdlib.h>
  29.  
  30. #include <sys/unix.h>
  31. #include <sys/syslib.h>
  32. #include <sys/os.h>
  33. #include <sys/types.h>
  34. #include <dirent.h>
  35.  
  36. # Size of the buffers we employ. Should be >= MAXNAMLEN.
  37. #define DIRBUFSIZ 1024
  38.  
  39. typedef struct { DIR dir;
  40.                  char * wildcard; # search wildcards
  41.                  struct dirent entry; # used to return entries
  42.                                       # (could use a static buffer instead)
  43.                }
  44.         big_dir;
  45.  
  46. DIR * opendir (const char * name, const char * wildcard)
  47. {
  48.   { int r[10];
  49.     os_error * err;
  50.  
  51.     # ensure directory exists
  52.     err = os_file(0x05,(char*)name,r);
  53.     if (err) { __seterr(err); return NULL; }
  54.     # make sure it is a directory or image directory
  55.     if (!(r[0]==2 || r[0]==3)) { return NULL; }
  56.   }
  57.   { big_dir * bd;
  58.     DIR * d;
  59.  
  60.     bd = (big_dir *) malloc(sizeof(big_dir));
  61.     if (!bd) { return NULL; }
  62.     d = &bd->dir;
  63.     if (!(d->dd_buf = malloc(DIRBUFSIZ)))
  64.       { free(bd); return NULL; }
  65.     if (!(d->dd_name = strdup(name)))
  66.       { free(d->dd_buf); free(bd); return NULL; }
  67.     if (!(bd->wildcard = strdup(wildcard)))
  68.       { free(d->dd_name); free(d->dd_buf); free(bd); return NULL; }
  69.     d->dd_fd = 0;
  70.     d->dd_loc = 0;
  71.     d->dd_size = 0;
  72.     d->dd_bsize = DIRBUFSIZ;
  73.     d->dd_off = 0;
  74.     d->dd_off2 = 0;
  75.     return d;
  76. } }
  77.  
  78. struct dirent * readdir (DIR * d)
  79. {
  80.   big_dir * bd;
  81.  
  82.   if (!d) { return NULL; }
  83.  
  84.   bd = (big_dir *) ((char *) d - offsetof(big_dir,dir));
  85.   # Now d = &bd->dir.
  86.  
  87.   while (d->dd_loc >= d->dd_size)
  88.     {
  89.       int r[10];
  90.       os_error * err;
  91.       char * s;
  92.       int i;
  93.  
  94.       if (d->dd_off2 < 0) { return NULL; }
  95.  
  96.       r[0] = 9;
  97.       r[1] = (long) d->dd_name;
  98.       r[2] = (long) d->dd_buf;
  99.       r[3] = DIRBUFSIZ / MAXNAMLEN;
  100.       r[4] = d->dd_off2;
  101.       r[5] = DIRBUFSIZ;
  102.       r[6] = (long) bd->wildcard;
  103.       err = os_swi(0x0c,r);
  104.       if (err) { __seterr(err); return NULL; }
  105.  
  106.       # find the end of r[3] strings in the buffer:
  107.       s = (char *) d->dd_buf;
  108.       for (i = r[3]; i > 0; i--) # loop r[3] times
  109.         { while (*s) { s++; } # skip a string
  110.           s++;                # and its terminating '\0'
  111.         }
  112.       d->dd_loc = 0;
  113.       d->dd_size = s - d->dd_buf;
  114.       d->dd_off = d->dd_off2 * DIRBUFSIZ;
  115.       d->dd_off2 = r[4];
  116.       if (r[4] < 0 && r[3] == 0) { return NULL; } # end of directory reached
  117.     }
  118.   # Now 0 <= d->dd_loc < d->dd_size, return the name beginning at d->dd_loc.
  119.   {
  120.     char * s = d->dd_buf + d->dd_loc;
  121.     int i = strlen(s) + 1;
  122.     struct dirent * result = &bd->entry;
  123.  
  124.     result->d_off = d->dd_off;
  125.     d->dd_off += i; d->dd_loc += i;
  126.     result->d_fileno = 0;
  127.     if (i < MAXNAMLEN)
  128.       { memcpy(result->d_name,s,i);
  129.         result->d_namlen = i-1;
  130.       }
  131.     else
  132.       { memcpy(result->d_name,s,MAXNAMLEN-1);
  133.         result->d_name[MAXNAMLEN-1] = '\0';
  134.         result->d_namlen = MAXNAMLEN-1;
  135.       }
  136.     result->d_reclen = DIRSIZ(result);
  137.  
  138.     return result;
  139. } }
  140.  
  141. int closedir (DIR * d)
  142. {
  143.   big_dir * bd;
  144.  
  145.   if (!d) { return -1; }
  146.  
  147.   bd = (big_dir *) ((char *) d - offsetof(big_dir,dir));
  148.   # Now d = &bd->dir.
  149.  
  150.   free(bd->wildcard);
  151.   free(d->dd_name);
  152.   free(d->dd_buf);
  153.   free(bd);
  154.  
  155.   return 0;
  156. }
  157.  
  158. #endif # RISCOS
  159.