home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c065 / 1.ddi / CLIB1.ZIP / FNSPLIT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-07  |  6.2 KB  |  249 lines

  1. /*------------------------------------------------------------------------
  2.  * filename - fnsplit.c
  3.  *
  4.  * function(s)
  5.  *      CopyIt   - copies a string to another
  6.  *      DotFound - checks for special directory names
  7.  *      fnsplit  - splits a full path name into its components
  8.  *-----------------------------------------------------------------------*/
  9.  
  10. /*[]------------------------------------------------------------[]*/
  11. /*|                                                              |*/
  12. /*|     Turbo C Run Time Library - Version 3.0                   |*/
  13. /*|                                                              |*/
  14. /*|                                                              |*/
  15. /*|     Copyright (c) 1987,1988,1990 by Borland International    |*/
  16. /*|     All Rights Reserved.                                     |*/
  17. /*|                                                              |*/
  18. /*[]------------------------------------------------------------[]*/
  19.  
  20.  
  21. #include <dir.h>
  22. #include <string.h>
  23.  
  24. /*---------------------------------------------------------------------*
  25.  
  26. Name        CopyIt - copies a string to another
  27.  
  28. Usage        void pascal near CopyIt(char *dst, const char *src,
  29.                     unsigned maxlen)
  30.  
  31. Prototype in    local to this module
  32.  
  33. Description    copies string scr to string dst.
  34.  
  35. Return value    nothing
  36.  
  37. *---------------------------------------------------------------------*/
  38. static void pascal near CopyIt(char *dst, const char *src, unsigned maxlen)
  39. {
  40.     if (dst) {
  41.         if(strlen(src) >= maxlen)
  42.         {
  43.             strncpy(dst, src, maxlen);
  44.             dst[maxlen] = 0;
  45.         }
  46.         else
  47.             strcpy(dst, src);
  48.     }
  49. }
  50.  
  51. /*---------------------------------------------------------------------*
  52.  
  53. Name        DotFound - checks for special dir name cases
  54.  
  55. Usage        int pascal near DotFound(char *pB);
  56.  
  57. Prototype in    local to this module
  58.  
  59. Description    checks for special directory names
  60.  
  61. *---------------------------------------------------------------------*/
  62. static    int pascal near DotFound(char *pB)
  63. {
  64.     if (*(pB-1) == '.')
  65.         pB--;
  66.     switch (*--pB) {
  67.     case ':'  :
  68.         if (*(pB-2) != '\0')
  69.             break;
  70.     case '/'  :
  71.     case '\\' :
  72.     case '\0' :
  73.         return 1;
  74.     }
  75.     return 0;
  76. }
  77.  
  78. /*---------------------------------------------------------------------*
  79.  
  80. Name        fnsplit - splits a full path name into its components
  81.  
  82. Usage        #include <dir.h>
  83.         void fnsplit(const char *path, char * drive, char * dir,
  84.                  char * name, char * ext);
  85.  
  86. Related
  87. functions usage int fnmerge(char *path, const char *drive, const char *dir,
  88.                 const char *name, const char *ext);
  89.  
  90. Prototype in    dir.h
  91.  
  92. Description    fnmerge makes a file name from its components. The
  93.         new file's full path name is
  94.  
  95.             X:\DIR\SUBDIR\NAME.EXT
  96.  
  97.         where
  98.  
  99.             X is given by drive
  100.             \DIR\SUBDIR\ is given by dir
  101.             NAME.EXT is given by name and ext
  102.  
  103.         fnsplit takes a file's full path name (path) as a string
  104.         in the form
  105.  
  106.             X:\DIR\SUBDIR\NAME.EXT
  107.  
  108.         and splits path into its four components. It then stores
  109.         those components in the strings pointed to by drive, dir,
  110.         name and ext. (Each component is required but can be a
  111.         NULL, which means the corresponding component will be
  112.         parsed but not stored.)
  113.  
  114.         The maximum sizes for these strings are given by the
  115.         constants MAXDRIVE, MAXDIR, MAXPATH, MAXNAME and MAXEXT,
  116.         (defined in dir.h) and each size includes space for the
  117.         null-terminator.
  118.  
  119.             Constant    (Max.)    String
  120.  
  121.             MAXPATH     (80)    path
  122.             MAXDRIVE    (3)    drive; includes colon (:)
  123.             MAXDIR        (66)    dir; includes leading and
  124.                         trailing backslashes (\)
  125.             MAXFILE     (9)    name
  126.             MAXEXT        (5)    ext; includes leading dot (.)
  127.  
  128.         fnsplit assumes that there is enough space to store each
  129.         non-NULL component. fnmerge assumes that there is enough
  130.         space for the constructed path name. The maximum constructed
  131.         length is MAXPATH.
  132.  
  133.         When fnsplit splits path, it treats the punctuation as
  134.         follows:
  135.  
  136.         * drive keeps the colon attached (C:, A:, etc.)
  137.  
  138.         * dir keeps the leading and trailing backslashes
  139.           (\turboc\include\,\source\, etc.)
  140.  
  141.         * ext keeps the dot preceding the extension (.c, .exe, etc.)
  142.  
  143.         These two functions are invertible; if you split a given path
  144.         with fnsplit, then merge the resultant components with fnmerge,
  145.         you end up with path.
  146.  
  147. Return value    fnsplit returns an integer (composed of five flags,
  148.         defined in dir.h) indicating which of the full path name
  149.         components were present in path; these flags and the components
  150.         they represent are:
  151.  
  152.             EXTENSION    an extension
  153.             FILENAME    a filename
  154.             DIRECTORY    a directory (and possibly
  155.                     sub-directories)
  156.             DRIVE        a drive specification (see dir.h)
  157.             WILDCARDS    wildcards (* or ? cards)
  158.  
  159. *---------------------------------------------------------------------*/
  160. int _CType fnsplit(const char *pathP, char *driveP, char *dirP,
  161. char *nameP, char *extP)
  162. {
  163.     register char    *pB;
  164.     register int    Wrk;
  165.     int    Ret;
  166.  
  167.     char buf[ MAXPATH+2 ];
  168.  
  169.     /*
  170.       Set all string to default value zero
  171.     */
  172.     Ret = 0;
  173.     if (driveP)
  174.         *driveP = 0;
  175.     if (dirP)
  176.         *dirP = 0;
  177.     if (nameP)
  178.         *nameP = 0;
  179.     if (extP)
  180.         *extP = 0;
  181.  
  182.     /*
  183.       Copy filename into template up to MAXPATH characters
  184.     */
  185.     pB = buf;
  186.     while (*pathP == ' ')
  187.         pathP++;
  188.     if ((Wrk = strlen(pathP)) > MAXPATH)
  189.         Wrk = MAXPATH;
  190.     *pB++ = 0;
  191.     strncpy(pB, pathP, Wrk);
  192.     *(pB += Wrk) = 0;
  193.  
  194.     /*
  195.       Split the filename and fill corresponding nonzero pointers
  196.     */
  197.     Wrk = 0;
  198.     for (; ; ) {
  199.         switch (*--pB) {
  200.         case '.'  :
  201.             if (!Wrk && (*(pB+1) == '\0'))
  202.                 Wrk = DotFound(pB);
  203.             if ((!Wrk) && ((Ret & EXTENSION) == 0)) {
  204.                 Ret |= EXTENSION;
  205.                 CopyIt(extP, pB, MAXEXT - 1);
  206.                 *pB = 0;
  207.             }
  208.             continue;
  209.         case ':'  :
  210.             if (pB != &buf[2])
  211.                 continue;
  212.         case '\0' :
  213.             if (Wrk) {
  214.                 if (*++pB)
  215.                     Ret |= DIRECTORY;
  216.                 CopyIt(dirP, pB, MAXDIR - 1);
  217.                 *pB-- = 0;
  218.                 break;
  219.             }
  220.         case '/'  :
  221.         case '\\' :
  222.             if (!Wrk) {
  223.                 Wrk++;
  224.                 if (*++pB)
  225.                     Ret |= FILENAME;
  226.                 CopyIt(nameP, pB, MAXFILE - 1);
  227.                 *pB-- = 0;
  228.                 if (*pB == 0 || (*pB == ':' && pB == &buf[2]))
  229.                     break;
  230.             }
  231.             continue;
  232.         case '*'  :
  233.         case '?'  :
  234.             if (!Wrk)
  235.                 Ret |= WILDCARDS;
  236.         default :
  237.             continue;
  238.         }
  239.         break;
  240.     }
  241.     if (*pB == ':') {
  242.         if (buf[1])
  243.             Ret |= DRIVE;
  244.         CopyIt(driveP, &buf[1], MAXDRIVE - 1);
  245.     }
  246.  
  247.     return (Ret);
  248. }
  249.