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 *
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)
fail (TRUE, "At least one of text or text-file must be set");
GMappedFile *mf = g_mapped_file_new (text_file, FALSE, NULL);
if (!mf)
fail (FALSE, "Failed opening text file `%s'", g_filename_display_name (text_file));
text = g_mapped_file_get_contents (mf);
text_len = g_mapped_file_get_length (mf);
if (0 != strcmp (text_file, "-"))
fp = fopen (text_file, "r");
else
fp = stdin;
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)
text_len = strlen (text);
if (!text_len) {
*len = 0;
return NULL;
g_string_set_size (gs, 0);
char buf[BUFSIZ];
while (fgets (buf, sizeof (buf), fp)) {
unsigned int bytes = strlen (buf);
if (buf[bytes - 1] == '\n') {
bytes--;
g_string_append_len (gs, buf, bytes);
break;
}
g_string_append_len (gs, buf, bytes);
}
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 (ferror (fp))
fail (FALSE, "Failed reading text: %s",
strerror (errno));
*len = gs->len;
return !*len && feof (fp) ? NULL : gs->str;
}

View File

@ -178,14 +178,17 @@ struct text_options_t : option_group_t
text = NULL;
text_file = NULL;
file = NULL;
fp = NULL;
gs = NULL;
text_len = (unsigned int) -1;
add_options (parser);
}
~text_options_t (void) {
if (file)
g_mapped_file_unref (file);
if (gs)
g_string_free (gs, TRUE);
if (fp)
fclose (fp);
}
void add_options (option_parser_t *parser);
@ -204,8 +207,9 @@ struct text_options_t : option_group_t
const char *text_file;
private:
mutable GMappedFile *file;
mutable unsigned int text_len;
FILE *fp;
GString *gs;
unsigned int text_len;
};
struct output_options_t : option_group_t
@ -219,7 +223,7 @@ struct output_options_t : option_group_t
add_options (parser);
}
~output_options_t (void) {
if (fp && fp != stdout)
if (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.utf8 = g_strndup (text, 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++)
if (hb_glyph[i].cluster != hb_glyph[i-1].cluster)
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]));
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;
g_assert (l.num_glyphs);
unsigned int cluster = 0;
if (!l.num_glyphs)
goto done;
l.clusters[cluster].num_glyphs++;
if (backward) {
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;
}
done:
g_array_append_val (lines, l);
}