/* * libzvbi test * * Copyright (C) 2000, 2001 Michael H. Schimek * * 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* $Id: explist.c,v 1.10 2006/02/10 06:25:38 mschimek Exp $ */ #undef NDEBUG #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #ifdef HAVE_GETOPT_LONG #include #endif #include #include "src/libzvbi.h" #ifndef _ #ifdef ENABLE_NLS # include # define _(String) dgettext (PACKAGE, String) # ifdef gettext_noop # define N_(String) gettext_noop (String) # else # define N_(String) (String) # endif #else /* Stubs that do something close enough. */ # define textdomain(String) (String) # define gettext(String) (String) # define dgettext(Domain,Message) (Message) # define dcgettext(Domain,Message,Type) (Message) # define bindtextdomain(Domain,Directory) (Domain) # define _(String) (String) # define N_(String) (String) #endif #endif vbi_bool check = FALSE; #define TYPE_STR(type) case type : type_str = #type ; break #define INT_TYPE(oi) ((oi)->type == VBI_OPTION_BOOL \ || (oi)->type == VBI_OPTION_INT \ || (oi)->type == VBI_OPTION_MENU) #define REAL_TYPE(oi) ((oi)->type == VBI_OPTION_REAL) #define MENU_TYPE(oi) ((oi)->menu.str != NULL) #define ASSERT_ERRSTR(expr) \ do { \ if (!(expr)) { \ printf("Assertion '" #expr "' failed; errstr=\"%s\"\n", \ vbi_export_errstr(ex)); \ exit(EXIT_FAILURE); \ } \ } while (0) #define BOUNDS_CHECK(type) \ do { \ if (oi->menu.type) { \ assert(oi->def.num >= 0); \ assert(oi->def.num <= oi->max.num); \ assert(oi->min.num == 0); \ assert(oi->max.num > 0); \ assert(oi->step.num == 1); \ } else { \ assert(oi->max.type >= oi->min.type); \ assert(oi->step.type > 0); \ assert(oi->def.type >= oi->min.type \ && oi->def.type <= oi->max.type); \ } \ } while (0) #define STRING_CHECK(type) \ do { \ if (oi->menu.type) { \ assert(oi->def.num >= 0); \ assert(oi->def.num <= oi->max.num); \ assert(oi->min.num == 0); \ assert(oi->max.num > 0); \ assert(oi->step.num == 1); \ } else { \ assert(oi->def.str != NULL); \ } \ } while (0) static void keyword_check(char *keyword) { int i, l; assert(keyword != NULL); l = strlen(keyword); assert(strlen(keyword) > 0); for (i = 0; i < l; i++) { if (isalnum(keyword[i])) continue; if (strchr("_", keyword[i])) continue; fprintf(stderr, "Bad keyword: '%s'\n", keyword); exit(EXIT_FAILURE); } } static void print_current(vbi_option_info *oi, vbi_option_value current) { if (REAL_TYPE(oi)) { printf(" current value=%f\n", current.dbl); if (!oi->menu.dbl) assert(current.dbl >= oi->min.dbl && current.dbl <= oi->max.dbl); } else { printf(" current value=%d\n", current.num); if (!oi->menu.num) assert(current.num >= oi->min.num && current.num <= oi->max.num); } } static void test_modified(vbi_option_info *oi, vbi_option_value old, vbi_option_value new) { if (REAL_TYPE(oi)) { /* XXX unsafe */ if (old.dbl != new.dbl) { printf("but modified current value to %f\n", new.dbl); exit(EXIT_FAILURE); } } else { if (old.num != new.num) { printf("but modified current value to %d\n", new.num); exit(EXIT_FAILURE); } } } static void test_set_int(vbi_export *ex, vbi_option_info *oi, vbi_option_value *current, int value) { vbi_option_value new_current; vbi_bool r; printf(" try to set %d: ", value); r = vbi_export_option_set(ex, oi->keyword, value); if (r) printf("success."); else printf("failed, errstr=\"%s\".", vbi_export_errstr(ex)); new_current.num = 0x54321; if (!vbi_export_option_get(ex, oi->keyword, &new_current)) { printf("vbi_export_option_get failed, errstr==\"%s\"\n", vbi_export_errstr(ex)); if (new_current.num != 0x54321) printf("but modified destination to %d\n", new_current.num); exit(EXIT_FAILURE); } if (!r) test_modified(oi, *current, new_current); print_current(oi, *current = new_current); } static void test_set_real(vbi_export *ex, vbi_option_info *oi, vbi_option_value *current, double value) { vbi_option_value new_current; vbi_bool r; printf(" try to set %f: ", value); r = vbi_export_option_set(ex, oi->keyword, value); if (r) printf("success."); else printf("failed, errstr=\"%s\".", vbi_export_errstr(ex)); new_current.dbl = 8192.0; if (!vbi_export_option_get(ex, oi->keyword, &new_current)) { printf("vbi_export_option_get failed, errstr==\"%s\"\n", vbi_export_errstr(ex)); /* XXX unsafe */ if (new_current.dbl != 8192.0) printf("but modified destination to %f\n", new_current.dbl); exit(EXIT_FAILURE); } if (!r) test_modified(oi, *current, new_current); print_current(oi, *current = new_current); } static void test_set_entry(vbi_export *ex, vbi_option_info *oi, vbi_option_value *current, int entry) { vbi_option_value new_current; int new_entry; vbi_bool r0, r1; vbi_bool valid; valid = (MENU_TYPE(oi) && entry >= oi->min.num && entry <= oi->max.num); printf(" try to set menu entry %d: ", entry); r0 = vbi_export_option_menu_set(ex, oi->keyword, entry); switch (r0 = r0 * 2 + valid) { case 0: printf("failed as expected, errstr=\"%s\".", vbi_export_errstr(ex)); break; case 1: printf("failed, errstr=\"%s\".", vbi_export_errstr(ex)); break; case 2: printf("unexpected success."); break; default: printf("success."); } ASSERT_ERRSTR(vbi_export_option_get(ex, oi->keyword, &new_current)); if (r0 == 0 || r0 == 1) test_modified(oi, *current, new_current); valid = MENU_TYPE(oi); new_entry = 0x33333; r1 = vbi_export_option_menu_get(ex, oi->keyword, &new_entry); switch (r1 = r1 * 2 + valid) { case 1: printf("\nvbi_export_option_menu_get failed, errstr==\"%s\"\n", vbi_export_errstr(ex)); break; case 2: printf("\nvbi_export_option_menu_get: unexpected success.\n"); break; default: break; } if ((r1 == 0 || r1 == 1) && new_entry != 0x33333) { printf("vbi_export_option_menu_get failed, " "but modified destination to %d\n", new_current.num); exit(EXIT_FAILURE); } if (r0 == 1 || r0 == 2 || r1 == 1 || r1 == 2) exit(EXIT_FAILURE); switch (oi->type) { case VBI_OPTION_BOOL: case VBI_OPTION_INT: if (oi->menu.num) assert(new_current.num == oi->menu.num[new_entry]); else test_modified(oi, *current, new_current); print_current(oi, *current = new_current); break; case VBI_OPTION_REAL: if (oi->menu.dbl) { /* XXX unsafe */ assert(new_current.dbl == oi->menu.dbl[new_entry]); } else { test_modified(oi, *current, new_current); } print_current(oi, *current = new_current); break; case VBI_OPTION_MENU: print_current(oi, *current = new_current); break; default: assert(!"reached"); break; } } static void dump_option_info(vbi_export *ex, vbi_option_info *oi) { vbi_option_value val; char *type_str; int i; switch (oi->type) { TYPE_STR(VBI_OPTION_BOOL); TYPE_STR(VBI_OPTION_INT); TYPE_STR(VBI_OPTION_REAL); TYPE_STR(VBI_OPTION_STRING); TYPE_STR(VBI_OPTION_MENU); default: printf(" * Option %s has invalid type %d\n", oi->keyword, oi->type); exit(EXIT_FAILURE); } printf(" * type=%s keyword=%s label=\"%s\" tooltip=\"%s\"\n", type_str, oi->keyword, _(oi->label), _(oi->tooltip)); keyword_check(oi->keyword); switch (oi->type) { case VBI_OPTION_BOOL: case VBI_OPTION_INT: BOUNDS_CHECK(num); if (oi->menu.num) { printf(" %d menu entries, default=%d: ", oi->max.num - oi->min.num + 1, oi->def.num); for (i = oi->min.num; i <= oi->max.num; i++) printf("%d%s", oi->menu.num[i], (i < oi->max.num) ? ", " : ""); printf("\n"); } else printf(" default=%d, min=%d, max=%d, step=%d\n", oi->def.num, oi->min.num, oi->max.num, oi->step.num); ASSERT_ERRSTR(vbi_export_option_get(ex, oi->keyword, &val)); print_current(oi, val); if (check) { if (oi->menu.num) { test_set_entry(ex, oi, &val, oi->min.num); test_set_entry(ex, oi, &val, oi->max.num); test_set_entry(ex, oi, &val, oi->min.num - 1); test_set_entry(ex, oi, &val, oi->max.num + 1); test_set_int(ex, oi, &val, oi->menu.num[oi->min.num]); test_set_int(ex, oi, &val, oi->menu.num[oi->max.num]); test_set_int(ex, oi, &val, oi->menu.num[oi->min.num] - 1); test_set_int(ex, oi, &val, oi->menu.num[oi->max.num] + 1); } else { test_set_entry(ex, oi, &val, 0); test_set_int(ex, oi, &val, oi->min.num); test_set_int(ex, oi, &val, oi->max.num); test_set_int(ex, oi, &val, oi->min.num - 1); test_set_int(ex, oi, &val, oi->max.num + 1); } } break; case VBI_OPTION_REAL: BOUNDS_CHECK(dbl); if (oi->menu.dbl) { printf(" %d menu entries, default=%d: ", oi->max.num - oi->min.num + 1, oi->def.num); for (i = oi->min.num; i <= oi->max.num; i++) printf("%f%s", oi->menu.dbl[i], (i < oi->max.num) ? ", " : ""); } else printf(" default=%f, min=%f, max=%f, step=%f\n", oi->def.dbl, oi->min.dbl, oi->max.dbl, oi->step.dbl); ASSERT_ERRSTR(vbi_export_option_get(ex, oi->keyword, &val)); print_current(oi, val); if (check) { if (oi->menu.num) { test_set_entry(ex, oi, &val, oi->min.num); test_set_entry(ex, oi, &val, oi->max.num); test_set_entry(ex, oi, &val, oi->min.num - 1); test_set_entry(ex, oi, &val, oi->max.num + 1); test_set_real(ex, oi, &val, oi->menu.dbl[oi->min.num]); test_set_real(ex, oi, &val, oi->menu.dbl[oi->max.num]); test_set_real(ex, oi, &val, oi->menu.dbl[oi->min.num] - 1); test_set_real(ex, oi, &val, oi->menu.dbl[oi->max.num] + 1); } else { test_set_entry(ex, oi, &val, 0); test_set_real(ex, oi, &val, oi->min.dbl); test_set_real(ex, oi, &val, oi->max.dbl); test_set_real(ex, oi, &val, oi->min.dbl - 1); test_set_real(ex, oi, &val, oi->max.dbl + 1); } } break; case VBI_OPTION_STRING: if (oi->menu.str) { STRING_CHECK(str); printf(" %d menu entries, default=%d: ", oi->max.num - oi->min.num + 1, oi->def.num); for (i = oi->min.num; i <= oi->max.num; i++) printf("%s%s", oi->menu.str[i], (i < oi->max.num) ? ", " : ""); } else printf(" default=\"%s\"\n", oi->def.str); ASSERT_ERRSTR(vbi_export_option_get(ex, oi->keyword, &val)); printf(" current value=\"%s\"\n", val.str); assert(val.str); free(val.str); if (check) { printf(" try to set \"foobar\": "); if (vbi_export_option_set(ex, oi->keyword, "foobar")) printf("success."); else printf("failed, errstr=\"%s\".", vbi_export_errstr(ex)); ASSERT_ERRSTR(vbi_export_option_get(ex, oi->keyword, &val)); printf(" current value=\"%s\"\n", val.str); assert(val.str); free(val.str); } break; case VBI_OPTION_MENU: printf(" %d menu entries, default=%d: ", oi->max.num - oi->min.num + 1, oi->def.num); for (i = oi->min.num; i <= oi->max.num; i++) { assert(oi->menu.str[i] != NULL); printf("%s%s", _(oi->menu.str[i]), (i < oi->max.num) ? ", " : ""); } printf("\n"); ASSERT_ERRSTR(vbi_export_option_get(ex, oi->keyword, &val)); print_current(oi, val); if (check) { test_set_entry(ex, oi, &val, oi->min.num); test_set_entry(ex, oi, &val, oi->max.num); test_set_entry(ex, oi, &val, oi->min.num - 1); test_set_entry(ex, oi, &val, oi->max.num + 1); } break; default: assert(!"reached"); break; } } static void list_options(vbi_export *ex) { vbi_option_info *oi; int i; puts(" List of options:"); for (i = 0; (oi = vbi_export_option_info_enum(ex, i)); i++) { assert(oi->keyword != NULL); ASSERT_ERRSTR(oi == vbi_export_option_info_keyword(ex, oi->keyword)); dump_option_info(ex, oi); } } static void list_modules(void) { vbi_export_info *xi; vbi_export *ex; char *errstr; int i; puts("List of export modules:"); for (i = 0; (xi = vbi_export_info_enum(i)); i++) { assert(xi->keyword != NULL); assert(xi == vbi_export_info_keyword(xi->keyword)); printf("* keyword=%s label=\"%s\"\n" " tooltip=\"%s\" mime_type=%s extension=%s\n", xi->keyword, _(xi->label), _(xi->tooltip), xi->mime_type, xi->extension); keyword_check(xi->keyword); if (!(ex = vbi_export_new(xi->keyword, &errstr))) { printf("Could not open '%s': %s\n", xi->keyword, errstr); exit(EXIT_FAILURE); } ASSERT_ERRSTR(xi == vbi_export_info_export(ex)); list_options(ex); vbi_export_delete(ex); } puts("-- end of list --"); } static const char short_options[] = "c"; #ifdef HAVE_GETOPT_LONG static const struct option long_options[] = { { "check", no_argument, NULL, 'c' }, { 0, 0, 0, 0 } }; #else #define getopt_long(ac, av, s, l, i) getopt(ac, av, s) #endif int main(int argc, char **argv) { int index, c; setlocale (LC_ALL, ""); textdomain ("foobar"); /* we are not the library */ while ((c = getopt_long(argc, argv, short_options, long_options, &index)) != -1) switch (c) { case 'c': check = TRUE; break; default: fprintf(stderr, "Unknown option\n"); exit(EXIT_FAILURE); } list_modules(); exit(EXIT_SUCCESS); }