555 lines
14 KiB
C
555 lines
14 KiB
C
/*
|
|
* 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., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*/
|
|
|
|
/* $Id: explist.c,v 1.13 2008/03/01 07:36:54 mschimek Exp $ */
|
|
|
|
#undef NDEBUG
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include <assert.h>
|
|
#include <unistd.h>
|
|
#ifdef HAVE_GETOPT_LONG
|
|
#include <getopt.h>
|
|
#endif
|
|
#include <locale.h>
|
|
|
|
#include "src/libzvbi.h"
|
|
|
|
#ifndef _
|
|
#ifdef ENABLE_NLS
|
|
# include <libintl.h>
|
|
# 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;
|
|
const 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);
|
|
}
|