lynx-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

lynx-dev dev.15 patch 5 - mostly TRST


From: Klaus Weide
Subject: lynx-dev dev.15 patch 5 - mostly TRST
Date: Sun, 28 Nov 1999 08:39:06 -0600 (CST)

This would be dev.15 patch 4 except that Leonid (with his much appreciated
patch) stole the number. :)  Should be applied after
   dev.15 patch 1, dev.15 patch 2, dev.15 patch 3.

John Bley, if you're listening - I would appreciate if you could run this
through your checking.  There are two tests I put up:
  <http://www.enteract.com/~kweide/test/rsinf.html>
  <http://www.enteract.com/~kweide/test/span-vs-group.html>
You might want to undefine SAVE_TIME_NOT_SPACE (or change CELLS_GROWBY,
ROWS_GROWBY to something smaller in TRSTable.c) for a higher chance to
detect something.  Also the second example should be viewed with a screen
width of 100 or higher.  (One can use -dump -width=100 if that is not
possible.)
Yes, I found real (observable) errors (as in: repeated ^Reloading of
some tests showed different results) that corresponded with the kind
of uninitialized elements you were detecting, so your examination is
very useful.  I hope those errors are gone now, but then I never thought
they existed in the first place..

   Klaus

* Minor doc & comment changes
* Avoid accesss to uninitialized members in TRSTable.c.
* Limit span values accepted for TRST with TRST_MAXCOLSPAN and
  TRST_MAXROWSPAN, which can be changed in userdefs.h.  Without imposing
  a limit, attempts to trick lynx into allocating huge blocks of memory
  (which might cause thrashing without apparent reason) with something
  like ROWSPAN=10000000 are just too easy.
* Moved definition of SAVE_TIME_NOT_SPACE to userdefs.h.  You may
  want to undefine it for a platform where running out of memory is a
  frequent problem (DOS?), although the effect won't be very pronounced.
  Used in TRST code to affect size of some allocations (also used as before
  for HTSprintf0/HTSprinf).
* Implement COLSPAN=0 and ROWSPAN=0 according to HTML 4.01 (not HTML 4.0).
  The span extends until the end of the current column group and row group
  (i.e. next THEAD/TFOOT/TBODY), respectively; or until the end of the row
  or table, respecitively, if there is no containing group (thus acting as
  per HTML 4.0).  Also cancel effect of all ROWSPANs at a THEAD/TFOOT/TBODY
  boundary (problem with other browser described and behavior proposed by
  G. James Berigan in
  <http://www.war-of-the-worlds.org/html/span-vs-group.html>).

Index: 2.23/WWW/Library/Implementation/HTString.c
--- 2.23/WWW/Library/Implementation/HTString.c Thu, 25 Nov 1999 07:18:32 -0600
+++ 2.23(w)/WWW/Library/Implementation/HTString.c Sun, 28 Nov 1999 06:36:38 
-0600
@@ -501,8 +501,8 @@
  * in each invocation.  They only grow and never shrink, and won't be
  * cleaned up on exit. - kw
  */
-#if !(defined(_REENTRANT) || defined(_THREAD_SAFE))
-#define SAVE_TIME_NOT_SPACE
+#if defined(_REENTRANT) || defined(_THREAD_SAFE)
+#undef SAVE_TIME_NOT_SPACE
 #endif
 
 /*
Index: 2.23/src/LYOptions.c
--- 2.23/src/LYOptions.c Thu, 25 Nov 1999 11:29:56 -0600
+++ 2.23(w)/src/LYOptions.c Sat, 27 Nov 1999 02:18:27 -0600
@@ -3573,6 +3573,7 @@
 }
 
 PRIVATE int gen_options PARAMS((char **newfile));
+
 /*
  * Handle options from the pseudo-post.  I think we really only need
  * post_data here, but bring along everything just in case.  It's only a
@@ -4204,9 +4205,14 @@
 
     LYLocalFileToURL(newfile, tempfile);
 
-    /* This should not be needed, as long as we regenerate the
-       temp file every time with a new name (which just happened
-       above.  If access to the actual file via getfile()
+    /* This should not be needed if we regenerate the temp file every
+       time with a new name, which just happened above in the case
+       LYReuseTempfiles==FALSE.  Even for LYReuseTempfiles=TRUE, code
+       at the end of postoptions() may remove an older cached version
+       from memory if that version of the page was left by submitting
+       changes. (But that code doesn't do that - HTuncache_current_document
+       is currently commented out.) - kw 1999-11-27
+       If access to the actual file via getfile() later fails
        (maybe because of some restrictions), mainloop may leave
        this flag on after popping the previous doc which is then
        unnecessarily reloaded.  But I changed mainloop to reset
Index: 2.23/src/GridText.c
--- 2.23/src/GridText.c Thu, 25 Nov 1999 11:29:56 -0600
+++ 2.23(w)/src/GridText.c Sun, 28 Nov 1999 01:13:02 -0600
@@ -4709,8 +4709,16 @@
 {
     if (!me || !me->stbl)
        return;
-    if (colspan <= 0)
+    if (colspan < 0)
        colspan = 1;
+    if (colspan > TRST_MAXCOLSPAN) {
+       CTRACE((tfp, "*** COLSPAN=%d is too large, ignored!\n", colspan));
+       colspan = 1;
+    }
+    if (rowspan > TRST_MAXROWSPAN) {
+       CTRACE((tfp, "*** ROWSPAN=%d is too large, ignored!\n", rowspan));
+       rowspan = 1;
+    }
     if (Stbl_addCellToTable(me->stbl, colspan, rowspan, alignment, isheader,
                            me->Lines, HText_LastLineSize(me,FALSE)) < 0)
        HText_cancelStbl(me);   /* give up */
@@ -4740,6 +4748,10 @@
        return;
     if (span <= 0)
        span = 1;
+    if (span > TRST_MAXCOLSPAN) {
+       CTRACE((tfp, "*** SPAN=%d is too large, ignored!\n", span));
+       span = 1;
+    }
     if (Stbl_addColInfo(me->stbl, span, alignment, isgroup) < 0)
        HText_cancelStbl(me);   /* give up */
 }
Index: 2.23/userdefs.h
--- 2.23/userdefs.h Thu, 25 Nov 1999 11:29:56 -0600
+++ 2.23(w)/userdefs.h Sun, 28 Nov 1999 06:36:36 -0600
@@ -1337,6 +1337,9 @@
 #endif
 
 #define MAXCHARSETS 60         /* max character sets supported */
+#define TRST_MAXROWSPAN 10000  /* max rowspan accepted by TRST code */
+#define TRST_MAXCOLSPAN 1000   /* max colspan and COL/COLGROUP span accepted */
+#define SAVE_TIME_NOT_SPACE    /* minimize number of some malloc calls */
 
 /* Win32 may support more, but old win16 helper apps may not. */
 #if defined(__DJGPP__) || defined(_WINDOWS)
Index: 2.23/lynx.cfg
--- 2.23/lynx.cfg Thu, 25 Nov 1999 11:29:56 -0600
+++ 2.23(w)/lynx.cfg Sat, 27 Nov 1999 01:49:37 -0600
@@ -2164,7 +2164,7 @@
 # XWINDOWS; this is equivalent to TRUE when the user has the environment
 # variable DISPLAY defined *at program start*, and equivalent to FALSE
 # otherwise.  The non-restarting behavior can also be changed to TRUE
-# or FALSE with -nonrestarting_sigwinch switch, which overrides the
+# or FALSE with the -nonrestarting_sigwinch switch, which overrides the
 # value in this file.
 # Note that Lynx never re-parses document text purely as a result of a
 # window size change, so text lines may appear truncated after narrowing
@@ -2421,7 +2421,7 @@
 # users who use alphanumeric keys for navigation (or other keys that have
 # special meaning in the line editor - ' ', 'b', INS, DEL, etc), and don't
 # want to 'get stuck' in form fields.  Instead of setting the option here,
-# explictit activation can also be requested with the -tna command line
+# explicit activation can also be requested with the -tna command line
 # option.
 #
 #TEXTFIELDS_NEED_ACTIVATION:FALSE
Index: 2.23/docs/README.defines
--- 2.23/docs/README.defines Thu, 25 Nov 1999 06:54:09 -0600
+++ 2.23(w)/docs/README.defines Sun, 28 Nov 1999 06:34:21 -0600
@@ -144,7 +144,6 @@
 symbols.
 
 COOKIE_FILE            LYMain.c        default cookie file in HOME dir
-SAVE_TIME_NOT_SPACE    HTString.c      minimize number of some malloc calls
 SHOW_WHEREIS_TARGETS   LYCurses.h      whereis search highlighting
 USE_KEYMAPS            LYCurses.h      use of .lynx-keymaps files
 
Index: 2.23/src/TRSTable.h
--- 2.23/src/TRSTable.h Thu, 25 Nov 1999 07:18:32 -0600
+++ 2.23(w)/src/TRSTable.h Sun, 28 Nov 1999 06:25:55 -0600
@@ -1,6 +1,8 @@
 #ifndef TRSTABLE_H
 #define TRSTABLE_H
 
+/* TRST_MAXCOLSPAN and TRST_MAXCOLSPAN are defined in userdefs.h */
+
 typedef struct _STable_info STable_info;
 extern STable_info * Stbl_startTABLE PARAMS((short));
 extern int Stbl_finishTABLE PARAMS((STable_info *));
Index: 2.23/src/TRSTable.c
--- 2.23/src/TRSTable.c Thu, 25 Nov 1999 07:30:47 -0600
+++ 2.23(w)/src/TRSTable.c Sun, 28 Nov 1999 06:33:06 -0600
@@ -13,13 +13,21 @@
 
 #include <LYLeaks.h>
 
+#ifdef SAVE_TIME_NOT_SPACE
+#define CELLS_GROWBY 16
+#define ROWS_GROWBY 16
+#else
 #define CELLS_GROWBY 2
 #define ROWS_GROWBY 2
+#endif
+
 #define MAX_STBL_POS (LYcols-1)
 
 /* must be different from HT_ALIGN_NONE and HT_LEFT, HT_CENTER etc.: */
 #define RESERVEDCELL (-2)  /* cell's alignment field is overloaded, this
                              value means cell was reserved by ROWSPAN */
+#define EOCOLG (-2)    /* sumcols' Line field isn't used for line info, this
+                             special value means end of COLGROUP */
 typedef enum {
     CS_invalid = -1,
     CS_new     =  0,
@@ -76,6 +84,7 @@
        int     ncolinfo;               /* number of COL info collected */
        STable_cellinfo * sumcols; /* for summary (max len/pos) col info */
        STable_rowinfo * rows;
+       STable_rowinfo  rowspans2eog;
        short   alignment;      /* global align attribute for this table */
        short   rowgroup_align; /* align default for current group of rows */
        short   pending_colgroup_align;
@@ -172,6 +181,7 @@
            free_rowinfo(me->rows + i);
        FREE(me->rows);
     }
+    free_rowinfo(&me->rowspans2eog);
     if (me)
        FREE(me->sumcols);
     FREE(me);
@@ -412,6 +422,9 @@
                cells = realloc(me->cells,
                                  (me->allocated + growby)
                                  * sizeof(STable_cellinfo));
+                for (i = 0; cells && i < growby; i++) {
+                   cells[me->allocated + i].alignment = HT_ALIGN_NONE;
+                }
            }
            if (cells) {
                me->allocated += growby;
@@ -426,8 +439,6 @@
     me->cells[me->ncells].pos = *ppos;
     me->cells[me->ncells].len = -1;
     me->cells[me->ncells].colspan = colspan;
-    me->cells[me->ncells].alignment =
-       (alignment==HT_ALIGN_NONE) ? me->alignment : alignment;
 
     if (alignment != HT_ALIGN_NONE)
            me->cells[me->ncells].alignment = alignment;
@@ -466,6 +477,9 @@
                        (me->allocated + growby)
                        * sizeof(STable_cellinfo));
        if (cells) {
+           for (i = 0; i < growby; i++) {
+               cells[me->allocated + i].alignment = HT_ALIGN_NONE;
+           }
            me->allocated += growby;
            me->cells = cells;
        } else {
@@ -883,8 +897,10 @@
 }
 
 /*
- *  Reserve cells, of colspan=spolspan each, in (rowspan-1) rows after
- *  the current row.
+ *  Reserve cells, each of given colspan, in (rowspan-1) rows after
+ *  the current row of rowspan>1.  If rowspan==0, use special 'row'
+ *  rowspans2eog to keep track of rowspans that are to remain in effect
+ *  until the end of the row group (until next THEAD/TFOOT/TBODY) or table.
  */
 PRIVATE int Stbl_reserveCellsInTable ARGS4(
     STable_info *,     me,
@@ -897,25 +913,49 @@
     int i;
     if (me->nrows <= 0)
        return -1;              /* must already have at least one row */
+
+    if (rowspan == 0) {
+       if (!me->rowspans2eog.cells) {
+           me->rowspans2eog.cells = calloc(icell + colspan, 
sizeof(STable_cellinfo));
+           if (!me->rowspans2eog.cells)
+               return 0;       /* fail silently */
+           else
+               me->rowspans2eog.allocated = icell + colspan;
+       }
+       Stbl_reserveCellsInRow(&me->rowspans2eog, icell, colspan);
+    }
+
     growby = me->nrows + rowspan - 1 - me->allocated_rows;
     if (growby > 0) {
        rows = realloc(me->rows,
                       (me->allocated_rows + growby)
                       * sizeof(STable_rowinfo));
        if (!rows)
-           return 0; /* ignore silently, maybe someone said ROWSPAN=9999999 */
+           return 0; /* ignore silently, no free memory, may be recoverable */
        for (i = 0; i < growby; i++) {
            row = rows + me->allocated_rows + i;
            row->allocated = 0;
+           if (!me->rowspans2eog.allocated) {
+               row->cells = NULL;
+           } else {
+               row->cells = calloc(me->rowspans2eog.allocated,
+                                   sizeof(STable_cellinfo));
+               if (row->cells) {
+                   row->allocated = me->rowspans2eog.allocated;
+                   memcpy(row->cells, me->rowspans2eog.cells,
+                          row->allocated * sizeof(STable_cellinfo));
+               }
+           }
            row->ncells = 0;
            row->fixed_line = NO;
-           row->cells = NULL;
            row->alignment = HT_ALIGN_NONE;
        }
        me->allocated_rows += growby;
        me->rows = rows;
     }
-    for (i = me->nrows; i < me->nrows + rowspan - 1; i++) {
+    for (i = me->nrows;
+        i < (rowspan == 0 ? me->allocated_rows : me->nrows + rowspan - 1);
+        i++) {
        if (!me->rows[i].allocated) {
            me->rows[i].cells = calloc(icell + colspan, 
sizeof(STable_cellinfo));
            if (!me->rows[i].cells)
@@ -928,6 +968,22 @@
     return 0;
 }
 
+/* Remove reserved cells in trailing rows that were added for rowspan,
+ * to be used when a THEAD/TFOOT/TBODY ends. */
+PRIVATE void Stbl_cancelRowSpans ARGS1(
+    STable_info *,     me)
+{
+    int i;
+    for (i = me->nrows; i < me->allocated_rows; i++) {
+       if (!me->rows[i].ncells) { /* should always be the case */
+           FREE(me->rows[i].cells);
+           me->rows[i].allocated = 0;
+       }
+    }
+    free_rowinfo(&me->rowspans2eog);
+    me->rowspans2eog.allocated = 0;
+}
+
 /*
  * Returns -1 on error, otherwise index of just-added table row.
  */
@@ -974,10 +1030,23 @@
                                  * sizeof(STable_rowinfo));
                for (i = 0; rows && i < growby; i++) {
                    row = rows + me->allocated_rows + i;
-                   row->allocated = 0;
+                   if (!me->rowspans2eog.allocated) {
+                       row->allocated = 0;
+                       row->cells = NULL;
+                   } else {
+                       row->cells = calloc(me->rowspans2eog.allocated,
+                                           sizeof(STable_cellinfo));
+                       if (row->cells) {
+                           row->allocated = me->rowspans2eog.allocated;
+                           memcpy(row->cells, me->rowspans2eog.cells,
+                                  row->allocated * sizeof(STable_cellinfo));
+                       } else {
+                           FREE(rows);
+                           break;
+                       }
+                   }
                    row->ncells = 0;
                    row->fixed_line = NO;
-                   row->cells = NULL;
                    row->alignment = HT_ALIGN_NONE;
                }
            }
@@ -1084,6 +1153,29 @@
     }
 }
 
+PRIVATE int get_remaining_colspan ARGS5(
+    STable_rowinfo *,  me,
+    STable_cellinfo *, colinfo,
+    int,               ncolinfo,
+    int,               colspan,
+    int,               ncols_sofar)
+{
+    int i;
+    int last_colspan = me->ncells ?
+       me->cells[me->ncells - 1].colspan : 1;
+
+    if (ncolinfo == 0 || me->ncells + last_colspan > ncolinfo) {
+       colspan = HTMAX(TRST_MAXCOLSPAN,
+                       ncols_sofar - (me->ncells + last_colspan - 1));
+    } else {
+       for (i = me->ncells + last_colspan - 1; i < ncolinfo - 1; i++)
+           if (colinfo[i].Line == EOCOLG)
+               break;
+       colspan = i - (me->ncells + last_colspan - 2);
+    }
+    return colspan;
+}
+
 /*
  * Returns -1 on error, otherwise 0.
  */
@@ -1110,6 +1202,10 @@
     Stbl_finishCellInTable(me, YES,
                           lineno, pos);
     lastrow = me->rows + (me->nrows - 1);
+    if (colspan == 0) {
+       colspan = get_remaining_colspan(lastrow, me->sumcols, me->ncolinfo,
+                                       colspan, me->ncols);
+    }
     ncells = lastrow->ncells;  /* remember what it was before adding cell. */
     icell = Stbl_addCellToRow(lastrow, me->sumcols, me->ncolinfo, s,
                              colspan, alignment, isheader,
@@ -1119,7 +1215,7 @@
     if (me->nrows == 1 && me->startline < lastrow->Line)
        me->startline = lastrow->Line;
 
-    if (rowspan > 1) {
+    if (rowspan != 1) {
        Stbl_reserveCellsInTable(me, icell, colspan, rowspan);
        /* me->rows may now have been realloc'd, make lastrow valid pointer */
        lastrow = me->rows + (me->nrows - 1);
@@ -1141,6 +1237,8 @@
                    sumcol->pos = sumcols[me->allocated_sumcols-1].pos;
                    sumcol->len = 0;
                    sumcol->colspan = 0;
+                   sumcol->Line = 0;
+                   sumcol->alignment = HT_ALIGN_NONE;
                }
            }
            if (sumcols) {
@@ -1342,6 +1440,8 @@
        if (me->pending_colgroup_next > me->ncolinfo)
            me->ncolinfo = me->pending_colgroup_next;
        me->pending_colgroup_next = me->ncolinfo + colspan;
+       if (me->ncolinfo > 0)
+           me->sumcols[me->ncolinfo -  1].Line = EOCOLG;
        me->pending_colgroup_align = alignment;
     } else {
        for (i = me->pending_colgroup_next - 1;
@@ -1369,6 +1469,7 @@
                    sumcol->pos = sumcols[me->allocated_sumcols-1].pos;
                    sumcol->len = 0;
                    sumcol->colspan = 0;
+                   sumcol->Line = 0;
                }
            }
            if (sumcols) {
@@ -1394,8 +1495,11 @@
 PUBLIC int Stbl_finishColGroup ARGS1(
     STable_info *,     me)
 {
-    if (me->pending_colgroup_next > me->ncolinfo)
+    if (me->pending_colgroup_next >= me->ncolinfo) {
        me->ncolinfo = me->pending_colgroup_next;
+       if (me->ncolinfo > 0)
+           me->sumcols[me->ncolinfo -  1].Line = EOCOLG;
+    }
     me->pending_colgroup_next = 0;
     me->pending_colgroup_align = HT_ALIGN_NONE;
     return 0;
@@ -1405,6 +1509,7 @@
     STable_info *,     me,
     short,             alignment)
 {
+    Stbl_cancelRowSpans(me);
     me->rowgroup_align = alignment;
     return 0;                  /* that's all! */
 }
@@ -1469,7 +1574,7 @@
     if (!me)
        return -1;
     while (i < me->ncells) {
-       next_i = i + me->cells[i].colspan;
+       next_i = i + HTMAX(1, me->cells[i].colspan);
        if (me->cells[i].Line != me->Line) {
            if (me->cells[i].Line > me->Line)
                break;


reply via email to

[Prev in Thread] Current Thread [Next in Thread]