1*2d1272b8SAndroid Build Coastguard Worker /*
2*2d1272b8SAndroid Build Coastguard Worker * Copyright © 2011 Google, Inc.
3*2d1272b8SAndroid Build Coastguard Worker *
4*2d1272b8SAndroid Build Coastguard Worker * This is part of HarfBuzz, a text shaping library.
5*2d1272b8SAndroid Build Coastguard Worker *
6*2d1272b8SAndroid Build Coastguard Worker * Permission is hereby granted, without written agreement and without
7*2d1272b8SAndroid Build Coastguard Worker * license or royalty fees, to use, copy, modify, and distribute this
8*2d1272b8SAndroid Build Coastguard Worker * software and its documentation for any purpose, provided that the
9*2d1272b8SAndroid Build Coastguard Worker * above copyright notice and the following two paragraphs appear in
10*2d1272b8SAndroid Build Coastguard Worker * all copies of this software.
11*2d1272b8SAndroid Build Coastguard Worker *
12*2d1272b8SAndroid Build Coastguard Worker * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
13*2d1272b8SAndroid Build Coastguard Worker * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
14*2d1272b8SAndroid Build Coastguard Worker * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
15*2d1272b8SAndroid Build Coastguard Worker * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
16*2d1272b8SAndroid Build Coastguard Worker * DAMAGE.
17*2d1272b8SAndroid Build Coastguard Worker *
18*2d1272b8SAndroid Build Coastguard Worker * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
19*2d1272b8SAndroid Build Coastguard Worker * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20*2d1272b8SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21*2d1272b8SAndroid Build Coastguard Worker * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
22*2d1272b8SAndroid Build Coastguard Worker * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
23*2d1272b8SAndroid Build Coastguard Worker *
24*2d1272b8SAndroid Build Coastguard Worker * Google Author(s): Behdad Esfahbod
25*2d1272b8SAndroid Build Coastguard Worker */
26*2d1272b8SAndroid Build Coastguard Worker
27*2d1272b8SAndroid Build Coastguard Worker #ifndef TEXT_OPTIONS_HH
28*2d1272b8SAndroid Build Coastguard Worker #define TEXT_OPTIONS_HH
29*2d1272b8SAndroid Build Coastguard Worker
30*2d1272b8SAndroid Build Coastguard Worker #include "options.hh"
31*2d1272b8SAndroid Build Coastguard Worker
32*2d1272b8SAndroid Build Coastguard Worker struct text_options_t
33*2d1272b8SAndroid Build Coastguard Worker {
text_options_ttext_options_t34*2d1272b8SAndroid Build Coastguard Worker text_options_t ()
35*2d1272b8SAndroid Build Coastguard Worker : gs (g_string_new (nullptr))
36*2d1272b8SAndroid Build Coastguard Worker {}
~text_options_ttext_options_t37*2d1272b8SAndroid Build Coastguard Worker ~text_options_t ()
38*2d1272b8SAndroid Build Coastguard Worker {
39*2d1272b8SAndroid Build Coastguard Worker g_free (text);
40*2d1272b8SAndroid Build Coastguard Worker g_free (text_file);
41*2d1272b8SAndroid Build Coastguard Worker if (gs)
42*2d1272b8SAndroid Build Coastguard Worker g_string_free (gs, true);
43*2d1272b8SAndroid Build Coastguard Worker if (in_fp && in_fp != stdin)
44*2d1272b8SAndroid Build Coastguard Worker fclose (in_fp);
45*2d1272b8SAndroid Build Coastguard Worker }
46*2d1272b8SAndroid Build Coastguard Worker
47*2d1272b8SAndroid Build Coastguard Worker void add_options (option_parser_t *parser);
48*2d1272b8SAndroid Build Coastguard Worker
post_parsetext_options_t49*2d1272b8SAndroid Build Coastguard Worker void post_parse (GError **error G_GNUC_UNUSED)
50*2d1272b8SAndroid Build Coastguard Worker {
51*2d1272b8SAndroid Build Coastguard Worker if (!text && !text_file)
52*2d1272b8SAndroid Build Coastguard Worker text_file = g_strdup ("-");
53*2d1272b8SAndroid Build Coastguard Worker
54*2d1272b8SAndroid Build Coastguard Worker if (text && text_file)
55*2d1272b8SAndroid Build Coastguard Worker {
56*2d1272b8SAndroid Build Coastguard Worker g_set_error (error,
57*2d1272b8SAndroid Build Coastguard Worker G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
58*2d1272b8SAndroid Build Coastguard Worker "Only one of text and text-file can be set");
59*2d1272b8SAndroid Build Coastguard Worker return;
60*2d1272b8SAndroid Build Coastguard Worker }
61*2d1272b8SAndroid Build Coastguard Worker
62*2d1272b8SAndroid Build Coastguard Worker if (text_file)
63*2d1272b8SAndroid Build Coastguard Worker {
64*2d1272b8SAndroid Build Coastguard Worker if (0 != strcmp (text_file, "-"))
65*2d1272b8SAndroid Build Coastguard Worker in_fp = fopen (text_file, "r");
66*2d1272b8SAndroid Build Coastguard Worker else
67*2d1272b8SAndroid Build Coastguard Worker in_fp = stdin;
68*2d1272b8SAndroid Build Coastguard Worker
69*2d1272b8SAndroid Build Coastguard Worker if (!in_fp)
70*2d1272b8SAndroid Build Coastguard Worker g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
71*2d1272b8SAndroid Build Coastguard Worker "Failed opening text file `%s': %s",
72*2d1272b8SAndroid Build Coastguard Worker text_file, strerror (errno));
73*2d1272b8SAndroid Build Coastguard Worker }
74*2d1272b8SAndroid Build Coastguard Worker }
75*2d1272b8SAndroid Build Coastguard Worker
76*2d1272b8SAndroid Build Coastguard Worker const char *get_line (unsigned int *len);
77*2d1272b8SAndroid Build Coastguard Worker
78*2d1272b8SAndroid Build Coastguard Worker int text_len = -1;
79*2d1272b8SAndroid Build Coastguard Worker char *text = nullptr;
80*2d1272b8SAndroid Build Coastguard Worker char *text_file = nullptr;
81*2d1272b8SAndroid Build Coastguard Worker
82*2d1272b8SAndroid Build Coastguard Worker private:
83*2d1272b8SAndroid Build Coastguard Worker FILE *in_fp = nullptr;
84*2d1272b8SAndroid Build Coastguard Worker GString *gs = nullptr;
85*2d1272b8SAndroid Build Coastguard Worker char *line = nullptr;
86*2d1272b8SAndroid Build Coastguard Worker unsigned line_len = UINT_MAX;
87*2d1272b8SAndroid Build Coastguard Worker hb_bool_t single_par = false;
88*2d1272b8SAndroid Build Coastguard Worker };
89*2d1272b8SAndroid Build Coastguard Worker
90*2d1272b8SAndroid Build Coastguard Worker struct shape_text_options_t : text_options_t
91*2d1272b8SAndroid Build Coastguard Worker {
~shape_text_options_tshape_text_options_t92*2d1272b8SAndroid Build Coastguard Worker ~shape_text_options_t ()
93*2d1272b8SAndroid Build Coastguard Worker {
94*2d1272b8SAndroid Build Coastguard Worker g_free (text_before);
95*2d1272b8SAndroid Build Coastguard Worker g_free (text_after);
96*2d1272b8SAndroid Build Coastguard Worker }
97*2d1272b8SAndroid Build Coastguard Worker
98*2d1272b8SAndroid Build Coastguard Worker void add_options (option_parser_t *parser);
99*2d1272b8SAndroid Build Coastguard Worker
100*2d1272b8SAndroid Build Coastguard Worker char *text_before = nullptr;
101*2d1272b8SAndroid Build Coastguard Worker char *text_after = nullptr;
102*2d1272b8SAndroid Build Coastguard Worker };
103*2d1272b8SAndroid Build Coastguard Worker
104*2d1272b8SAndroid Build Coastguard Worker
105*2d1272b8SAndroid Build Coastguard Worker static gboolean
parse_text(const char * name G_GNUC_UNUSED,const char * arg,gpointer data,GError ** error G_GNUC_UNUSED)106*2d1272b8SAndroid Build Coastguard Worker parse_text (const char *name G_GNUC_UNUSED,
107*2d1272b8SAndroid Build Coastguard Worker const char *arg,
108*2d1272b8SAndroid Build Coastguard Worker gpointer data,
109*2d1272b8SAndroid Build Coastguard Worker GError **error G_GNUC_UNUSED)
110*2d1272b8SAndroid Build Coastguard Worker {
111*2d1272b8SAndroid Build Coastguard Worker text_options_t *text_opts = (text_options_t *) data;
112*2d1272b8SAndroid Build Coastguard Worker
113*2d1272b8SAndroid Build Coastguard Worker if (text_opts->text)
114*2d1272b8SAndroid Build Coastguard Worker {
115*2d1272b8SAndroid Build Coastguard Worker g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
116*2d1272b8SAndroid Build Coastguard Worker "Either --text or --unicodes can be provided but not both");
117*2d1272b8SAndroid Build Coastguard Worker return false;
118*2d1272b8SAndroid Build Coastguard Worker }
119*2d1272b8SAndroid Build Coastguard Worker
120*2d1272b8SAndroid Build Coastguard Worker text_opts->text_len = -1;
121*2d1272b8SAndroid Build Coastguard Worker text_opts->text = g_strdup (arg);
122*2d1272b8SAndroid Build Coastguard Worker return true;
123*2d1272b8SAndroid Build Coastguard Worker }
124*2d1272b8SAndroid Build Coastguard Worker
125*2d1272b8SAndroid Build Coastguard Worker static bool
encode_unicodes(const char * unicodes,GString * gs,GError ** error)126*2d1272b8SAndroid Build Coastguard Worker encode_unicodes (const char *unicodes,
127*2d1272b8SAndroid Build Coastguard Worker GString *gs,
128*2d1272b8SAndroid Build Coastguard Worker GError **error)
129*2d1272b8SAndroid Build Coastguard Worker {
130*2d1272b8SAndroid Build Coastguard Worker #define DELIMITERS "<+-|>{},;&#\\xXuUnNiI\n\t\v\f\r "
131*2d1272b8SAndroid Build Coastguard Worker
132*2d1272b8SAndroid Build Coastguard Worker char *s = (char *) unicodes;
133*2d1272b8SAndroid Build Coastguard Worker char *p;
134*2d1272b8SAndroid Build Coastguard Worker
135*2d1272b8SAndroid Build Coastguard Worker while (s && *s)
136*2d1272b8SAndroid Build Coastguard Worker {
137*2d1272b8SAndroid Build Coastguard Worker while (*s && strchr (DELIMITERS, *s))
138*2d1272b8SAndroid Build Coastguard Worker s++;
139*2d1272b8SAndroid Build Coastguard Worker if (!*s)
140*2d1272b8SAndroid Build Coastguard Worker break;
141*2d1272b8SAndroid Build Coastguard Worker
142*2d1272b8SAndroid Build Coastguard Worker errno = 0;
143*2d1272b8SAndroid Build Coastguard Worker hb_codepoint_t u = strtoul (s, &p, 16);
144*2d1272b8SAndroid Build Coastguard Worker if (errno || s == p)
145*2d1272b8SAndroid Build Coastguard Worker {
146*2d1272b8SAndroid Build Coastguard Worker g_string_free (gs, TRUE);
147*2d1272b8SAndroid Build Coastguard Worker g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
148*2d1272b8SAndroid Build Coastguard Worker "Failed parsing Unicode value at: '%s'", s);
149*2d1272b8SAndroid Build Coastguard Worker return false;
150*2d1272b8SAndroid Build Coastguard Worker }
151*2d1272b8SAndroid Build Coastguard Worker
152*2d1272b8SAndroid Build Coastguard Worker g_string_append_unichar (gs, u);
153*2d1272b8SAndroid Build Coastguard Worker
154*2d1272b8SAndroid Build Coastguard Worker s = p;
155*2d1272b8SAndroid Build Coastguard Worker }
156*2d1272b8SAndroid Build Coastguard Worker
157*2d1272b8SAndroid Build Coastguard Worker #undef DELIMITERS
158*2d1272b8SAndroid Build Coastguard Worker
159*2d1272b8SAndroid Build Coastguard Worker return true;
160*2d1272b8SAndroid Build Coastguard Worker }
161*2d1272b8SAndroid Build Coastguard Worker
162*2d1272b8SAndroid Build Coastguard Worker static gboolean
parse_unicodes(const char * name G_GNUC_UNUSED,const char * arg,gpointer data,GError ** error G_GNUC_UNUSED)163*2d1272b8SAndroid Build Coastguard Worker parse_unicodes (const char *name G_GNUC_UNUSED,
164*2d1272b8SAndroid Build Coastguard Worker const char *arg,
165*2d1272b8SAndroid Build Coastguard Worker gpointer data,
166*2d1272b8SAndroid Build Coastguard Worker GError **error G_GNUC_UNUSED)
167*2d1272b8SAndroid Build Coastguard Worker {
168*2d1272b8SAndroid Build Coastguard Worker text_options_t *text_opts = (text_options_t *) data;
169*2d1272b8SAndroid Build Coastguard Worker
170*2d1272b8SAndroid Build Coastguard Worker if (text_opts->text)
171*2d1272b8SAndroid Build Coastguard Worker {
172*2d1272b8SAndroid Build Coastguard Worker g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
173*2d1272b8SAndroid Build Coastguard Worker "Either --text or --unicodes can be provided but not both");
174*2d1272b8SAndroid Build Coastguard Worker return false;
175*2d1272b8SAndroid Build Coastguard Worker }
176*2d1272b8SAndroid Build Coastguard Worker
177*2d1272b8SAndroid Build Coastguard Worker GString *gs = g_string_new (nullptr);
178*2d1272b8SAndroid Build Coastguard Worker if (0 == strcmp (arg, "*"))
179*2d1272b8SAndroid Build Coastguard Worker g_string_append_c (gs, '*');
180*2d1272b8SAndroid Build Coastguard Worker else
181*2d1272b8SAndroid Build Coastguard Worker if (!encode_unicodes (arg, gs, error))
182*2d1272b8SAndroid Build Coastguard Worker return false;
183*2d1272b8SAndroid Build Coastguard Worker
184*2d1272b8SAndroid Build Coastguard Worker text_opts->text_len = gs->len;
185*2d1272b8SAndroid Build Coastguard Worker text_opts->text = g_string_free (gs, FALSE);
186*2d1272b8SAndroid Build Coastguard Worker return true;
187*2d1272b8SAndroid Build Coastguard Worker }
188*2d1272b8SAndroid Build Coastguard Worker
189*2d1272b8SAndroid Build Coastguard Worker static gboolean
parse_text_before(const char * name G_GNUC_UNUSED,const char * arg,gpointer data,GError ** error)190*2d1272b8SAndroid Build Coastguard Worker parse_text_before (const char *name G_GNUC_UNUSED,
191*2d1272b8SAndroid Build Coastguard Worker const char *arg,
192*2d1272b8SAndroid Build Coastguard Worker gpointer data,
193*2d1272b8SAndroid Build Coastguard Worker GError **error)
194*2d1272b8SAndroid Build Coastguard Worker {
195*2d1272b8SAndroid Build Coastguard Worker auto *opts = (shape_text_options_t *) data;
196*2d1272b8SAndroid Build Coastguard Worker
197*2d1272b8SAndroid Build Coastguard Worker if (opts->text_before)
198*2d1272b8SAndroid Build Coastguard Worker {
199*2d1272b8SAndroid Build Coastguard Worker g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
200*2d1272b8SAndroid Build Coastguard Worker "Either --text-before or --unicodes-before can be provided but not both");
201*2d1272b8SAndroid Build Coastguard Worker return false;
202*2d1272b8SAndroid Build Coastguard Worker }
203*2d1272b8SAndroid Build Coastguard Worker
204*2d1272b8SAndroid Build Coastguard Worker opts->text_before = g_strdup (arg);
205*2d1272b8SAndroid Build Coastguard Worker fprintf(stderr, "%s\n", opts->text_before);
206*2d1272b8SAndroid Build Coastguard Worker return true;
207*2d1272b8SAndroid Build Coastguard Worker }
208*2d1272b8SAndroid Build Coastguard Worker
209*2d1272b8SAndroid Build Coastguard Worker static gboolean
parse_unicodes_before(const char * name G_GNUC_UNUSED,const char * arg,gpointer data,GError ** error)210*2d1272b8SAndroid Build Coastguard Worker parse_unicodes_before (const char *name G_GNUC_UNUSED,
211*2d1272b8SAndroid Build Coastguard Worker const char *arg,
212*2d1272b8SAndroid Build Coastguard Worker gpointer data,
213*2d1272b8SAndroid Build Coastguard Worker GError **error)
214*2d1272b8SAndroid Build Coastguard Worker {
215*2d1272b8SAndroid Build Coastguard Worker auto *opts = (shape_text_options_t *) data;
216*2d1272b8SAndroid Build Coastguard Worker
217*2d1272b8SAndroid Build Coastguard Worker if (opts->text_before)
218*2d1272b8SAndroid Build Coastguard Worker {
219*2d1272b8SAndroid Build Coastguard Worker g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
220*2d1272b8SAndroid Build Coastguard Worker "Either --text-before or --unicodes-before can be provided but not both");
221*2d1272b8SAndroid Build Coastguard Worker return false;
222*2d1272b8SAndroid Build Coastguard Worker }
223*2d1272b8SAndroid Build Coastguard Worker
224*2d1272b8SAndroid Build Coastguard Worker GString *gs = g_string_new (nullptr);
225*2d1272b8SAndroid Build Coastguard Worker if (!encode_unicodes (arg, gs, error))
226*2d1272b8SAndroid Build Coastguard Worker return false;
227*2d1272b8SAndroid Build Coastguard Worker
228*2d1272b8SAndroid Build Coastguard Worker opts->text_before = g_string_free (gs, FALSE);
229*2d1272b8SAndroid Build Coastguard Worker return true;
230*2d1272b8SAndroid Build Coastguard Worker }
231*2d1272b8SAndroid Build Coastguard Worker
232*2d1272b8SAndroid Build Coastguard Worker static gboolean
parse_text_after(const char * name G_GNUC_UNUSED,const char * arg,gpointer data,GError ** error)233*2d1272b8SAndroid Build Coastguard Worker parse_text_after (const char *name G_GNUC_UNUSED,
234*2d1272b8SAndroid Build Coastguard Worker const char *arg,
235*2d1272b8SAndroid Build Coastguard Worker gpointer data,
236*2d1272b8SAndroid Build Coastguard Worker GError **error)
237*2d1272b8SAndroid Build Coastguard Worker {
238*2d1272b8SAndroid Build Coastguard Worker auto *opts = (shape_text_options_t *) data;
239*2d1272b8SAndroid Build Coastguard Worker
240*2d1272b8SAndroid Build Coastguard Worker if (opts->text_after)
241*2d1272b8SAndroid Build Coastguard Worker {
242*2d1272b8SAndroid Build Coastguard Worker g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
243*2d1272b8SAndroid Build Coastguard Worker "Either --text-after or --unicodes-after can be provided but not both");
244*2d1272b8SAndroid Build Coastguard Worker return false;
245*2d1272b8SAndroid Build Coastguard Worker }
246*2d1272b8SAndroid Build Coastguard Worker
247*2d1272b8SAndroid Build Coastguard Worker opts->text_after = g_strdup (arg);
248*2d1272b8SAndroid Build Coastguard Worker return true;
249*2d1272b8SAndroid Build Coastguard Worker }
250*2d1272b8SAndroid Build Coastguard Worker
251*2d1272b8SAndroid Build Coastguard Worker static gboolean
parse_unicodes_after(const char * name G_GNUC_UNUSED,const char * arg,gpointer data,GError ** error)252*2d1272b8SAndroid Build Coastguard Worker parse_unicodes_after (const char *name G_GNUC_UNUSED,
253*2d1272b8SAndroid Build Coastguard Worker const char *arg,
254*2d1272b8SAndroid Build Coastguard Worker gpointer data,
255*2d1272b8SAndroid Build Coastguard Worker GError **error)
256*2d1272b8SAndroid Build Coastguard Worker {
257*2d1272b8SAndroid Build Coastguard Worker auto *opts = (shape_text_options_t *) data;
258*2d1272b8SAndroid Build Coastguard Worker
259*2d1272b8SAndroid Build Coastguard Worker if (opts->text_after)
260*2d1272b8SAndroid Build Coastguard Worker {
261*2d1272b8SAndroid Build Coastguard Worker g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
262*2d1272b8SAndroid Build Coastguard Worker "Either --text-after or --unicodes-after can be provided but not both");
263*2d1272b8SAndroid Build Coastguard Worker return false;
264*2d1272b8SAndroid Build Coastguard Worker }
265*2d1272b8SAndroid Build Coastguard Worker
266*2d1272b8SAndroid Build Coastguard Worker GString *gs = g_string_new (nullptr);
267*2d1272b8SAndroid Build Coastguard Worker if (!encode_unicodes (arg, gs, error))
268*2d1272b8SAndroid Build Coastguard Worker return false;
269*2d1272b8SAndroid Build Coastguard Worker
270*2d1272b8SAndroid Build Coastguard Worker opts->text_after = g_string_free (gs, FALSE);
271*2d1272b8SAndroid Build Coastguard Worker return true;
272*2d1272b8SAndroid Build Coastguard Worker }
273*2d1272b8SAndroid Build Coastguard Worker
274*2d1272b8SAndroid Build Coastguard Worker const char *
get_line(unsigned int * len)275*2d1272b8SAndroid Build Coastguard Worker text_options_t::get_line (unsigned int *len)
276*2d1272b8SAndroid Build Coastguard Worker {
277*2d1272b8SAndroid Build Coastguard Worker if (text)
278*2d1272b8SAndroid Build Coastguard Worker {
279*2d1272b8SAndroid Build Coastguard Worker if (!line)
280*2d1272b8SAndroid Build Coastguard Worker {
281*2d1272b8SAndroid Build Coastguard Worker line = text;
282*2d1272b8SAndroid Build Coastguard Worker line_len = text_len;
283*2d1272b8SAndroid Build Coastguard Worker }
284*2d1272b8SAndroid Build Coastguard Worker if (line_len == UINT_MAX)
285*2d1272b8SAndroid Build Coastguard Worker line_len = strlen (line);
286*2d1272b8SAndroid Build Coastguard Worker
287*2d1272b8SAndroid Build Coastguard Worker if (!line_len)
288*2d1272b8SAndroid Build Coastguard Worker {
289*2d1272b8SAndroid Build Coastguard Worker *len = 0;
290*2d1272b8SAndroid Build Coastguard Worker return nullptr;
291*2d1272b8SAndroid Build Coastguard Worker }
292*2d1272b8SAndroid Build Coastguard Worker
293*2d1272b8SAndroid Build Coastguard Worker const char *ret = line;
294*2d1272b8SAndroid Build Coastguard Worker const char *p = single_par ? nullptr : (const char *) memchr (line, '\n', line_len);
295*2d1272b8SAndroid Build Coastguard Worker unsigned int ret_len;
296*2d1272b8SAndroid Build Coastguard Worker if (!p)
297*2d1272b8SAndroid Build Coastguard Worker {
298*2d1272b8SAndroid Build Coastguard Worker ret_len = line_len;
299*2d1272b8SAndroid Build Coastguard Worker line += ret_len;
300*2d1272b8SAndroid Build Coastguard Worker line_len = 0;
301*2d1272b8SAndroid Build Coastguard Worker }
302*2d1272b8SAndroid Build Coastguard Worker else
303*2d1272b8SAndroid Build Coastguard Worker {
304*2d1272b8SAndroid Build Coastguard Worker ret_len = p - ret;
305*2d1272b8SAndroid Build Coastguard Worker line += ret_len + 1;
306*2d1272b8SAndroid Build Coastguard Worker line_len -= ret_len + 1;
307*2d1272b8SAndroid Build Coastguard Worker }
308*2d1272b8SAndroid Build Coastguard Worker
309*2d1272b8SAndroid Build Coastguard Worker *len = ret_len;
310*2d1272b8SAndroid Build Coastguard Worker return ret;
311*2d1272b8SAndroid Build Coastguard Worker }
312*2d1272b8SAndroid Build Coastguard Worker
313*2d1272b8SAndroid Build Coastguard Worker g_string_set_size (gs, 0);
314*2d1272b8SAndroid Build Coastguard Worker char buf[BUFSIZ];
315*2d1272b8SAndroid Build Coastguard Worker while (fgets (buf, sizeof (buf), in_fp))
316*2d1272b8SAndroid Build Coastguard Worker {
317*2d1272b8SAndroid Build Coastguard Worker unsigned bytes = strlen (buf);
318*2d1272b8SAndroid Build Coastguard Worker if (!single_par && bytes && buf[bytes - 1] == '\n')
319*2d1272b8SAndroid Build Coastguard Worker {
320*2d1272b8SAndroid Build Coastguard Worker bytes--;
321*2d1272b8SAndroid Build Coastguard Worker g_string_append_len (gs, buf, bytes);
322*2d1272b8SAndroid Build Coastguard Worker break;
323*2d1272b8SAndroid Build Coastguard Worker }
324*2d1272b8SAndroid Build Coastguard Worker g_string_append_len (gs, buf, bytes);
325*2d1272b8SAndroid Build Coastguard Worker }
326*2d1272b8SAndroid Build Coastguard Worker if (ferror (in_fp))
327*2d1272b8SAndroid Build Coastguard Worker fail (false, "Failed reading text: %s", strerror (errno));
328*2d1272b8SAndroid Build Coastguard Worker *len = gs->len;
329*2d1272b8SAndroid Build Coastguard Worker return !*len && feof (in_fp) ? nullptr : gs->str;
330*2d1272b8SAndroid Build Coastguard Worker }
331*2d1272b8SAndroid Build Coastguard Worker
332*2d1272b8SAndroid Build Coastguard Worker void
add_options(option_parser_t * parser)333*2d1272b8SAndroid Build Coastguard Worker text_options_t::add_options (option_parser_t *parser)
334*2d1272b8SAndroid Build Coastguard Worker {
335*2d1272b8SAndroid Build Coastguard Worker GOptionEntry entries[] =
336*2d1272b8SAndroid Build Coastguard Worker {
337*2d1272b8SAndroid Build Coastguard Worker {"text", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_text, "Set input text", "string"},
338*2d1272b8SAndroid Build Coastguard Worker {"text-file", 0, 0, G_OPTION_ARG_STRING, &this->text_file, "Set input text file-name", "filename"},
339*2d1272b8SAndroid Build Coastguard Worker {"unicodes", 'u', 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_unicodes, "Set input Unicode codepoints", "list of hex numbers"},
340*2d1272b8SAndroid Build Coastguard Worker {"single-par", 0, 0, G_OPTION_ARG_NONE, &this->single_par, "Treat text as single paragraph", nullptr},
341*2d1272b8SAndroid Build Coastguard Worker {nullptr}
342*2d1272b8SAndroid Build Coastguard Worker };
343*2d1272b8SAndroid Build Coastguard Worker parser->add_group (entries,
344*2d1272b8SAndroid Build Coastguard Worker "text",
345*2d1272b8SAndroid Build Coastguard Worker "Text options:\n\nIf no text is provided, standard input is used for input.\n",
346*2d1272b8SAndroid Build Coastguard Worker "Options for the input text",
347*2d1272b8SAndroid Build Coastguard Worker this);
348*2d1272b8SAndroid Build Coastguard Worker }
349*2d1272b8SAndroid Build Coastguard Worker
350*2d1272b8SAndroid Build Coastguard Worker void
add_options(option_parser_t * parser)351*2d1272b8SAndroid Build Coastguard Worker shape_text_options_t::add_options (option_parser_t *parser)
352*2d1272b8SAndroid Build Coastguard Worker {
353*2d1272b8SAndroid Build Coastguard Worker text_options_t::add_options (parser);
354*2d1272b8SAndroid Build Coastguard Worker
355*2d1272b8SAndroid Build Coastguard Worker GOptionEntry entries[] =
356*2d1272b8SAndroid Build Coastguard Worker {
357*2d1272b8SAndroid Build Coastguard Worker {"text-before", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_text_before, "Set text context before each line", "string"},
358*2d1272b8SAndroid Build Coastguard Worker {"text-after", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_text_after, "Set text context after each line", "string"},
359*2d1272b8SAndroid Build Coastguard Worker {"unicodes-before", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_unicodes_before, "Set Unicode codepoints context before each line", "list of hex numbers"},
360*2d1272b8SAndroid Build Coastguard Worker {"unicodes-after", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_unicodes_after, "Set Unicode codepoints context after each line", "list of hex numbers"},
361*2d1272b8SAndroid Build Coastguard Worker {nullptr}
362*2d1272b8SAndroid Build Coastguard Worker };
363*2d1272b8SAndroid Build Coastguard Worker parser->add_group (entries,
364*2d1272b8SAndroid Build Coastguard Worker "text-context",
365*2d1272b8SAndroid Build Coastguard Worker "Textual context options:",
366*2d1272b8SAndroid Build Coastguard Worker "Options for the input context text",
367*2d1272b8SAndroid Build Coastguard Worker this);
368*2d1272b8SAndroid Build Coastguard Worker }
369*2d1272b8SAndroid Build Coastguard Worker
370*2d1272b8SAndroid Build Coastguard Worker #endif
371