output: Modernize how drivers are initialized.
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 6 Feb 2023 16:17:45 +0000 (08:17 -0800)
committerBen Pfaff <blp@cs.stanford.edu>
Tue, 7 Feb 2023 18:05:35 +0000 (10:05 -0800)
14 files changed:
src/output/ascii.c
src/output/cairo.c
src/output/csv.c
src/output/driver-provider.h
src/output/driver.c
src/output/html.c
src/output/journal.c
src/output/msglog.c
src/output/odt.c
src/output/options.c
src/output/options.h
src/output/spv-driver.c
src/output/tex.c
src/ui/gui/psppire-output-window.c

index e654691cd65209356399e28f16044ef5a55f7834..b94d4941c2362d05a198e844e9685d02bce79e7b 100644 (file)
@@ -278,13 +278,20 @@ box_get (const struct box_chars *box,
   return box->c[right][bottom][left][top];
 }
 
+/* How the page width is determined. */
+enum ascii_width_mode
+  {
+    FIXED_WIDTH,              /* Specified by configuration. */
+    VIEW_WIDTH,               /* From SET WIDTH. */
+    TERMINAL_WIDTH            /* From the terminal's width. */
+  };
+
 /* ASCII output driver. */
 struct ascii_driver
   {
     struct output_driver driver;
 
     /* User parameters. */
-    bool append;                /* Append if output file already exists? */
     bool emphasis;              /* Enable bold and underline in output? */
     char *chart_file_name;      /* Name of files used for charts. */
 
@@ -293,11 +300,7 @@ struct ascii_driver
     struct cell_color bg;
 
     /* How the page width is determined: */
-    enum {
-      FIXED_WIDTH,              /* Specified by configuration. */
-      VIEW_WIDTH,               /* From SET WIDTH. */
-      TERMINAL_WIDTH            /* From the terminal's width. */
-    } width_mode;
+    enum ascii_width_mode width_mode;
     int width;                  /* Page width. */
 
     int min_hbreak;             /* Min cell size to break across pages. */
@@ -344,10 +347,9 @@ ascii_driver_cast (struct output_driver *driver)
 }
 
 static struct driver_option *
-opt (struct output_driver *d, struct string_map *options, const char *key,
-     const char *default_value)
+opt (struct string_map *options, const char *key, const char *default_value)
 {
-  return driver_option_get (d, options, key, default_value);
+  return driver_option_get ("ascii", options, key, default_value);
 }
 
 /* Return true iff the terminal appears to be an xterm with
@@ -367,43 +369,25 @@ static struct output_driver *
 ascii_create (struct  file_handle *fh, enum settings_output_devices device_type,
               struct string_map *o)
 {
-  enum { BOX_ASCII, BOX_UNICODE } box;
-  struct output_driver *d;
-  struct ascii_driver *a = XZALLOC (struct ascii_driver);
-  d = &a->driver;
-  output_driver_init (&a->driver, &ascii_driver_class, fh_get_file_name (fh), device_type);
-  a->append = parse_boolean (opt (d, o, "append", "false"));
-  a->emphasis = parse_boolean (opt (d, o, "emphasis", "false"));
-
-  a->chart_file_name = parse_chart_file_name (opt (d, o, "charts", fh_get_file_name (fh)));
-  a->handle = fh;
-
+  bool append = parse_boolean (opt (o, "append", "false"));
+  FILE *file = fn_open (fh, append ? "a" : "w");
+  if (!file)
+    {
+      msg_error (errno, _("ascii: opening output file `%s'"),
+                 fh_get_file_name (fh));
+      return NULL;
+    }
 
+  int width = parse_page_size (opt (o, "width", "-1"));
   bool terminal = !strcmp (fh_get_file_name (fh), "-") && isatty (1);
-  a->width = parse_page_size (opt (d, o, "width", "-1"));
-  a->width_mode = (a->width > 0 ? FIXED_WIDTH
-                   : terminal ? TERMINAL_WIDTH
-                   : VIEW_WIDTH);
-  a->min_hbreak = parse_int (opt (d, o, "min-hbreak", "-1"), -1, INT_MAX);
-
-  a->bg = parse_color (opt (d, o, "background-color", "#FFFFFFFFFFFF"));
-  a->fg = parse_color (opt (d, o, "foreground-color", "#000000000000"));
 
   const char *default_box = (terminal && (!strcmp (locale_charset (), "UTF-8")
                                           || term_is_utf8_xterm ())
                              ? "unicode" : "ascii");
-  box = parse_enum (opt (d, o, "box", default_box),
-                    "ascii", BOX_ASCII,
-                    "unicode", BOX_UNICODE,
-                    NULL_SENTINEL);
-  a->box = box == BOX_ASCII ? get_ascii_box () : get_unicode_box ();
-
-  a->file = NULL;
-  a->error = false;
-  a->lines = NULL;
-  a->allocated_lines = 0;
-  a->n_charts = 0;
-  a->n_objects = 0;
+  enum { BOX_ASCII, BOX_UNICODE } box = parse_enum (opt (o, "box", default_box),
+                                                    "ascii", BOX_ASCII,
+                                                    "unicode", BOX_UNICODE,
+                                                    NULL_SENTINEL);
 
   static const struct render_ops ascii_render_ops = {
     .draw_line = ascii_draw_line,
@@ -412,12 +396,6 @@ ascii_create (struct  file_handle *fh, enum settings_output_devices device_type,
     .adjust_break = NULL,
     .draw_cell = ascii_draw_cell,
   };
-  a->params.ops = &ascii_render_ops;
-  a->params.aux = a;
-  a->params.size[H] = a->width;
-  a->params.size[V] = INT_MAX;
-  a->params.font_size[H] = 1;
-  a->params.font_size[V] = 1;
 
   static const int ascii_line_widths[TABLE_N_STROKES] = {
     [TABLE_STROKE_NONE] = 0,
@@ -427,26 +405,52 @@ ascii_create (struct  file_handle *fh, enum settings_output_devices device_type,
     [TABLE_STROKE_THIN] = 1,
     [TABLE_STROKE_DOUBLE] = 1,
   };
-  a->params.line_widths = ascii_line_widths;
-  a->params.supports_margins = false;
-  a->params.rtl = render_direction_rtl ();
-  a->params.printing = true;
+
+  struct ascii_driver *a = xmalloc (sizeof *a);
+  *a = (struct ascii_driver) {
+    .driver = {
+      .class = &ascii_driver_class,
+      .name = xstrdup (fh_get_file_name (fh)),
+      .device_type = device_type
+    },
+
+    .emphasis = parse_boolean (opt (o, "emphasis", "false")),
+    .chart_file_name = parse_chart_file_name (opt (o, "charts",
+                                                   fh_get_file_name (fh))),
+
+    .fg = parse_color (opt (o, "foreground-color", "#000000000000")),
+    .bg = parse_color (opt (o, "background-color", "#FFFFFFFFFFFF")),
+
+    .width_mode = (width > 0 ? FIXED_WIDTH
+                   : terminal ? TERMINAL_WIDTH
+                   : VIEW_WIDTH),
+    .width = width,
+
+    .min_hbreak = parse_int (opt (o, "min-hbreak", "-1"), -1, INT_MAX),
+
+    .box = box == BOX_ASCII ? get_ascii_box () : get_unicode_box (),
+
+    .handle = fh,
+    .file = file,
+
+    .params = (struct render_params) {
+      .ops = &ascii_render_ops,
+      .aux = a,
+      .size = { [H] = a->width, [V] = INT_MAX },
+      .font_size = { [H] = 1, [V] = 1 },
+      .line_widths = ascii_line_widths,
+      .rtl = render_direction_rtl (),
+      .printing = true,
+    },
+  };
 
   if (!update_page_size (a, true))
     goto error;
 
-  a->file = fn_open (a->handle, a->append ? "a" : "w");
-  if (!a->file)
-    {
-      msg_error (errno, _("ascii: opening output file `%s'"),
-                 fh_get_file_name (a->handle));
-      goto error;
-    }
-
-  return d;
+  return &a->driver;
 
 error:
-  output_driver_destroy (d);
+  output_driver_destroy (&a->driver);
   return NULL;
 }
 
index a08771bb449ae68cb2d0d126c3c439a0e2907395..da224346f83f1e3a4db63503a3629247a2714865 100644 (file)
@@ -130,10 +130,9 @@ xr_driver_cast (struct output_driver *driver)
 }
 
 static struct driver_option *
-opt (struct output_driver *d, struct string_map *options, const char *key,
-     const char *default_value)
+opt (struct string_map *options, const char *key, const char *default_value)
 {
-  return driver_option_get (d, options, key, default_value);
+  return driver_option_get ("cairo", options, key, default_value);
 }
 
 static PangoFontDescription *
@@ -163,11 +162,11 @@ parse_font (const char *font, int default_size, bool bold, bool italic)
 }
 
 static PangoFontDescription *
-parse_font_option (struct output_driver *d, struct string_map *options,
+parse_font_option (struct string_map *options,
                    const char *key, const char *default_value,
                    int default_size, bool bold, bool italic)
 {
-  char *string = parse_string (opt (d, options, key, default_value));
+  char *string = parse_string (opt (options, key, default_value));
   PangoFontDescription *desc = parse_font (string, default_size, bold, italic);
   if (!desc)
     {
@@ -187,55 +186,49 @@ static struct xr_driver *
 xr_allocate (const char *name, int device_type,
              enum xr_output_type output_type, struct string_map *o)
 {
-  struct xr_driver *xr = XZALLOC (struct xr_driver);
-  struct output_driver *d = &xr->driver;
-
-  output_driver_init (d, &cairo_driver_class, name, device_type);
-  xr->output_type = output_type;
-
   /* Scale factor from inch/72000 to inch/(72 * XR_POINT). */
   const double scale = XR_POINT / 1000.;
 
   int paper[TABLE_N_AXES];
-  parse_paper_size (opt (d, o, "paper-size", ""), &paper[H], &paper[V]);
+  parse_paper_size (opt (o, "paper-size", ""), &paper[H], &paper[V]);
   for (int a = 0; a < TABLE_N_AXES; a++)
     paper[a] *= scale;
 
   int margins[TABLE_N_AXES][2];
-  margins[H][0] = parse_dimension (opt (d, o, "left-margin", ".5in")) * scale;
-  margins[H][1] = parse_dimension (opt (d, o, "right-margin", ".5in")) * scale;
-  margins[V][0] = parse_dimension (opt (d, o, "top-margin", ".5in")) * scale;
-  margins[V][1] = parse_dimension (opt (d, o, "bottom-margin", ".5in")) * scale;
+  margins[H][0] = parse_dimension (opt (o, "left-margin", ".5in")) * scale;
+  margins[H][1] = parse_dimension (opt (o, "right-margin", ".5in")) * scale;
+  margins[V][0] = parse_dimension (opt (o, "top-margin", ".5in")) * scale;
+  margins[V][1] = parse_dimension (opt (o, "bottom-margin", ".5in")) * scale;
 
   int size[TABLE_N_AXES];
   for (int a = 0; a < TABLE_N_AXES; a++)
     size[a] = paper[a] - margins[a][0] - margins[a][1];
 
   int min_break[TABLE_N_AXES];
-  min_break[H] = parse_dimension (opt (d, o, "min-hbreak", NULL)) * scale;
-  min_break[V] = parse_dimension (opt (d, o, "min-vbreak", NULL)) * scale;
+  min_break[H] = parse_dimension (opt (o, "min-hbreak", NULL)) * scale;
+  min_break[V] = parse_dimension (opt (o, "min-vbreak", NULL)) * scale;
   for (int a = 0; a < TABLE_N_AXES; a++)
     if (min_break[a] <= 0)
       min_break[a] = size[a] / 2;
 
-  int font_size = parse_int (opt (d, o, "font-size", "10000"), 1000, 1000000);
+  int font_size = parse_int (opt (o, "font-size", "10000"), 1000, 1000000);
   PangoFontDescription *font = parse_font_option (
-    d, o, "prop-font", "Sans Serif", font_size, false, false);
+    o, "prop-font", "Sans Serif", font_size, false, false);
 
-  struct cell_color fg = parse_color (opt (d, o, "foreground-color", "black"));
+  struct cell_color fg = parse_color (opt (o, "foreground-color", "black"));
 
-  bool systemcolors = parse_boolean (opt (d, o, "systemcolors", "false"));
+  bool systemcolors = parse_boolean (opt (o, "systemcolors", "false"));
 
   int object_spacing
-    = parse_dimension (opt (d, o, "object-spacing", NULL)) * scale;
+    = parse_dimension (opt (o, "object-spacing", NULL)) * scale;
   if (object_spacing <= 0)
     object_spacing = XR_POINT * 12;
 
   const char *default_resolution = (output_type == XR_PNG ? "96" : "72");
-  int font_resolution = parse_int (opt (d, o, "font-resolution",
+  int font_resolution = parse_int (opt (o, "font-resolution",
                                         default_resolution), 10, 1000);
 
-  xr->trim = parse_boolean (opt (d, o, "trim", "false"));
+  bool trim = parse_boolean (opt (o, "trim", "false"));
 
   /* Cairo 1.16.0 has a bug that causes crashes if outlines are enabled at the
      same time as trimming:
@@ -243,10 +236,10 @@ xr_allocate (const char *name, int device_type,
      For now, just disable the outline if trimming is enabled. */
   bool include_outline
     = (output_type == XR_PDF
-       && parse_boolean (opt (d, o, "outline", xr->trim ? "false" : "true")));
+       && parse_boolean (opt (o, "outline", trim ? "false" : "true")));
 
-  xr->page_style = xmalloc (sizeof *xr->page_style);
-  *xr->page_style = (struct xr_page_style) {
+  struct xr_page_style *page_style = xmalloc (sizeof *page_style);
+  *page_style = (struct xr_page_style) {
     .ref_cnt = 1,
 
     .margins = {
@@ -258,8 +251,8 @@ xr_allocate (const char *name, int device_type,
     .include_outline = include_outline,
   };
 
-  xr->fsm_style = xmalloc (sizeof *xr->fsm_style);
-  *xr->fsm_style = (struct xr_fsm_style) {
+  struct xr_fsm_style *fsm_style = xmalloc (sizeof *fsm_style);
+  *fsm_style = (struct xr_fsm_style) {
     .ref_cnt = 1,
     .size = { [H] = size[H], [V] = size[V] },
     .min_break = { [H] = min_break[H], [V] = min_break[V] },
@@ -270,6 +263,19 @@ xr_allocate (const char *name, int device_type,
     .font_resolution = font_resolution,
   };
 
+  struct xr_driver *xr = xmalloc (sizeof *xr);
+  *xr = (struct xr_driver) {
+    .driver = {
+      .class = &cairo_driver_class,
+      .name = xstrdup (name),
+      .device_type = device_type,
+    },
+    .output_type = output_type,
+    .fsm_style = fsm_style,
+    .page_style = page_style,
+    .trim = trim,
+  };
+
   return xr;
 }
 
index ba1481c9a0c44caf9ab2de9873b67aa2f49dd604..e63e828d4e7daf219a231fcb996220578d93d265 100644 (file)
@@ -66,42 +66,45 @@ csv_driver_cast (struct output_driver *driver)
 }
 
 static struct driver_option *
-opt (struct output_driver *d, struct string_map *options, const char *key,
-     const char *default_value)
+opt (struct string_map *options, const char *key, const char *default_value)
 {
-  return driver_option_get (d, options, key, default_value);
+  return driver_option_get ("csv", options, key, default_value);
 }
 
 static struct output_driver *
 csv_create (struct file_handle *fh, enum settings_output_devices device_type,
             struct string_map *o)
 {
-  struct output_driver *d;
-  char *quote;
-
-  struct csv_driver *csv = XZALLOC (struct csv_driver);
-  d = &csv->driver;
-  output_driver_init (&csv->driver, &csv_driver_class, fh_get_file_name (fh), device_type);
-
-  csv->separator = parse_string (opt (d, o, "separator", ","));
-  quote = parse_string (opt (d, o, "quote", "\""));
-  csv->quote = quote[0];
-  free (quote);
-  csv->quote_set = xasprintf ("\n\r\t%s%c", csv->separator, csv->quote);
-  csv->titles = parse_boolean (opt (d, o, "titles", "true"));
-  csv->captions = parse_boolean (opt (d, o, "captions", "true"));
-  csv->handle = fh;
-  csv->file = fn_open (fh, "w");
-  csv->n_items = 0;
-
-  if (csv->file == NULL)
+  FILE *file = fn_open (fh, "w");
+  if (!file)
     {
       msg_error (errno, _("error opening output file `%s'"), fh_get_file_name (fh));
-      output_driver_destroy (d);
       return NULL;
     }
 
-  return d;
+  char *quote_s = parse_string (opt (o, "quote", "\""));
+  int quote = quote_s[0];
+  free (quote_s);
+
+  char *separator = parse_string (opt (o, "separator", ","));
+
+  struct csv_driver *csv = xmalloc (sizeof *csv);
+  *csv = (struct csv_driver) {
+    .driver = {
+      .class = &csv_driver_class,
+      .name = xstrdup (fh_get_file_name (fh)),
+      .device_type = device_type,
+    },
+    .separator = separator,
+    .quote = quote,
+    .quote_set = xasprintf ("\n\r\t%s%c", separator, quote),
+    .titles = parse_boolean (opt (o, "titles", "true")),
+    .captions = parse_boolean (opt (o, "captions", "true")),
+    .handle = fh,
+    .file = file,
+  };
+
+  return &csv->driver;
 }
 
 static void
index 1f3f726949575adf2905086f125bf44cac2f6d53..d0a054e8e0ef5ca1396b6a9bf42962c786a40d85 100644 (file)
@@ -37,10 +37,6 @@ struct output_driver
     enum settings_output_devices device_type; /* One of SETTINGS_DEVICE_*. */
   };
 
-void output_driver_init (struct output_driver *,
-                         const struct output_driver_class *,
-                         const char *, enum settings_output_devices);
-
 void output_driver_destroy (struct output_driver *);
 
 const char *output_driver_get_name (const struct output_driver *);
index f627e31248d69c1398739bd369307ec94dcd86fc..92de2f5f176092254a775a8d33195b68f4c9939f 100644 (file)
@@ -411,16 +411,6 @@ output_set_filename (const char *filename)
   string_map_replace (&e->heading_vars, "Filename", filename);
 }
 \f
-void
-output_driver_init (struct output_driver *driver,
-                    const struct output_driver_class *class,
-                    const char *name, enum settings_output_devices type)
-{
-  driver->class = class;
-  driver->name = xstrdup (name);
-  driver->device_type = type;
-}
-
 void
 output_driver_destroy (struct output_driver *driver)
 {
index 6c5348a871df9f2a959bfda4d1b7d10d4f311043..0e6e8d822d71abedb0d761f702a5719c0aa42590 100644 (file)
@@ -85,10 +85,9 @@ html_driver_cast (struct output_driver *driver)
 }
 
 static struct driver_option *
-opt (struct output_driver *d, struct string_map *options, const char *key,
-     const char *default_value)
+opt (struct string_map *options, const char *key, const char *default_value)
 {
-  return driver_option_get (d, options, key, default_value);
+  return driver_option_get ("html", options, key, default_value);
 }
 
 static void
@@ -179,37 +178,37 @@ static struct output_driver *
 html_create (struct file_handle *fh, enum settings_output_devices device_type,
              struct string_map *o)
 {
-  struct output_driver *d;
-  struct html_driver *html = XZALLOC (struct html_driver);
-  d = &html->driver;
-  output_driver_init (&html->driver, &html_driver_class, fh_get_file_name (fh),
-                      device_type);
-  html->bare = parse_boolean (opt (d, o, "bare", "false"));
-  html->css = parse_boolean (opt (d, o, "css", "true"));
-  html->borders = parse_boolean (opt (d, o, "borders", "true"));
-
-  html->handle = fh;
-  html->chart_file_name = parse_chart_file_name (opt (d, o, "charts",
-                                                      fh_get_file_name (fh)));
-  html->file = NULL;
-  html->n_charts = 1;
-  html->bg = parse_color (opt (d, o, "background-color", "#FFFFFFFFFFFF"));
-  html->fg = parse_color (opt (d, o, "foreground-color", "#000000000000"));
-  html->file = fn_open (html->handle, "w");
-  if (html->file == NULL)
+  FILE *file = fn_open (fh, "w");
+  if (!file)
     {
-      msg_error (errno, _("error opening output file `%s'"), fh_get_file_name (html->handle));
-      goto error;
+      msg_error (errno, _("error opening output file `%s'"),
+                 fh_get_file_name (fh));
+      return NULL;
     }
 
+  struct html_driver *html = xmalloc (sizeof *html);
+  *html = (struct html_driver) {
+    .driver = {
+      .class = &html_driver_class,
+      .name = xstrdup (fh_get_file_name (fh)),
+      .device_type = device_type
+    },
+    .bare = parse_boolean (opt (o, "bare", "false")),
+    .css = parse_boolean (opt (o, "css", "true")),
+    .borders = parse_boolean (opt (o, "borders", "true")),
+    .handle = fh,
+    .chart_file_name = parse_chart_file_name (opt (o, "charts",
+                                                   fh_get_file_name (fh))),
+    .file = file,
+    .n_charts = 1,
+    .bg = parse_color (opt (o, "background-color", "#FFFFFFFFFFFF")),
+    .fg = parse_color (opt (o, "foreground-color", "#000000000000")),
+  };
+
   if (!html->bare)
     put_header (html);
 
-  return d;
-
- error:
-  output_driver_destroy (d);
-  return NULL;
+  return &html->driver;
 }
 
 /* Emits <NAME>CONTENT</NAME> to the output, escaping CONTENT as
index a07fd4a094fdc1f213e82c67f965f14eb570973a..f708e6d787cb40b9090af06e552a6b79c9892dbd 100644 (file)
@@ -140,16 +140,16 @@ static const struct output_driver_class journal_class =
 void
 journal_init (void)
 {
-  /* Create journal driver. */
-  output_driver_init (&journal.driver, &journal_class, "journal",
-                     SETTINGS_DEVICE_UNFILTERED);
-  journal.file = NULL;
+  journal = (struct journal_driver) {
+    .driver = {
+      .class = &journal_class,
+      .name = xstrdup ("journal"),
+      .device_type = SETTINGS_DEVICE_UNFILTERED,
+    }
+  };
 
-  /* Register journal driver. */
   output_driver_register (&journal.driver);
-
   journal_enable ();
-  journal.destroyed = false;
 }
 
 /* Disables journaling. */
index 20cfe3a3b2a74384b9073a64bf8ea3daf9881189..3cb4dc38e90d83e7b6503c4d8271c0e5cae8a04d 100644 (file)
@@ -72,13 +72,17 @@ msglog_create (const char *file_name)
           ? SETTINGS_DEVICE_TERMINAL
           : SETTINGS_DEVICE_UNFILTERED);
 
-  struct msglog_driver *ml = XZALLOC (struct msglog_driver);
-  ml->handle = handle;
-  output_driver_init (&ml->driver, &msglog_class, file_name, type);
-  ml->file = file;
-
+  struct msglog_driver *ml = xmalloc (sizeof *ml);
+  *ml = (struct msglog_driver) {
+    .driver = {
+      .class = &msglog_class,
+      .name = xstrdup (file_name),
+      .device_type = type,
+    },
+    .file = file,
+    .handle = handle,
+  };
   output_driver_register (&ml->driver);
-
   return &ml->driver;
 }
 
index abb30cb530c7c1c85b3edd46afdd825fbe573fe6..2f58586530ac78cb8b927656756797e360d26345 100644 (file)
@@ -284,22 +284,22 @@ static struct output_driver *
 odt_create (struct file_handle *fh, enum settings_output_devices device_type,
             struct string_map *o UNUSED)
 {
-  struct output_driver *d;
-  struct zip_writer *zip;
   const char *file_name = fh_get_file_name (fh);
-
-  zip = zip_writer_create (file_name);
+  struct zip_writer *zip = zip_writer_create (file_name);
   if (zip == NULL)
     return NULL;
 
-  struct odt_driver *odt = XZALLOC (struct odt_driver);
-  d = &odt->driver;
-
-  output_driver_init (d, &odt_driver_class, file_name, device_type);
-
-  odt->zip = zip;
-  odt->handle = fh;
-  odt->file_name = xstrdup (file_name);
+  struct odt_driver *odt = xmalloc (sizeof *odt);
+  *odt = (struct odt_driver) {
+    .driver = {
+      .class = &odt_driver_class,
+      .name = xstrdup (file_name),
+      .device_type = device_type,
+    },
+    .zip = zip,
+    .handle = fh,
+    .file_name = xstrdup (file_name),
+  };
 
   zip_writer_add_string (zip, "mimetype",
                          "application/vnd.oasis.opendocument.text");
@@ -351,7 +351,7 @@ odt_create (struct file_handle *fh, enum settings_output_devices device_type,
   zip_writer_add (odt->zip, odt->manifest_file, "META-INF/manifest.xml");
   close_temp_file (odt->manifest_file);
 
-  return d;
+  return &odt->driver;
 }
 
 static void
index a212d1c63ee5190c752a7a007087df6338c47087..23715c693204e6c4b6a21684880f604bafb223a7 100644 (file)
 #include "gettext.h"
 #define _(msgid) gettext (msgid)
 
-/* Creates and returns a new struct driver_option that contains copies of
-   all of the supplied arguments.  All of the arguments must be nonnull,
-   except that VALUE may be NULL (if the user did not supply a value for this
-   option).
-
-   Refer to struct driver_option for the meaning of each argument. */
-struct driver_option *
-driver_option_create (const char *driver_name, const char *name,
-                      const char *value, const char *default_value)
-{
-  struct driver_option *o = xmalloc (sizeof *o);
-  o->driver_name = xstrdup (driver_name);
-  o->name = xstrdup (name);
-  o->value = xstrdup_if_nonnull (value);
-  o->default_value = xstrdup_if_nonnull (default_value);
-  return o;
-}
-
-/* Creates and returns a new struct driver_option for output driver DRIVER
-   (which is needed only to the extent that its name will be used in error
-   messages).  The option named NAME is extracted from OPTIONS.  DEFAULT_VALUE
-   is the default value of the option, used if the given option was not
-   supplied or was invalid. */
+/* Creates and returns a new struct driver_option for driver DRIVER_NAME (which
+   is used only in error messages).  The option named NAME is extracted from
+   OPTIONS.  DEFAULT_VALUE is the default value of the option, used if the
+   given option was not supplied or was invalid. */
 struct driver_option *
-driver_option_get (struct output_driver *driver, struct string_map *options,
+driver_option_get (const char *driver_name, struct string_map *options,
                    const char *name, const char *default_value)
 {
-  struct driver_option *option;
-  char *value;
-
-  value = string_map_find_and_delete (options, name);
-  option = driver_option_create (output_driver_get_name (driver), name, value,
-                                 default_value);
-  free (value);
+  struct driver_option *option = xmalloc (sizeof *option);
+  option->driver_name = xstrdup (driver_name);
+  option->name = xstrdup (name);
+  option->value = string_map_find_and_delete (options, name);
+  option->default_value = xstrdup_if_nonnull (default_value);
   return option;
 }
 
index 57bd2aea6654fc1ce38258900ad7ec3979244dca..36d7bac9fb4aba32b9bd188014cb954fa96faf43 100644 (file)
@@ -34,11 +34,7 @@ struct driver_option
     char *default_value;        /* Default value supplied by driver. */
   };
 
-struct driver_option *driver_option_create (const char *driver_name,
-                                            const char *name,
-                                            const char *value,
-                                            const char *default_value);
-struct driver_option *driver_option_get (struct output_driver *,
+struct driver_option *driver_option_get (const char *driver_name,
                                          struct string_map *,
                                          const char *name,
                                          const char *default_value);
index 7e22cf0c1bac7469904b4b545415683c407d3f53..5dcb9fee21835e54243f3143817afb968eb435cd 100644 (file)
@@ -51,26 +51,26 @@ static struct output_driver *
 spv_create (struct file_handle *fh, enum settings_output_devices device_type,
             struct string_map *o UNUSED)
 {
-  struct output_driver *d;
-  struct spv_driver *spv = XZALLOC (struct spv_driver);
-  d = &spv->driver;
-  spv->handle = fh;
-  output_driver_init (&spv->driver, &spv_driver_class, fh_get_file_name (fh),
-                      device_type);
-
-  char *error = spv_writer_open (fh_get_file_name (fh), &spv->writer);
-  if (spv->writer == NULL)
+  struct spv_writer *writer;
+  char *error = spv_writer_open (fh_get_file_name (fh), &writer);
+  if (!writer)
     {
       msg (ME, "%s", error);
       free (error);
-      goto error;
+      return NULL;
     }
 
-  return d;
-
-error:
-  output_driver_destroy (d);
-  return NULL;
+  struct spv_driver *spv = xmalloc (sizeof *spv);
+  *spv = (struct spv_driver) {
+    .driver = {
+      .class = &spv_driver_class,
+      .name = xstrdup (fh_get_file_name (fh)),
+      .device_type = device_type,
+    },
+    .handle = fh,
+    .writer = writer,
+  };
+  return &spv->driver;
 }
 
 static void
index de111ec13f47b74177b0a48aed47046a59053e39..4ffe33b1f9954e3b8edb51f277a06119a086148c 100644 (file)
@@ -109,45 +109,42 @@ tex_driver_cast (struct output_driver *driver)
 }
 
 static struct driver_option *
-opt (struct output_driver *d, struct string_map *options, const char *key,
-     const char *default_value)
+opt (struct string_map *options, const char *key, const char *default_value)
 {
-  return driver_option_get (d, options, key, default_value);
+  return driver_option_get ("tex", options, key, default_value);
 }
 
 static struct output_driver *
 tex_create (struct file_handle *fh, enum settings_output_devices device_type,
              struct string_map *o)
 {
-  struct output_driver *d;
-  struct tex_driver *tex = XZALLOC (struct tex_driver);
-  hmap_init (&tex->macros);
-  ll_init (&tex->preamble_list);
-  ll_init (&tex->token_list);
-
-  d = &tex->driver;
-  output_driver_init (&tex->driver, &tex_driver_class, fh_get_file_name (fh),
-                      device_type);
-  tex->handle = fh;
-  tex->chart_file_name = parse_chart_file_name (opt (d, o, "charts",
-                                                      fh_get_file_name (fh)));
-  tex->n_charts = 1;
-  tex->bg = parse_color (opt (d, o, "background-color", "#FFFFFFFFFFFF"));
-  tex->fg = parse_color (opt (d, o, "foreground-color", "#000000000000"));
-
-  tex->file = fn_open (tex->handle, "w");
-  if (tex->file == NULL)
+  FILE *file = fn_open (fh, "w");
+  if (!file)
     {
       msg_error (errno, _("error opening output file `%s'"),
-                 fh_get_file_name (tex->handle));
-      goto error;
+                 fh_get_file_name (fh));
+      return NULL;
     }
 
-  return d;
-
- error:
-  output_driver_destroy (d);
-  return NULL;
+  struct tex_driver *tex = xmalloc (sizeof *tex);
+  *tex = (struct tex_driver) {
+    .driver = {
+      .class = &tex_driver_class,
+      .name = xstrdup (fh_get_file_name (fh)),
+      .device_type = device_type,
+    },
+    .macros = HMAP_INITIALIZER (tex->macros),
+    .bg = parse_color (opt (o, "background-color", "#FFFFFFFFFFFF")),
+    .fg = parse_color (opt (o, "foreground-color", "#000000000000")),
+    .handle = fh,
+    .chart_file_name = parse_chart_file_name (opt (o, "charts",
+                                                   fh_get_file_name (fh))),
+    .file = file,
+    .n_charts = 1,
+    .preamble_list = LL_INITIALIZER (tex->preamble_list),
+    .token_list = LL_INITIALIZER (tex->token_list),
+  };
+  return &tex->driver;
 }
 
 
index 46535b0f2362fd7cc8777cdeeaf18a67057c7e9b..14fc1fd0dcd5588d47bab694006ef8ddb624506a 100644 (file)
@@ -166,13 +166,15 @@ static struct output_driver_class psppire_output_class =
 void
 psppire_output_window_setup (void)
 {
-  struct psppire_output_driver *pod = XZALLOC (struct psppire_output_driver);
-  struct output_driver *d;
-
-  d = &pod->driver;
-  output_driver_init (d, &psppire_output_class, "PSPPIRE",
-                      SETTINGS_DEVICE_UNFILTERED);
-  output_driver_register (d);
+  struct psppire_output_driver *pod = xmalloc (sizeof *pod);
+  *pod = (struct psppire_output_driver) {
+    .driver = {
+      .class = &psppire_output_class,
+      .name = xstrdup ("PSPPIRE"),
+      .device_type = SETTINGS_DEVICE_UNFILTERED,
+    },
+  };
+  output_driver_register (&pod->driver);
 }
 
 \f