1 /*
2  * filename.c - Operate filename.
3  *
4  * Last change: 20-Sep-2009.
5  * Written by:  Muraoka Taro  <koron@tka.att.ne.jp>
6  */
7 module migemo_d.filename;
8 
9 
10 private static import core.stdc.string;
11 
12 pure nothrow @trusted @nogc
13 private int my_strlen(const (char)* s)
14 
15 	in
16 	{
17 		assert(s != null);
18 	}
19 
20 	do
21 	{
22 		size_t len = core.stdc..string.strlen(s);
23 
24 		return (len <= int.max) ? (cast(int)(len)) : (int.max);
25 	}
26 
27 /**
28  * Cut out base string of filename from filepath.  If base is null, then
29  * return length that require for store base name.
30  */
31 extern (C)
32 pure nothrow @nogc
33 public int filename_base(char* base, const (char)* path)
34 
35 	in
36 	{
37 		assert(path != null);
38 	}
39 
40 	do
41 	{
42 		int len = .my_strlen(path) - 1;
43 		int i;
44 
45 		for (i = len; i >= 0; --i) {
46 			if (path[i] == '.') {
47 				break;
48 			}
49 		}
50 
51 		int end;
52 
53 		if (i <= 0) {
54 			end = len;
55 		} else {
56 			end = i - 1;
57 		}
58 
59 		for (i = end; i >= 0; --i) {
60 			if ((path[i] == '\\') || (path[i] == '/')) {
61 				++i;
62 
63 				break;
64 			}
65 		}
66 
67 		if (i < 0) {
68 			++i;
69 		}
70 
71 		len = end - i + 1;
72 
73 		if (base != null) {
74 			core.stdc..string.strncpy(base, path + i, len);
75 			base[len] = '\0';
76 		}
77 
78 		return len;
79 	}
80 
81 /**
82  * Cut out directroy string from filepath.  If dir is null, then return
83  * length that require for store directory.
84  */
85 extern (C)
86 pure nothrow @nogc
87 public int filename_directory(char* dir, const (char)* path)
88 
89 	in
90 	{
91 		assert(path != null);
92 	}
93 
94 	do
95 	{
96 		int i;
97 
98 		for (i = .my_strlen(path) - 1; i >= 0; --i) {
99 			if ((path[i] == '\\') || (path[i] == '/')) {
100 				break;
101 			}
102 		}
103 
104 		if (i <= 0) {
105 			if (dir != null) {
106 				dir[0] = '\0';
107 			}
108 
109 			return 0;
110 		}
111 
112 		if (dir != null) {
113 			core.stdc..string.strncpy(dir, path, i + 1);
114 			dir[i] = '\0';
115 		}
116 
117 		return i;
118 	}
119 
120 /**
121  * Cut out extension of filename or filepath. If ext is null, then return
122  * length that require for store extension.
123  */
124 extern (C)
125 pure nothrow @nogc
126 public int filename_extension(char* ext, const (char)* path)
127 
128 	in
129 	{
130 		assert(path != null);
131 	}
132 
133 	do
134 	{
135 		int len = .my_strlen(path);
136 		int i;
137 
138 		for (i = len - 1; i >= 0; --i) {
139 			if (path[i] == '.') {
140 				break;
141 			}
142 		}
143 
144 		if ((i < 0) || (i == (len - 1))) {
145 			assert(ext != null);
146 			ext[0] = '\0';
147 
148 			return 0;
149 		}
150 
151 		len -= ++i;
152 
153 		if (ext != null) {
154 			core.stdc..string.strcpy(ext, path + i);
155 		}
156 
157 		return len;
158 	}
159 
160 /**
161  * Cut out filename string from filepath.  If name is null, then return
162  * length that require for store directory.
163  */
164 extern (C)
165 pure nothrow @nogc
166 public int filename_filename(char* name, const (char)* path)
167 
168 	in
169 	{
170 		assert(path != null);
171 	}
172 
173 	do
174 	{
175 		int len = .my_strlen(path);
176 		int i;
177 
178 		for (i = len - 1; i >= 0; --i) {
179 			if ((path[i] == '\\') || (path[i] == '/')) {
180 				break;
181 			}
182 		}
183 
184 		++i;
185 		len -= i;
186 
187 		if (name != null) {
188 			core.stdc..string.strncpy(name, path + i, len);
189 			name[len] = '\0';
190 		}
191 
192 		return len;
193 	}
194 
195 /**
196  * Generate file full path name.
197  */
198 extern (C)
199 pure nothrow @nogc
200 public int filename_generate(char* filepath, const (char)* dir, const (char)* base, const (char)* ext)
201 
202 	in
203 	{
204 	}
205 
206 	do
207 	{
208 		if (filepath != null) {
209 			filepath[0] = '\0';
210 		}
211 
212 		int len = 0;
213 
214 		if (dir != null) {
215 			if (filepath != null) {
216 				core.stdc..string.strcat(filepath, dir);
217 				core.stdc..string.strcat(filepath, "/");
218 			}
219 
220 			len += .my_strlen(dir) + 1;
221 		}
222 
223 		if (base != null) {
224 			if (filepath != null) {
225 				core.stdc..string.strcat(filepath, base);
226 			}
227 
228 			len += .my_strlen(base);
229 		}
230 
231 		if (ext != null) {
232 			if (filepath != null) {
233 				core.stdc..string.strcat(filepath, ".");
234 				core.stdc..string.strcat(filepath, ext);
235 			}
236 
237 			len += 1 + .my_strlen(ext);
238 		}
239 
240 		return len;
241 	}