X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ftab.c;h=4aa7f069bc0cdceb43e426ca0d938aa16bc24091;hb=d594340cb1ae007a92d094ae67116f9f622f2b5d;hp=862028a8c5ab56959896e8b9cb8c9deb1f9c1c65;hpb=7b98b3a4f58f6dc5a8e9cbc188b627966d5e652d;p=pspp-builds.git diff --git a/src/tab.c b/src/tab.c index 862028a8..4aa7f069 100644 --- a/src/tab.c +++ b/src/tab.c @@ -14,16 +14,16 @@ 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 "tab.h" #include -#include #include #include #include +#include "error.h" #include "alloc.h" #include "command.h" #include "format.h" @@ -34,30 +34,21 @@ #include "som.h" #include "var.h" +#include "gettext.h" +#define _(msgid) gettext (msgid) + #include "debug-print.h" struct som_table_class tab_table_class; -#if DEBUGGING -#define DEFFIRST(NAME, LABEL) LABEL, -#define DEFTAB(NAME, LABEL) LABEL, -/* -static const char *tab_names[] = - { -#include "tab.def" - }; -*/ -#undef DEFFIRST -#undef DEFTAB -#endif - /* Creates a table with NC columns and NR rows. If REALLOCABLE is nonzero then the table's size can be increased later; otherwise, its size can only be reduced. */ struct tab_table * tab_create (int nc, int nr, int reallocable) { - void *(*alloc_func) (struct pool *, size_t); + void *(*alloc_func) (struct pool *, size_t n); + void *(*nalloc_func) (struct pool *, size_t n, size_t s); struct tab_table *t; @@ -75,28 +66,29 @@ tab_create (int nc, int nr, int reallocable) t->nc = t->cf = nc; t->l = t->r = t->t = t->b = 0; + nalloc_func = reallocable ? pool_nmalloc : pool_nalloc; alloc_func = reallocable ? pool_malloc : pool_alloc; #if GLOBAL_DEBUGGING t->reallocable = reallocable; #endif - t->cc = alloc_func (t->container, nr * nc * sizeof *t->cc); + t->cc = nalloc_func (t->container, nr * nc, sizeof *t->cc); t->ct = alloc_func (t->container, nr * nc); memset (t->ct, TAB_EMPTY, nc * nr); - t->rh = alloc_func (t->container, nc * (nr + 1)); + t->rh = nalloc_func (t->container, nc, nr + 1); memset (t->rh, 0, nc * (nr + 1)); - t->hrh = alloc_func (t->container, sizeof *t->hrh * (nr + 1)); + t->hrh = nalloc_func (t->container, nr + 1, sizeof *t->hrh); memset (t->hrh, 0, sizeof *t->hrh * (nr + 1)); t->trh = alloc_func (t->container, nr + 1); memset (t->trh, 0, nr + 1); - t->rv = alloc_func (t->container, (nc + 1) * nr); + t->rv = nalloc_func (t->container, nr, nc + 1); memset (t->rv, 0, (nc + 1) * nr); - t->wrv = alloc_func (t->container, sizeof *t->wrv * (nc + 1)); + t->wrv = nalloc_func (t->container, nc + 1, sizeof *t->wrv); memset (t->wrv, 0, sizeof *t->wrv * (nc + 1)); t->trv = alloc_func (t->container, nc + 1); @@ -169,11 +161,11 @@ tab_realloc (struct tab_table *t, int nc, int nr) int mr1 = min (nr, t->nr); int mc1 = min (nc, t->nc); - struct len_string *new_cc; + struct fixed_string *new_cc; unsigned char *new_ct; int r; - new_cc = pool_malloc (t->container, nr * nc * sizeof *new_cc); + new_cc = pool_nmalloc (t->container, nr * nc, sizeof *new_cc); new_ct = pool_malloc (t->container, nr * nc); for (r = 0; r < mr1; r++) { @@ -189,14 +181,13 @@ tab_realloc (struct tab_table *t, int nc, int nr) } else if (nr != t->nr) { - t->cc = pool_realloc (t->container, t->cc, nr * nc * sizeof *t->cc); + t->cc = pool_nrealloc (t->container, t->cc, nr * nc, sizeof *t->cc); t->ct = pool_realloc (t->container, t->ct, nr * nc); - t->rh = pool_realloc (t->container, t->rh, nc * (nr + 1)); - t->rv = pool_realloc (t->container, t->rv, (nc + 1) * nr); + t->rh = pool_nrealloc (t->container, t->rh, nc, nr + 1); + t->rv = pool_nrealloc (t->container, t->rv, nr, nc + 1); t->trh = pool_realloc (t->container, t->trh, nr + 1); - t->hrh = pool_realloc (t->container, t->hrh, - sizeof *t->hrh * (nr + 1)); + t->hrh = pool_nrealloc (t->container, t->hrh, nr + 1, sizeof *t->hrh); if (nr > t->nr) { @@ -223,6 +214,12 @@ void tab_headers (struct tab_table *table, int l, int r, int t, int b) { assert (table != NULL); + assert (l < table->nc); + assert (r < table->nc); + assert (t < table->nr); + assert (b < table->nr); + + table->l = l; table->r = r; table->t = t; @@ -252,11 +249,6 @@ tab_vline (struct tab_table *t, int style, int x, int y1, int y2) int y; assert (t != NULL); - assert (x > 0); - assert (x < t->nc); - assert (y1 >= 0); - assert (y2 >= y1); - assert (y2 <= t->nr); #if GLOBAL_DEBUGGING if (x + t->col_ofs < 0 || x + t->col_ofs > t->nc @@ -277,6 +269,12 @@ tab_vline (struct tab_table *t, int style, int x, int y1, int y2) y1 += t->row_ofs; y2 += t->row_ofs; + assert (x > 0); + assert (x < t->nc); + assert (y1 >= 0); + assert (y2 >= y1); + assert (y2 <= t->nr); + if (style != -1) { if ((style & TAL_SPACING) == 0) @@ -295,16 +293,16 @@ tab_hline (struct tab_table * t, int style, int x1, int x2, int y) assert (t != NULL); + x1 += t->col_ofs; + x2 += t->col_ofs; + y += t->row_ofs; + assert (y >= 0); assert (y < t->nr); assert (x2 >= x1 ); assert (x1 >= 0 ); assert (x2 < t->nc); - x1 += t->col_ofs; - x2 += t->col_ofs; - y += t->row_ofs; - if (style != -1) { if ((style & TAL_SPACING) == 0) @@ -326,13 +324,6 @@ tab_box (struct tab_table *t, int f_h, int f_v, int i_h, int i_v, { assert (t != NULL); - assert (x2 >= x1); - assert (y2 >= y1); - assert (x1 >= 0); - assert (y1 >= 0); - assert (x2 < t->nc); - assert (y2 < t->nr); - #if GLOBAL_DEBUGGING if (x1 + t->col_ofs < 0 || x1 + t->col_ofs >= t->nc || x2 + t->col_ofs < 0 || x2 + t->col_ofs >= t->nc @@ -355,6 +346,13 @@ tab_box (struct tab_table *t, int f_h, int f_v, int i_h, int i_v, y1 += t->row_ofs; y2 += t->row_ofs; + assert (x2 >= x1); + assert (y2 >= y1); + assert (x1 >= 0); + assert (y1 >= 0); + assert (x2 < t->nc); + assert (y2 < t->nr); + if (f_h != -1) { int x; @@ -416,7 +414,7 @@ tab_box (struct tab_table *t, int f_h, int f_v, int i_h, int i_v, the resultant string into S in TABLE's pool. */ static void text_format (struct tab_table *table, int opt, const char *text, va_list args, - struct len_string *s) + struct fixed_string *s) { int len; @@ -432,7 +430,8 @@ text_format (struct tab_table *table, int opt, const char *text, va_list args, else len = strlen (text); - ls_create_buffer (table->container, s, text, len); + ls_create_buffer (s, text, len); + pool_register (table->container, free, s->string); if (opt & TAT_PRINTF) local_free (text); @@ -570,7 +569,6 @@ tab_value (struct tab_table *table, int c, int r, unsigned char opt, const union value *v, const struct fmt_spec *f) { char *contents; - union value temp_val; assert (table != NULL && v != NULL && f != NULL); #if GLOBAL_DEBUGGING @@ -591,11 +589,6 @@ tab_value (struct tab_table *table, int c, int r, unsigned char opt, ls_init (&table->cc[c + r * table->cf], contents, f->w); table->ct[c + r * table->cf] = opt; - if (formats[f->type].cat & FCAT_STRING) - { - temp_val.c = (char *) v->s; - v = &temp_val; - } data_out (contents, f, v); } @@ -609,6 +602,7 @@ tab_float (struct tab_table *table, int c, int r, unsigned char opt, char buf[40], *cp; struct fmt_spec f; + union value double_value; assert (table != NULL && w <= 40); @@ -617,9 +611,7 @@ tab_float (struct tab_table *table, int c, int r, unsigned char opt, assert (r >= 0); assert (r < table->nr); - f.type = FMT_F; - f.w = w; - f.d = d; + f = make_output_format (FMT_F, w, d); #if GLOBAL_DEBUGGING if (c + table->col_ofs < 0 || r + table->row_ofs < 0 @@ -635,7 +627,9 @@ tab_float (struct tab_table *table, int c, int r, unsigned char opt, } #endif - data_out (buf, &f, (union value *) &val); + double_value.f = val; + data_out (buf, &f, &double_value); + cp = buf; while (isspace ((unsigned char) *cp) && cp < &buf[w]) cp++; @@ -692,12 +686,12 @@ tab_joint_text (struct tab_table *table, int x1, int y1, int x2, int y2, assert (table != NULL && text != NULL); - assert (x1 >= 0); - assert (y1 >= 0); + assert (x1 + table->col_ofs >= 0); + assert (y1 + table->row_ofs >= 0); assert (y2 >= y1); assert (x2 >= x1); - assert (y2 < table->nr); - assert (x2 < table->nc); + assert (y2 + table->row_ofs < table->nr); + assert (x2 + table->col_ofs < table->nc); #if GLOBAL_DEBUGGING if (x1 + table->col_ofs < 0 || x1 + table->col_ofs >= table->nc @@ -734,7 +728,7 @@ tab_joint_text (struct tab_table *table, int x1, int y1, int x2, int y2, opt |= TAB_JOIN; { - struct len_string *cc = &table->cc[x1 + y1 * table->cf]; + struct fixed_string *cc = &table->cc[x1 + y1 * table->cf]; unsigned char *ct = &table->ct[x1 + y1 * table->cf]; const int ofs = table->cf - (x2 - x1); @@ -759,7 +753,7 @@ tab_joint_text (struct tab_table *table, int x1, int y1, int x2, int y2, /* Sets cell (C,R) in TABLE, with options OPT, to contents STRING. */ void tab_raw (struct tab_table *table, int c, int r, unsigned opt, - struct len_string *string) + struct fixed_string *string) { assert (table != NULL && string != NULL); @@ -876,11 +870,12 @@ tab_flags (struct tab_table *t, unsigned flags) void tab_submit (struct tab_table *t) { - struct som_table s; + struct som_entity s; assert (t != NULL); s.class = &tab_table_class; s.ext = t; + s.type = SOM_TABLE; som_submit (&s); tab_destroy (t); } @@ -935,15 +930,17 @@ int tab_hit; /* Set the current table to TABLE. */ static void -tabi_table (struct som_table *table) +tabi_table (struct som_entity *table) { assert (table != NULL); + assert (table->type == SOM_TABLE); + t = table->ext; tab_offset (t, 0, 0); assert (t->w == NULL && t->h == NULL); - t->w = pool_alloc (t->container, sizeof *t->w * t->nc); - t->h = pool_alloc (t->container, sizeof *t->h * t->nr); + t->w = pool_nalloc (t->container, t->nc, sizeof *t->w); + t->h = pool_nalloc (t->container, t->nr, sizeof *t->h); } /* Set the current output device to DRIVER. */ @@ -1142,6 +1139,45 @@ tabi_flags (unsigned *flags) *flags = t->flags; } +/* Returns true if the table will fit in the given page WIDTH, + false otherwise. */ +static bool +tabi_fits_width (int width) +{ + int i; + + for (i = t->l; i < t->nc - t->r; i++) + if (t->wl + t->wr + t->w[i] > width) + return false; + + return true; +} + +/* Returns true if the table will fit in the given page LENGTH, + false otherwise. */ +static bool +tabi_fits_length (int length) +{ + int i; + + for (i = t->t; i < t->nr - t->b; i++) + if (t->ht + t->hb + t->h[i] > length) + return false; + + return true; +} + +/* Sets the number of header rows/columns on the left, right, top, + and bottom sides to HL, HR, HT, and HB, respectively. */ +static void +tabi_set_headers (int hl, int hr, int ht, int hb) +{ + t->l = hl; + t->r = hr; + t->t = ht; + t->b = hb; +} + /* Render title for current table, with major index X and minor index Y. Y may be zero, or X and Y may be zero, but X should be nonzero if Y is nonzero. */ @@ -1164,7 +1200,7 @@ tabi_title (int x, int y) cp = stpcpy (cp, ". "); if (!ls_empty_p (&t->title)) { - memcpy (cp, ls_value (&t->title), ls_length (&t->title)); + memcpy (cp, ls_c_str (&t->title), ls_length (&t->title)); cp += ls_length (&t->title); } *cp = 0; @@ -1242,9 +1278,12 @@ struct som_table_class tab_table_class = NULL, tabi_cumulate, tabi_flags, + tabi_fits_width, + tabi_fits_length, NULL, NULL, + tabi_set_headers, tabi_title, tabi_render, @@ -1339,7 +1378,7 @@ render_strip (int x, int y, int r, int c1, int c2, int r1 UNUSED, int r2) } } else { struct tab_joined_cell *j = - (struct tab_joined_cell *) ls_value (&t->cc[index]); + (struct tab_joined_cell *) ls_c_str (&t->cc[index]); if (j->hit != tab_hit) {