28 #define _POSIX_C_SOURCE 200809L
36 static void squash_options_free (
void* options);
155 squash_options_find (SquashOptions* options,
const char* key) {
156 assert (options != NULL);
157 assert (key != NULL);
160 unsigned int option_n = 0;
163 while (info->name != NULL) {
164 if (strcasecmp (key, info->name) == 0)
190 const int option_n = squash_options_find (options, key);
195 const SquashOptionValue* val = &(options->values[option_n]);
197 switch ((
int) info->type) {
198 case SQUASH_OPTION_TYPE_ENUM_STRING:
199 return info->info.enum_string.values[val->int_value].name;
200 case SQUASH_OPTION_TYPE_STRING:
201 return val->string_value;
206 squash_assert_unreachable ();
221 const int option_n = squash_options_find (options, key);
226 const SquashOptionValue* val = &(options->values[option_n]);
228 switch ((
int) info->type) {
229 case SQUASH_OPTION_TYPE_BOOL:
230 return val->bool_value;
235 squash_assert_unreachable ();
250 const int option_n = squash_options_find (options, key);
255 const SquashOptionValue* val = &(options->values[option_n]);
257 switch ((
int) info->type) {
258 case SQUASH_OPTION_TYPE_INT:
259 case SQUASH_OPTION_TYPE_ENUM_INT:
260 case SQUASH_OPTION_TYPE_RANGE_INT:
261 return val->int_value;
266 squash_assert_unreachable ();
281 const int option_n = squash_options_find (options, key);
286 const SquashOptionValue* val = &(options->values[option_n]);
288 switch ((
int) info->type) {
289 case SQUASH_OPTION_TYPE_SIZE:
290 case SQUASH_OPTION_TYPE_RANGE_SIZE:
291 return val->size_value;
296 squash_assert_unreachable ();
312 assert (options != NULL);
313 assert (key != NULL);
314 assert (options->codec != NULL);
321 assert (options->values != NULL);
323 const int option_n = squash_options_find (options, key);
327 SquashOptionValue* val = &(options->values[option_n]);
328 info = info + option_n;
330 switch (info->type) {
331 case SQUASH_OPTION_TYPE_RANGE_INT:
332 case SQUASH_OPTION_TYPE_INT: {
333 int res = atoi (value);
334 if (info->type == SQUASH_OPTION_TYPE_RANGE_INT) {
335 if (!((res == 0 && info->info.range_int.allow_zero) ||
336 (res >= info->info.range_int.min && res <= info->info.range_int.max)))
339 val->int_value = res;
344 case SQUASH_OPTION_TYPE_RANGE_SIZE:
345 case SQUASH_OPTION_TYPE_SIZE: {
347 unsigned long long int res = strtoull (value, &endptr, 10);
350 if (*endptr !=
'\0') {
368 if (*endptr !=
'\0') {
369 if (*endptr ==
'i' || *endptr ==
'I')
372 if (*endptr ==
'b' || *endptr ==
'B')
382 if (info->type == SQUASH_OPTION_TYPE_RANGE_SIZE) {
383 if (!((res == 0 && info->info.range_size.allow_zero) ||
384 (res >= info->info.range_size.min && res <= info->info.range_size.max)))
387 val->size_value = (size_t) res;
392 case SQUASH_OPTION_TYPE_ENUM_STRING: {
393 for (
unsigned int i = 0 ; info->info.enum_string.values[i].name != NULL ; i++) {
394 if (strcasecmp (value, info->info.enum_string.values[i].name) == 0) {
395 val->int_value = info->info.enum_string.values[i].value;
403 case SQUASH_OPTION_TYPE_BOOL: {
404 if (strcasecmp (value,
"true") == 0 ||
405 strcasecmp (value,
"yes") == 0 ||
406 strcasecmp (value,
"on") == 0 ||
407 strcasecmp (value,
"t") == 0 ||
408 strcasecmp (value,
"y") == 0 ||
409 strcasecmp (value,
"1") == 0) {
410 val->bool_value =
true;
411 }
else if (strcasecmp (value,
"false") == 0 ||
412 strcasecmp (value,
"no") == 0 ||
413 strcasecmp (value,
"off") == 0 ||
414 strcasecmp (value,
"f") == 0 ||
415 strcasecmp (value,
"n") == 0 ||
416 strcasecmp (value,
"0") == 0) {
417 val->bool_value =
false;
425 case SQUASH_OPTION_TYPE_ENUM_INT: {
426 int res = atoi (value);
427 for (
unsigned int i = 0 ; i < info->info.enum_int.values_length ; i++) {
428 if (res == info->info.enum_int.values[i]) {
429 val->int_value = res;
437 case SQUASH_OPTION_TYPE_STRING:
438 val->string_value = strdup (value);
441 case SQUASH_OPTION_TYPE_NONE:
443 squash_assert_unreachable();
462 assert (options != NULL);
464 if (keys == NULL || values == NULL)
467 for ( n = 0 ; keys[n] != NULL ; n++ ) {
491 assert (options != NULL);
493 while ( (key = va_arg (options_list,
char*)) != NULL ) {
494 value = va_arg (options_list,
char*);
515 va_list options_list;
518 va_start (options_list, options);
520 va_end (options_list);
534 va_list options_list;
535 SquashOptions* options;
537 va_start (options_list, codec);
539 va_end (options_list);
544 static SquashOptions*
545 squash_options_create (SquashCodec* codec) {
546 SquashOptions* options = malloc (
sizeof (SquashOptions));
561 SquashOptions* opts = NULL;
563 assert (codec != NULL);
566 opts = squash_options_create (codec);
583 SquashOptions* opts = NULL;
585 assert (codec != NULL);
588 opts = squash_options_create (codec);
612 assert (options != NULL);
613 assert (codec != NULL);
615 o = (SquashOptions*) options;
623 for (n_options = 0 ; info[n_options].name != NULL ; n_options++) { }
625 o->values = calloc (n_options,
sizeof (SquashOptionValue));
626 for (
size_t c_option = 0 ; c_option < n_options ; c_option++) {
627 switch (info[c_option].type) {
628 case SQUASH_OPTION_TYPE_ENUM_STRING:
629 case SQUASH_OPTION_TYPE_RANGE_INT:
630 case SQUASH_OPTION_TYPE_INT:
631 case SQUASH_OPTION_TYPE_ENUM_INT:
632 o->values[c_option].int_value = info[c_option].default_value.int_value;
634 case SQUASH_OPTION_TYPE_BOOL:
635 o->values[c_option].bool_value = info[c_option].default_value.bool_value;
637 case SQUASH_OPTION_TYPE_SIZE:
638 case SQUASH_OPTION_TYPE_RANGE_SIZE:
639 o->values[c_option].size_value = info[c_option].default_value.size_value;
641 case SQUASH_OPTION_TYPE_STRING:
642 o->values[c_option].string_value = strdup (info[c_option].default_value.string_value);
644 case SQUASH_OPTION_TYPE_NONE:
646 squash_assert_unreachable();
664 assert (options != NULL);
666 o = (SquashOptions*) options;
668 SquashOptionValue* values = o->values;
669 if (values != NULL) {
671 assert (info != NULL);
673 for (
int i = 0 ; info[i].name != NULL ; i++)
674 if (info[i].type == SQUASH_OPTION_TYPE_STRING)
675 free (values[i].string_value);
684 squash_options_free (
void* options) {
void squash_options_init(void *options, SquashCodec *codec, SquashDestroyNotify destroy_notify)
Initialize a new SquashOptions instance.
SquashStatus squash_options_parse(SquashOptions *options,...)
Parse a variadic list of options.
int squash_options_get_int(SquashOptions *options, const char *key)
SquashStatus squash_options_parsev(SquashOptions *options, va_list options_list)
Parse a va_list of options.
SquashStatus squash_options_parsea(SquashOptions *options, const char *const *keys, const char *const *values)
Parse an array of options.
SquashOptions * squash_options_new(SquashCodec *codec,...)
Create a new group of options.
void(* SquashDestroyNotify)(void *data)
Callback to be invoked when information data is no longer needed.
const char * squash_options_get_string(SquashOptions *options, const char *key)
SquashStatus squash_options_parse_option(SquashOptions *options, const char *key, const char *value)
Parse a single option.
SquashOptions * squash_options_newv(SquashCodec *codec, va_list options)
Create a new group of options from a variadic list.
bool squash_options_get_bool(SquashOptions *options, const char *key)
SquashOptions * squash_options_newa(SquashCodec *codec, const char *const *keys, const char *const *values)
Create a new group of options from key and value arrays.
const SquashOptionInfo * squash_codec_get_option_info(SquashCodec *codec)
Get a list of options applicable to the codec.
SquashStatus
Status codes.
SquashStatus squash_error(SquashStatus status)
Emit an error.
One or more parameter values was not valid.
void squash_options_destroy(void *options)
Destroy a SquashOptions instance.
Operation completed successfully.
void squash_object_destroy(void *obj)
Destroy an object.
size_t squash_options_get_size(SquashOptions *options, const char *key)
One or more of the parameters were not valid.
void squash_object_init(void *obj, bool is_floating, SquashDestroyNotify destroy_notify)
Initialize a new object.