1 /*
2  * Copyright © 2011  Google, Inc.
3  *
4  *  This is part of HarfBuzz, a text shaping library.
5  *
6  * Permission is hereby granted, without written agreement and without
7  * license or royalty fees, to use, copy, modify, and distribute this
8  * software and its documentation for any purpose, provided that the
9  * above copyright notice and the following two paragraphs appear in
10  * all copies of this software.
11  *
12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16  * DAMAGE.
17  *
18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23  *
24  * Google Author(s): Behdad Esfahbod
25  */
26 
27 #ifndef OUTPUT_OPTIONS_HH
28 #define OUTPUT_OPTIONS_HH
29 
30 #include "options.hh"
31 
32 template <bool default_stdout = true>
33 struct output_options_t
34 {
~output_options_toutput_options_t35   ~output_options_t ()
36   {
37     g_free (output_file);
38     g_free (output_format);
39     if (out_fp && out_fp != stdout)
40       fclose (out_fp);
41   }
42 
add_optionsoutput_options_t43   void add_options (option_parser_t *parser,
44 		    const char **supported_formats = nullptr)
45   {
46     const char *text = nullptr;
47 
48     if (supported_formats)
49     {
50       char *items = g_strjoinv ("/", const_cast<char **> (supported_formats));
51       text = g_strdup_printf ("Set output format\n\n    Supported output formats are: %s", items);
52       g_free (items);
53       parser->free_later ((char *) text);
54     }
55 
56     GOptionEntry entries[] =
57     {
58       {"output-file",   'o', 0, G_OPTION_ARG_STRING,	&this->output_file,		"Set output file-name (default: stdout)","filename"},
59       {"output-format", 'O', supported_formats ? 0 : G_OPTION_FLAG_HIDDEN,
60 				G_OPTION_ARG_STRING,	&this->output_format,		text,					"format"},
61       {nullptr}
62     };
63     parser->add_group (entries,
64 		       "output",
65 		       "Output destination & format options:",
66 		       "Options for the destination & form of the output",
67 		       this);
68   }
69 
post_parseoutput_options_t70   void post_parse (GError **error)
71   {
72     if (output_format)
73       explicit_output_format = true;
74 
75     if (output_file && !output_format)
76     {
77       output_format = strrchr (output_file, '.');
78       if (output_format)
79       {
80 	  output_format++; /* skip the dot */
81 	  output_format = g_strdup (output_format);
82       }
83     }
84 
85     if (output_file && 0 != strcmp (output_file, "-"))
86       out_fp = fopen (output_file, "wb");
87     else
88     {
89       if (!default_stdout && !output_file)
90       {
91 	g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
92 		     "No output file was specified");
93         return;
94       }
95 
96 #if defined(_WIN32) || defined(__CYGWIN__)
97       setmode (fileno (stdout), O_BINARY);
98 #endif
99       out_fp = stdout;
100     }
101     if (!out_fp)
102     {
103       g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
104 		   "Cannot open output file `%s': %s",
105 		   g_filename_display_name (output_file), strerror (errno));
106       return;
107     }
108   }
109 
110   char *output_file = nullptr;
111   char *output_format = nullptr;
112 
113   bool explicit_output_format = false;
114   FILE *out_fp = nullptr;
115 };
116 
117 #endif
118