home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / mtools_3.6.src.lzh / MTOOLS_3.6 / parse.c < prev    next >
C/C++ Source or Header  |  1997-11-12  |  3KB  |  190 lines

  1. #include "sysincludes.h"
  2. #include "msdos.h"
  3. #include "vfat.h"
  4.  
  5. /*
  6.  * Get name component of filename.
  7.  *
  8.  * Formerly translated name to upper case; now preserves case.
  9.  * This is because long DOS names are case sensitive, but also because we
  10.  * want to preserve the user-specified case for the copied Unix files
  11.  */
  12.  
  13. char *get_name(const char *filename, char *ans, char *mcwd)
  14. {
  15.     char *s;
  16.     const char *temp;
  17.  
  18.     temp = filename;
  19.                     /* skip drive letter */
  20.     if (temp[0] && temp[1] == ':')
  21.         temp = &temp[2];
  22.                     /* find the last separator */
  23.     if ((s = strrchr(temp, '/')))
  24.         temp = s + 1;
  25.     if ((s = strrchr(temp, '\\')))
  26.         temp = s + 1;
  27.  
  28.     strncpy(ans, temp, VBUFSIZE-1);
  29.     ans[VBUFSIZE-1]='\0';
  30.  
  31.     return ans;
  32. }
  33.  
  34. static inline void strip_last_dir(char *begin, char **targetp)
  35. {
  36.     char *tmp;
  37.  
  38.     /* IN condition: begin stops with a slash */
  39.  
  40.     /* remove slash */
  41.     (*targetp) --;
  42.     **targetp = '\0';
  43.  
  44.     tmp = strrchr(begin,'/');
  45.     if(tmp) {
  46.         tmp++;
  47.     } else {
  48.         begin[0]='/';
  49.         tmp=begin+1;
  50.     }
  51.     *tmp = '\0';
  52.     *targetp = tmp;
  53. }
  54.  
  55. static inline int handle_dot(char *begin, char **sourcep, char **targetp)
  56. {
  57.     char *source = *sourcep;
  58.  
  59.     switch(source[1]) {
  60.         case '/':
  61.             (*sourcep) += 2;
  62.             return 1;
  63.         case '.':
  64.             switch(source[2]) {
  65.                 case '\0':
  66.                     strip_last_dir(begin, targetp);
  67.                     (*sourcep) += 2;
  68.                     return 1;
  69.                 case '/':
  70.                     strip_last_dir(begin, targetp);
  71.                     (*sourcep) += 3;
  72.                     return 1;
  73.                 default:
  74.                     return 0;
  75.             }
  76.         case '\0':
  77.             (*sourcep) ++;
  78.             return 1;
  79.         default:
  80.             return 0;
  81.     }
  82. }
  83.  
  84.  
  85. static inline void canonize_path(char *begin)
  86. {
  87.     char tmp, *source, *target;
  88.  
  89.     /* transform all backslashes into slashes */
  90.     for(source = begin; *source; source++)
  91.         if(*source == '\\')
  92.             *source ='/';
  93.  
  94.     /* prune off double slashes */
  95.     source = begin;
  96.     target = begin;
  97.     while(*source) {
  98.         tmp = *target++ = *source++;
  99.         if(tmp == '/') {
  100.             while(1) {                
  101.                 switch(source[0]) {
  102.                     case '/':
  103.                         source++;
  104.                         continue;
  105.                     case '.':
  106.                         if(handle_dot(begin, &source,
  107.                                   &target))
  108.                             continue;
  109.                         break;
  110.                 }
  111.                 break;
  112.             }
  113.             if(!*source)
  114.                 target--;
  115.         }
  116.     }
  117.  
  118.     *target='\0';
  119.     if(!*begin) {
  120.         begin[0] = '/';
  121.         begin[1] = '\0';
  122.     }
  123. }
  124.  
  125. /*
  126.  * Get the path component of the filename.
  127.  * Doesn't alter leading separator, always strips trailing separator (unless
  128.  * it is the path itself).
  129.  *
  130.  * Formerly translated name to upper case; now preserves case.
  131.  * This is because long DOS names are case sensitive, but also because we
  132.  * want to preserve the user-specified case for the copied Unix files
  133.  */
  134.  
  135. char *get_path(const char *filename, char *ans, char *mcwd, int mode)
  136. {
  137.     char *s;
  138.     const char *end;
  139.     const char *begin;
  140.     char drive;
  141.  
  142.     begin = filename;
  143.  
  144.     /* skip drive letter */
  145.     drive = '\0';
  146.     if (begin[0] && begin[1] == ':') {
  147.         drive = toupper(begin[0]);
  148.         begin += 2;
  149.     }
  150.  
  151.     ans[0] = '/';
  152.     ans[1] = '\0';
  153.     if ((*begin != '/') && (!drive || drive == *mcwd))
  154.         strcpy(ans+1, mcwd + 2);
  155.  
  156.     strcat(ans, "/");
  157.  
  158.     /* cut last separator (if needed) */
  159.     if(mode) 
  160.         end = begin + strlen(begin);
  161.     else {
  162.         if ((s = strrchr(begin, '/')))
  163.             end = s;
  164.         else
  165.             end = begin;
  166.     }
  167.  
  168.     if(strlen(ans)+end-begin+1 > MAX_PATH){
  169.         fprintf(stderr,"Path too long\n");
  170.         exit(1);
  171.     }
  172.  
  173.     strncat(ans, begin, end - begin);
  174.     ans[strlen(ans)+end-begin] = '\0';
  175.     canonize_path(ans);
  176.     return ans;
  177. }
  178.  
  179. /*
  180.  * get the drive letter designation
  181.  */
  182.  
  183. char get_drive(const char *filename, char def)
  184. {
  185.     if (*filename && *(filename + 1) == ':')
  186.         return(toupper(*filename));
  187.     else
  188.         return def;
  189. }
  190.