Main Page | Modules | Data Structures | Data Fields | Related Pages | Examples

src/exp-templ.c

Template for internal export module.

/*
 *  Template for export modules
 */

/* $Id: exp-templ.c,v 1.10 2007/11/27 18:26:32 mschimek Exp $ */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <limits.h>

#include "export.h"

typedef struct tmpl_instance
{
        /* Common to all export modules */
        vbi_export              export;

        /* Our private stuff */

        /* Options */
        int                     flip;
        int                     day;
        int                     prime;
        double                  quality;
        char *                  comment;
        int                     weekday;

        int                     counter;
} tmpl_instance;

/* Safer than tmpl_instance *tmpl = (tmpl_instance *)(vbi_export *) e */
#define TMPL(e) PARENT(e, tmpl_instance, export);

static vbi_export *
tmpl_new(void)
{
        tmpl_instance *tmpl;

        if (!(tmpl = calloc(1, sizeof(*tmpl))))
                return NULL;

        /*
         *  The caller will initialize tmpl->export.class for us
         *  and reset all options to their defaults, we only
         *  have to initialize our private stuff.
         */

        tmpl->counter = 0;

        return &tmpl->export;
}

static void
tmpl_delete(vbi_export *e)
{
        tmpl_instance *tmpl = TMPL(e);

        /* Uninitialize our private stuff and options */

        if (tmpl->comment)
                free(tmpl->comment);

        free(tmpl);
}

/* convenience */
#define elements(array) (sizeof(array) / sizeof(array[0]))

/* N_(), _() are NLS functions, see info gettext. */
static const char *
string_menu_items[] = {
        N_("Sunday"), N_("Monday"), N_("Tuesday"),
        N_("Wednesday"), N_("Thursday"), N_("Friday"), N_("Saturday")
};

static int
int_menu_items[] = {
        1, 3, 5, 7, 11, 13, 17, 19
};

static vbi_option_info
tmpl_options[] = {
        VBI_OPTION_BOOL_INITIALIZER
          /*
           *  Option keywords must be unique within their module
           *  and shall contain only "AZaz09_" (be filesystem safe that is).
           *  Note "network", "creator" and "reveal" are reserved generic
           *  options, filtered by the export api functions.
           */
          ("flip", N_("Boolean option"),
           FALSE, N_("This is a boolean option")),
        VBI_OPTION_INT_RANGE_INITIALIZER
          ("day", N_("Select a month day"),
           /* default, min, max, step, has no tooltip */
              13,       1,   31,  1,      NULL),
        VBI_OPTION_INT_MENU_INITIALIZER
          ("prime", N_("Select a prime"),
           0, int_menu_items, elements(int_menu_items),
           N_("Default is the first, '1'")),
        VBI_OPTION_REAL_RANGE_INITIALIZER
          ("quality", N_("Compression quality"),
           100, 1, 100, 0.01, NULL),
        /* VBI_OPTION_REAL_MENU_INITIALIZER like int */
        VBI_OPTION_STRING_INITIALIZER
          ("comment", N_("Add a comment"),
           "default comment", N_("Another tooltip")),
        VBI_OPTION_MENU_INITIALIZER
          ("weekday", N_("Select a weekday"),
           2, string_menu_items, 7, N_("Default is Tuesday"))
};

/*
 *  Enumerate our options (optional if we have no options).
 *  Instead of using a table one could also dynamically create
 *  vbi_option_info's in tmpl_instance.
 */
static vbi_option_info *
option_enum(vbi_export *e, int index)
{
        e = e;

        /* Enumeration 0 ... n */
        if (index < 0 || index >= (int) elements(tmpl_options))
                return NULL;

        return tmpl_options + index;
}

#define KEYWORD(str) (strcmp(keyword, str) == 0)

/*
 *  Get an option (optional if we have no options).
 */
static vbi_bool
option_get(vbi_export *e, const char *keyword, vbi_option_value *value)
{
        tmpl_instance *tmpl = TMPL(e);

        if (KEYWORD("flip")) {
                value->num = tmpl->flip;
        } else if (KEYWORD("day")) {
                value->num = tmpl->day;
        } else if (KEYWORD("prime")) {
                value->num = tmpl->prime;
        } else if (KEYWORD("quality")) {
                value->dbl = tmpl->quality;
        } else if (KEYWORD("comment")) {
                if (!(value->str = vbi_export_strdup(e, NULL,
                        tmpl->comment ? tmpl->comment : "")))
                        return FALSE;
        } else if (KEYWORD("weekday")) {
                value->num = tmpl->weekday;
        } else {
                vbi_export_unknown_option(e, keyword);
                return FALSE;
        }

        return TRUE; /* success */
}

/*
 *  Set an option (optional if we have no options).
 */
static vbi_bool
option_set(vbi_export *e, const char *keyword, va_list args)
{
        tmpl_instance *tmpl = TMPL(e);

        if (KEYWORD("flip")) {
                tmpl->flip = !!va_arg(args, int);
        } else if (KEYWORD("day")) {
                int day = va_arg(args, int);

                /* or clamp */
                if (day < 1 || day > 31) {
                        vbi_export_invalid_option(e, keyword, day);
                        return FALSE;
                }

                tmpl->day = day;

        } else if (KEYWORD("prime")) {
                unsigned int i;
                unsigned int d, dmin = UINT_MAX;
                int value = va_arg(args, int);

                /* or return an error */
                for (i = 0; i < elements(int_menu_items); i++)
                        if ((d = abs(int_menu_items[i] - value)) < dmin) {
                                tmpl->prime = int_menu_items[i];
                                dmin = d;
                        }

        } else if (KEYWORD("quality")) {
                double quality = va_arg(args, double);

                /* or return an error */
                if (quality < 1)
                        quality = 1;
                else if (quality > 100)
                        quality = 100;

                tmpl->quality = quality;
        } else if (KEYWORD("comment")) {
                char *comment = va_arg(args, char *);

                /* Note the option remains unchanged in case of error */
                if (!vbi_export_strdup(e, &tmpl->comment, comment))
                        return FALSE;
        } else if (KEYWORD("weekday")) {
                int day = va_arg(args, int);

                /* or return an error */
                tmpl->weekday = day % 7;
        } else {
                vbi_export_unknown_option(e, keyword);
                return FALSE;
        }

        return TRUE; /* success */
}

/*
 *  The output function, mandatory.
 */
static vbi_bool
export(vbi_export *e, vbi_page *pg)
{
        tmpl_instance *tmpl = TMPL(e);

        /* Write pg to target, that's all. */
        vbi_export_printf (e, "Page %x.%x\n", pg->pgno, pg->subno);

        tmpl->counter++; /* just for fun */

        /*
         *  Should any of the module functions return unsuccessful
         *  they better post a description of the problem.
         *  Parameters like printf, no linefeeds '\n' please.
         */
        /*
        vbi_export_error_printf(_("Writing failed: %s"), strerror(errno));
         */

        return FALSE; /* no success (since we didn't write anything) */
}

/*
 *  Let's describe us.
 *  You can leave away assignments unless mandatory.
 */
static vbi_export_info
info_tmpl = {
        /* The mandatory keyword must be unique and shall
           contain only "AZaz09_" */
        .keyword        = "templ",
        /* When omitted this module can still be used by
           libzvbi clients but won't be listed in a UI. */
        .label          = N_("Template"),
        .tooltip        = N_("This is just an export template"),

        .mime_type      = "misc/example",
        .extension      = "tmpl",
};

vbi_export_class
vbi_export_class_tmpl = {
        ._public                = &info_tmpl,

        /* Functions to allocate and free a tmpl_class vbi_export instance.
           When you omit these, libzvbi will allocate a bare struct vbi_export */
        ._new                   = tmpl_new,
        ._delete                = tmpl_delete,

        /* Functions to enumerate, read and write options */
        .option_enum            = option_enum,
        .option_get             = option_get,
        .option_set             = option_set,

        /* Function to export a page, mandatory */
        .export                 = export
};

/*
 *  This is a constructor calling vbi_register_export_module().
 *  (Commented out since we don't want to register the example module.)
 */
#if 0
VBI_AUTOREG_EXPORT_MODULE(vbi_export_class_tmpl)
#endif

/*
Local variables:
c-set-style: K&R
c-basic-offset: 8
End:
*/

Generated on Wed Jun 11 04:41:21 2008 for ZVBI Library by  doxygen 1.3.9.1