Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: xz/src/xz/suffix.c

Issue 2869016: Add an unpatched version of xz, XZ Utils, to /trunk/deps/third_party (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/
Patch Set: Created 10 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « xz/src/xz/suffix.h ('k') | xz/src/xz/util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 /// \file suffix.c
4 /// \brief Checks filename suffix and creates the destination filename
5 //
6 // Author: Lasse Collin
7 //
8 // This file has been put into the public domain.
9 // You can do whatever you want with this file.
10 //
11 ///////////////////////////////////////////////////////////////////////////////
12
13 #include "private.h"
14
15 // For case-insensitive filename suffix on case-insensitive systems
16 #if defined(TUKLIB_DOSLIKE) || defined(__VMS)
17 # define strcmp strcasecmp
18 #endif
19
20
21 static char *custom_suffix = NULL;
22
23
24 struct suffix_pair {
25 const char *compressed;
26 const char *uncompressed;
27 };
28
29
30 /// \brief Checks if src_name has given compressed_suffix
31 ///
32 /// \param suffix Filename suffix to look for
33 /// \param src_name Input filename
34 /// \param src_len strlen(src_name)
35 ///
36 /// \return If src_name has the suffix, src_len - strlen(suffix) is
37 /// returned. It's always a positive integer. Otherwise zero
38 /// is returned.
39 static size_t
40 test_suffix(const char *suffix, const char *src_name, size_t src_len)
41 {
42 const size_t suffix_len = strlen(suffix);
43
44 // The filename must have at least one character in addition to
45 // the suffix. src_name may contain path to the filename, so we
46 // need to check for directory separator too.
47 if (src_len <= suffix_len || src_name[src_len - suffix_len - 1] == '/')
48 return 0;
49
50 if (strcmp(suffix, src_name + src_len - suffix_len) == 0)
51 return src_len - suffix_len;
52
53 return 0;
54 }
55
56
57 /// \brief Removes the filename suffix of the compressed file
58 ///
59 /// \return Name of the uncompressed file, or NULL if file has unknown
60 /// suffix.
61 static char *
62 uncompressed_name(const char *src_name, const size_t src_len)
63 {
64 static const struct suffix_pair suffixes[] = {
65 { ".xz", "" },
66 { ".txz", ".tar" }, // .txz abbreviation for .txt.gz is rare.
67 { ".lzma", "" },
68 { ".tlz", ".tar" },
69 // { ".gz", "" },
70 // { ".tgz", ".tar" },
71 };
72
73 const char *new_suffix = "";
74 size_t new_len = 0;
75
76 if (opt_format == FORMAT_RAW) {
77 // Don't check for known suffixes when --format=raw was used.
78 if (custom_suffix == NULL) {
79 message_error(_("%s: With --format=raw, "
80 "--suffix=.SUF is required unless "
81 "writing to stdout"), src_name);
82 return NULL;
83 }
84 } else {
85 for (size_t i = 0; i < ARRAY_SIZE(suffixes); ++i) {
86 new_len = test_suffix(suffixes[i].compressed,
87 src_name, src_len);
88 if (new_len != 0) {
89 new_suffix = suffixes[i].uncompressed;
90 break;
91 }
92 }
93 }
94
95 if (new_len == 0 && custom_suffix != NULL)
96 new_len = test_suffix(custom_suffix, src_name, src_len);
97
98 if (new_len == 0) {
99 message_warning(_("%s: Filename has an unknown suffix, "
100 "skipping"), src_name);
101 return NULL;
102 }
103
104 const size_t new_suffix_len = strlen(new_suffix);
105 char *dest_name = xmalloc(new_len + new_suffix_len + 1);
106
107 memcpy(dest_name, src_name, new_len);
108 memcpy(dest_name + new_len, new_suffix, new_suffix_len);
109 dest_name[new_len + new_suffix_len] = '\0';
110
111 return dest_name;
112 }
113
114
115 /// \brief Appends suffix to src_name
116 ///
117 /// In contrast to uncompressed_name(), we check only suffixes that are valid
118 /// for the specified file format.
119 static char *
120 compressed_name(const char *src_name, const size_t src_len)
121 {
122 // The order of these must match the order in args.h.
123 static const struct suffix_pair all_suffixes[][3] = {
124 {
125 { ".xz", "" },
126 { ".txz", ".tar" },
127 { NULL, NULL }
128 }, {
129 { ".lzma", "" },
130 { ".tlz", ".tar" },
131 { NULL, NULL }
132 /*
133 }, {
134 { ".gz", "" },
135 { ".tgz", ".tar" },
136 { NULL, NULL }
137 */
138 }, {
139 // --format=raw requires specifying the suffix
140 // manually or using stdout.
141 { NULL, NULL }
142 }
143 };
144
145 // args.c ensures this.
146 assert(opt_format != FORMAT_AUTO);
147
148 const size_t format = opt_format - 1;
149 const struct suffix_pair *const suffixes = all_suffixes[format];
150
151 for (size_t i = 0; suffixes[i].compressed != NULL; ++i) {
152 if (test_suffix(suffixes[i].compressed, src_name, src_len)
153 != 0) {
154 message_warning(_("%s: File already has `%s' "
155 "suffix, skipping"), src_name,
156 suffixes[i].compressed);
157 return NULL;
158 }
159 }
160
161 // TODO: Hmm, maybe it would be better to validate this in args.c,
162 // since the suffix handling when decoding is weird now.
163 if (opt_format == FORMAT_RAW && custom_suffix == NULL) {
164 message_error(_("%s: With --format=raw, "
165 "--suffix=.SUF is required unless "
166 "writing to stdout"), src_name);
167 return NULL;
168 }
169
170 const char *suffix = custom_suffix != NULL
171 ? custom_suffix : suffixes[0].compressed;
172 const size_t suffix_len = strlen(suffix);
173
174 char *dest_name = xmalloc(src_len + suffix_len + 1);
175
176 memcpy(dest_name, src_name, src_len);
177 memcpy(dest_name + src_len, suffix, suffix_len);
178 dest_name[src_len + suffix_len] = '\0';
179
180 return dest_name;
181 }
182
183
184 extern char *
185 suffix_get_dest_name(const char *src_name)
186 {
187 assert(src_name != NULL);
188
189 // Length of the name is needed in all cases to locate the end of
190 // the string to compare the suffix, so calculate the length here.
191 const size_t src_len = strlen(src_name);
192
193 return opt_mode == MODE_COMPRESS
194 ? compressed_name(src_name, src_len)
195 : uncompressed_name(src_name, src_len);
196 }
197
198
199 extern void
200 suffix_set(const char *suffix)
201 {
202 // Empty suffix and suffixes having a slash are rejected. Such
203 // suffixes would break things later.
204 if (suffix[0] == '\0' || strchr(suffix, '/') != NULL)
205 message_fatal(_("%s: Invalid filename suffix"), optarg);
206
207 // Replace the old custom_suffix (if any) with the new suffix.
208 free(custom_suffix);
209 custom_suffix = xstrdup(suffix);
210 return;
211 }
OLDNEW
« no previous file with comments | « xz/src/xz/suffix.h ('k') | xz/src/xz/util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698