summaryrefslogtreecommitdiff
path: root/reference/C/CONTRIB/SNIP/psplit.c
blob: a1837b32626e31c1eace7c46c0afd4e99813a966 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*
**  psplit() - Portable replacement for fnsplit(), _splitpath(), etc.
**
**  Splits a full DOS pathname into drive, path, file, and extension
**  specifications. Works with forward or back slash path separators and
**  network file names, e.g. NET:LOONEY/BIN\WUMPUS.COM, Z:\MYDIR.NEW/NAME.EXT
**
**  Arguments: 1 - Full pathname to split
**             2 - Buffer for drive
**             3 - Buffer for path
**             4 - Buffer for name
**             5 - Buffer for extension
**
**  Returns: Nothing
**
**  public domain by Bob Stout
*/

#include <stdlib.h>
#include <string.h>

#define NUL '\0'

void psplit(char *path, char *drv, char *dir, char *fname, char *ext)
{
      char ch, *ptr, *p;

      /* convert slashes to backslashes for searching       */

      for (ptr = path; *ptr; ++ptr)
      {
            if ('/' == *ptr)
                  *ptr = '\\';
      }

      /* look for drive spec                                */

      if (NULL != (ptr = strchr(path, ':')))
      {
            ++ptr;
            if (drv)
            {
                  strncpy(drv, path, ptr - path);
                  drv[ptr - path] = NUL;
            }
            path = ptr;
      }
      else if (drv)
            *drv = NUL;
      
      /* find rightmost backslash or leftmost colon         */

      if (NULL == (ptr = strrchr(path, '\\')))
            ptr = (strchr(path, ':'));

      if (!ptr)
      {
            ptr = path;             /* obviously, no path   */
            if (dir)
                  *dir = NUL;
      }
      else
      {
            ++ptr;                  /* skip the delimiter   */
            if (dir)
            {
                  ch = *ptr;
                  *ptr = NUL;
                  strcpy(dir, path);
                  *ptr = ch;
            }
      }

      if (NULL == (p = strrchr(ptr, '.')))
      {
            if (fname)
                  strcpy(fname, ptr);
            if (ext)
                  *ext = NUL;
      }
      else
      {
            *p = NUL;
            if (fname)
                  strcpy(fname, ptr);
            *p = '.';
            if (ext)
                  strcpy(ext, p);
      }
}

#ifdef TEST

#include <stdio.h>

int main(int argc, char *argv[])
{
      char drive[10], pathname[FILENAME_MAX], fname[9], ext[5];

      while (--argc)
      {
            psplit(*++argv, drive, pathname, fname, ext);
            printf("psplit(%s) returns:\n drive = %s\n path  = %s\n"
                  " name  = %s\n ext   = %s\n",
                  *argv, drive, pathname, fname, ext);
      }
      return EXIT_SUCCESS;
}

#endif