+ if ((fp = fopen(filename, "r")) == 0) {
+ failed("cannot open input-file");
+ }
+
+ if ((my_blob = malloc((size_t) sb.st_size + 1)) == 0) {
+ failed("cannot allocate memory for input-file");
+ }
+
+ len = fread(my_blob, sizeof(char), (size_t) sb.st_size, fp);
+ my_blob[sb.st_size] = '\0';
+ fclose(fp);
+
+ for (pass = 0; pass < 2; ++pass) {
+ char *base = my_blob;
+ k = 0;
+ for (j = 0; j < len; ++j) {
+ if (my_blob[j] == '\n') {
+ if (pass) {
+ my_vec[k] = base;
+ my_blob[j] = '\0';
+ }
+ base = my_blob + j + 1;
+ ++k;
+ }
+ }
+ num_lines = k;
+ if (base != (my_blob + j))
+ ++num_lines;
+ if (!pass &&
+ ((my_vec = typeCalloc(char *, (size_t) k + 2)) == 0)) {
+ failed("cannot allocate line-vector #1");
+ }
+ }
+
+#if USE_WIDEC_SUPPORT
+ if (!memcmp("\357\273\277", my_blob, 3)) {
+ char *s = my_blob + 3;
+ char *d = my_blob;
+ Trace(("trim BOM"));
+ do {
+ } while ((*d++ = *s++) != '\0');
+ }
+#endif
+
+ width = (int) strlen(my_vec[0]);
+ for (k = 1; my_vec[k]; ++k) {
+ int check = (int) (my_vec[k] - my_vec[k - 1]);
+ if (width < check)
+ width = check;
+ }
+ width = (width + 1) * 5;
+ my_win = newwin(2, width, 0, 0);
+ if (my_win == 0)
+ failed("cannot allocate temporary window");
+
+ if ((vec_lines = typeCalloc(NCURSES_CH_T *, (size_t) num_lines + 2)) == 0)
+ failed("cannot allocate line-vector #2");
+
+ /*
+ * Use the curses library for rendering, including tab-conversion. This
+ * will not make the resulting array's indices correspond to column for
+ * lines containing double-width cells because the "in_wch" functions will
+ * ignore the skipped cells. Use pads for that sort of thing.
+ */
+ Trace(("slurp the file"));
+ for (k = 0; my_vec[k]; ++k) {
+ char *s;
+ int y, x;
+#if USE_WIDEC_SUPPORT
+ char *last = my_vec[k] + (int) strlen(my_vec[k]);
+ wchar_t wch[2];
+ size_t rc;
+#ifndef state_unused
+ mbstate_t state;
+#endif
+#endif /* USE_WIDEC_SUPPORT */
+
+ werase(my_win);
+ wmove(my_win, 0, 0);
+#if USE_WIDEC_SUPPORT
+ wch[1] = 0;
+ reset_mbytes(state);
+#endif
+ for (s = my_vec[k]; *s != '\0'; ++s) {
+#if USE_WIDEC_SUPPORT
+ if (!n_option) {
+ rc = (size_t) check_mbytes(wch[0], s, (size_t) (last - s), state);
+ if ((long) rc == -1 || (long) rc == -2) {
+ break;
+ }
+ s += rc - 1;
+ waddwstr(my_win, wch);
+ } else
+#endif
+ waddch(my_win, *s & 0xff);
+ }
+ getyx(my_win, y, x);
+ if (y)
+ x = width - 1;
+ wmove(my_win, 0, 0);
+ /* "x + 1" works with standard curses; some implementations are buggy */
+ if ((vec_lines[k] = typeCalloc(NCURSES_CH_T, x + width + 1)) == 0)
+ failed("cannot allocate line-vector #3");
+#if USE_WIDEC_SUPPORT
+ win_wchnstr(my_win, vec_lines[k], x);
+#else
+ winchnstr(my_win, vec_lines[k], x);
+#endif
+ }
+
+ delwin(my_win);
+ free(my_vec);
+ free(my_blob);