home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 2 / RISC_DISC_2.iso / pd_share / program / language / as / source / c / uname < prev    next >
Encoding:
Text File  |  1994-09-27  |  5.2 KB  |  185 lines

  1.  
  2. /* uname.c (c) Copyright 1992 Niklas Röjemo */
  3.  
  4. #include <ctype.h>
  5. #include <string.h>
  6. #include <stdlib.h>
  7.  
  8. #include "kernel.h"
  9.  
  10.  
  11. #define EXTRA(x) ((x)<<1)  /* Reserve double space */
  12.  
  13. char *special1(char const *dotpos, char const *end)
  14. {
  15.   int s = end - dotpos;
  16.   if(s == 1)
  17.     switch(*dotpos) {
  18.       case 'c': return "c";
  19.       case 'h': return "h";
  20.       case 'p': return "p";
  21.       case 'o': return "o";
  22.       case 's': return "s";
  23.       case 'm': return "m";
  24.       case 't': return "t";
  25.       case 'M': return "mc";
  26.     }
  27.   else {
  28.     if(!strncmp(dotpos,"mc",s)) return "mc";
  29.   }
  30.   return 0;
  31. }
  32.  
  33. char *special2(char const *dotpos, char const *end)
  34. {
  35.   int s = end - dotpos;
  36.   if(s == 1)
  37.     switch(*dotpos) {
  38.       case 'l': return "l";
  39.       case 'y': return "y";
  40.     }
  41.   else {
  42.     if(!strncmp(dotpos,"tt",s)) return "tt";
  43.   }
  44.   return 0;
  45. }
  46.  
  47.  
  48. static int  sizeName;   /* Length of buffer */
  49. static char *newName;   /* Name buffer */
  50.  
  51. char *uname(const char *name, int PrefixDir)
  52. {
  53.   char const *src;
  54.   char *dst;
  55.   char const *dotpos,*end,*pre;
  56.   int  c;
  57.  
  58.   if (!name) return("");                        /* What no filename ! */
  59.  
  60.   if (EXTRA(c = strlen(name)) > sizeName) {     /* Reserve space */
  61.     if(sizeName)
  62.       free(newName);
  63.       sizeName = c+100;            /* Add 100 increases chance we don't need to allocate again */
  64.     if((newName = malloc(sizeName))==0) {
  65.       sizeName = 0;
  66.       return 0;
  67.     }
  68.   }
  69.  
  70.   src = name;
  71.   dst = newName;
  72.  
  73.   if ((c=*src)==0) {        /* name == "" */
  74.     *dst++ = 0;
  75.     return newName;
  76.   }
  77.  
  78.   if(  c == '<'  || c ==':'               /* No sane unixfiles start with < or : */
  79.     || (src[1] == '.' &&                  /* $. @. %. ^. &. is not a unixfile    */
  80.        (c == '$' || c == '@' || c == '%' || c == '^' || c == '&')) ) {
  81.     if(PrefixDir && c == '@' && getenv("Prefix$Dir")) {
  82.       strcpy(newName,"<Prefix$Dir>");
  83.       strcat(newName,name+1);
  84.     } else
  85.       strcpy(newName,name);
  86.     return newName;
  87.   }
  88.  
  89.   if (c == '/') {                   /* Probably a unixfile */
  90.     if (strncmp (src, "/tmp/", 5) == 0) {   /* if file is going into /tmp, check for */
  91.       char *tmpdir = getenv("UnixFS$/tmp"); /* UnixFS$/tmp, else put in <wimp$Scrapdir> */
  92.       if (!tmpdir || *tmpdir == 0)
  93.     tmpdir = "<Wimp$ScrapDir>";
  94.       strcpy (dst, tmpdir);
  95.       dst += strlen (tmpdir);
  96.       src += 4;
  97.     } else
  98.       *dst++ = '$';             /* change / to $. The dot is set in the while loop below */
  99.   } else {
  100.     if(PrefixDir && getenv("Prefix$Dir")) {
  101.       strcpy(newName,"<Prefix$Dir>");
  102.       dst += strlen("<Prefix$Dir>");
  103.     } else
  104.       *dst++ = '@';                        /* insert current dir */
  105.   }
  106.  
  107.   while (*src) {
  108.     while (*src == '/')               /* change multiple / to . */
  109.       src++;
  110.     *dst++ = '.';
  111.  
  112.     if (src[0] == '.' && src[1] == '.' && (src[2] == '/' || !src[2])) {
  113.       *dst++ = '^';                      /* change .. to ^ */
  114.       src += 2;
  115.       continue;
  116.     }
  117.     if (src[0] == '.' && (src[1] == '/' || !src[1])) {
  118.       dst--;                             /* remove the previous . in newName */
  119.       src++;                             /* and skip . in name */
  120.       continue;
  121.     }
  122.  
  123.     end = dotpos = src;                 /* locate end of this filename */
  124.     while ((c = *end)!=0 && c != '/') {    /* and the position of the last dot in the name */
  125.       if (c == '.')
  126.         dotpos = end;
  127.       end++;
  128.     }
  129.     if((pre = special2(src,end))!=0) {          /* This is a /-prefix  ! */
  130.       if(dst>newName)
  131.         dst[-1] = '/';
  132.       while((*dst++=*pre++)!=0)
  133.         ;
  134.       dst--;
  135.       src = end;
  136.     } else {
  137.       if (dotpos++ > src && dotpos < end) { /* We have a base.suffix */
  138.         if((pre = special1(dotpos,end))!=0) {
  139.           while((*dst++ = *pre++)!=0)        /* This is a special suffix */
  140.             ;                                /* now prefix */
  141.           dst[-1] = '.';
  142.           dotpos --;                         /* point to dot */
  143.           while(src<dotpos)                  /* Change all other dots into _ */
  144.             if((*dst++ = *src++) == '.')     /* when copying */
  145.               dst[-1] = '_';
  146.           src = end;
  147.         } else {                             /* is it a /prefix? */
  148.           if((pre = special1(src,--dotpos))!=0) { /* But the prefix is special ! */
  149.             while(src<end)                       /* Copy as is  */
  150.               *dst++ = *src++;
  151.           } else {
  152.             while(src<dotpos)                  /* Change all dots except the last into _ */
  153.               if((*dst++ = *src++) == '.')
  154.                 dst[-1] = '_';
  155.             *dst++ = '/';
  156.              src++;
  157.             while(src<end)                     /* And now the suffix */
  158.               *dst++ = *src++;
  159.           }
  160.         }
  161.       } else {       /* No dot or .base or base. */
  162.           while(src<end)                     /* Change all dots into _ */
  163.             if((*dst++ = *src++) == '.')
  164.               dst[-1] = '_';
  165.       }
  166.     }
  167.   }
  168.   *dst = 0;
  169.  
  170.  
  171.   /* a quick and dirty way to ensure the directory exists */
  172.   while (dst>newName && *dst != '.')
  173.     dst--;
  174.   if(*dst == '.') {
  175.     _kernel_osfile_block block;
  176.     *dst = '\0';
  177.     block.start = 0;
  178.     (void)_kernel_osfile(8,newName, &block);
  179.     *dst = '.';
  180.   }
  181.  
  182.  
  183.   return newName;
  184. }
  185.