Fix CLI wildcards conflicting with paths

This commit is contained in:
bnnm 2020-07-31 00:02:45 +02:00
parent 30eef7ed43
commit 79944f56c6
2 changed files with 17 additions and 13 deletions

View File

@ -74,12 +74,12 @@ for /L %A in (5,1,10) do test.exe -s %A -o file_%A.wav file.fsb
``` ```
Output filename in `-o` may use multiple wildcards: Output filename in `-o` may use multiple wildcards:
- `:s`: sets current subsong (or 0 if format doesn't have subsongs) - `?s`: sets current subsong (or 0 if format doesn't have subsongs)
- `:0Ns`: same, but left pads subsong with up to `N` zeroes - `?0Ns`: same, but left pads subsong with up to `N` zeroes
- `:n`: internal stream name, or input filename if format doesn't have name - `?n`: internal stream name, or input filename if format doesn't have name
- `:f`: input filename - `?f`: input filename
For example `test.exe -s 2 -o :04s_:n.wav file.fsb` could generate `0002_song1.wav` For example `test.exe -s 2 -o ?04s_?n.wav file.fsb` could generate `0002_song1.wav`
### in_vgmstream ### in_vgmstream

View File

@ -37,7 +37,7 @@ static void usage(const char* name, int is_full) {
"Usage: %s [-o <outfile.wav>] [options] <infile>\n" "Usage: %s [-o <outfile.wav>] [options] <infile>\n"
"Options:\n" "Options:\n"
" -o <outfile.wav>: name of output .wav file, default <infile>.wav\n" " -o <outfile.wav>: name of output .wav file, default <infile>.wav\n"
" <outfile> wildcards can be :s=subsong, :n=stream name, :f=infile\n" " <outfile> wildcards can be ?s=subsong, ?n=stream name, ?f=infile\n"
" -l loop count: loop count, default 2.0\n" " -l loop count: loop count, default 2.0\n"
" -f fade time: fade time in seconds after N loops, default 10.0\n" " -f fade time: fade time in seconds after N loops, default 10.0\n"
" -d fade delay: fade delay in seconds, default 0.0\n" " -d fade delay: fade delay in seconds, default 0.0\n"
@ -306,8 +306,8 @@ static void apply_config(VGMSTREAM* vgmstream, cli_config* cfg) {
} }
vcfg.play_forever = cfg->play_forever; vcfg.play_forever = cfg->play_forever;
vcfg.fade_period = cfg->fade_time; vcfg.fade_time = cfg->fade_time;
vcfg.loop_times = cfg->loop_count; vcfg.loop_count = cfg->loop_count;
vcfg.fade_delay = cfg->fade_delay; vcfg.fade_delay = cfg->fade_delay;
vcfg.ignore_loop = cfg->ignore_loop; vcfg.ignore_loop = cfg->ignore_loop;
@ -356,8 +356,8 @@ static void clean_filename(char* dst, int clean_paths) {
} }
} }
/* replaces a filename with ":n" (stream name), ":f" (infilename) or ":s" (subsong) wildcards /* replaces a filename with "?n" (stream name), "?f" (infilename) or "?s" (subsong) wildcards
* (":" was chosen since it's not a valid Windows filename char and hopefully nobody uses it on Linux) */ * ("?" was chosen since it's not a valid Windows filename char and hopefully nobody uses it on Linux) */
void replace_filename(char* dst, size_t dstsize, const char* outfilename, const char* infilename, VGMSTREAM* vgmstream) { void replace_filename(char* dst, size_t dstsize, const char* outfilename, const char* infilename, VGMSTREAM* vgmstream) {
int subsong; int subsong;
char stream_name[PATH_LIMIT]; char stream_name[PATH_LIMIT];
@ -390,29 +390,33 @@ void replace_filename(char* dst, size_t dstsize, const char* outfilename, const
/* do controlled replaces of each wildcard (in theory could appear N times) */ /* do controlled replaces of each wildcard (in theory could appear N times) */
do { do {
char* pos = strchr(buf, ':'); char* pos = strchr(buf, '?');
if (!pos) if (!pos)
break; break;
/* use buf as format and copy formatted result to tmp (assuming sprintf's format must not overlap with dst) */ /* use buf as format and copy formatted result to tmp (assuming sprintf's format must not overlap with dst) */
pos[0] = '%';
if (pos[1] == 'n') { if (pos[1] == 'n') {
pos[0] = '%';
pos[1] = 's'; /* use %s */ pos[1] = 's'; /* use %s */
snprintf(tmp, sizeof(tmp), buf, stream_name); snprintf(tmp, sizeof(tmp), buf, stream_name);
} }
else if (pos[1] == 'f') { else if (pos[1] == 'f') {
pos[0] = '%';
pos[1] = 's'; /* use %s */ pos[1] = 's'; /* use %s */
snprintf(tmp, sizeof(tmp), buf, infilename); snprintf(tmp, sizeof(tmp), buf, infilename);
} }
else if (pos[1] == 's') { else if (pos[1] == 's') {
pos[0] = '%';
pos[1] = 'i'; /* use %i */ pos[1] = 'i'; /* use %i */
snprintf(tmp, sizeof(tmp), buf, subsong); snprintf(tmp, sizeof(tmp), buf, subsong);
} }
else if ((pos[1] == '0' && pos[2] >= '1' && pos[2] <= '9' && pos[3] == 's')) { else if ((pos[1] == '0' && pos[2] >= '1' && pos[2] <= '9' && pos[3] == 's')) {
pos[0] = '%';
pos[3] = 'i'; /* use %0Ni */ pos[3] = 'i'; /* use %0Ni */
snprintf(tmp, sizeof(tmp), buf, subsong); snprintf(tmp, sizeof(tmp), buf, subsong);
} }
else { else {
/* not recognized */
continue; continue;
} }
@ -529,7 +533,7 @@ int main(int argc, char** argv) {
/* maybe should avoid overwriting with this auto-name, for the unlikely /* maybe should avoid overwriting with this auto-name, for the unlikely
* case of file header-body pairs (file.ext+file.ext.wav) */ * case of file header-body pairs (file.ext+file.ext.wav) */
} }
else if (strchr(cfg.outfilename, ':') != NULL) { else if (strchr(cfg.outfilename, '?') != NULL) {
/* special substitution */ /* special substitution */
replace_filename(outfilename_temp, sizeof(outfilename_temp), cfg.outfilename, cfg.infilename, vgmstream); replace_filename(outfilename_temp, sizeof(outfilename_temp), cfg.outfilename, cfg.infilename, vgmstream);
cfg.outfilename = outfilename_temp; cfg.outfilename = outfilename_temp;