Пример #1
0
FLAC__bool parse_option(int option_index, const char *option_argument, CommandLineOptions *options)
{
	const char *opt = long_options_[option_index].name;
	Operation *op;
	Argument *arg;
	FLAC__bool ok = true;

	if(0 == strcmp(opt, "preserve-modtime")) {
		options->preserve_modtime = true;
	}
	else if(0 == strcmp(opt, "with-filename")) {
		options->prefix_with_filename = true;
	}
	else if(0 == strcmp(opt, "no-filename")) {
		options->prefix_with_filename = false;
	}
	else if(0 == strcmp(opt, "no-utf8-convert")) {
		options->utf8_convert = false;
	}
	else if(0 == strcmp(opt, "dont-use-padding")) {
		options->use_padding = false;
	}
	else if(0 == strcmp(opt, "no-cued-seekpoints")) {
		options->cued_seekpoints = false;
	}
	else if(0 == strcmp(opt, "show-md5sum")) {
		(void) append_shorthand_operation(options, OP__SHOW_MD5SUM);
	}
	else if(0 == strcmp(opt, "show-min-blocksize")) {
		(void) append_shorthand_operation(options, OP__SHOW_MIN_BLOCKSIZE);
	}
	else if(0 == strcmp(opt, "show-max-blocksize")) {
		(void) append_shorthand_operation(options, OP__SHOW_MAX_BLOCKSIZE);
	}
	else if(0 == strcmp(opt, "show-min-framesize")) {
		(void) append_shorthand_operation(options, OP__SHOW_MIN_FRAMESIZE);
	}
	else if(0 == strcmp(opt, "show-max-framesize")) {
		(void) append_shorthand_operation(options, OP__SHOW_MAX_FRAMESIZE);
	}
	else if(0 == strcmp(opt, "show-sample-rate")) {
		(void) append_shorthand_operation(options, OP__SHOW_SAMPLE_RATE);
	}
	else if(0 == strcmp(opt, "show-channels")) {
		(void) append_shorthand_operation(options, OP__SHOW_CHANNELS);
	}
	else if(0 == strcmp(opt, "show-bps")) {
		(void) append_shorthand_operation(options, OP__SHOW_BPS);
	}
	else if(0 == strcmp(opt, "show-total-samples")) {
		(void) append_shorthand_operation(options, OP__SHOW_TOTAL_SAMPLES);
	}
	else if(0 == strcmp(opt, "set-md5sum")) {
		op = append_shorthand_operation(options, OP__SET_MD5SUM);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_md5(option_argument, op->argument.streaminfo_md5.value)) {
			flac_fprintf(stderr, "ERROR (--%s): bad MD5 sum\n", opt);
			ok = false;
		}
		else
			undocumented_warning(opt);
	}
	else if(0 == strcmp(opt, "set-min-blocksize")) {
		op = append_shorthand_operation(options, OP__SET_MIN_BLOCKSIZE);
		if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value < FLAC__MIN_BLOCK_SIZE || op->argument.streaminfo_uint32.value > FLAC__MAX_BLOCK_SIZE) {
			flac_fprintf(stderr, "ERROR (--%s): value must be >= %u and <= %u\n", opt, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE);
			ok = false;
		}
		else
			undocumented_warning(opt);
	}
	else if(0 == strcmp(opt, "set-max-blocksize")) {
		op = append_shorthand_operation(options, OP__SET_MAX_BLOCKSIZE);
		if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value < FLAC__MIN_BLOCK_SIZE || op->argument.streaminfo_uint32.value > FLAC__MAX_BLOCK_SIZE) {
			flac_fprintf(stderr, "ERROR (--%s): value must be >= %u and <= %u\n", opt, FLAC__MIN_BLOCK_SIZE, FLAC__MAX_BLOCK_SIZE);
			ok = false;
		}
		else
			undocumented_warning(opt);
	}
	else if(0 == strcmp(opt, "set-min-framesize")) {
		op = append_shorthand_operation(options, OP__SET_MIN_FRAMESIZE);
		if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value >= (1u<<FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN)) {
			flac_fprintf(stderr, "ERROR (--%s): value must be a %u-bit unsigned integer\n", opt, FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN);
			ok = false;
		}
		else
			undocumented_warning(opt);
	}
	else if(0 == strcmp(opt, "set-max-framesize")) {
		op = append_shorthand_operation(options, OP__SET_MAX_FRAMESIZE);
		if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value >= (1u<<FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN)) {
			flac_fprintf(stderr, "ERROR (--%s): value must be a %u-bit unsigned integer\n", opt, FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN);
			ok = false;
		}
		else
			undocumented_warning(opt);
	}
	else if(0 == strcmp(opt, "set-sample-rate")) {
		op = append_shorthand_operation(options, OP__SET_SAMPLE_RATE);
		if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || !FLAC__format_sample_rate_is_valid(op->argument.streaminfo_uint32.value)) {
			flac_fprintf(stderr, "ERROR (--%s): invalid sample rate\n", opt);
			ok = false;
		}
		else
			undocumented_warning(opt);
	}
	else if(0 == strcmp(opt, "set-channels")) {
		op = append_shorthand_operation(options, OP__SET_CHANNELS);
		if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value > FLAC__MAX_CHANNELS) {
			flac_fprintf(stderr, "ERROR (--%s): value must be > 0 and <= %u\n", opt, FLAC__MAX_CHANNELS);
			ok = false;
		}
		else
			undocumented_warning(opt);
	}
	else if(0 == strcmp(opt, "set-bps")) {
		op = append_shorthand_operation(options, OP__SET_BPS);
		if(!parse_uint32(option_argument, &(op->argument.streaminfo_uint32.value)) || op->argument.streaminfo_uint32.value < FLAC__MIN_BITS_PER_SAMPLE || op->argument.streaminfo_uint32.value > FLAC__MAX_BITS_PER_SAMPLE) {
			flac_fprintf(stderr, "ERROR (--%s): value must be >= %u and <= %u\n", opt, FLAC__MIN_BITS_PER_SAMPLE, FLAC__MAX_BITS_PER_SAMPLE);
			ok = false;
		}
		else
			undocumented_warning(opt);
	}
	else if(0 == strcmp(opt, "set-total-samples")) {
		op = append_shorthand_operation(options, OP__SET_TOTAL_SAMPLES);
		if(!parse_uint64(option_argument, &(op->argument.streaminfo_uint64.value)) || op->argument.streaminfo_uint64.value >= (((FLAC__uint64)1)<<FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN)) {
			flac_fprintf(stderr, "ERROR (--%s): value must be a %u-bit unsigned integer\n", opt, FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN);
			ok = false;
		}
		else
			undocumented_warning(opt);
	}
	else if(0 == strcmp(opt, "show-vendor-tag")) {
		(void) append_shorthand_operation(options, OP__SHOW_VC_VENDOR);
	}
	else if(0 == strcmp(opt, "show-tag")) {
		const char *violation;
		op = append_shorthand_operation(options, OP__SHOW_VC_FIELD);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_vorbis_comment_field_name(option_argument, &(op->argument.vc_field_name.value), &violation)) {
			FLAC__ASSERT(0 != violation);
			flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field name \"%s\",\n       %s\n", opt, option_argument, violation);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "remove-all-tags")) {
		(void) append_shorthand_operation(options, OP__REMOVE_VC_ALL);
	}
	else if(0 == strcmp(opt, "remove-tag")) {
		const char *violation;
		op = append_shorthand_operation(options, OP__REMOVE_VC_FIELD);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_vorbis_comment_field_name(option_argument, &(op->argument.vc_field_name.value), &violation)) {
			FLAC__ASSERT(0 != violation);
			flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field name \"%s\",\n       %s\n", opt, option_argument, violation);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "remove-first-tag")) {
		const char *violation;
		op = append_shorthand_operation(options, OP__REMOVE_VC_FIRSTFIELD);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_vorbis_comment_field_name(option_argument, &(op->argument.vc_field_name.value), &violation)) {
			FLAC__ASSERT(0 != violation);
			flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field name \"%s\",\n       %s\n", opt, option_argument, violation);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "set-tag")) {
		const char *violation;
		op = append_shorthand_operation(options, OP__SET_VC_FIELD);
		FLAC__ASSERT(0 != option_argument);
		op->argument.vc_field.field_value_from_file = false;
		if(!parse_vorbis_comment_field(option_argument, &(op->argument.vc_field.field), &(op->argument.vc_field.field_name), &(op->argument.vc_field.field_value), &(op->argument.vc_field.field_value_length), &violation)) {
			FLAC__ASSERT(0 != violation);
			flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field \"%s\",\n       %s\n", opt, option_argument, violation);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "set-tag-from-file")) {
		const char *violation;
		op = append_shorthand_operation(options, OP__SET_VC_FIELD);
		FLAC__ASSERT(0 != option_argument);
		op->argument.vc_field.field_value_from_file = true;
		if(!parse_vorbis_comment_field(option_argument, &(op->argument.vc_field.field), &(op->argument.vc_field.field_name), &(op->argument.vc_field.field_value), &(op->argument.vc_field.field_value_length), &violation)) {
			FLAC__ASSERT(0 != violation);
			flac_fprintf(stderr, "ERROR (--%s): malformed vorbis comment field \"%s\",\n       %s\n", opt, option_argument, violation);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "import-tags-from")) {
		op = append_shorthand_operation(options, OP__IMPORT_VC_FROM);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_string(option_argument, &(op->argument.filename.value))) {
			flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "export-tags-to")) {
		op = append_shorthand_operation(options, OP__EXPORT_VC_TO);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_string(option_argument, &(op->argument.filename.value))) {
			flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "import-cuesheet-from")) {
		if(0 != find_shorthand_operation(options, OP__IMPORT_CUESHEET_FROM)) {
			flac_fprintf(stderr, "ERROR (--%s): may be specified only once\n", opt);
			ok = false;
		}
		op = append_shorthand_operation(options, OP__IMPORT_CUESHEET_FROM);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_string(option_argument, &(op->argument.import_cuesheet_from.filename))) {
			flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "export-cuesheet-to")) {
		op = append_shorthand_operation(options, OP__EXPORT_CUESHEET_TO);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_string(option_argument, &(op->argument.filename.value))) {
			flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "import-picture-from")) {
		op = append_shorthand_operation(options, OP__IMPORT_PICTURE_FROM);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_string(option_argument, &(op->argument.specification.value))) {
			flac_fprintf(stderr, "ERROR (--%s): missing specification\n", opt);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "export-picture-to")) {
		arg = find_argument(options, ARG__BLOCK_NUMBER);
		op = append_shorthand_operation(options, OP__EXPORT_PICTURE_TO);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_string(option_argument, &(op->argument.export_picture_to.filename))) {
			flac_fprintf(stderr, "ERROR (--%s): missing filename\n", opt);
			ok = false;
		}
		op->argument.export_picture_to.block_number_link = arg? &(arg->value.block_number) : 0;
	}
	else if(0 == strcmp(opt, "add-seekpoint")) {
		const char *violation;
		char *spec;
		FLAC__ASSERT(0 != option_argument);
		if(!parse_add_seekpoint(option_argument, &spec, &violation)) {
			FLAC__ASSERT(0 != violation);
			flac_fprintf(stderr, "ERROR (--%s): malformed seekpoint specification \"%s\",\n       %s\n", opt, option_argument, violation);
			ok = false;
		}
		else {
			op = find_shorthand_operation(options, OP__ADD_SEEKPOINT);
			if(0 == op)
				op = append_shorthand_operation(options, OP__ADD_SEEKPOINT);
			local_strcat(&(op->argument.add_seekpoint.specification), spec);
			local_strcat(&(op->argument.add_seekpoint.specification), ";");
			free(spec);
		}
	}
	else if(0 == strcmp(opt, "add-replay-gain")) {
		(void) append_shorthand_operation(options, OP__ADD_REPLAY_GAIN);
	}
	else if(0 == strcmp(opt, "remove-replay-gain")) {
		const FLAC__byte * const tags[5] = {
			GRABBAG__REPLAYGAIN_TAG_REFERENCE_LOUDNESS,
			GRABBAG__REPLAYGAIN_TAG_TITLE_GAIN,
			GRABBAG__REPLAYGAIN_TAG_TITLE_PEAK,
			GRABBAG__REPLAYGAIN_TAG_ALBUM_GAIN,
			GRABBAG__REPLAYGAIN_TAG_ALBUM_PEAK
		};
		size_t i;
		for(i = 0; i < sizeof(tags)/sizeof(tags[0]); i++) {
			op = append_shorthand_operation(options, OP__REMOVE_VC_FIELD);
			op->argument.vc_field_name.value = local_strdup((const char *)tags[i]);
		}
	}
	else if(0 == strcmp(opt, "add-padding")) {
		op = append_shorthand_operation(options, OP__ADD_PADDING);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_add_padding(option_argument, &(op->argument.add_padding.length))) {
			flac_fprintf(stderr, "ERROR (--%s): illegal length \"%s\", length must be >= 0 and < 2^%u\n", opt, option_argument, FLAC__STREAM_METADATA_LENGTH_LEN);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "help")) {
		options->show_long_help = true;
	}
	else if(0 == strcmp(opt, "version")) {
		options->show_version = true;
	}
	else if(0 == strcmp(opt, "list")) {
		(void) append_major_operation(options, OP__LIST);
	}
	else if(0 == strcmp(opt, "append")) {
		(void) append_major_operation(options, OP__APPEND);
	}
	else if(0 == strcmp(opt, "remove")) {
		(void) append_major_operation(options, OP__REMOVE);
	}
	else if(0 == strcmp(opt, "remove-all")) {
		(void) append_major_operation(options, OP__REMOVE_ALL);
	}
	else if(0 == strcmp(opt, "merge-padding")) {
		(void) append_major_operation(options, OP__MERGE_PADDING);
	}
	else if(0 == strcmp(opt, "sort-padding")) {
		(void) append_major_operation(options, OP__SORT_PADDING);
	}
	else if(0 == strcmp(opt, "block-number")) {
		arg = append_argument(options, ARG__BLOCK_NUMBER);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_block_number(option_argument, &(arg->value.block_number))) {
			flac_fprintf(stderr, "ERROR: malformed block number specification \"%s\"\n", option_argument);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "block-type")) {
		arg = append_argument(options, ARG__BLOCK_TYPE);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_block_type(option_argument, &(arg->value.block_type))) {
			flac_fprintf(stderr, "ERROR (--%s): malformed block type specification \"%s\"\n", opt, option_argument);
			ok = false;
		}
		options->args.checks.has_block_type = true;
	}
	else if(0 == strcmp(opt, "except-block-type")) {
		arg = append_argument(options, ARG__EXCEPT_BLOCK_TYPE);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_block_type(option_argument, &(arg->value.block_type))) {
			flac_fprintf(stderr, "ERROR (--%s): malformed block type specification \"%s\"\n", opt, option_argument);
			ok = false;
		}
		options->args.checks.has_except_block_type = true;
	}
	else if(0 == strcmp(opt, "data-format")) {
		arg = append_argument(options, ARG__DATA_FORMAT);
		FLAC__ASSERT(0 != option_argument);
		if(!parse_data_format(option_argument, &(arg->value.data_format))) {
			flac_fprintf(stderr, "ERROR (--%s): illegal data format \"%s\"\n", opt, option_argument);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "application-data-format")) {
		FLAC__ASSERT(0 != option_argument);
		if(!parse_application_data_format(option_argument, &(options->application_data_format_is_hexdump))) {
			flac_fprintf(stderr, "ERROR (--%s): illegal application data format \"%s\"\n", opt, option_argument);
			ok = false;
		}
	}
	else if(0 == strcmp(opt, "from-file")) {
		arg = append_argument(options, ARG__FROM_FILE);
		FLAC__ASSERT(0 != option_argument);
		arg->value.from_file.file_name = local_strdup(option_argument);
	}
	else {
		FLAC__ASSERT(0);
	}

	return ok;
}
Пример #2
0
void
parse_param_list(token tag_name, param *param_list, token end_token)
{
	param *param_ptr;
	int param_index;
	char old_name[256];

	// Initialise the parameter list.

	init_param_list();

	// Parse the parameter list.

	while ((param_ptr = parse_next_param(param_list)) != NULL) {
		switch (param_ptr->value_type) {
		case VALUE_BLOCK_NAME:
			parse_string(old_name, 256);
			if (!parse_name(old_name, (char *)param_ptr->variable_ptr, false))
				file_error("Expected a valid block name rather than '%s'",
					old_name);
			break;
		case VALUE_BLOCK_TYPE:
			*(blocktype *)param_ptr->variable_ptr = parse_block_type();
			break;
		case VALUE_BOOL:
			*(bool *)param_ptr->variable_ptr = parse_bool();
			break;
		case VALUE_CHAR:
			*(char *)param_ptr->variable_ptr = parse_char();
			break;
		case VALUE_DEGREES:
			*(double *)param_ptr->variable_ptr = parse_degrees();
			break;
		case VALUE_DOUBLE:
			*(double *)param_ptr->variable_ptr = parse_double();
			break;
		case VALUE_INTEGER:
			*(int *)param_ptr->variable_ptr = parse_integer();
			break;
		case VALUE_PART_NAME:
			parse_string(old_name, 256);
			if (!parse_name(old_name, (char *)param_ptr->variable_ptr, false))
				file_error("Expected a valid part name rather than '%s'",
					old_name);
			break;
		case VALUE_PERCENTAGE:
			*(double *)param_ptr->variable_ptr = parse_percentage();
			break;
		case VALUE_REF_LIST:
			parse_ref_list((ref_list *)param_ptr->variable_ptr);
			break;
		case VALUE_RGB:
			*(RGBcolour *)param_ptr->variable_ptr = parse_RGB();
			break;
		case VALUE_STRING:
			parse_string((char *)param_ptr->variable_ptr, 256);
			break;
		case VALUE_TEXCOORDS_LIST:
			parse_texcoords_list((texcoords_list *)param_ptr->variable_ptr);
			break;
		case VALUE_TEXTURE_STYLE:
			*(texstyle *)param_ptr->variable_ptr = parse_texture_style();
			break;
		case VALUE_VERTEX_COORDS:
			*(vertex *)param_ptr->variable_ptr = parse_vertex_coordinates();
			break;
		default:
			file_error("internal error--unrecognised parameter value type");
		}
	}

	// If an end_token was specified, then verify that the end token parsed
	// matches it.

	if (end_token != TOKEN_NONE && file_token != end_token)
		expected_token(get_token_str(end_token));

	// If there was a parameter list, verify that all required parameters were
	// parsed.

	if (param_list) {
		param_index = 0;
		while (param_list[param_index].param_name != TOKEN_NONE) {
			if (param_list[param_index].required && 
				!matched_param[param_index])
				file_error("parameter '%s' is missing from tag '%s'", 
					get_token_str(param_list[param_index].param_name), 
					get_token_str(tag_name));
			param_index++;
		}
	}
}