This repository has been archived by the owner on Sep 23, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathoptions.cpp
233 lines (219 loc) · 7.97 KB
/
options.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
/* oggted: options.cpp
* Copyright (c) 2011 Bert Muennich <be.muennich at googlemail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <iostream>
#include <cstring>
#include <cstdlib>
#include "options.h"
bool Options::parseCommandLine(int argc, char **argv) {
int opt, nlen, vlen;
String t;
GenericInfo ginfo;
FieldInfo finfo;
char *sep;
bool error = false;
while (!error) {
opt = getopt_long(argc, argv, options, longOptions, NULL);
if (opt == -1)
break;
switch (opt) {
/* invalid option given */
case '?':
error = true;
break;
/* help, general info & others */
case 'h':
printUsage();
exit(0);
case 'v':
printVersion();
exit(0);
case 'p':
preserveTimes = true;
break;
/* generic tag infomation */
case 'a':
case 'A':
case 't':
case 'c':
case 'g':
case 'T':
case 'y': {
ginfo.id = opt;
ginfo.value = String(optarg, DEF_TSTR_ENC);
generics.push_back(ginfo);
write = true;
break;
}
/* modification of fields */
case 'F':
case 'f':
if (!(sep = strchr(optarg, '=')) || !(vlen = strlen(sep + 1))) {
cerr << command << ": invalid argument for option -" << opt << ": "
<< optarg << endl;
exit(1);
}
nlen = sep - optarg;
t = String(optarg, DEF_TSTR_ENC);
finfo.name = t.substr(0, nlen);
finfo.value = t.substr(nlen + 1, vlen);
finfo.replace = opt == 'F';
fields.push_back(finfo);
write = true;
break;
/* information from the files */
case 'i':
info = true;
break;
case 'l':
list = true;
break;
/* tag removal & version to write */
case 'r':
removals.push_back(optarg);
write = true;
break;
case 'D':
strip = true;
write = true;
break;
/* filename <-> tag information */
case 'N':
case 'n':
fromFilename = inPattern.setPattern(optarg, opt == 'N');
write = true;
break;
case 'o':
organize = outPattern.setPattern(optarg);
break;
case OPT_LO_FORCE:
force = true;
break;
case OPT_LO_ORG_MOVE:
move = true;
break;
}
}
fileCount = argc - optind;
filenames = argv + optind;
if (!error) {
// check for missing mandatory arguments
if (optind == 1) {
cerr << command << ": missing arguments" << endl;
error = true;
} else if (fileCount == 0) {
cerr << command << ": missing <FILES>" << endl;
error = true;
}
}
return error;
}
void Options::printVersion() {
cout << PROGNAME << " " << VERSION " - command line ogg vorbis tag editor\n"
<< "Uses TagLib v" << TAGLIB_MAJOR_VERSION << "."
<< TAGLIB_MINOR_VERSION << "." << TAGLIB_PATCH_VERSION
<< ", written by Scott Wheeler" << endl;
}
void Options::printUsage() {
cout << "Usage: " << command << " [OPTIONS]... <FILES>\n\n"
<< "OPTIONS:\n"
<< "If a long option shows an argument as mandatory,\n"
<< "then it is also mandatory for the equivalent short option.\n\n"
<< " -h, --help display this help and exit\n"
<< " -v, --version display version information and exit\n"
<< " -p, --preserve-times preserve access and modification times of the files\n\n";
cout << "To alter the most common tag information:\n"
<< " -a, --artist ARTIST set the artist information\n"
<< " -A, --album ALBUM set the album title information\n"
<< " -t, --title SONG set the song title information\n"
<< " -c, --comment COMMENT set the comment information\n"
<< " -g, --genre NUM set the genre number\n"
<< " -T, --track NUM set the track number\n"
<< " -y, --year NUM set the year\n\n";
cout << "To add/modify all fields:\n"
<< " -f, --add-field NAME=VALUE\n"
<< " add field with name NAME and content VALUE to the tags\n"
<< " -F, --replace-field NAME=VALUE\n"
<< " same as -f, but remove all other fields with the same\n"
<< " name from the tags first\n\n";
cout << "Get information from the files:\n"
<< " -i, --info display general information for the files\n"
<< " -l, --list list the tag contents of the files\n\n"
<< "To remove fields and whole tags\n"
<< " -r, --remove NAME remove all fields with the given name from the tags\n"
<< " -D, --delete-all delete the whole tags of the files\n\n";
cout << "Filename <-> tag information:\n"
<< " -n, --file-pattern PATTERN\n"
<< " extract tag information from the given filenames,\n"
<< " using PATTERN (for supported wildcards see below)\n"
<< " -N, --file-regex PATTERN\n"
<< " same as -n, but interpret PATTERN as an extended regex\n"
<< " -o, --organize PATTERN organize files into directory structure specified\n"
<< " by PATTERN (for supported wildcards see below)\n"
<< " --force overwrite existing files without asking (-o)\n"
<< " --move when using -o, move files instead of copying them\n\n";
cout << "The following wildcards are supported for the -o,-n,-N option arguments:\n"
<< " %a: Artist, %A: album, %t: title, %g: genre, %y: year,\n"
<< " %d: disc number, %T: track number, %%: percent sign" << endl;
}
bool Options::write = false;
bool Options::strip = false;
bool Options::info = false;
bool Options::list = false;
bool Options::force = false;
bool Options::preserveTimes = false;
bool Options::move = false;
bool Options::fromFilename = false;
IPattern Options::inPattern;
bool Options::organize = false;
OPattern Options::outPattern;
vector<GenericInfo> Options::generics;
vector<char*> Options::removals;
vector<FieldInfo> Options::fields;
uint Options::fileCount = 0;
char **Options::filenames = NULL;
const char* Options::options = "hvpa:A:t:c:g:T:y:F:f:ilr:Dn:N:o:";
const struct option Options::longOptions[] = {
/* help, general info & others */
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'v' },
{ "preserve-times", no_argument, NULL, 'p' },
/* alter generic tag infomation */
{ "artist", required_argument, NULL, 'a' },
{ "album", required_argument, NULL, 'A' },
{ "title", required_argument, NULL, 't' },
{ "comment", required_argument, NULL, 'c' },
{ "genre", required_argument, NULL, 'g' },
{ "track", required_argument, NULL, 'T' },
{ "year", required_argument, NULL, 'y' },
/* add/modify fields */
{ "add-field", required_argument, NULL, 'f' },
{ "replace-field", required_argument, NULL, 'F' },
/* get information from the files */
{ "info", no_argument, NULL, 'i' },
{ "list", no_argument, NULL, 'l' },
/* Remove fields and whole tags */
{ "remove", required_argument, NULL, 'r' },
{ "delete-all", no_argument, NULL, 'D' },
/* Filename <-> tag information */
{ "file-pattern", required_argument, NULL, 'n' },
{ "file-regex", required_argument, NULL, 'N' },
{ "organize", required_argument, NULL, 'o' },
{ "force", no_argument, NULL, OPT_LO_FORCE },
{ "move", no_argument, NULL, OPT_LO_ORG_MOVE },
{ 0, 0, 0, 0 },
};