Fix reading text from stdin

This commit is contained in:
Behdad Esfahbod 2011-09-16 02:08:36 -04:00
parent a75c1b1251
commit 55aeb04904
3 changed files with 66 additions and 36 deletions

View File

@ -509,40 +509,64 @@ font_options_t::get_font (void) const
const char * const char *
text_options_t::get_line (unsigned int *len) text_options_t::get_line (unsigned int *len)
{ {
if (!text) { if (text) {
if (text_len == (unsigned int) -1)
text_len = strlen (text);
if (!text_len) {
*len = 0;
return NULL;
}
const char *ret = text;
const char *p = (const char *) memchr (text, '\n', text_len);
unsigned int ret_len;
if (!p) {
ret_len = text_len;
text += ret_len;
text_len = 0;
} else {
ret_len = p - ret;
text += ret_len + 1;
text_len -= ret_len + 1;
}
*len = ret_len;
return ret;
}
if (!fp) {
if (!text_file) if (!text_file)
fail (TRUE, "At least one of text or text-file must be set"); fail (TRUE, "At least one of text or text-file must be set");
GMappedFile *mf = g_mapped_file_new (text_file, FALSE, NULL); if (0 != strcmp (text_file, "-"))
if (!mf) fp = fopen (text_file, "r");
fail (FALSE, "Failed opening text file `%s'", g_filename_display_name (text_file)); else
text = g_mapped_file_get_contents (mf); fp = stdin;
text_len = g_mapped_file_get_length (mf);
if (!fp)
fail (FALSE, "Failed opening text file `%s': %s",
text_file, strerror (errno));
gs = g_string_new (NULL);
} }
if (text_len == (unsigned int) -1) g_string_set_size (gs, 0);
text_len = strlen (text); char buf[BUFSIZ];
while (fgets (buf, sizeof (buf), fp)) {
if (!text_len) { unsigned int bytes = strlen (buf);
*len = 0; if (buf[bytes - 1] == '\n') {
return NULL; bytes--;
g_string_append_len (gs, buf, bytes);
break;
}
g_string_append_len (gs, buf, bytes);
} }
if (ferror (fp))
const char *ret = text; fail (FALSE, "Failed reading text: %s",
const char *p = (const char *) memchr (text, '\n', text_len); strerror (errno));
unsigned int ret_len; *len = gs->len;
if (!p) { return !*len && feof (fp) ? NULL : gs->str;
ret_len = text_len;
text += ret_len;
text_len = 0;
} else {
ret_len = p - ret;
text += ret_len + 1;
text_len -= ret_len + 1;
}
*len = ret_len;
return ret;
} }

View File

@ -178,14 +178,17 @@ struct text_options_t : option_group_t
text = NULL; text = NULL;
text_file = NULL; text_file = NULL;
file = NULL; fp = NULL;
gs = NULL;
text_len = (unsigned int) -1; text_len = (unsigned int) -1;
add_options (parser); add_options (parser);
} }
~text_options_t (void) { ~text_options_t (void) {
if (file) if (gs)
g_mapped_file_unref (file); g_string_free (gs, TRUE);
if (fp)
fclose (fp);
} }
void add_options (option_parser_t *parser); void add_options (option_parser_t *parser);
@ -204,8 +207,9 @@ struct text_options_t : option_group_t
const char *text_file; const char *text_file;
private: private:
mutable GMappedFile *file; FILE *fp;
mutable unsigned int text_len; GString *gs;
unsigned int text_len;
}; };
struct output_options_t : option_group_t struct output_options_t : option_group_t
@ -219,7 +223,7 @@ struct output_options_t : option_group_t
add_options (parser); add_options (parser);
} }
~output_options_t (void) { ~output_options_t (void) {
if (fp && fp != stdout) if (fp)
fclose (fp); fclose (fp);
} }

View File

@ -96,7 +96,7 @@ view_cairo_t::consume_line (hb_buffer_t *buffer,
l.glyphs = cairo_glyph_allocate (l.num_glyphs + 1); l.glyphs = cairo_glyph_allocate (l.num_glyphs + 1);
l.utf8 = g_strndup (text, text_len); l.utf8 = g_strndup (text, text_len);
l.utf8_len = text_len; l.utf8_len = text_len;
l.num_clusters = 1; l.num_clusters = l.num_glyphs ? 1 : 0;
for (unsigned int i = 1; i < l.num_glyphs; i++) for (unsigned int i = 1; i < l.num_glyphs; i++)
if (hb_glyph[i].cluster != hb_glyph[i-1].cluster) if (hb_glyph[i].cluster != hb_glyph[i-1].cluster)
l.num_clusters++; l.num_clusters++;
@ -129,8 +129,9 @@ view_cairo_t::consume_line (hb_buffer_t *buffer,
memset ((void *) l.clusters, 0, l.num_clusters * sizeof (l.clusters[0])); memset ((void *) l.clusters, 0, l.num_clusters * sizeof (l.clusters[0]));
bool backward = HB_DIRECTION_IS_BACKWARD (hb_buffer_get_direction (buffer)); bool backward = HB_DIRECTION_IS_BACKWARD (hb_buffer_get_direction (buffer));
l.cluster_flags = backward ? CAIRO_TEXT_CLUSTER_FLAG_BACKWARD : (cairo_text_cluster_flags_t) 0; l.cluster_flags = backward ? CAIRO_TEXT_CLUSTER_FLAG_BACKWARD : (cairo_text_cluster_flags_t) 0;
g_assert (l.num_glyphs);
unsigned int cluster = 0; unsigned int cluster = 0;
if (!l.num_glyphs)
goto done;
l.clusters[cluster].num_glyphs++; l.clusters[cluster].num_glyphs++;
if (backward) { if (backward) {
for (i = l.num_glyphs - 2; i >= 0; i--) { for (i = l.num_glyphs - 2; i >= 0; i--) {
@ -154,6 +155,7 @@ view_cairo_t::consume_line (hb_buffer_t *buffer,
l.clusters[cluster].num_bytes += text_len - hb_glyph[i - 1].cluster; l.clusters[cluster].num_bytes += text_len - hb_glyph[i - 1].cluster;
} }
done:
g_array_append_val (lines, l); g_array_append_val (lines, l);
} }