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