1 /* filename.c: Function manipulate file names
2 Was: find-suffix, extend-fname, make-suffix, remove-suffx
3 substring, concat3 */
4
5 /* remove-suffx.c: remove any suffix.
6
7 Copyright (C) 1999 Free Software Foundation, Inc.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif /* Def: HAVE_CONFIG_H */
26
27 #include "filename.h"
28 #include "xstd.h"
29 #include <string.h>
30
31 /* Return a fresh copy of SOURCE[START..LIMIT], or NULL if LIMIT<START.
32 If LIMIT>strlen(START), it is reassigned. */
33 static at_string substring (at_string source, const unsigned start, const unsigned limit);
34
35 /* Return a fresh copy of S1 followed by S2, et al. */
36 static at_string concat3 (at_string, at_string, at_string);
37
38 at_string
find_suffix(at_string name)39 find_suffix (at_string name)
40 {
41 at_string dot_pos = strrchr (name, '.');
42 #ifdef WIN32
43 at_string slash_pos = strrchr (name, '\\');
44 #else
45 at_string slash_pos = strrchr (name, '/');
46 #endif
47
48 /* If the name is `foo' or `/foo.bar/baz', we have no extension. */
49 return
50 dot_pos == NULL || dot_pos < slash_pos
51 ? NULL
52 : dot_pos + 1;
53 }
54
55 at_string
extend_filename(at_string name,at_string default_suffix)56 extend_filename (at_string name, at_string default_suffix)
57 {
58 at_string new_s;
59 at_string suffix = find_suffix (name);
60
61 new_s = suffix == NULL
62 ? concat3 (name, ".", default_suffix) : name;
63 return new_s;
64 }
65
66 at_string
make_suffix(at_string s,at_string new_suffix)67 make_suffix (at_string s, at_string new_suffix)
68 {
69 at_string new_s;
70 at_string old_suffix = find_suffix (s);
71
72 if (old_suffix == NULL)
73 new_s = concat3 (s, ".", new_suffix);
74 else
75 {
76 size_t length_through_dot = old_suffix - s;
77
78 XMALLOC (new_s, length_through_dot + strlen (new_suffix) + 1);
79 strncpy (new_s, s, length_through_dot);
80 strcpy (new_s + length_through_dot, new_suffix);
81 }
82
83 return new_s;
84 }
85
86 at_string
remove_suffix(at_string s)87 remove_suffix (at_string s)
88 {
89 at_string suffix = find_suffix (s);
90
91 return suffix == NULL ? s : suffix - 2 - s < 0 ? NULL : substring (s, 0, (unsigned)(suffix - 2 - s));
92 }
93
94 /* From substring.c */
95 static at_string
substring(at_string source,const unsigned start,const unsigned limit)96 substring (at_string source, const unsigned start, const unsigned limit)
97 {
98 at_string result;
99 unsigned this_char;
100 size_t length = strlen (source);
101 size_t lim = limit;
102
103 /* Upper bound out of range? */
104 if (lim >= length)
105 lim = length - 1;
106
107 /* Null substring? */
108 if (start > lim)
109 return "";
110
111 /* The `2' here is one for the null and one for limit - start inclusive. */
112 XMALLOC (result, lim - start + 2);
113
114 for (this_char = start; this_char <= lim; this_char++)
115 result[this_char - start] = source[this_char];
116
117 result[this_char - start] = 0;
118
119 return result;
120 }
121
122 static at_string
concat3(at_string s1,at_string s2,at_string s3)123 concat3 (at_string s1, at_string s2, at_string s3)
124 {
125 at_string answer;
126 XMALLOC (answer, strlen (s1) + strlen (s2) + strlen (s3) + 1);
127 strcpy (answer, s1);
128 strcat (answer, s2);
129 strcat (answer, s3);
130
131 return answer;
132 }
133