We're abusing the current ASCII driver by telling it to allocate a
authorBen Pfaff <blp@gnu.org>
Tue, 27 Apr 2004 05:54:31 +0000 (05:54 +0000)
committerBen Pfaff <blp@gnu.org>
Tue, 27 Apr 2004 05:54:31 +0000 (05:54 +0000)
9999-line, 9999-character page in the tests.  This causes some systems
to curl up and die because it allocates 20 MB of contiguous RAM.  This
change alleviates at least part of the problem.  It is mostly a
stop-gap until the new output system is ready.

Also, get rid of unused matrix.[ch].

src/ChangeLog
src/Makefile.am
src/ascii.c
src/matrix.c [deleted file]
src/matrix.h [deleted file]

index a9112641a8097f25e8e6f802177208d21316f789..9691ad7c7ca006130ba3df167f6b2ccc24862393 100644 (file)
@@ -1,3 +1,33 @@
+Mon Apr 26 22:40:07 2004  Ben Pfaff  <blp@gnu.org>
+
+       We're abusing the current ASCII driver by telling it to allocate a
+       9999-line, 9999-character page in the tests.  This causes some
+       systems to curl up and die because it allocates 20 MB of
+       contiguous RAM.  This change alleviates at least part of the
+       problem.  It is mostly a stop-gap until the new output system is
+       ready.
+       
+       * ascii.c: (struct line) New structure.
+       (struct ascii_driver_ext) Remove `page', `page_size', `line_len',
+       `line_len_size', `n_output' members.  Add `lines', `lines_cap'.
+       (ascii_preopen_driver) Initialize new members, not old ones.
+       (ascii_close_driver) Destroy new members, not old ones.
+       (ascii_open_page) Allocate new members, not old ones.
+       (expand_line) Allocate room in line.
+       (draw_line) Use new members.
+       (ascii_line_horz) Ditto.
+       (ascii_line_vert) Ditto.
+       (ascii_line_intersection) Ditto.
+       (text_draw) Ditto.
+       (output_lines) Ditto.
+       (ascii_close_page) Ditto.
+
+Sun Apr 25 23:40:15 2004  Ben Pfaff  <blp@gnu.org>
+
+       * matrix.c: Dead code.  Removed.
+
+       * matrix.h: Dead code.  Removed.
+
 Fri Apr 16 23:59:51 2004  Ben Pfaff  <blp@gnu.org>
 
        Contrary to what I'd always understood, there is an efficient
index 80195782e9f799d025d8d0ee0605f5312d28561a..b96d96e8420e1fcb65943743d8ebe2219b2e7e4f 100644 (file)
@@ -60,7 +60,7 @@ file-type.c filename.c filename.h flip.c font.h format.c format.def   \
 format.h formats.c get.c getline.c getline.h glob.c glob.h             \
 groff-font.c hash.c hash.h html.c htmlP.h include.c inpt-pgm.c lexer.c \
 lexer.h levene.c levene.h log.h loop.c magic.c magic.h main.c main.h   \
-matrix-data.c matrix.c matrix.h mis-val.c misc.c misc.h modify-vars.c  \
+matrix-data.c mis-val.c misc.c misc.h modify-vars.c                    \
 moments.c moments.h numeric.c output.c output.h pfm-read.c pfm-write.c \
 pfm.h pool.c pool.h postscript.c print.c random.c random.h recode.c    \
 rename-vars.c repeat.c repeat.h sample.c sel-if.c settings.h           \
index 9c0103e0c5e2b044a97f200d5a2acbd1254da62a..bdaac410566cdf55a5ef26e7bb0e4a319ac6db31 100644 (file)
@@ -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,12 +175,9 @@ 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(). */
@@ -246,11 +251,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;
@@ -392,8 +394,14 @@ ascii_close_driver (struct outp_driver *this)
   msg (VM (2), _("%s: Beginning closing..."), this->name);
   
   x = this->ext;
-  free (x->page);
-  free (x->line_len);
+  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);
@@ -679,7 +687,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++;
@@ -690,21 +698,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)
+  if (x->l > x->lines_cap)
     {
-      x->page_size = req_page_size;
-      x->page = xrealloc (x->page, sizeof *x->page * req_page_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;
     }
 
-  if (x->l > x->line_len_size)
-    {
-      x->line_len_size = x->l;
-      x->line_len = xrealloc (x->line_len,
-                             sizeof *x->line_len * x->line_len_size);
-    }
-
-  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;
@@ -715,18 +722,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<<LNS_TOP)
@@ -761,7 +776,7 @@ 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++)
@@ -796,7 +811,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++)
@@ -828,7 +843,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);
 }
@@ -1086,7 +1101,7 @@ 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);
 
@@ -1111,7 +1126,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);
 
   {
@@ -1120,7 +1135,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;
   }
 }
 \f
@@ -1356,8 +1371,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;
 
@@ -1367,8 +1383,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
@@ -1576,7 +1592,7 @@ ascii_close_page (struct outp_driver *this)
   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;
@@ -1593,8 +1609,6 @@ ascii_close_page (struct outp_driver *this)
   if (line_p != line_buf && !commit_line_buf (this))
     return 0;
 
-  x->n_output = 0;
-  
   this->page_open = 0;
   return 1;
 }
diff --git a/src/matrix.c b/src/matrix.c
deleted file mode 100644 (file)
index 4631e7d..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-/* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
-   Written by Ben Pfaff <blp@gnu.org>.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   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. */
-
-#include <config.h>
-#include "matrix.h"
-#include "error.h"
-#include <stdlib.h>
-#include "alloc.h"
-\f
-/* Kahan summation formula, Thm. 8, _What Every Computer Scientist
-   Should Know About Floating-Point Arithmetic_, David Goldberg,
-   orig. March 1991 issue of Computing Surveys, also at
-   <URL:http://www.wam.umd.edu/whats_new/workshop3.0/common-tools/numerical_comp_guide/goldberg1.doc.html>.
-   Hopefully your compiler won't try to optimize the code below too
-   much, because that will ruin the precision. */
-#define KAHAN_SUMMATION_FORMULA(S)                             \
-       do                                                      \
-         {                                                     \
-           double S_c;                                         \
-           int S_j;                                            \
-                                                               \
-           S = SUMMATION_ELEMENT (0);                          \
-           S_c = 0.;                                           \
-           for (S_j = 1; S_j < SUMMATION_COUNT; S_j++)         \
-             {                                                 \
-               double S_y = SUMMATION_ELEMENT (S_j) - S_c;     \
-               double S_t = S + S_y;                           \
-               S_c = (S_t - S) - S_y;                          \
-               S = S_t;                                        \
-             }                                                 \
-         }                                                     \
-       while (0)
-
-\f
-/* Vectors. */
-
-/* Allocate a new vector of length N. */
-struct vector *
-vec_alloc (int n)
-{
-  struct vector *vec = xmalloc (sizeof *vec);
-  vec->data = xmalloc (sizeof *vec->data * n);
-  vec->n = vec->m = n;
-  return vec;
-}
-
-/* Change the length of VEC to N.  The amount of space allocated will
-   not be lowered, but may be enlarged. */
-void
-vec_realloc (struct vector *vec, int n)
-{
-  if (n < vec->m)
-    {
-      vec->m = n;
-      vec->data = xrealloc (vec->data, sizeof *vec->data * n);
-    }
-  vec->n = n;
-}
-
-/* Free vector VEC. */
-void
-vec_free (struct vector *vec)
-{
-  free (vec->data);
-  free (vec);
-}
-
-/* Set the values in vector VEC to constant VALUE. */
-#if 0
-void
-vec_init (struct vector *vec, double value)
-{
-  double *p;
-  int i;
-
-  p = vec->data;
-  for (i = 0; i < vec->n; i++)
-    *p++ = value;
-}
-#endif
-
-/* Print out vector VEC to stdout for debugging purposes. */
-#if GLOBAL_DEBUGGING
-#include <stdio.h>
-#include "settings.h"
-
-void
-vec_print (const struct vector *vec)
-{
-  int i;
-
-  for (i = 0; i < vec->n; i++)
-    {
-      if (i % ((get_viewwidth() - 4) / 8) == 0)
-       {
-         if (i)
-           putchar ('\n');
-         printf ("%3d:", i);
-       }
-      
-      printf ("%8g", vec_elem (vec, i));
-    }
-}
-#endif
-
-/* Return the sum of the values in VEC. */
-double
-vec_total (const struct vector *vec)
-{
-  double sum;
-
-#define SUMMATION_COUNT (vec->n)
-#define SUMMATION_ELEMENT(INDEX) (vec_elem (vec, (INDEX)))
-  KAHAN_SUMMATION_FORMULA (sum);
-#undef SUMMATION_COUNT
-#undef SUMMATION_ELEMENT
-
-  return sum;
-}
-\f
-/* Matrices. */
-
-/* Allocate a new matrix with NR rows and NC columns. */
-struct matrix *
-mat_alloc (int nr, int nc)
-{
-  struct matrix *mat = xmalloc (sizeof *mat);
-  mat->nr = nr;
-  mat->nc = nc;
-  mat->m = nr * nc;
-  mat->data = xmalloc (sizeof *mat->data * nr * nc);
-  return mat;
-}
-
-/* Set the size of matrix MAT to NR rows and NC columns.  The matrix
-   data array will be enlarged if necessary but will not be shrunk. */
-void
-mat_realloc (struct matrix *mat, int nr, int nc)
-{
-  if (nc * nr > mat->m)
-    {
-      mat->m = nc * nr;
-      mat->data = xrealloc (mat->data, sizeof *mat->data * mat->m);
-    }
-  mat->nr = nr;
-  mat->nc = nc;
-}
-
-/* Free matrix MAT. */
-void
-mat_free (struct matrix *mat)
-{
-  free (mat->data);
-  free (mat);
-}
-
-/* Set all matrix MAT entries to VALUE. */
-void
-mat_init (struct matrix *mat, double value)
-{
-  double *p;
-  int i;
-
-  p = mat->data;
-  for (i = 0; i < mat->nr * mat->nc; i++)
-    *p++ = value;
-}
-
-/* Set all MAT entries in row R to VALUE. */
-void
-mat_init_row (struct matrix *mat, int r, double value)
-{
-  double *p;
-  int i;
-
-  p = &mat_elem (mat, r, 0);
-  for (i = 0; i < mat->nc; i++)
-    *p++ = value;
-}
-
-/* Set all MAT entries in column C to VALUE. */
-void
-mat_init_col (struct matrix *mat, int c, double value)
-{
-  double *p;
-  int i;
-
-  p = &mat_elem (mat, 0, c);
-  for (i = 0; i < mat->nr; i++)
-    {
-      *p = value;
-      p += mat->nc;
-    }
-}
-
-/* Print out MAT entries to stdout, optionally with row and column
-   labels ROW_LABELS and COL_LABELS. */
-#if GLOBAL_DEBUGGING
-void
-mat_print (const struct matrix *mat,
-          const struct vector *row_labels,
-          const struct vector *col_labels)
-{
-  int r, c;
-  
-  assert (!row_labels || row_labels->n == mat->nr);
-  if (col_labels)
-    {
-      int c;
-      
-      assert (col_labels->n == mat->nc);
-      if (row_labels)
-       printf ("        ");
-      for (c = 0; c < mat->nc; c++)
-       printf ("%8g", vec_elem (col_labels, c));
-    }
-
-  for (r = 0; r < mat->nr; r++)
-    {
-      if (row_labels)
-       printf ("%8g:", vec_elem (row_labels, r));
-      for (c = 0; c < mat->nc; c++)
-       printf ("%8g", mat_elem (mat, r, c));
-      putchar ('\n');
-    }
-}
-#endif /* GLOBAL_DEBUGGING */
-
-/* Calculate row totals for matrix MAT into vector ROW_TOTS. */
-void
-mat_row_totals (const struct matrix *mat, struct vector *row_tots)
-{
-  int r;
-  
-  vec_realloc (row_tots, mat->nr);
-  for (r = 0; r < mat->nr; r++)
-    {
-      double sum;
-
-#define SUMMATION_COUNT (mat->nc)
-#define SUMMATION_ELEMENT(INDEX) (mat_elem (mat, r, INDEX))
-      KAHAN_SUMMATION_FORMULA (sum);
-#undef SUMMATION_COUNT
-#undef SUMMATION_ELEMENT
-
-      vec_elem (row_tots, r) = sum;
-    }
-}
-
-/* Calculate column totals for matrix MAT into vector COL_TOTS. */
-void
-mat_col_totals (const struct matrix *mat, struct vector *col_tots)
-{
-  int c;
-  
-  vec_realloc (col_tots, mat->nc);
-  for (c = 0; c < mat->nc; c++)
-    {
-      double sum;
-
-#define SUMMATION_COUNT (mat->nr)
-#define SUMMATION_ELEMENT(INDEX) (mat_elem (mat, INDEX, c))
-      KAHAN_SUMMATION_FORMULA (sum);
-#undef SUMMATION_COUNT
-#undef SUMMATION_ELEMENT
-
-      vec_elem (col_tots, c) = sum;
-    }
-}
-
-/* Return the grand total for matrix MAT.  Of course, if you're also
-   calculating column or row totals, it would be faster to use
-   vec_total on one of those sets of totals. */
-double
-mat_grand_total (const struct matrix *mat)
-{
-  double sum;
-
-#define SUMMATION_COUNT (mat->nr * mat->nc)
-#define SUMMATION_ELEMENT(INDEX) (mat->data[INDEX])
-  KAHAN_SUMMATION_FORMULA (sum);
-#undef SUMMATION_COUNT
-#undef SUMMATION_ELEMENT
-
-  return sum;
-}
diff --git a/src/matrix.h b/src/matrix.h
deleted file mode 100644 (file)
index c1e5c61..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-/* PSPP - computes sample statistics.
-   Copyright (C) 1997-9, 2000 Free Software Foundation, Inc.
-   Written by Ben Pfaff <blp@gnu.org>.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of the
-   License, or (at your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   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. */
-
-#if !matrix_h
-#define matrix_h 1
-\f
-/* Vector representation. */
-struct vector
-  {
-    int n;
-    int m;
-    double *data;
-  };
-
-/* Allocate vectors. */
-struct vector *vec_alloc (int n);
-void vec_realloc (struct vector *, int n);
-void vec_free (struct vector *);
-
-/* Vector elements. */
-#define vec_elem(VEC, INDEX) ((VEC)->data[INDEX])
-
-/* Set the vector to a constant value. */
-void vec_init (struct vector *, double);
-
-/* Print out the vector to stdout. */
-#if GLOBAL_DEBUGGING
-void vec_print (const struct vector *);
-#endif
-
-/* Sum the vector values. */
-double vec_total (const struct vector *);
-\f
-/* Matrix representation. */
-struct matrix
-  {
-    int nr, nc;
-    int m;
-    double *data;
-  };
-
-/* Allocate matrices. */
-struct matrix *mat_alloc (int nr, int nc);
-void mat_realloc (struct matrix *, int nr, int nc);
-void mat_free (struct matrix *);
-
-/* Matrix elements. */
-#define mat_elem(MAT, R, C) ((MAT)->data[(C) + (R) * (MAT)->nc])
-
-/* Set matrix values to a constant. */
-void mat_init (struct matrix *, double);
-void mat_init_row (struct matrix *, int r, double);
-void mat_init_col (struct matrix *, int c, double);
-
-/* Print out the matrix values to stdout, optionally with row and
-   column labels (for debugging purposes). */
-#if GLOBAL_DEBUGGING
-void mat_print (const struct matrix *,
-               const struct vector *row_labels, const struct vector *col_labels);
-#endif
-
-/* Sum matrix values. */
-void mat_row_totals (const struct matrix *, struct vector *row_tots);
-void mat_col_totals (const struct matrix *, struct vector *col_tots);
-double mat_grand_total (const struct matrix *);
-
-/* Chi-square statistics. */
-enum
-  {
-    CHISQ_PEARSON,
-    CHISQ_LIKELIHOOD_RATIO,
-    CHISQ_FISHER,
-    CHISQ_CC,
-    CHISQ_LINEAR,
-    N_CHISQ
-  };
-
-void mat_chisq (const struct matrix *, double chisq[N_CHISQ], int df[N_CHISQ]);
-
-#endif /* matrix_h */