X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fascii.c;h=4a30663fa452df1fa9ef46e24708e87940a71fd7;hb=eeb3352d718b0cd85afab3f7a7466fcac7791c1c;hp=72e536b16b0dbe53af90c9c151e2e258df774340;hpb=205ac3afa4c2b19c85819d8695abf3975bb11807;p=pspp-builds.git diff --git a/src/ascii.c b/src/ascii.c index 72e536b1..4a30663f 100644 --- a/src/ascii.c +++ b/src/ascii.c @@ -141,6 +141,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 { @@ -167,34 +175,38 @@ struct ascii_driver_ext /* 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 *); +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 (struct outp_option_info ) ) ; + option_info->initial = 0; + option_info->options = 0; return 1; } + +static unsigned char *s=0; 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; } @@ -246,11 +258,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; @@ -286,11 +295,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"; } @@ -349,7 +358,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); } } @@ -387,13 +396,26 @@ 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); @@ -444,7 +466,6 @@ static struct outp_option option_tab[] = {"squeeze", boolean_arg, 2}, {"", 0, 0}, }; -static struct outp_option_info option_info; static void ascii_option (struct outp_driver *this, const char *key, @@ -454,7 +475,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; @@ -468,11 +489,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: @@ -595,18 +616,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: @@ -650,7 +672,7 @@ postopen (struct file_ext *f) struct ascii_driver_ext *x = f->param; struct len_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)); @@ -665,7 +687,7 @@ preclose (struct file_ext *f) struct ascii_driver_ext *x = f->param; struct len_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)); @@ -678,7 +700,7 @@ 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++; @@ -689,21 +711,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 = xrealloc (x->lines, sizeof *x->lines * x->l); + 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; @@ -714,18 +735,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 = xrealloc (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<line_len[y1] < x2) + if (ext->lines[y1].char_cnt < x2) expand_line (ext, y1, x2); for (x = x1; x < x2; x++) @@ -795,7 +824,7 @@ 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++) @@ -827,7 +856,7 @@ 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); } @@ -955,7 +984,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. */ @@ -1085,9 +1114,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). */ @@ -1110,7 +1139,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); { @@ -1119,7 +1148,7 @@ 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; } } @@ -1185,7 +1214,7 @@ output_shorts (struct outp_driver *this, if (remaining >= len) { - memcpy (line_p, ls_value (box), len); + memcpy (line_p, ls_c_str (box), len); line_p += len; remaining -= len; } @@ -1193,7 +1222,7 @@ 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); } } @@ -1216,6 +1245,7 @@ output_shorts (struct outp_driver *this, break; default: assert (0); + abort (); } if (!on) { @@ -1244,6 +1274,7 @@ output_shorts (struct outp_driver *this, break; default: assert (0); + abort (); } else { @@ -1330,6 +1361,7 @@ return_carriage (struct outp_driver *this, int n_chars) break; default: assert (0); + abort (); } } @@ -1352,8 +1384,9 @@ output_lines (struct outp_driver *this, int first, int count) /* Iterate over all the lines to be output. */ for (line_num = first; line_num < first + count; line_num++) { - unsigned short *p = &ext->page[ext->w * line_num]; - unsigned short *end_p = p + ext->line_len[line_num]; + 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; @@ -1363,8 +1396,8 @@ output_lines (struct outp_driver *this, int first, int count) requested. */ if (ext->squeeze_blank_lines && line_num > first - && ext->line_len[line_num] == 0 - && ext->line_len[line_num - 1] == 0) + && 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 @@ -1403,9 +1436,10 @@ 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. */ @@ -1427,9 +1461,10 @@ 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; @@ -1463,6 +1498,7 @@ output_lines (struct outp_driver *this, int first, int count) break; default: assert (0); + abort (); } output_char (this, 1, ch); n_chars += ep - bp + 1; @@ -1487,14 +1523,14 @@ output_lines (struct outp_driver *this, int first, int count) } } - output_string (this, ls_value (newline), ls_end (newline)); + output_string (this, ls_c_str (newline), ls_end (newline)); } } + static int ascii_close_page (struct outp_driver *this) { - static unsigned char *s; static int s_len; struct ascii_driver_ext *x = this->ext; @@ -1519,7 +1555,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]); @@ -1549,7 +1585,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); @@ -1562,14 +1598,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; @@ -1577,17 +1613,20 @@ 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)) + { + free(s); + s=0; return 0; + } - x->n_output = 0; - this->page_open = 0; return 1; }