Code

windows portability fixes by guenter knauf[M f3
[rrdtool-all.git] / program / src / plbasename.c
1 /*
2  * Cross-platform basename/dirname 
3  *
4  * Copyright 2005 Syd Logan, All Rights Reserved
5  *
6  * This code is distributed without warranty. You are free to use this
7  * code for any purpose, however, if this code is republished or
8  * redistributed in its original form, as hardcopy or electronically,
9  * then you must include this copyright notice along with the code.
10  *
11  * Minor changes 2008 by Stefan Ludewig stefan.ludewig@exitgames.com
12  * for WIN32 version RRDtool
13  */
14 #ifndef HAVE_LIBGEN_H
16 #include <memory.h>
17 #include <stdlib.h>
18 #include "plbasename.h"
19 #include <string.h>
20 #if defined(TEST)
21 #include <stdio.h>
22 #endif
24 #if defined(__cplusplus)
25 extern "C" {
26 #endif
28 const char *
29 PL_basename(const char *name)
30 {
31     const char *base;
32     char *p;
33     static char *tmp = NULL;
34     int len; 
36     if (tmp) {
37         free(tmp);
38         tmp = NULL;
39     }
41     if (!name || !strcmp(name, ""))
42         return "";
44     if (!strcmp(name, "/"))
45         return "/";
47     len = strlen(name);
48     if (name[len - 1] == '/') {
49         // ditch the trailing '/'
50         p = tmp = (char*)malloc(len);
51         strncpy(p, name, len - 1); 
52     } else {
53         p = (char *) name;
54     }
56     for (base = p; *p; p++) 
57         if (*p == '/') 
58             base = p + 1;
59     
60     return base;
61 }
63 const char *
64 PL_dirname(const char *name)
65 {
66     static char *ret = NULL;
67     int len;
68     int size = 0;
69     const char *p;
71     if (ret) {
72         free(ret);
73         ret = NULL;
74     }
76     if (!name || !strcmp(name, "") || !strstr(name, "/"))
77         return(".");
79     if (!strcmp(name, "/"))
80         return(name);
82     /* find the last slash in the string */
84     len = strlen(name);
85     p = &name[len - 1];
87     if (*p == '/') p--;  /* skip the trailing */
89     while (p != name && *p != '/') p--;
91     size = p - name;
92     if (size) {
93         ret = (char*)malloc(size + 1);
94         memcpy(ret, name, size);
95         ret[size] = '\0';
96     } else if (*p == '/')
97         return "/";
98     else
99         return "";
100     
101     return (const char *) ret;
104 #if defined(__cplusplus)
106 #endif 
108 #if defined(TEST)
110 int
111 main(int argc, char *argv[])
113 /*     run the following tests:
115        path           dirname        basename
116        "/usr/lib"     "/usr"         "lib"
117        "/usr/"        "/"            "usr"
118        "usr"          "."            "usr"
119        "/"            "/"            "/"
120        "."            "."            "."
121        ".."           "."            ".."
122        NULL           "."            ""
123        ""             "."            ""
124        "./.."         "."            ".."
126       These results can be verified by running the unix commands
127       basename(1) and dirname(1). One tweek to the test strategy
128       used here would be, on darwin and linux, to shell out to 
129       get the expected results vs hardcoding. 
130 */
131     if (!strcmp(PL_basename("/usr/lib"), "lib"))
132         printf("PL_basename /usr/lib passed\n");
133     else
134         printf("PL_basename /usr/lib failed expected lib\n");
135     if (!strcmp(PL_dirname("/usr/lib"), "/usr"))
136         printf("PL_dirname /usr/lib passed\n");
137     else
138         printf("PL_dirname /usr/lib failed expected /usr\n");
139     if (!strcmp(PL_basename("/usr/"), "usr"))
140         printf("PL_basename /usr/ passed\n");
141     else
142         printf("PL_basename /usr/ failed expected usr\n");
143     if (!strcmp(PL_dirname("/usr/"), "/"))
144         printf("PL_dirname /usr/ passed\n");
145     else
146         printf("PL_dirname /usr/ failed expected /\n");
147     if (!strcmp(PL_basename("usr"), "usr"))
148         printf("PL_basename usr passed\n");
149     else
150         printf("PL_basename usr failed expected usr\n");
151     if (!strcmp(PL_dirname("usr"), "."))
152         printf("PL_dirname usr passed\n");
153     else
154         printf("PL_dirname usr failed expected .\n");
155     if (!strcmp(PL_basename("/"), "/"))
156         printf("PL_basename / passed\n");
157     else
158         printf("PL_basename / failed expected /\n");
159     if (!strcmp(PL_dirname("/"), "/"))
160         printf("PL_dirname / passed\n");
161     else
162         printf("PL_dirname / failed expected /\n");
163     if (!strcmp(PL_basename("."), "."))
164         printf("PL_basename . passed\n");
165     else
166         printf("PL_basename . failed\n");
167     if (!strcmp(PL_dirname("."), "."))
168         printf("PL_dirname . passed\n");
169     else
170         printf("PL_dirname . failed expected .\n");
171     if (!strcmp(PL_basename(".."), ".."))
172         printf("PL_basename .. passed\n");
173     else
174         printf("PL_basename .. failed expected  ..\n");
175     if (!strcmp(PL_dirname(".."), "."))
176         printf("PL_dirname .. passed\n");
177     else
178         printf("PL_dirname .. failed expected .\n");
179     if (!strcmp(PL_basename(NULL), ""))
180         printf("PL_basename NULL passed\n");
181     else
182         printf("PL_basename NULL failed expected \"\"\n");
183     if (!strcmp(PL_dirname(NULL), "."))
184         printf("PL_dirname NULL passed\n");
185     else
186         printf("PL_dirname NULL failed expected .\n");
187     if (!strcmp(PL_basename(""), ""))
188         printf("PL_basename \"\" passed\n");
189     else
190         printf("PL_basename \"\" failed expected \"\"\n");
191     if (!strcmp(PL_dirname(""), "."))
192         printf("PL_dirname \"\" passed\n");
193     else
194         printf("PL_dirname \"\" failed expected .\n");
196     if (!strcmp(PL_basename("./.."), ".."))
197         printf("PL_basename ./.. passed\n");
198     else
199         printf("PL_basename ./.. failed expected ..\n");
200     if (!strcmp(PL_dirname("./.."), "."))
201         printf("PL_dirname ./.. passed\n");
202     else
203         printf("PL_dirname ./.. failed expected .\n");
205 #endif
207 #endif /* HAVE_LIBGEN_H */