X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fascii.c;h=738526f388e2b4ba3241471faeac348133374d29;hb=0ef6ac022673935ef842a1059aad45b89d59f025;hp=06addff506fe6e447548695f20410f2e41341f6e;hpb=73d0e3cb5a4e99b5d46ea0ca2af5e8cdbaf445bc;p=pspp-builds.git diff --git a/src/ascii.c b/src/ascii.c index 06addff5..738526f3 100644 --- a/src/ascii.c +++ b/src/ascii.c @@ -14,11 +14,11 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ #include -#include +#include "error.h" #include #include #include @@ -26,12 +26,16 @@ #include "alloc.h" #include "error.h" #include "filename.h" +#include "glob.h" #include "main.h" #include "misc.h" #include "output.h" #include "pool.h" #include "version.h" +#include "gettext.h" +#define _(msgid) gettext (msgid) + /* ASCII driver options: (defaults listed first) output-file="pspp.list" @@ -49,6 +53,7 @@ width=130 lpi=6 Only used to determine font size. cpi=10 + squeeze=off|on Squeeze multiple newlines into exactly one. left-margin=0 right-margin=0 @@ -140,6 +145,14 @@ enum FSTY_COUNT = 6 /* Number of font styles. */ }; +/* A line of text. */ +struct line + { + unsigned short *chars; /* Characters and attributes. */ + int char_cnt; /* Length. */ + int char_cap; /* Allocated bytes. */ + }; + /* ASCII output driver extension record. */ struct ascii_driver_ext { @@ -156,48 +169,53 @@ struct ascii_driver_ext int bottom_margin; /* Bottom margin in lines. */ int paginate; /* 1=insert formfeeds. */ int tab_width; /* Width of a tab; 0 not to use tabs. */ - struct len_string ops[OPS_COUNT]; /* Basic output strings. */ - struct len_string box[LNS_COUNT]; /* Line & box drawing characters. */ - struct len_string fonts[FSTY_COUNT]; /* Font styles; NULL=overstrike. */ + struct fixed_string ops[OPS_COUNT]; /* Basic output strings. */ + struct fixed_string box[LNS_COUNT]; /* Line & box drawing characters. */ + struct fixed_string fonts[FSTY_COUNT]; /* Font styles; NULL=overstrike. */ int overstrike_style; /* OVS_SINGLE or OVS_LINE. */ int carriage_return_style; /* Carriage return style. */ + int squeeze_blank_lines; /* 1=squeeze multiple blank lines into one. */ /* Internal state. */ struct file_ext file; /* Output file. */ int page_number; /* Current page number. */ - unsigned short *page; /* Page content. */ - int page_size; /* Number of bytes allocated for page, attr. */ - int *line_len; /* Length of each line in page, attr. */ - int line_len_size; /* Number of ints allocated for line_len. */ + struct line *lines; /* Page content. */ + int lines_cap; /* Number of lines allocated. */ int w, l; /* Actual width & length w/o margins, etc. */ - int n_output; /* Number of lines output so far. */ int cur_font; /* Current font by OUTP_F_*. */ #if GLOBAL_DEBUGGING int debug; /* Set by som_text_draw(). */ #endif }; -static struct pool *ascii_pool; - static int postopen (struct file_ext *); static int preclose (struct file_ext *); -int -ascii_open_global (struct outp_class *this unused) +static struct outp_option_info *option_info; + +static int +ascii_open_global (struct outp_class *this UNUSED) { - ascii_pool = pool_create (); + option_info = xmalloc (sizeof *option_info); + option_info->initial = 0; + option_info->options = 0; return 1; } -int -ascii_close_global (struct outp_class *this unused) + +static char *s; +static int +ascii_close_global (struct outp_class *this UNUSED) { - pool_destroy (ascii_pool); + free(option_info->initial); + free(option_info->options); + free(option_info); + free(s); return 1; } -int * -ascii_font_sizes (struct outp_class *this unused, int *n_valid_sizes) +static int * +ascii_font_sizes (struct outp_class *this UNUSED, int *n_valid_sizes) { static int valid_sizes[] = {12, 12, 0, 0}; @@ -206,7 +224,7 @@ ascii_font_sizes (struct outp_class *this unused, int *n_valid_sizes) return valid_sizes; } -int +static int ascii_preopen_driver (struct outp_driver *this) { struct ascii_driver_ext *x; @@ -214,7 +232,7 @@ ascii_preopen_driver (struct outp_driver *this) assert (this->driver_open == 0); msg (VM (1), _("ASCII driver initializing as `%s'..."), this->name); - this->ext = x = xmalloc (sizeof (struct ascii_driver_ext)); + this->ext = x = xmalloc (sizeof *x); x->char_set = CHS_ASCII; x->headers = 1; x->page_length = 66; @@ -235,6 +253,7 @@ ascii_preopen_driver (struct outp_driver *this) ls_null (&x->fonts[i]); x->overstrike_style = OVS_SINGLE; x->carriage_return_style = CRS_BS; + x->squeeze_blank_lines = 0; x->file.filename = NULL; x->file.mode = "wb"; x->file.file = NULL; @@ -243,11 +262,8 @@ ascii_preopen_driver (struct outp_driver *this) x->file.postopen = postopen; x->file.preclose = preclose; x->page_number = 0; - x->page = NULL; - x->page_size = 0; - x->line_len = NULL; - x->line_len_size = 0; - x->n_output = 0; + x->lines = NULL; + x->lines_cap = 0; x->cur_font = OUTP_F_R; #if GLOBAL_DEBUGGING x->debug = 0; @@ -255,7 +271,7 @@ ascii_preopen_driver (struct outp_driver *this) return 1; } -int +static int ascii_postopen_driver (struct outp_driver *this) { struct ascii_driver_ext *x = this->ext; @@ -283,11 +299,11 @@ ascii_postopen_driver (struct outp_driver *this) this->length = x->l * this->vert; if (ls_null_p (&x->ops[OPS_FORMFEED])) - ls_create (ascii_pool, &x->ops[OPS_FORMFEED], "\f"); + ls_create (&x->ops[OPS_FORMFEED], "\f"); if (ls_null_p (&x->ops[OPS_NEWLINE]) - || !strcmp (ls_value (&x->ops[OPS_NEWLINE]), "default")) + || !strcmp (ls_c_str (&x->ops[OPS_NEWLINE]), "default")) { - ls_create (ascii_pool, &x->ops[OPS_NEWLINE], "\n"); + ls_create (&x->ops[OPS_NEWLINE], "\n"); x->file.mode = "wt"; } @@ -346,7 +362,7 @@ ascii_postopen_driver (struct outp_driver *this) c[0] = '+'; break; } - ls_create (ascii_pool, &x->box[i], c); + ls_create (&x->box[i], c); } } @@ -380,17 +396,30 @@ ascii_postopen_driver (struct outp_driver *this) return 1; } -int +static int ascii_close_driver (struct outp_driver *this) { struct ascii_driver_ext *x = this->ext; + int i; assert (this->driver_open == 1); msg (VM (2), _("%s: Beginning closing..."), this->name); x = this->ext; - free (x->page); - free (x->line_len); + for (i = 0; i < OPS_COUNT; i++) + ls_destroy (&x->ops[i]); + for (i = 0; i < LNS_COUNT; i++) + ls_destroy (&x->box[i]); + for (i = 0; i < FSTY_COUNT; i++) + ls_destroy (&x->fonts[i]); + if (x->lines != NULL) + { + int line; + + for (line = 0; line < x->lines_cap; line++) + free (x->lines[line].chars); + free (x->lines); + } fn_close_ext (&x->file); free (x->file.filename); free (x); @@ -438,11 +467,11 @@ static struct outp_option option_tab[] = {"overstrike-style", 3, 0}, {"tab-width", nonneg_int_arg, 4}, {"carriage-return-style", 4, 0}, + {"squeeze", boolean_arg, 2}, {"", 0, 0}, }; -static struct outp_option_info option_info; -void +static void ascii_option (struct outp_driver *this, const char *key, const struct string *val) { @@ -450,7 +479,7 @@ ascii_option (struct outp_driver *this, const char *key, int cat, subcat; const char *value; - value = ds_value (val); + value = ds_c_str (val); if (!strncmp (key, "box[", 4)) { char *tail; @@ -464,11 +493,11 @@ ascii_option (struct outp_driver *this, const char *key, } if (!ls_null_p (&x->box[indx])) msg (SW, _("Duplicate value for key `%s'."), key); - ls_create (ascii_pool, &x->box[indx], value); + ls_create (&x->box[indx], value); return; } - cat = outp_match_keyword (key, option_tab, &option_info, &subcat); + cat = outp_match_keyword (key, option_tab, option_info, &subcat); switch (cat) { case 0: @@ -574,7 +603,7 @@ ascii_option (struct outp_driver *this, const char *key, break; case string_arg: { - struct len_string *s; + struct fixed_string *s; switch (subcat) { case 0: @@ -591,18 +620,19 @@ ascii_option (struct outp_driver *this, const char *key, break; default: assert (0); + abort (); } - ls_create (ascii_pool, s, value); + ls_create (s, value); } break; case font_string_arg: { if (!strcmp (value, "overstrike")) { - ls_destroy (ascii_pool, &x->fonts[subcat]); + ls_destroy (&x->fonts[subcat]); return; } - ls_create (ascii_pool, &x->fonts[subcat], value); + ls_create (&x->fonts[subcat], value); } break; case boolean_arg: @@ -622,11 +652,14 @@ ascii_option (struct outp_driver *this, const char *key, switch (subcat) { case 0: - x->headers = 0; + x->headers = setting; break; case 1: x->paginate = setting; break; + case 2: + x->squeeze_blank_lines = setting; + break; default: assert (0); } @@ -641,9 +674,9 @@ int postopen (struct file_ext *f) { struct ascii_driver_ext *x = f->param; - struct len_string *s = &x->ops[OPS_INIT]; + struct fixed_string *s = &x->ops[OPS_INIT]; - if (!ls_empty_p (s) && fwrite (ls_value (s), ls_length (s), 1, f->file) < 1) + if (!ls_empty_p (s) && fwrite (ls_c_str (s), ls_length (s), 1, f->file) < 1) { msg (ME, _("ASCII output driver: %s: %s"), f->filename, strerror (errno)); @@ -656,9 +689,9 @@ int preclose (struct file_ext *f) { struct ascii_driver_ext *x = f->param; - struct len_string *d = &x->ops[OPS_DONE]; + struct fixed_string *d = &x->ops[OPS_DONE]; - if (!ls_empty_p (d) && fwrite (ls_value (d), ls_length (d), 1, f->file) < 1) + if (!ls_empty_p (d) && fwrite (ls_c_str (d), ls_length (d), 1, f->file) < 1) { msg (ME, _("ASCII output driver: %s: %s"), f->filename, strerror (errno)); @@ -667,11 +700,11 @@ preclose (struct file_ext *f) return 1; } -int +static int ascii_open_page (struct outp_driver *this) { struct ascii_driver_ext *x = this->ext; - int req_page_size; + int i; assert (this->driver_open && !this->page_open); x->page_number++; @@ -682,21 +715,20 @@ ascii_open_page (struct outp_driver *this) return 0; } - req_page_size = x->w * x->l; - if (req_page_size > x->page_size || req_page_size / 2 < x->page_size) - { - x->page_size = req_page_size; - x->page = xrealloc (x->page, sizeof *x->page * req_page_size); - } - - if (x->l > x->line_len_size) + if (x->l > x->lines_cap) { - x->line_len_size = x->l; - x->line_len = xrealloc (x->line_len, - sizeof *x->line_len * x->line_len_size); + x->lines = xnrealloc (x->lines, x->l, sizeof *x->lines); + for (i = x->lines_cap; i < x->l; i++) + { + struct line *line = &x->lines[i]; + line->chars = NULL; + line->char_cap = 0; + } + x->lines_cap = x->l; } - memset (x->line_len, 0, sizeof *x->line_len * x->l); + for (i = 0; i < x->l; i++) + x->lines[i].char_cnt = 0; this->page_open = 1; return 1; @@ -707,18 +739,26 @@ ascii_open_page (struct outp_driver *this) static inline void expand_line (struct ascii_driver_ext *x, int i, int l) { - int limit = i * x->w + l; + struct line *line; int j; - for (j = i * x->w + x->line_len[i]; j < limit; j++) - x->page[j] = ' '; - x->line_len[i] = l; + assert (i < x->lines_cap); + line = &x->lines[i]; + if (l > line->char_cap) + { + line->char_cap = l * 2; + line->chars = xnrealloc (line->chars, + line->char_cap, sizeof *line->chars); + } + for (j = line->char_cnt; j < l; j++) + line->chars[j] = ' '; + line->char_cnt = l; } /* Puts line L at (H,K) in the current output page. Assumes struct ascii_driver_ext named `ext'. */ #define draw_line(H, K, L) \ - ext->page[ext->w * (K) + (H)] = (L) | 0x800 + ext->lines[K].chars[H] = (L) | 0x800 /* Line styles for each position. */ #define T(STYLE) (STYLE<ext; int x1 = r->x1 / this->horiz; @@ -753,16 +793,16 @@ ascii_line_horz (struct outp_driver *this, const struct rect *r, } #endif - if (ext->line_len[y1] < x2) + if (ext->lines[y1].char_cnt < x2) expand_line (ext, y1, x2); for (x = x1; x < x2; x++) draw_line (x, y1, (style << LNS_LEFT) | (style << LNS_RIGHT)); } -void +static void ascii_line_vert (struct outp_driver *this, const struct rect *r, - const struct color *c unused, int style) + const struct color *c UNUSED, int style) { struct ascii_driver_ext *ext = this->ext; int x1 = r->x1 / this->horiz; @@ -788,16 +828,16 @@ ascii_line_vert (struct outp_driver *this, const struct rect *r, #endif for (y = y1; y < y2; y++) - if (ext->line_len[y] <= x1) + if (ext->lines[y].char_cnt <= x1) expand_line (ext, y, x1 + 1); for (y = y1; y < y2; y++) draw_line (x1, y, (style << LNS_TOP) | (style << LNS_BOTTOM)); } -void +static void ascii_line_intersection (struct outp_driver *this, const struct rect *r, - const struct color *c unused, + const struct color *c UNUSED, const struct outp_styles *style) { struct ascii_driver_ext *ext = this->ext; @@ -820,52 +860,38 @@ ascii_line_intersection (struct outp_driver *this, const struct rect *r, l = ((style->l << LNS_LEFT) | (style->r << LNS_RIGHT) | (style->t << LNS_TOP) | (style->b << LNS_BOTTOM)); - if (ext->line_len[y] <= x) + if (ext->lines[y].char_cnt <= x) expand_line (ext, y, x + 1); draw_line (x, y, l); } -void -ascii_line_width (struct outp_driver *this, int *width, int *height) -{ - int i; - - assert (this->driver_open && this->page_open); - width[0] = height[0] = 0; - for (i = 1; i < OUTP_L_COUNT; i++) - { - width[i] = this->horiz; - height[i] = this->vert; - } -} - /* FIXME: Later we could set this up so that for certain devices it performs shading? */ -void -ascii_box (struct outp_driver *this unused, const struct rect *r unused, - const struct color *bord unused, const struct color *fill unused) +static void +ascii_box (struct outp_driver *this UNUSED, const struct rect *r UNUSED, + const struct color *bord UNUSED, const struct color *fill UNUSED) { assert (this->driver_open && this->page_open); } /* Polylines not supported. */ -void -ascii_polyline_begin (struct outp_driver *this unused, const struct color *c unused) +static void +ascii_polyline_begin (struct outp_driver *this UNUSED, const struct color *c UNUSED) { assert (this->driver_open && this->page_open); } -void -ascii_polyline_point (struct outp_driver *this unused, int x unused, int y unused) +static void +ascii_polyline_point (struct outp_driver *this UNUSED, int x UNUSED, int y UNUSED) { assert (this->driver_open && this->page_open); } -void -ascii_polyline_end (struct outp_driver *this unused) +static void +ascii_polyline_end (struct outp_driver *this UNUSED) { assert (this->driver_open && this->page_open); } -void +static void ascii_text_set_font_by_name (struct outp_driver * this, const char *s) { struct ascii_driver_ext *x = this->ext; @@ -886,7 +912,7 @@ ascii_text_set_font_by_name (struct outp_driver * this, const char *s) x->cur_font = OUTP_F_B; } -void +static void ascii_text_set_font_by_position (struct outp_driver *this, int pos) { struct ascii_driver_ext *x = this->ext; @@ -894,13 +920,13 @@ ascii_text_set_font_by_position (struct outp_driver *this, int pos) x->cur_font = pos >= 0 && pos < 4 ? pos : 0; } -void -ascii_text_set_font_by_family (struct outp_driver *this unused, const char *s unused) +static void +ascii_text_set_font_by_family (struct outp_driver *this UNUSED, const char *s UNUSED) { assert (this->driver_open && this->page_open); } -const char * +static const char * ascii_text_get_font_name (struct outp_driver *this) { struct ascii_driver_ext *x = this->ext; @@ -922,21 +948,21 @@ ascii_text_get_font_name (struct outp_driver *this) abort (); } -const char * -ascii_text_get_font_family (struct outp_driver *this unused) +static const char * +ascii_text_get_font_family (struct outp_driver *this UNUSED) { assert (this->driver_open && this->page_open); return ""; } -int +static int ascii_text_set_size (struct outp_driver *this, int size) { assert (this->driver_open && this->page_open); return size == this->vert; } -int +static int ascii_text_get_size (struct outp_driver *this, int *em_width) { assert (this->driver_open && this->page_open); @@ -962,7 +988,7 @@ delineate (struct outp_driver *this, struct outp_text *t, int draw) int max_y; /* Current position in string, character following end of string. */ - const char *s = ls_value (&t->s); + const char *s = ls_c_str (&t->s); const char *end = ls_end (&t->s); /* Temporary struct outp_text to pass to low-level function. */ @@ -1050,7 +1076,7 @@ delineate (struct outp_driver *this, struct outp_text *t, int draw) t->v = (temp.y * this->vert) - t->y; } -void +static void ascii_text_metrics (struct outp_driver *this, struct outp_text *t) { assert (this->driver_open && this->page_open); @@ -1063,7 +1089,7 @@ ascii_text_metrics (struct outp_driver *this, struct outp_text *t) delineate (this, t, 0); } -void +static void ascii_text_draw (struct outp_driver *this, struct outp_text *t) { /* FIXME: orientations not supported. */ @@ -1092,9 +1118,9 @@ text_draw (struct outp_driver *this, struct outp_text *t) unsigned attr = ext->cur_font << 8; int x = t->x; - int y = t->y * ext->w; + int y = t->y; - char *s = ls_value (&t->s); + char *s = ls_c_str (&t->s); /* Expand the line with the assumption that S takes up LEN character spaces (sometimes it takes up less). */ @@ -1117,7 +1143,7 @@ text_draw (struct outp_driver *this, struct outp_text *t) if (!(t->y < ext->l && x < ext->w)) return; min_len = min (x + ls_length (&t->s), ext->w); - if (ext->line_len[t->y] < min_len) + if (ext->lines[t->y].char_cnt < min_len) expand_line (ext, t->y, min_len); { @@ -1126,15 +1152,15 @@ text_draw (struct outp_driver *this, struct outp_text *t) if (len + x > ext->w) len = ext->w - x; while (len--) - ext->page[y + x++] = *s++ | attr; + ext->lines[y].chars[x++] = *s++ | attr; } } /* ascii_close_page () and support routines. */ #define LINE_BUF_SIZE 1024 -static unsigned char *line_buf; -static unsigned char *line_p; +static char *line_buf; +static char *line_p; static inline int commit_line_buf (struct outp_driver *this) @@ -1187,12 +1213,12 @@ output_shorts (struct outp_driver *this, { if (*bp & 0x800) { - struct len_string *box = &ext->box[*bp & 0xff]; + struct fixed_string *box = &ext->box[*bp & 0xff]; size_t len = ls_length (box); if (remaining >= len) { - memcpy (line_p, ls_value (box), len); + memcpy (line_p, ls_c_str (box), len); line_p += len; remaining -= len; } @@ -1200,13 +1226,13 @@ output_shorts (struct outp_driver *this, { if (!commit_line_buf (this)) return 0; - output_string (this, ls_value (box), ls_end (box)); + output_string (this, ls_c_str (box), ls_end (box)); remaining = LINE_BUF_SIZE - (line_p - line_buf); } } else if (*bp & 0x0300) { - struct len_string *on; + struct fixed_string *on; char buf[5]; int len; @@ -1223,6 +1249,7 @@ output_shorts (struct outp_driver *this, break; default: assert (0); + abort (); } if (!on) { @@ -1251,6 +1278,7 @@ output_shorts (struct outp_driver *this, break; default: assert (0); + abort (); } else { @@ -1285,7 +1313,7 @@ output_shorts (struct outp_driver *this, /* Writes CH into line_buf N times, or to THIS->output if line_buf overflows. */ static inline void -output_char (struct outp_driver *this, int n, int ch) +output_char (struct outp_driver *this, int n, char ch) { if (LINE_BUF_SIZE - (line_p - line_buf) >= n) { @@ -1337,6 +1365,7 @@ return_carriage (struct outp_driver *this, int n_chars) break; default: assert (0); + abort (); } } @@ -1346,10 +1375,9 @@ static void output_lines (struct outp_driver *this, int first, int count) { struct ascii_driver_ext *ext = this->ext; + int line_num; - unsigned short *p = &ext->page[ext->w * first]; - int *len = &ext->line_len[first]; - struct len_string *newline = &ext->ops[OPS_NEWLINE]; + struct fixed_string *newline = &ext->ops[OPS_NEWLINE]; int n_chars; int n_passes; @@ -1357,15 +1385,25 @@ output_lines (struct outp_driver *this, int first, int count) if (NULL == ext->file.file) return; - while (count--) /* Iterate over all the lines to be output. */ + /* Iterate over all the lines to be output. */ + for (line_num = first; line_num < first + count; line_num++) { - unsigned short *end_p; + struct line *line = &ext->lines[line_num]; + unsigned short *p = line->chars; + unsigned short *end_p = p + line->char_cnt; unsigned short *bp, *ep; unsigned short attr = 0; - end_p = p + *len++; assert (end_p >= p); + /* Squeeze multiple blank lines into a single blank line if + requested. */ + if (ext->squeeze_blank_lines + && line_num > first + && ext->lines[line_num].char_cnt == 0 + && ext->lines[line_num - 1].char_cnt == 0) + continue; + /* Output every character in the line in the appropriate manner. */ n_passes = 1; @@ -1387,7 +1425,7 @@ output_lines (struct outp_driver *this, int first, int count) /* Turn off old font. */ if (attr != (OUTP_F_R << 8)) { - struct len_string *off; + struct fixed_string *off; switch (attr) { @@ -1402,16 +1440,17 @@ output_lines (struct outp_driver *this, int first, int count) break; default: assert (0); + abort (); } if (off) - output_string (this, ls_value (off), ls_end (off)); + output_string (this, ls_c_str (off), ls_end (off)); } /* Turn on new font. */ attr = (*bp & 0x0300); if (attr != (OUTP_F_R << 8)) { - struct len_string *on; + struct fixed_string *on; switch (attr) { @@ -1426,16 +1465,17 @@ output_lines (struct outp_driver *this, int first, int count) break; default: assert (0); + abort (); } if (on) - output_string (this, ls_value (on), ls_end (on)); + output_string (this, ls_c_str (on), ls_end (on)); } ep = bp + 1; } if (n_passes > 1) { - unsigned char ch; + char ch; return_carriage (this, n_chars); n_chars = 0; @@ -1460,6 +1500,9 @@ output_lines (struct outp_driver *this, int first, int count) ch = *ep; n_passes = 3; break; + default: + assert (0); + abort (); } output_char (this, 1, ch); n_chars += ep - bp + 1; @@ -1483,21 +1526,20 @@ output_lines (struct outp_driver *this, int first, int count) ep = bp; } } - p += ext->w; - output_string (this, ls_value (newline), ls_end (newline)); + output_string (this, ls_c_str (newline), ls_end (newline)); } } -int + +static int ascii_close_page (struct outp_driver *this) { - static unsigned char *s; static int s_len; struct ascii_driver_ext *x = this->ext; int nl_len, ff_len, total_len; - unsigned char *cp; + char *cp; int i; assert (this->driver_open && this->page_open); @@ -1517,7 +1559,7 @@ ascii_close_page (struct outp_driver *this) } for (cp = s, i = 0; i < x->top_margin; i++) { - memcpy (cp, ls_value (&x->ops[OPS_NEWLINE]), nl_len); + memcpy (cp, ls_c_str (&x->ops[OPS_NEWLINE]), nl_len); cp += nl_len; } output_string (this, s, &s[total_len]); @@ -1538,7 +1580,8 @@ ascii_close_page (struct outp_driver *this) { char temp[40]; - snprintf (temp, 80, _("%s - Page %d"), curdate, x->page_number); + snprintf (temp, 80, _("%s - Page %d"), get_start_date (), + x->page_number); memcpy (&s[x->w - strlen (temp)], temp, strlen (temp)); } @@ -1547,7 +1590,7 @@ ascii_close_page (struct outp_driver *this) len = min ((int) strlen (outp_title), x->w); memcpy (s, outp_title, len); } - memcpy (&s[x->w], ls_value (&x->ops[OPS_NEWLINE]), nl_len); + memcpy (&s[x->w], ls_c_str (&x->ops[OPS_NEWLINE]), nl_len); output_string (this, s, &s[total_len]); memset (s, ' ', x->w); @@ -1560,14 +1603,14 @@ ascii_close_page (struct outp_driver *this) len = min ((int) strlen (string), x->w); memcpy (s, string, len); } - memcpy (&s[x->w], ls_value (&x->ops[OPS_NEWLINE]), nl_len); + memcpy (&s[x->w], ls_c_str (&x->ops[OPS_NEWLINE]), nl_len); output_string (this, s, &s[total_len]); output_string (this, &s[x->w], &s[total_len]); } if (line_p != line_buf && !commit_line_buf (this)) return 0; - output_lines (this, x->n_output, x->l - x->n_output); + output_lines (this, 0, x->l); ff_len = ls_length (&x->ops[OPS_FORMFEED]); total_len = x->bottom_margin * nl_len + ff_len; @@ -1575,21 +1618,35 @@ ascii_close_page (struct outp_driver *this) s = xrealloc (s, total_len); for (cp = s, i = 0; i < x->bottom_margin; i++) { - memcpy (cp, ls_value (&x->ops[OPS_NEWLINE]), nl_len); + memcpy (cp, ls_c_str (&x->ops[OPS_NEWLINE]), nl_len); cp += nl_len; } - memcpy (cp, ls_value (&x->ops[OPS_FORMFEED]), ff_len); + memcpy (cp, ls_c_str (&x->ops[OPS_FORMFEED]), ff_len); if ( x->paginate ) output_string (this, s, &s[total_len]); + if (line_p != line_buf && !commit_line_buf (this)) return 0; - x->n_output = 0; - this->page_open = 0; return 1; } + + +static void +ascii_chart_initialise(struct outp_driver *d UNUSED, struct chart *ch ) +{ + msg(MW, _("Charts are unsupported with ascii drivers.")); + ch->lp = 0; +} + +static void +ascii_chart_finalise(struct outp_driver *d UNUSED, struct chart *ch UNUSED) +{ + +} + struct outp_class ascii_class = { "ascii", @@ -1628,4 +1685,7 @@ struct outp_class ascii_class = ascii_text_get_size, ascii_text_metrics, ascii_text_draw, + + ascii_chart_initialise, + ascii_chart_finalise };