📄 options.c
字号:
options->args.arguments[options->args.num_arguments++] = argument;
}
Operation *append_major_operation(CommandLineOptions *options, OperationType type)
{
Operation op;
memset(&op, 0, sizeof(op));
op.type = type;
append_new_operation(options, op);
options->args.checks.num_major_ops++;
return options->ops.operations + (options->ops.num_operations - 1);
}
Operation *append_shorthand_operation(CommandLineOptions *options, OperationType type)
{
Operation op;
memset(&op, 0, sizeof(op));
op.type = type;
append_new_operation(options, op);
options->args.checks.num_shorthand_ops++;
return options->ops.operations + (options->ops.num_operations - 1);
}
Operation *find_shorthand_operation(CommandLineOptions *options, OperationType type)
{
unsigned i;
for(i = 0; i < options->ops.num_operations; i++)
if(options->ops.operations[i].type == type)
return &options->ops.operations[i];
return 0;
}
Argument *append_argument(CommandLineOptions *options, ArgumentType type)
{
Argument arg;
memset(&arg, 0, sizeof(arg));
arg.type = type;
append_new_argument(options, arg);
return options->args.arguments + (options->args.num_arguments - 1);
}
FLAC__bool parse_md5(const char *src, FLAC__byte dest[16])
{
unsigned i, d;
int c;
FLAC__ASSERT(0 != src);
if(strlen(src) != 32)
return false;
/* strtoul() accepts negative numbers which we do not want, so we do it the hard way */
for(i = 0; i < 16; i++) {
c = (int)(*src++);
if(isdigit(c))
d = (unsigned)(c - '0');
else if(c >= 'a' && c <= 'f')
d = (unsigned)(c - 'a') + 10u;
else if(c >= 'A' && c <= 'F')
d = (unsigned)(c - 'A') + 10u;
else
return false;
d <<= 4;
c = (int)(*src++);
if(isdigit(c))
d |= (unsigned)(c - '0');
else if(c >= 'a' && c <= 'f')
d |= (unsigned)(c - 'a') + 10u;
else if(c >= 'A' && c <= 'F')
d |= (unsigned)(c - 'A') + 10u;
else
return false;
dest[i] = (FLAC__byte)d;
}
return true;
}
FLAC__bool parse_uint32(const char *src, FLAC__uint32 *dest)
{
FLAC__ASSERT(0 != src);
if(strlen(src) == 0 || strspn(src, "0123456789") != strlen(src))
return false;
*dest = strtoul(src, 0, 10);
return true;
}
/* There's no stroull() in MSVC6 so we just write a specialized one */
static FLAC__uint64 local__strtoull(const char *src)
{
FLAC__uint64 ret = 0;
int c;
FLAC__ASSERT(0 != src);
while(0 != (c = *src++)) {
c -= '0';
if(c >= 0 && c <= 9)
ret = (ret * 10) + c;
else
break;
}
return ret;
}
FLAC__bool parse_uint64(const char *src, FLAC__uint64 *dest)
{
FLAC__ASSERT(0 != src);
if(strlen(src) == 0 || strspn(src, "0123456789") != strlen(src))
return false;
*dest = local__strtoull(src);
return true;
}
FLAC__bool parse_filename(const char *src, char **dest)
{
if(0 == src || strlen(src) == 0)
return false;
*dest = strdup(src);
return true;
}
FLAC__bool parse_vorbis_comment_field_name(const char *field_ref, char **name, const char **violation)
{
static const char * const violations[] = {
"field name contains invalid character"
};
char *q, *s;
s = local_strdup(field_ref);
for(q = s; *q; q++) {
if(*q < 0x20 || *q > 0x7d || *q == 0x3d) {
free(s);
*violation = violations[0];
return false;
}
}
*name = s;
return true;
}
FLAC__bool parse_add_seekpoint(const char *in, char **out, const char **violation)
{
static const char *garbled_ = "garbled specification";
const unsigned n = strlen(in);
FLAC__ASSERT(0 != in);
FLAC__ASSERT(0 != out);
if(n == 0) {
*violation = "specification is empty";
return false;
}
if(n > strspn(in, "0123456789.Xsx")) {
*violation = "specification contains invalid character";
return false;
}
if(in[n-1] == 'X') {
if(n > 1) {
*violation = garbled_;
return false;
}
}
else if(in[n-1] == 's') {
if(n-1 > strspn(in, "0123456789.")) {
*violation = garbled_;
return false;
}
}
else if(in[n-1] == 'x') {
if(n-1 > strspn(in, "0123456789")) {
*violation = garbled_;
return false;
}
}
else {
if(n > strspn(in, "0123456789")) {
*violation = garbled_;
return false;
}
}
*out = local_strdup(in);
return true;
}
FLAC__bool parse_add_padding(const char *in, unsigned *out)
{
FLAC__ASSERT(0 != in);
FLAC__ASSERT(0 != out);
*out = (unsigned)strtoul(in, 0, 10);
return *out < (1u << FLAC__STREAM_METADATA_LENGTH_LEN);
}
FLAC__bool parse_block_number(const char *in, Argument_BlockNumber *out)
{
char *p, *q, *s, *end;
long i;
unsigned entry;
if(*in == '\0')
return false;
s = local_strdup(in);
/* first count the entries */
for(out->num_entries = 1, p = strchr(s, ','); p; out->num_entries++, p = strchr(++p, ','))
;
/* make space */
FLAC__ASSERT(out->num_entries > 0);
if(0 == (out->entries = (unsigned*)malloc(sizeof(unsigned) * out->num_entries)))
die("out of memory allocating space for option list");
/* load 'em up */
entry = 0;
q = s;
while(q) {
FLAC__ASSERT(entry < out->num_entries);
if(0 != (p = strchr(q, ',')))
*p++ = '\0';
if(!isdigit((int)(*q)) || (i = strtol(q, &end, 10)) < 0 || *end) {
free(s);
return false;
}
out->entries[entry++] = (unsigned)i;
q = p;
}
FLAC__ASSERT(entry == out->num_entries);
free(s);
return true;
}
FLAC__bool parse_block_type(const char *in, Argument_BlockType *out)
{
char *p, *q, *r, *s;
unsigned entry;
if(*in == '\0')
return false;
s = local_strdup(in);
/* first count the entries */
for(out->num_entries = 1, p = strchr(s, ','); p; out->num_entries++, p = strchr(++p, ','))
;
/* make space */
FLAC__ASSERT(out->num_entries > 0);
if(0 == (out->entries = (Argument_BlockTypeEntry*)malloc(sizeof(Argument_BlockTypeEntry) * out->num_entries)))
die("out of memory allocating space for option list");
/* load 'em up */
entry = 0;
q = s;
while(q) {
FLAC__ASSERT(entry < out->num_entries);
if(0 != (p = strchr(q, ',')))
*p++ = 0;
r = strchr(q, ':');
if(r)
*r++ = '\0';
if(0 != r && 0 != strcmp(q, "APPLICATION")) {
free(s);
return false;
}
if(0 == strcmp(q, "STREAMINFO")) {
out->entries[entry++].type = FLAC__METADATA_TYPE_STREAMINFO;
}
else if(0 == strcmp(q, "PADDING")) {
out->entries[entry++].type = FLAC__METADATA_TYPE_PADDING;
}
else if(0 == strcmp(q, "APPLICATION")) {
out->entries[entry].type = FLAC__METADATA_TYPE_APPLICATION;
out->entries[entry].filter_application_by_id = (0 != r);
if(0 != r) {
if(strlen(r) == 4) {
strcpy(out->entries[entry].application_id, r);
}
else if(strlen(r) == 10 && strncmp(r, "0x", 2) == 0 && strspn(r+2, "0123456789ABCDEFabcdef") == 8) {
FLAC__uint32 x = strtoul(r+2, 0, 16);
out->entries[entry].application_id[3] = (FLAC__byte)(x & 0xff);
out->entries[entry].application_id[2] = (FLAC__byte)((x>>=8) & 0xff);
out->entries[entry].application_id[1] = (FLAC__byte)((x>>=8) & 0xff);
out->entries[entry].application_id[0] = (FLAC__byte)((x>>=8) & 0xff);
}
else {
free(s);
return false;
}
}
entry++;
}
else if(0 == strcmp(q, "SEEKTABLE")) {
out->entries[entry++].type = FLAC__METADATA_TYPE_SEEKTABLE;
}
else if(0 == strcmp(q, "VORBIS_COMMENT")) {
out->entries[entry++].type = FLAC__METADATA_TYPE_VORBIS_COMMENT;
}
else if(0 == strcmp(q, "CUESHEET")) {
out->entries[entry++].type = FLAC__METADATA_TYPE_CUESHEET;
}
else {
free(s);
return false;
}
q = p;
}
FLAC__ASSERT(entry == out->num_entries);
free(s);
return true;
}
FLAC__bool parse_data_format(const char *in, Argument_DataFormat *out)
{
if(0 == strcmp(in, "binary"))
out->is_binary = true;
else if(0 == strcmp(in, "text"))
out->is_binary = false;
else
return false;
return true;
}
FLAC__bool parse_application_data_format(const char *in, FLAC__bool *out)
{
if(0 == strcmp(in, "hexdump"))
*out = true;
else if(0 == strcmp(in, "text"))
*out = false;
else
return false;
return true;
}
void undocumented_warning(const char *opt)
{
fprintf(stderr, "WARNING: undocmented option --%s should be used with caution,\n only for repairing a damaged STREAMINFO block\n", opt);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -