diff options
author | Thomas E. Dickey <dickey@invisible-island.net> | 2003-01-22 10:09:18 -0500 |
---|---|---|
committer | Thomas E. Dickey <dickey@invisible-island.net> | 2003-01-22 10:09:18 -0500 |
commit | 533c7482785176296637df81cd1a6318a0c29f97 (patch) | |
tree | e50cece290409516ee62f08c8912863f5f1ba80a /src | |
parent | 490d581c911f53008a7eaaed72b655cf40071b03 (diff) | |
download | lynx-snapshots-533c7482785176296637df81cd1a6318a0c29f97.tar.gz |
snapshot of project "lynx", label v2-8-5dev_13
Diffstat (limited to 'src')
38 files changed, 1263 insertions, 897 deletions
diff --git a/src/GridText.c b/src/GridText.c index e070f164..d5189c46 100644 --- a/src/GridText.c +++ b/src/GridText.c @@ -98,8 +98,14 @@ struct _HTStream { /* only know it as object */ }; #define TITLE_LINES 1 + #define IS_UTF_EXTRA(ch) (text->T.output_utf8 && \ (UCH((ch))&0xc0) == 0x80) + +#define IS_UTF8_EXTRA(ch) (!(text && text->T.output_utf8) || \ + !is8bits(ch) || \ + (UCH(line->data[i] & 0xc0) == 0xc0)) + /* a test in compact form: how many extra UTF-8 chars after initial? - kw */ #define UTF8_XNEGLEN(c) (c&0xC0? 0 :c&32? 1 :c&16? 2 :c&8? 3 :c&4? 4 :c&2? 5:0) #define UTF_XLEN(c) UTF8_XNEGLEN(((char)~(c))) @@ -149,8 +155,30 @@ PUBLIC int LYsb_begin = -1; PUBLIC int LYsb_end = -1; #endif +#ifndef VMS /* VMS has a better way - right? - kw */ +#define CHECK_FREE_MEM +#endif + +#ifdef CHECK_FREE_MEM +PRIVATE void * LY_check_calloc PARAMS((size_t nmemb, size_t size)); +#define LY_CALLOC LY_check_calloc +#else + /* using the regular calloc */ +#define LY_CALLOC calloc +#endif + +/* + * The HTPool.data[] array has to align the same as malloc() would, to make the + * ALLOC_POOL scheme portable. For many platforms, that is the same as the + * number of bytes in a pointer. It may be larger, e.g., on machines which + * have more stringent requirements for floating point. 32-bits are plenty for + * representing styles, but we may need 64-bit or 128-bit alignment. + * + * The real issue is that performance is degraded if the alignment is not met, + * and some platforms such as Tru64 generate lots of warning messages. + */ +#define ALIGN_SIZE 8 - /*try to fit in 32bit */ typedef struct { unsigned int direction:2; /* on or off */ unsigned int horizpos:14; /* horizontal position of this change */ @@ -163,10 +191,12 @@ typedef struct { static HTStyleChange stylechanges_buffers[2][MAX_STYLES_ON_LINE]; #endif -enum { POOL_SIZE = (8192 - 4*sizeof(void*) - sizeof(struct _HTPool*) - sizeof(int)) / sizeof(HTStyleChange) }; +typedef HTStyleChange pool_data; + +enum { POOL_SIZE = (8192 - 4*sizeof(void*) - sizeof(struct _HTPool*) - sizeof(int)) / sizeof(pool_data) }; typedef struct _HTPool { - HTStyleChange data[POOL_SIZE]; + pool_data data[POOL_SIZE]; struct _HTPool* prev; int used; } HTPool; @@ -203,103 +233,93 @@ to be very efficient. lines, anchors, and FormInfo. Arrays of HTStyleChange are stored as is, other objects are stored using a cast.] - Pool are referenced by pointer to the chunk that contains free slots. Macros -that allocate memory in pools update that pointer if needed. - There are 3 macros that deal with pools - POOL_NEW, POOL_FREE and -ALLOC_IN_POOL. - Here is a description of those macros as C++ functions (with names mentioned -above and with use of C++ references) - -void ALLOC_IN_POOL( P*& pool, pool_type, int toalloc, T*& ptr) - - allocates 'toalloc' items in the pool of type 'pool_type' pointed by - 'pool', sets the pointer 'ptr' to the "allocated" memory and updates 'pool' - if necessary. Sets 'ptr' to NULL if fails. - -void POOL_NEW( pool_type , P*& ptr) - Initializes a pool of type 'pool_type' pointed by 'ptr', updating 'ptr'. - Sets 'ptr' to NULL if fails. - -void POOL_FREE( pool_type , P*& ptr) - Frees a pool of type 'pool_type' pointed by ptr. Sets ptr to NULL. + Pool is referenced by the pointer to the last chunk that contains free slots. +Functions that allocate memory in pool update that pointer if needed. +There are 3 functions - POOL_NEW, POOL_FREE, and ALLOC_IN_POOL. - VH *************************************************************************/ + +#define POOLallocstyles(ptr, n) ptr = ALLOC_IN_POOL(&HTMainText->pool, n * sizeof(pool_data)) +#define POOLallocHTLine(ptr, size) ptr = (HTLine*) ALLOC_IN_POOL(&HTMainText->pool, LINE_SIZE(size)) +#define POOLallocstring(ptr, len) ptr = (char*) ALLOC_IN_POOL(&HTMainText->pool, len + 1) +#define POOLtypecalloc(T,ptr) ptr = (T*) ALLOC_IN_POOL(&HTMainText->pool, sizeof(T)) + +/**************************************************************************/ /* - * void ALLOC_IN_POOL( P*& pool, pool_type, int toalloc, T*& ptr) - * - allocates 'toalloc' items in the pool of type 'pool_type' pointed by - * 'pool', sets the pointer 'ptr' to the "allocated" memory and updates - * 'pool' if necessary. Sets 'ptr' to NULL if fails. + * Allocates 'n' items in the pool of type 'HTPool' pointed by 'poolptr'. + * Returns a pointer to the "allocated" memory or NULL if fails. + * Updates 'poolptr' if necessary. */ -#define ALLOC_IN_POOL(pool,pool_type,toalloc,ptr) \ - if (!pool) { \ - ptr = NULL; \ - } else { \ - if (POOL_SIZE - pool->used >= toalloc) { \ - ptr = pool->data + pool->used; \ - pool->used += toalloc; \ - } else { \ - pool_type* newpool = (pool_type*)LY_CALLOC(1, sizeof(pool_type)); \ - if (!newpool) { \ - ptr = NULL; \ - } else { \ - newpool->prev = pool; \ - newpool->used = toalloc; \ - ptr = newpool->data; \ - pool = newpool; \ - } \ - } \ +PRIVATE pool_data* ALLOC_IN_POOL ARGS2( + HTPool**, ppoolptr, + unsigned, request) +{ + HTPool* pool = *ppoolptr; + pool_data* ptr; + unsigned n; + unsigned j; + + if (!pool) { + ptr = NULL; + } else { + n = request; + if (n == 0) + n = 1; + j = (n % ALIGN_SIZE); + if (j != 0) + n += (ALIGN_SIZE - j); + n /= sizeof(pool_data); + if (POOL_SIZE >= (pool->used + n)) { + ptr = pool->data + pool->used; + pool->used += n; + } else { + HTPool* newpool = (HTPool*)LY_CALLOC(1, sizeof(HTPool)); + if (!newpool) { + ptr = NULL; + } else { + newpool->prev = pool; + newpool->used = n; + ptr = newpool->data; + pool = newpool; + } + } } + *ppoolptr = pool; + return ptr; +} + /* - * void POOL_NEW( pool_type , P*& ptr) - * Initializes a pool of type 'pool_type' pointed by 'ptr', updating 'ptr'. - * Sets 'ptr' to NULL if fails. + * Returns a pointer to initialized pool of type 'HTPool', or NULL if fails. */ -#define POOL_NEW(pool_type,ptr) \ - { \ - ptr = (pool_type*)LY_CALLOC(1, sizeof(pool_type)); \ - if (ptr) { \ - ptr->prev = NULL; \ - ptr->used = 0; \ - } \ +PRIVATE HTPool* POOL_NEW NOARGS +{ + HTPool* poolptr = (HTPool*)LY_CALLOC(1, sizeof(HTPool)); + if (poolptr) { + (poolptr)->prev = NULL; + (poolptr)->used = 0; } + return poolptr; +} + /* - * void POOL_FREE( pool_type, P*& ptr) - * Frees a pool of type 'pool_type' pointed by ptr. Sets ptr to NULL. + * Frees a pool of type 'HTPool' pointed by poolptr. */ -#define POOL_FREE(pool_type,ptr) \ - { \ - pool_type* cur = ptr; \ - pool_type* prev; \ - while (cur) { \ - prev = cur->prev; \ - FREE(cur); \ - cur = prev; \ - } \ - ptr = NULL; \ +PRIVATE void POOL_FREE ARGS1( + HTPool*, poolptr) +{ + HTPool* cur = poolptr; + HTPool* prev; + while (cur) { + prev = cur->prev; + free(cur); + cur = prev; } -/**************************************************************************/ +} -#define _sz_ sizeof(HTStyleChange) /* 4 */ -#define _round_up_(x) (x%_sz_ ? x/_sz_ + 1: x/_sz_) - -#define POOLallocstyles(ptr, N) ALLOC_IN_POOL(HTMainText->pool,HTPool,\ - N, \ - ptr) -#define POOLallocHTLine(ptr, size) { HTStyleChange* _tmp_; \ - int N = _round_up_(LINE_SIZE(size)); \ - ALLOC_IN_POOL(HTMainText->pool,HTPool,\ - N, \ - _tmp_); \ - ptr = (HTLine*)_tmp_; \ - } -#define POOLtypecalloc(T,ptr) { HTStyleChange* _tmp_; \ - int N = _round_up_(sizeof(T)); \ - ALLOC_IN_POOL(HTMainText->pool,HTPool,\ - N, \ - _tmp_); \ - ptr = (T*)_tmp_; \ - } +/**************************************************************************/ +/**************************************************************************/ typedef struct _line { struct _line *next; @@ -315,7 +335,20 @@ typedef struct _line { #define LINE_SIZE(l) (sizeof(HTLine)+(l)) /* Allow for terminator */ -#define allocHTLine(l) (HTLine *)calloc(1, LINE_SIZE(l)) + +/* + * Last line buffer; the second is used in split_line(). Not in pool! + * We cannot wrap in middle of multibyte sequences, so allocate 2 extra + * for a workspace. This is stored in the HText, to prevent confusion + * between different documents. Note also that it is declared with an + * HTLine at the beginning so pointers will be properly aligned. + */ +typedef struct { + HTLine base; + char data[MAX_LINE+2]; +} HTLineTemp; + +#define TEMP_LINE(p,n) ((HTLine *)&(p->temp_line[n])) typedef struct _TextAnchor { struct _TextAnchor * next; @@ -349,6 +382,7 @@ struct _HText { HTParentAnchor * node_anchor; HTLine * last_line; + HTLineTemp temp_line[2]; int Lines; /* Number of them */ TextAnchor * first_anchor; /* double-linked on demand */ TextAnchor * last_anchor; @@ -382,6 +416,7 @@ struct _HText { int last_lineno_last_disp_partial; #endif STable_info * stbl; + HTList * enclosed_stbl; HTkcode kcode; /* Kanji code? */ HTkcode specified_kcode; /* Specified Kanji code */ @@ -493,8 +528,6 @@ PUBLIC void mark_justify_start_position ARGS1(void*,text) HTCJK == NOCJK && !in_DT && \ can_justify_here && can_justify_this_line && !form_in_htext ) -#else -#define last_anchor_of_previous_line (TextAnchor*)0 #endif /* EXP_JUSTIFY_ELTS */ @@ -535,123 +568,16 @@ PUBLIC HTList * search_queries = NULL; /* isindex and whereis queries */ #ifdef LY_FIND_LEAKS PRIVATE void free_all_texts NOARGS; #endif -PRIVATE int HText_TrueLineSize PARAMS(( + +PRIVATE BOOL HText_TrueEmptyLine PARAMS(( HTLine * line, HText * text, BOOL IgnoreSpaces)); -#ifndef VMS /* VMS has a better way - right? - kw */ -#define CHECK_FREE_MEM -#endif - -/* - * Set the initial highlight information for a given anchor. - */ -PRIVATE void LYSetHiText ARGS3( - TextAnchor *, a, - char *, text, - int, len) -{ - unsigned have = a->lites.hl_len; - - if (a->lites.hl_info != NULL) { - while (have-- != 0) { - if ((int) (have + 1) < a->lites.hl_len) { - FREE(a->lites.hl_info[have].hl_text); - } - } - FREE(a->lites.hl_info); - } - FREE(a->lites.hl_base.hl_text); - a->lites.hl_len = 0; - - if (text != NULL) { - StrnAllocCopy(a->lites.hl_base.hl_text, text, len); - a->lites.hl_len = 1; - } -} - -/* - * Add highlight information for the next line of a anchor. - */ -PRIVATE void LYAddHiText ARGS3( - TextAnchor *, a, - char *, text, - int, x) -{ - HiliteInfo *have = a->lites.hl_info; - unsigned need = (a->lites.hl_len - 1); - unsigned want = ++(a->lites.hl_len) * sizeof(HiliteInfo); - - if (have != NULL) { - have = (HiliteInfo *) realloc(have, want); - } else { - have = (HiliteInfo *) malloc(want); - } - a->lites.hl_info = have; - - have[need].hl_text = NULL; - StrAllocCopy(have[need].hl_text, text); - have[need].hl_x = x; -} - -/* - * Get the highlight text, counting from zero. - */ -PRIVATE char *LYGetHiTextStr ARGS2( - TextAnchor *, a, - int, count) -{ - char *result; - - if (count >= a->lites.hl_len) - result = NULL; - else if (count > 0) - result = a->lites.hl_info[count - 1].hl_text; - else - result = a->lites.hl_base.hl_text; - return result; -} - -/* - * Get the X-ordinate at which to draw the corresponding highlight-text - */ -PRIVATE int LYGetHiTextPos ARGS2( - TextAnchor *, a, - int, count) -{ - int result; - - if (count >= a->lites.hl_len) - result = -1; - else if (count > 0) - result = a->lites.hl_info[count - 1].hl_x; - else - result = a->line_pos; - return result; -} - -/* - * Copy highlighting information from anchor 'a' to 'b'. - */ -PRIVATE void LYCopyHiText ARGS2( - TextAnchor *, a, - TextAnchor *, b) -{ - int count; - char *s; - - LYSetHiText(a, NULL, 0); - for (count = 0; ; ++count) { - if ((s = LYGetHiTextStr(b, count)) == NULL) - break; - if (count == 0) { - LYSetHiText(a, s, strlen(s)); - } else { - LYAddHiText(a, s, LYGetHiTextPos(b, count)); - } - } -} +PRIVATE int HText_TrueLineSize PARAMS(( + HTLine * line, + HText * text, + BOOL IgnoreSpaces)); #ifdef CHECK_FREE_MEM @@ -723,7 +649,6 @@ PRIVATE void * LY_check_calloc ARGS2( HText * t = (HText *) HTList_objectAt(loaded_texts, i); if (t == HTMainText) t = NULL; /* shouldn't happen */ - { CTRACE((tfp, "\nBUG *** Emergency freeing document %d/%d for '%s'%s!\n", i + 1, n, ((t && t->node_anchor && @@ -732,7 +657,6 @@ PRIVATE void * LY_check_calloc ARGS2( ((t && t->node_anchor && t->node_anchor->post_data) ? " with POST data" : ""))); - } HTList_removeObjectAt(loaded_texts, i); HText_free(t); if (mem_is_avail(4, nmemb * size)) { @@ -758,14 +682,119 @@ PRIVATE void * LY_check_calloc ARGS2( return (calloc(nmemb, size)); } -#define LY_CALLOC LY_check_calloc +#endif /* CHECK_FREE_MEM */ + +/* + * Clear highlight information for a given anchor + * (text was allocated in the pool). + */ +PRIVATE void LYClearHiText ARGS1( + TextAnchor *, a) +{ + FREE(a->lites.hl_info); -#else /* CHECK_FREE_MEM */ + a->lites.hl_base.hl_text = NULL; + a->lites.hl_len = 0; +} - /* using the regular calloc */ -#define LY_CALLOC calloc +/* + * Set the initial highlight information for a given anchor. + */ +PRIVATE void LYSetHiText ARGS3( + TextAnchor *, a, + char *, text, + int, len) +{ + if (text != NULL) { + POOLallocstring(a->lites.hl_base.hl_text, len); + memcpy(a->lites.hl_base.hl_text, text, len); + *(a->lites.hl_base.hl_text + len) = '\0'; -#endif /* CHECK_FREE_MEM */ + a->lites.hl_len = 1; + } +} + +/* + * Add highlight information for the next line of a anchor. + */ +PRIVATE void LYAddHiText ARGS3( + TextAnchor *, a, + char *, text, + int, x) +{ + HiliteInfo *have = a->lites.hl_info; + unsigned need = (a->lites.hl_len - 1); + unsigned want = (a->lites.hl_len += 1) * sizeof(HiliteInfo); + + if (have != NULL) { + have = (HiliteInfo *) realloc(have, want); + } else { + have = (HiliteInfo *) malloc(want); + } + a->lites.hl_info = have; + + POOLallocstring(have[need].hl_text, strlen(text)); + strcpy(have[need].hl_text, text); + have[need].hl_x = x; +} + +/* + * Get the highlight text, counting from zero. + */ +PRIVATE char *LYGetHiTextStr ARGS2( + TextAnchor *, a, + int, count) +{ + char *result; + + if (count >= a->lites.hl_len) + result = NULL; + else if (count > 0) + result = a->lites.hl_info[count - 1].hl_text; + else + result = a->lites.hl_base.hl_text; + return result; +} + +/* + * Get the X-ordinate at which to draw the corresponding highlight-text + */ +PRIVATE int LYGetHiTextPos ARGS2( + TextAnchor *, a, + int, count) +{ + int result; + + if (count >= a->lites.hl_len) + result = -1; + else if (count > 0) + result = a->lites.hl_info[count - 1].hl_x; + else + result = a->line_pos; + return result; +} + +/* + * Copy highlighting information from anchor 'b' to 'a'. + */ +PRIVATE void LYCopyHiText ARGS2( + TextAnchor *, a, + TextAnchor *, b) +{ + int count; + char *s; + + LYClearHiText(a); + for (count = 0; ; ++count) { + if ((s = LYGetHiTextStr(b, count)) == NULL) + break; + if (count == 0) { + LYSetHiText(a, s, strlen(s)); + } else { + LYAddHiText(a, s, LYGetHiTextPos(b, count)); + } + } +} PRIVATE void HText_getChartransInfo ARGS1( HText *, me) @@ -877,14 +906,14 @@ PUBLIC HText * HText_new ARGS1( #endif /* VMS && VAXC && !__DECC */ } - POOL_NEW(HTPool, self->pool); + self->pool = POOL_NEW(); if (!self->pool) outofmem(__FILE__, "HText_New"); - line = self->last_line = allocHTLine(MAX_LINE); - if (line == NULL) - outofmem(__FILE__, "HText_New"); + + line = self->last_line = TEMP_LINE(self, 0); line->next = line->prev = line; line->offset = line->size = 0; + line->data[line->size] = '\0'; #ifdef USE_COLOR_STYLE line->numstyles = 0; line->styles = stylechanges_buffers[0]; @@ -1058,24 +1087,6 @@ PUBLIC void HText_free ARGS1( HTAnchor_setDocument(self->node_anchor, (HyperDoc *)0); - while (YES) { /* Free off line array */ - HTLine * l = self->last_line; - if (l) { - l->next->prev = l->prev; - l->prev->next = l->next; /* Unlink l */ - self->last_line = l->prev; - if (l != self->last_line) { - FREE(l); - } else { - free(l); - } - } - if (l == self->last_line) { /* empty */ - l = self->last_line = NULL; - break; - } - } - while (self->first_anchor) { /* Free off anchor array */ TextAnchor * l = self->first_anchor; self->first_anchor = l->next; @@ -1126,7 +1137,7 @@ PUBLIC void HText_free ARGS1( FREE(l->input_field->accept_cs); } - LYSetHiText(l, NULL, 0); + LYClearHiText(l); } FormList_delete(self->forms); @@ -1184,7 +1195,7 @@ PUBLIC void HText_free ARGS1( HTMainAnchor = NULL; } - POOL_FREE(HTPool, self->pool); + POOL_FREE(self->pool); FREE(self); } @@ -1323,7 +1334,7 @@ PRIVATE int display_line ARGS4( while (current_style < line->numstyles && i >= (int) (CStyle.horizpos + line->offset + 1)) { - LynxChangeStyle (CStyle.style,CStyle.direction); + LynxChangeStyle (CStyle.style, CStyle.direction); current_style++; } #endif @@ -2430,7 +2441,7 @@ PRIVATE int set_style_by_embedded_chars ARGS4( PRIVATE void move_anchors_in_region ARGS7( HTLine *, line, int, line_number, - TextAnchor **, prev_anchor, + TextAnchor **, prev_anchor, /*updates++*/ int *, prev_head_processed, int, sbyte, int, ebyte, @@ -2496,9 +2507,9 @@ PRIVATE void move_anchors_in_region ARGS7( * in appropriate places - so that characters at/after the old * position end up at/after the new position, for each pair, if possible. * Some necessary changes for anchors starting on this line are also done - * here if needed. + * here if needed. Updates 'prev_anchor' internally. * Returns a newly allocated HTLine* if changes were made - * (caller has to free the old one). + * (lines allocated in pool, caller should not free the old one). * Returns NULL if no changes needed. (Remove-spaces code may be buggy...) * - kw */ @@ -2506,7 +2517,7 @@ PRIVATE HTLine * insert_blanks_in_line ARGS7( HTLine *, line, int, line_number, HText *, text, - TextAnchor *, prev_anchor, + TextAnchor **, prev_anchor, /*updates++*/ int, ninserts, int *, oldpos, /* Measured in cells */ int *, newpos) /* Likewise */ @@ -2533,16 +2544,20 @@ PRIVATE HTLine * insert_blanks_in_line ARGS7( added_chars = newpos[ip] - oldpos[ip]; if (line->size + added_chars > MAX_LINE - 2) return NULL; - if (line == text->last_line) - mod_line = allocHTLine(MAX_LINE); - else - mod_line = allocHTLine(line->size + added_chars); + if (line == text->last_line) { + if (line == TEMP_LINE(text, 0)) + mod_line = TEMP_LINE(text, 1); + else + mod_line = TEMP_LINE(text, 0); + } else { + POOLallocHTLine(mod_line, line->size + added_chars); + } if (!mod_line) return NULL; - if (!prev_anchor) - prev_anchor = text->first_anchor; - head_processed = (prev_anchor && prev_anchor->line_num < line_number); - memcpy(mod_line, line, LINE_SIZE(1)); + if (!*prev_anchor) + *prev_anchor = text->first_anchor; + head_processed = (*prev_anchor && (*prev_anchor)->line_num < line_number); + memcpy(mod_line, line, LINE_SIZE(0)); t = newdata = mod_line->data; ip = 0; while (ip <= ninserts) { @@ -2572,7 +2587,7 @@ PRIVATE HTLine * insert_blanks_in_line ARGS7( /* Now s is at the "displayed" char, pre is before the style change */ if (ip) /* Fix anchor positions */ - move_anchors_in_region(line, line_number, &prev_anchor, + move_anchors_in_region(line, line_number, prev_anchor /*updates++*/, &head_processed, copied - line->data, pre - line->data, shift); @@ -2600,8 +2615,8 @@ PRIVATE HTLine * insert_blanks_in_line ARGS7( while (pre < s) /* Copy remaining style-codes */ *t++ = *pre++; /* Check whether the last anchor continues on the next line */ - if (head_processed && prev_anchor && prev_anchor->line_num == line_number) - prev_anchor->extent += shift; + if (head_processed && *prev_anchor && (*prev_anchor)->line_num == line_number) + (*prev_anchor)->extent += shift; *t = '\0'; mod_line->size = t - newdata; return mod_line; @@ -2654,18 +2669,24 @@ PRIVATE void split_line ARGS2( int TailTrim = 0; int s, s_post, s_pre, t_underline = underline_on, t_bold = bold_on; char *p; - HTLine * previous = text->last_line; int ctrl_chars_on_previous_line = 0; int utfxtra_on_previous_line = UTFXTRA_ON_THIS_LINE; char * cp; - /* can't wrap in middle of multibyte sequences, so allocate 2 extra */ - HTLine * line = (HTLine *)LY_CALLOC(1, LINE_SIZE(MAX_LINE)+2); + + HTLine * previous = text->last_line; + HTLine * line; /* - * Make new line. + * Set new line. */ + if (previous == TEMP_LINE(text, 0)) + line = TEMP_LINE(text, 1); + else + line = TEMP_LINE(text, 0); if (line == NULL) - outofmem(__FILE__, "split_line_1"); + return; + memset(line, 0, LINE_SIZE(0)); + ctrl_chars_on_this_line = 0; /*reset since we are going to a new line*/ utfxtra_on_this_line = 0; /*reset too, we'll count them*/ text->LastChar = ' '; @@ -2924,7 +2945,7 @@ PRIVATE void split_line ARGS2( } if ( to < line->styles + MAX_STYLES_ON_LINE - 1 && to[1].direction == STACK_OFF - && to[1].horizpos <= SpecialAttrChars + && to[1].horizpos <= (unsigned) SpecialAttrChars && to[1].style == scan->style ) to++; else if (to >= line->styles) { @@ -2956,7 +2977,7 @@ PRIVATE void split_line ARGS2( { HTLine* temp; - temp = allocHTLine(previous->size); + POOLallocHTLine(temp, previous->size); if (!temp) outofmem(__FILE__, "split_line_2"); memcpy(temp, previous, LINE_SIZE(previous->size)); @@ -2966,7 +2987,6 @@ PRIVATE void split_line ARGS2( outofmem(__FILE__, "split_line_2"); memcpy(temp->styles, previous->styles, sizeof(HTStyleChange)*previous->numstyles); #endif - FREE(previous); previous = temp; } @@ -3243,7 +3263,7 @@ PRIVATE void split_line ARGS2( i++; } jline = insert_blanks_in_line(previous, CurLine, text, - last_anchor_of_previous_line, + &last_anchor_of_previous_line /*updates++*/, ht_num_runs - 1, oldpos, newpos); free((char*)oldpos); if (jline == NULL) @@ -3251,26 +3271,14 @@ PRIVATE void split_line ARGS2( previous->next->prev = jline; previous->prev->next = jline; - FREE(previous); - previous = jline; } { /* (ht_num_runs==1) */ - /* keep maintaining 'last_anchor_of_previous_line' */ - TextAnchor* a2 = last_anchor_of_previous_line; if (justify_start_position) { char* p2 = previous->data; for( ; p2 < previous->data + justify_start_position; ++p2) *p2 = (*p2 == HT_NON_BREAK_SPACE ? ' ' : *p2); } - - if (!a2) - a2 = text->first_anchor; - else - a2 = a2->next; /* 1st anchor on line we justify */ - - for (; a2 && a2->line_num <= text->Lines-1; - last_anchor_of_previous_line = a2, a2 = a2->next); } } else { if (REALLY_CAN_JUSTIFY(text) ) { @@ -3322,9 +3330,7 @@ PRIVATE void blank_lines ARGS2( HText *, text, int, newlines) { - BOOL IgnoreSpaces = FALSE; - - if (!HText_LastLineSize(text, IgnoreSpaces)) { /* No text on current line */ + if (HText_LastLineEmpty(text, FALSE)) { /* No text on current line */ HTLine * line = text->last_line->prev; #ifdef USE_COLOR_STYLE @@ -3333,8 +3339,8 @@ PRIVATE void blank_lines ARGS2( return; /* Do not add a blank line at start */ #endif - while ((line != text->last_line) && - (HText_TrueLineSize(line, text, IgnoreSpaces) == 0)) { + while (line != text->last_line && + HText_TrueEmptyLine(line, text, FALSE)) { if (newlines == 0) break; newlines--; /* Don't bother: already blank */ @@ -4356,7 +4362,7 @@ PUBLIC void _internal_HTC ARGS3(HText *,text, int,style, int,dir) if (line->numstyles > 0 && dir == 0 && line->styles[line->numstyles-1].direction && - line->styles[line->numstyles-1].style == style && + line->styles[line->numstyles-1].style == (unsigned) style && (int) line->styles[line->numstyles-1].horizpos == (int)line->size - ctrl_chars_on_this_line) { /* @@ -4488,7 +4494,7 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2( } } if (line == me->last_line) { - if (line->size == 0 || !HText_TrueLineSize(line, me, FALSE)) + if (line->size == 0 || HText_TrueEmptyLine(line, me, FALSE)) continue; /* * Last ditch effort to end the table with a line break, @@ -4517,7 +4523,7 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2( continue; } mod_line = insert_blanks_in_line(line, lineno, me, - me->last_anchor_before_stbl, + &me->last_anchor_before_stbl /*updates++*/, ninserts, oldpos, newpos); if (mod_line) { if (line == me->last_line) { @@ -4530,7 +4536,6 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2( lines_changed++; if (line == first_line) first_line = mod_line; - free(line); line = mod_line; #ifdef DISP_PARTIAL /* @@ -4733,6 +4738,25 @@ PUBLIC void HText_startStblTABLE ARGS2( } } +#ifdef EXP_NESTED_TABLES +PRIVATE void free_enclosed_stbl ARGS1( + HText *, me) +{ + if (me->enclosed_stbl != NULL) { + HTList *list = me->enclosed_stbl; + STable_info *stbl; + while (NULL != (stbl = (STable_info *)HTList_nextObject(list))) { + CTRACE((tfp, "endStblTABLE: finally free %p\n", me->stbl)); + Stbl_free(stbl); + } + HTList_delete(me->enclosed_stbl); + me->enclosed_stbl = NULL; + } +} +#else +#define free_enclosed_stbl(me) /* nothing */ +#endif + /* Finish simple table handling * Return TRUE if the table is nested inside another table. */ @@ -4744,11 +4768,14 @@ PUBLIC int HText_endStblTABLE ARGS1( if (!me || !me->stbl) { CTRACE((tfp, "endStblTABLE: ignored.\n")); + free_enclosed_stbl(me); return FALSE; } CTRACE((tfp, "endStblTABLE: ok, will try.\n")); + ncols = Stbl_finishTABLE(me->stbl); CTRACE((tfp, "endStblTABLE: ncols = %d.\n", ncols)); + if (ncols > 0) { lines_changed = HText_insertBlanksInStblLines(me, ncols); CTRACE((tfp, "endStblTABLE: changed %d lines, done.\n", lines_changed)); @@ -4759,19 +4786,33 @@ PUBLIC int HText_endStblTABLE ARGS1( NumOfLines_partial -= lines_changed; /* fake */ #endif /* DISP_PARTIAL */ } + #ifdef EXP_NESTED_TABLES if (nested_tables) { enclosing = Stbl_get_enclosing(me->stbl); me->last_anchor_before_stbl = Stbl_get_last_anchor_before(me->stbl); - } else -#endif - Stbl_free(me->stbl); -#ifdef EXP_NESTED_TABLES - if (nested_tables) + if (enclosing == NULL) { + Stbl_free(me->stbl); + free_enclosed_stbl(me); + } else { + if (me->enclosed_stbl == NULL) + me->enclosed_stbl = HTList_new(); + HTList_addObject(me->enclosed_stbl, me->stbl); + CTRACE((tfp, "endStblTABLE: postpone free %p\n", me->stbl)); + } me->stbl = enclosing; - else -#endif + } else { + Stbl_free(me->stbl); + me->stbl = NULL; + } +#else + Stbl_free(me->stbl); me->stbl = NULL; +#endif + + CTRACE((tfp, "endStblTABLE: have%s enclosing table (%p)\n", + enclosing == 0 ? " NO" : "", enclosing)); + return enclosing != 0; } @@ -5541,7 +5582,6 @@ PUBLIC void HText_endAppend ARGS1( */ next_to_the_last_line->next = line_ptr; line_ptr->prev = next_to_the_last_line; - FREE(text->last_line); text->last_line = next_to_the_last_line; text->Lines--; CTRACE((tfp, "GridText: New bottom line: `%s'\n", @@ -5660,7 +5700,7 @@ re_parse: * done the trimming & adjusting for this anchor, so avoid * doing it a second time. - kw */ - if ((hilite_str = LYGetHiTextStr(anchor_ptr, 0)) != NULL) + if (LYGetHiTextStr(anchor_ptr, 0) != NULL) continue; if (anchor_ptr->line_pos > (int) line_ptr->size) { @@ -5724,10 +5764,12 @@ re_parse: if (line_ptr->data && anchor_ptr->extent > 0 && anchor_ptr->line_pos >= 0) { + LYClearHiText(anchor_ptr); LYSetHiText(anchor_ptr, &line_ptr->data[anchor_ptr->line_pos], anchor_ptr->extent); } else { + LYClearHiText(anchor_ptr); LYSetHiText(anchor_ptr, "", 0); } @@ -5747,7 +5789,7 @@ re_parse: if (!final && count_line >= stop_before) { - LYSetHiText(anchor_ptr, NULL, 0); + LYClearHiText(anchor_ptr); break; } else if (line_ptr2 == text->last_line) { break; @@ -8440,6 +8482,15 @@ PUBLIC int HText_LastLineSize ARGS2( return HText_TrueLineSize(text->last_line, text, IgnoreSpaces); } +PUBLIC BOOL HText_LastLineEmpty ARGS2( + HText *, text, + BOOL, IgnoreSpaces) +{ + if (!text || !text->last_line || !text->last_line->size) + return TRUE; + return HText_TrueEmptyLine(text->last_line, text, IgnoreSpaces); +} + PUBLIC int HText_LastLineOffset ARGS1( HText *, text) { @@ -8461,6 +8512,22 @@ PUBLIC int HText_PreviousLineSize ARGS2( return HText_TrueLineSize(line, text, IgnoreSpaces); } +PUBLIC BOOL HText_PreviousLineEmpty ARGS2( + HText *, text, + BOOL, IgnoreSpaces) +{ + HTLine * line; + + if (!text || !text->last_line) + return TRUE; + if (!(line = text->last_line->prev)) + return TRUE; + return HText_TrueEmptyLine(line, text, IgnoreSpaces); +} + +/* + * Compute the "true" line size. + */ PRIVATE int HText_TrueLineSize ARGS3( HTLine *, line, HText *, text, @@ -8475,9 +8542,7 @@ PRIVATE int HText_TrueLineSize ARGS3( if (IgnoreSpaces) { for (i = 0; i < line->size; i++) { if (!IsSpecialAttrChar(UCH(line->data[i])) && - (!(text && text->T.output_utf8) || - !is8bits(line->data[i]) || - (UCH((line->data[i] & 0xc0)) == 0xc0)) && + IS_UTF8_EXTRA(line->data[i]) && !isspace(UCH(line->data[i])) && UCH(line->data[i]) != HT_NON_BREAK_SPACE && UCH(line->data[i]) != HT_EN_SPACE) { @@ -8487,9 +8552,7 @@ PRIVATE int HText_TrueLineSize ARGS3( } else { for (i = 0; i < line->size; i++) { if (!IsSpecialAttrChar(line->data[i]) && - (!(text && text->T.output_utf8) || - !is8bits(line->data[i]) || - (UCH(line->data[i] & 0xc0) == 0xc0))) { + IS_UTF8_EXTRA(line->data[i])) { true_size++; } } @@ -8497,6 +8560,42 @@ PRIVATE int HText_TrueLineSize ARGS3( return true_size; } +/* + * Tell if the line is really empty. This is invoked much more often than + * HText_TrueLineSize(), and most lines are not empty. So it is faster to + * do this check than to check if the line size happens to be zero. + */ +PRIVATE BOOL HText_TrueEmptyLine ARGS3( + HTLine *, line, + HText *, text, + BOOL, IgnoreSpaces) +{ + size_t i; + + if (!(line && line->size)) + return TRUE; + + if (IgnoreSpaces) { + for (i = 0; i < line->size; i++) { + if (!IsSpecialAttrChar(UCH(line->data[i])) && + IS_UTF8_EXTRA(line->data[i]) && + !isspace(UCH(line->data[i])) && + UCH(line->data[i]) != HT_NON_BREAK_SPACE && + UCH(line->data[i]) != HT_EN_SPACE) { + return FALSE; + } + } + } else { + for (i = 0; i < line->size; i++) { + if (!IsSpecialAttrChar(line->data[i]) && + IS_UTF8_EXTRA(line->data[i])) { + return FALSE; + } + } + } + return TRUE; +} + PUBLIC void HText_NegateLineOne ARGS1( HText *, text) { @@ -8538,7 +8637,6 @@ PUBLIC void HText_RemovePreviousLine ARGS1( previous->next = text->last_line; text->last_line->prev = previous; text->Lines--; - FREE(line); } /* @@ -8587,7 +8685,7 @@ PUBLIC void HText_setTabID ARGS2( HTList * cur = text->tabs; HTList * last = NULL; - if (!text || !name || !*name) + if (!text || isEmpty(name)) return; if (!cur) { @@ -9337,7 +9435,7 @@ PUBLIC int HText_beginInput ARGS3( a->link_type = INPUT_ANCHOR; a->show_anchor = YES; - LYSetHiText(a, NULL, 0); + LYClearHiText(a); a->extent = 2; a->input_field = f; @@ -9981,6 +10079,7 @@ PRIVATE unsigned check_form_specialchars ARGS1( return result; } +#ifdef EXP_FILE_UPLOAD PRIVATE CONST char *guess_content_type ARGS1(CONST char *, filename) { HTAtom *encoding; @@ -9990,6 +10089,7 @@ PRIVATE CONST char *guess_content_type ARGS1(CONST char *, filename) ? format->name : "text/plain"; } +#endif /* * HText_SubmitForm - generate submit data from form fields. @@ -11726,7 +11826,7 @@ PRIVATE void insert_new_textarea_anchor ARGS2( * Clone and initialize the struct's needed to add a new TEXTAREA * anchor. */ - l = allocHTLine(MAX_LINE); + POOLallocHTLine(l, MAX_LINE); POOLtypecalloc(TextAnchor, a); POOLtypecalloc(FormInfo, f); if (a == NULL || l == NULL || f == NULL) @@ -12550,7 +12650,7 @@ PUBLIC int HText_InsertFile ARGS1( break; } - l = allocHTLine(MAX_LINE); + POOLallocHTLine(l, MAX_LINE); POOLtypecalloc(TextAnchor, a); POOLtypecalloc(FormInfo, f); if (a == NULL || l == NULL || f == NULL) diff --git a/src/GridText.h b/src/GridText.h index 7f2ce6af..83bbbb23 100644 --- a/src/GridText.h +++ b/src/GridText.h @@ -58,8 +58,6 @@ US-ASCII control characters <32 which are not defined in Unicode standard extern int HTCurSelectGroupType; extern char * HTCurSelectGroupSize; -extern HText * HTMainText; /* Equivalent of main window */ -extern HTParentAnchor * HTMainAnchor; /* Anchor for HTMainText */ #if defined(VMS) && defined(VAXC) && !defined(__DECC) extern int HTVirtualMemorySize; @@ -161,6 +159,8 @@ extern char * HTLoadedDocumentBookmark NOPARAMS; extern int HText_LastLineSize PARAMS((HText *me, BOOL IgnoreSpaces)); extern int HText_LastLineOffset PARAMS((HText *me)); extern int HText_PreviousLineSize PARAMS((HText *me, BOOL IgnoreSpaces)); +extern BOOL HText_LastLineEmpty PARAMS((HText *me, BOOL IgnoreSpaces)); +extern BOOL HText_PreviousLineEmpty PARAMS((HText *me, BOOL IgnoreSpaces)); extern void HText_NegateLineOne PARAMS((HText *text)); extern BOOL HText_inLineOne PARAMS((HText *text)); extern void HText_RemovePreviousLine PARAMS((HText *text)); diff --git a/src/HTML.c b/src/HTML.c index 9698e568..93e0cdb2 100644 --- a/src/HTML.c +++ b/src/HTML.c @@ -1667,9 +1667,11 @@ PRIVATE int HTML_start_element ARGS6( */ if (me->inBASE && *isindex_href != '\0' && *isindex_href != '#') action = HTParse(isindex_href, me->base_href, PARSE_ALL); - if (!(action && *action)) + if (isEmpty(action)) { + FREE(action); action = HTParse(isindex_href, me->node_anchor->address, PARSE_ALL); + } FREE(isindex_href); if (action && *action) { @@ -2080,8 +2082,8 @@ PRIVATE int HTML_start_element ARGS6( * Otherwise, don't do anything. -DH 980814, TD 980827 */ if ((LYCollapseBRs == FALSE && - HText_PreviousLineSize(me->text, FALSE)) || - HText_LastLineSize(me->text, FALSE)) { + !HText_PreviousLineEmpty(me->text, FALSE)) || + !HText_LastLineEmpty(me->text, FALSE)) { HText_setLastChar(me->text, ' '); /* absorb white space */ HText_appendCharacter(me->text, '\r'); } @@ -2113,10 +2115,10 @@ PRIVATE int HTML_start_element ARGS6( * the last line are blank. - FM */ UPDATE_STYLE; - if (HText_LastLineSize(me->text, FALSE)) { + if (!HText_LastLineEmpty(me->text, FALSE)) { HText_setLastChar(me->text, ' '); /* absorb white space */ HText_appendCharacter(me->text, '\r'); - } else if (!HText_PreviousLineSize(me->text, FALSE)) { + } else if (HText_PreviousLineEmpty(me->text, FALSE)) { HText_RemovePreviousLine(me->text); } me->in_word = NO; @@ -2575,7 +2577,7 @@ PRIVATE int HTML_start_element ARGS6( CHECK_ID(HTML_GEN_ID); HText_setLastChar(me->text, ' '); /* absorb white space */ if (!me->style_change) { - if (HText_LastLineSize(me->text, FALSE)) { + if (!HText_LastLineEmpty(me->text, FALSE)) { HText_appendCharacter(me->text, '\r'); } else { HText_NegateLineOne(me->text); @@ -3019,32 +3021,15 @@ PRIVATE int HTML_start_element ARGS6( */ me->inBoldA = TRUE; - CHECK_FOR_INTERN(intern_flag,value[HTML_A_HREF]); - if (present[HTML_A_ISMAP]) /*???*/ - intern_flag = FALSE; + StrAllocCopy(href, value[HTML_A_HREF]); + CHECK_FOR_INTERN(intern_flag,href); /*NULL, '\0', or '#'*/ - if (intern_flag) { - /*** FAST WAY: ***/ - StrAllocCopy(href, value[HTML_A_HREF]); - if (href && *href) - TRANSLATE_AND_UNESCAPE_TO_STD(&href); - if (!href || !*href) - StrAllocCopy(href, "#"); /*extreme case*/ + if (intern_flag) { /*** FAST WAY: ***/ + if (isEmpty(href)) + StrAllocCopy(href, "#"); + TRANSLATE_AND_UNESCAPE_TO_STD(&href); } else { - /* - * Prepare to do housekeeping on the reference. - FM - */ - if (!value[HTML_A_HREF] || *value[HTML_A_HREF] == '\0') { - StrAllocCopy(href, me->node_anchor->address); - } else if (*value[HTML_A_HREF] == '#') { - StrAllocCopy(href, me->node_anchor->address); - if (strlen(value[HTML_A_HREF]) > 1) { - StrAllocCat(href, value[HTML_A_HREF]); - } - } else { - StrAllocCopy(href, value[HTML_A_HREF]); - } url_type = LYLegitimizeHREF(me, &href, TRUE, TRUE); /* @@ -3060,24 +3045,25 @@ PRIVATE int HTML_start_element ARGS6( /* * Check whether a base tag is in effect. - FM */ - if ((me->inBASE && *href != '\0' && *href != '#') && - (temp = HTParse(href, me->base_href, PARSE_ALL)) && - *temp != '\0') + if (me->inBASE) { /* * Use reference related to the base. */ - StrAllocCopy(href, temp); - FREE(temp); + temp = href; + href = HTParse(temp, me->base_href, PARSE_ALL); + FREE(temp); + } - /* + /* * Check whether to fill in localhost. - FM */ - LYFillLocalFileURL(&href, - ((*href != '\0' && *href != '#' && - me->inBASE) - ? me->base_href - : me->node_anchor->address)); + LYFillLocalFileURL(&href, + (me->inBASE + ? me->base_href + : me->node_anchor->address)); } + if (present[HTML_A_ISMAP]) /*???*/ + intern_flag = FALSE; } else { if (bold_name_anchors == TRUE) { me->inBoldA = TRUE; @@ -3086,7 +3072,7 @@ PRIVATE int HTML_start_element ARGS6( if (present && present[HTML_A_TYPE] && value[HTML_A_TYPE]) { StrAllocCopy(temp, value[HTML_A_TYPE]); - if (!intern_flag && href && + if (!intern_flag && !strcasecomp(value[HTML_A_TYPE], HTAtom_name(HTInternalLink)) && !LYIsUIPage3(me->node_anchor->address, UIP_LIST_PAGE, 0) && !LYIsUIPage3(me->node_anchor->address, UIP_ADDRLIST_PAGE, 0) && @@ -3809,7 +3795,7 @@ PRIVATE int HTML_start_element ARGS6( me->base_href : me->node_anchor->address)); if (!(url_type = is_url(href))) { temp = HTParse(href, me->node_anchor->address, PARSE_ALL); - if (!(temp && *temp)) { + if (isEmpty(temp)) { FREE(href); FREE(temp); break; @@ -4242,7 +4228,7 @@ PRIVATE int HTML_start_element ARGS6( FREE(base); FREE(code); - if (href && *href) { + if (!isEmpty(href)) { if (me->inA) { if (me->inBoldA == TRUE && me->inBoldH == FALSE) HText_appendCharacter(me->text, LY_BOLD_END_CHAR); @@ -5811,7 +5797,7 @@ PRIVATE int HTML_start_element ARGS6( HTML_end_element(me, HTML_U, include); } UPDATE_STYLE; - if (HText_LastLineSize(me->text, FALSE)) { + if (!HText_LastLineEmpty(me->text, FALSE)) { HText_setLastChar(me->text, ' '); /* absorb white space */ HText_appendCharacter(me->text, '\r'); } @@ -7558,12 +7544,16 @@ End_Object: me->DivisionAlignments[me->Division_Level]; change_paragraph_style(me, me->sp->style); UPDATE_STYLE; + #ifdef EXP_NESTED_TABLES if (nested_tables) { me->inTABLE = HText_endStblTABLE(me->text); - } else -#endif + } else { + HText_endStblTABLE(me->text); + } +#else HText_endStblTABLE(me->text); +#endif me->current_default_alignment = me->sp->style->alignment; if (me->List_Nesting_Level >= 0) @@ -7573,7 +7563,7 @@ End_Object: /* These TABLE related elements may now not be SGML_EMPTY. - kw */ case HTML_TR: HText_endStblTR(me->text); - if (HText_LastLineSize(me->text, FALSE)) { + if (!HText_LastLineEmpty(me->text, FALSE)) { HText_setLastChar(me->text, ' '); /* absorb next white space */ HText_appendCharacter(me->text, '\r'); } diff --git a/src/HTML.h b/src/HTML.h index 81cbfbcc..bbf9de45 100644 --- a/src/HTML.h +++ b/src/HTML.h @@ -285,4 +285,3 @@ extern int HTLoadError PARAMS(( CONST char * message)); #endif /* HTML_H */ - diff --git a/src/LYBookmark.h b/src/LYBookmark.h index 681777e5..e90a2e45 100644 --- a/src/LYBookmark.h +++ b/src/LYBookmark.h @@ -18,4 +18,3 @@ extern void save_bookmark_link PARAMS((char *address, char *title)); extern void set_default_bookmark_page PARAMS((char * value)); #endif /* LYBOOKMARK_H */ - diff --git a/src/LYCgi.c b/src/LYCgi.c index 8f80eec0..08350424 100644 --- a/src/LYCgi.c +++ b/src/LYCgi.c @@ -160,7 +160,7 @@ PRIVATE int LYLoadCGI ARGS4( char *pgm_buff = NULL; /* PATH_INFO extraction buffer */ char *path_translated; /* From document_root/path_info */ - if (!arg || !*arg || strlen(arg) <= 8) { + if (isEmpty(arg) || strlen(arg) <= 8) { HTAlert(BAD_REQUEST); status = -2; return(status); diff --git a/src/LYCharUtils.c b/src/LYCharUtils.c index 752934d5..0a537f40 100644 --- a/src/LYCharUtils.c +++ b/src/LYCharUtils.c @@ -64,7 +64,7 @@ PUBLIC void LYEntify ARGS2( int in_sjis = 0; #endif - if (p == NULL || *p == '\0') + if (isEmpty(p)) return; /* @@ -390,7 +390,7 @@ PUBLIC void LYFillLocalFileURL ARGS2( { char * temp = NULL; - if (*href == NULL || *(*href) == '\0') + if (isEmpty(*href)) return; if (!strcmp(*href, "//") || !strncmp(*href, "///", 3)) { @@ -1107,7 +1107,7 @@ PUBLIC char ** LYUCFullyTranslateString ARGS9( /* ** Make sure we have a non-empty string. - FM */ - if (!str || *str == NULL || **str == '\0') + if (!str || isEmpty(*str)) return str; /* @@ -2032,6 +2032,78 @@ PUBLIC BOOL LYUCTranslateBackFormData ARGS4( } /* + * Parse a parameter from an HTML META tag, i.e., the CONTENT. + */ +PUBLIC char *LYParseTagParam ARGS2( + char *, from, + char *, name) +{ + size_t len = strlen(name); + char *result = NULL; + char *string = from; + + do { + if ((string = strchr(string, ';')) == NULL) + return NULL; + while (*string != '\0' && (*string == ';' || isspace(UCH(*string)))) { + string++; + } + if (strlen(string) < len) return NULL; + } while (strncasecomp(string, name, len) != 0); + string += len; + while (*string != '\0' && (UCH(isspace(*string)) || *string == '=')) { + string++; + } + + StrAllocCopy(result, string); + len = 0; + while (isprint(UCH(string[len])) && string[len] != ';') { + len++; + } + result[len] = '\0'; + + /* + * Strip single quotes, just in case. + */ + if (len > 2 && result[0] == '\'' && result[len-1] == result[0]) { + result[len-1] = '\0'; + for (string = result; (string[0] = string[1]) != '\0'; ++string) + ; + } + return result; +} + +/* + * Given a refresh-URL content string, parses the delay time and the URL + * string. Ignore the remainder of the content. + */ +PUBLIC void LYParseRefreshURL ARGS3( + char *, content, + char **, p_seconds, + char **, p_address) +{ + char *cp; + char *cp1 = NULL; + char *Seconds = NULL; + + /* + * Look for the Seconds field. - FM + */ + cp = LYSkipBlanks(content); + if (*cp && isdigit(UCH(*cp))) { + cp1 = cp; + while (*cp1 && isdigit(UCH(*cp1))) + cp1++; + StrnAllocCopy(Seconds, cp, cp1 - cp); + } + *p_seconds = Seconds; + *p_address = LYParseTagParam(content, "URL"); + + CTRACE((tfp, "LYParseRefreshURL\n\tcontent: %s\n\tseconds: %s\n\taddress: %s\n", + content, NonNull(*p_seconds), NonNull(*p_address))); +} + +/* ** This function processes META tags in HTML streams. - FM */ PUBLIC void LYHandleMETA ARGS4( @@ -2414,38 +2486,9 @@ PUBLIC void LYHandleMETA ARGS4( } else if (!strcasecomp(NonNull(http_equiv), "Refresh")) { char *Seconds = NULL; - /* - * Look for the Seconds field. - FM - */ - cp = LYSkipBlanks(content); - if (*cp && isdigit(UCH(*cp))) { - cp1 = cp; - while (*cp1 && isdigit(UCH(*cp1))) - cp1++; - if (*cp1) - *cp1++ = '\0'; - StrAllocCopy(Seconds, cp); - } + LYParseRefreshURL(content, &Seconds, &href); + if (Seconds) { - /* - * We have the seconds field. - * Now look for a URL field - FM - */ - while (*cp1) { - if (!strncasecomp(cp1, "URL", 3)) { - cp = (cp1 + 3); - while (*cp && (*cp == '=' || isspace(UCH(*cp)))) - cp++; - cp1 = cp; - while (*cp1 && !isspace(UCH(*cp1))) - cp1++; - *cp1 = '\0'; - if (*cp) - StrAllocCopy(href, cp); - break; - } - cp1++; - } if (href) { /* * We found a URL field, so check it out. - FM @@ -2497,6 +2540,7 @@ PUBLIC void LYHandleMETA ARGS4( /* * Check for an anchor in http or https URLs. - FM */ + cp = NULL; #ifndef DONT_TRACK_INTERNAL_LINKS /* id_string seems to be used wrong below if given. not that it matters much. avoid setting it here. - kw */ @@ -2676,7 +2720,7 @@ PUBLIC void LYHandlePlike ARGS6( * to start a newline, if needed, then fall through * to handle attributes. - FM */ - if (HText_LastLineSize(me->text, FALSE)) { + if (!HText_LastLineEmpty(me->text, FALSE)) { HText_setLastChar(me->text, ' '); /* absorb white space */ HText_appendCharacter(me->text, '\r'); } @@ -2962,7 +3006,7 @@ PUBLIC int LYLegitimizeHREF ARGS4( char *pound = NULL; char *fragment = NULL; - if (!me || !href || *href == NULL || *(*href) == '\0') + if (!me || !href || isEmpty(*href)) return(url_type); if (!LYTrimStartfile(*href)) { @@ -3256,11 +3300,11 @@ PUBLIC void LYEnsureDoubleSpace ARGS1( if (!me || !me->text) return; - if (HText_LastLineSize(me->text, FALSE)) { + if (!HText_LastLineEmpty(me->text, FALSE)) { HText_setLastChar(me->text, ' '); /* absorb white space */ HText_appendCharacter(me->text, '\r'); HText_appendCharacter(me->text, '\r'); - } else if (HText_PreviousLineSize(me->text, FALSE)) { + } else if (!HText_PreviousLineEmpty(me->text, FALSE)) { HText_setLastChar(me->text, ' '); /* absorb white space */ HText_appendCharacter(me->text, '\r'); } else if (me->List_Nesting_Level >= 0) { @@ -3281,7 +3325,7 @@ PUBLIC void LYEnsureSingleSpace ARGS1( if (!me || !me->text) return; - if (HText_LastLineSize(me->text, FALSE)) { + if (!HText_LastLineEmpty(me->text, FALSE)) { HText_setLastChar(me->text, ' '); /* absorb white space */ HText_appendCharacter(me->text, '\r'); } else if (me->List_Nesting_Level >= 0) { diff --git a/src/LYCharUtils.h b/src/LYCharUtils.h index 4ca20000..8fad7644 100644 --- a/src/LYCharUtils.h +++ b/src/LYCharUtils.h @@ -55,6 +55,13 @@ extern void LYAddMETAcharsetToFD PARAMS(( extern void LYformTitle PARAMS(( char ** dst, CONST char * src)); +extern char *LYParseTagParam PARAMS(( + char * from, + char * name)); +extern void LYParseRefreshURL PARAMS(( + char * content, + char ** p_seconds, + char ** p_address)); #ifdef Lynx_HTML_Handler extern int OL_CONTINUE; /* flag for whether CONTINUE is set */ diff --git a/src/LYClean.c b/src/LYClean.c index cbdb820f..9c7a3012 100644 --- a/src/LYClean.c +++ b/src/LYClean.c @@ -157,7 +157,6 @@ PUBLIC void cleanup_files NOARGS PUBLIC void cleanup NOARGS { - int i; #ifdef VMS extern BOOLEAN DidCleanup; #endif /* VMS */ @@ -205,14 +204,17 @@ PUBLIC void cleanup NOARGS #endif cleanup_files(); - for (i = 0; i < nhist; i++) { - LYFreeDocInfo(&HDOC(i)); - } - nhist = 0; #ifdef VMS ttclose(); DidCleanup = TRUE; #endif /* VMS */ + /* + * If we're looking at memory leaks, hang onto the trace file, since there + * is no memory freed in this function, and it is a nuisance to not be able + * to trace the cleanup activity -TD + */ +#ifndef LY_FIND_LEAKS LYCloseTracelog(); +#endif } diff --git a/src/LYCookie.c b/src/LYCookie.c index d5cf0f38..6de3cf55 100644 --- a/src/LYCookie.c +++ b/src/LYCookie.c @@ -325,8 +325,8 @@ PRIVATE domain_entry * find_domain_entry ARGS1( } CTRACE((tfp, "find_domain_entry(%s) bv:%d, invcheck_bv:%d\n", name, - de ? de->bv : -1, - de ? de->invcheck_bv : -1)); + de ? (int) de->bv : -1, + de ? (int) de->invcheck_bv : -1)); return de; } diff --git a/src/LYCurses.c b/src/LYCurses.c index 7fe777f4..c2bf87e1 100644 --- a/src/LYCurses.c +++ b/src/LYCurses.c @@ -615,9 +615,11 @@ PRIVATE struct { */ PRIVATE int get_color_pair ARGS1(int, n) { +#ifdef USE_CURSES_PAIR_0 if (lynx_color_pairs[n].fg == default_fg && lynx_color_pairs[n].bg == default_bg) return 0; +#endif return COLOR_PAIR(n); } @@ -1058,7 +1060,9 @@ PUBLIC void start_curses NOARGS lynx_setup_colors(); } #else +#if defined(HAVE_USE_DEFAULT_COLORS) lynx_default_colors(); +#endif /* HAVE_USE_DEFAULT_COLORS */ #endif /* EXP_ASSUMED_COLOR */ #endif /* USE_DEFAULT_COLORS */ } @@ -1423,7 +1427,7 @@ PUBLIC BOOLEAN setup ARGS1( LYTrimTrailing(buffer); } - if (buffer == 0 || *buffer == 0) + if (isEmpty(buffer)) StrAllocCopy(buffer,"vt100"); HTSprintf0(&term_putenv,"TERM=%.106s", buffer); diff --git a/src/LYCurses.h b/src/LYCurses.h index e07d0e8f..db732a96 100644 --- a/src/LYCurses.h +++ b/src/LYCurses.h @@ -211,6 +211,9 @@ typedef struct { # if defined(NCURSES) && defined(HAVE_NCURSES_TERM_H) # include <ncurses/term.h> # else +# if defined(HAVE_NCURSESW_NCURSES_H) || defined(HAVE_NCURSES_NCURSES_H) || defined(HAVE_XCURSES) +# undef HAVE_TERM_H /* only use one in comparable path! */ +# endif # if defined(HAVE_TERM_H) # include <term.h> # endif @@ -258,6 +261,19 @@ typedef struct { #undef USE_CURSES_PADS #endif +/* + * Most implementations of curses treat pair 0 specially, as the default + * foreground and background color. Also, the COLORS variable corresponds to + * the total number of colors. + * + * PDCurses does not follow these rules. Its COLORS variable claims it has + * 8 colors, but it actually implements 16. That makes it hard to optimize + * color settings against color pair 0 in a portable fashion. + */ +#if defined(COLOR_CURSES) && !(defined(PDCURSES) || defined(HAVE_XCURSES)) +#define USE_CURSES_PAIR_0 +#endif + #endif /* USE_SLANG */ #ifdef USE_SLANG diff --git a/src/LYDownload.c b/src/LYDownload.c index 311bedbe..eb379746 100644 --- a/src/LYDownload.c +++ b/src/LYDownload.c @@ -485,16 +485,9 @@ PUBLIC int LYdownload_options ARGS2( StrAllocCopy(sug_filename, *newfile); change_sug_filename(sug_filename); - if (LYReuseTempfiles) { - fp0 = LYOpenTempRewrite(tempfile, HTML_SUFFIX, BIN_W); - } else { - LYRemoveTemp(tempfile); - fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, BIN_W); - } - if (fp0 == NULL) { - HTAlert(CANNOT_OPEN_TEMP); + if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0) return(-1); - } + StrAllocCopy(downloaded_url, *newfile); LYLocalFileToURL(newfile, tempfile); diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h index 821e9f94..4b769a77 100644 --- a/src/LYGlobalDefs.h +++ b/src/LYGlobalDefs.h @@ -185,6 +185,7 @@ extern BOOLEAN LYShowCursor; /* Show the cursor or hide it? */ extern BOOLEAN LYShowTransferRate; extern BOOLEAN LYUseDefShoCur; /* Command line -show_cursor toggle */ extern BOOLEAN LYUserSpecifiedURL; /* URL from a goto or document? */ +extern BOOLEAN LYfind_leaks; extern BOOLEAN LYforce_HTML_mode; extern BOOLEAN LYforce_no_cache; extern BOOLEAN LYinternal_flag; /* don't need fresh copy, was internal link */ @@ -511,6 +512,10 @@ extern BOOLEAN LYNoCore; extern BOOLEAN restore_sigpipe_for_children; #endif /* !VMS */ +#if defined(USE_COLOR_STYLE) +extern char *lynx_lss_file; +#endif + extern int HTNoDataOK; /* HT_NO_DATA-is-ok hack */ extern BOOLEAN FileInitAlreadyDone; diff --git a/src/LYHistory.c b/src/LYHistory.c index 0a9a91c5..ff27686e 100644 --- a/src/LYHistory.c +++ b/src/LYHistory.c @@ -41,6 +41,11 @@ PRIVATE VisitedLink *Last_by_first; int nhist_extra; #ifdef LY_FIND_LEAKS +PRIVATE int already_registered_free_messages_stack = 0; +PRIVATE int already_registered_clean_all_history = 0; +#endif + +#ifdef LY_FIND_LEAKS /* * Utility for freeing the list of visited links. - FM */ @@ -296,17 +301,33 @@ PUBLIC void LYFreeDocInfo ARGS1( /* * Free the information in the last history entry. */ -PRIVATE void clean_extra NOARGS +PRIVATE void clean_extra_history NOARGS { - trace_history("clean_extra"); + trace_history("clean_extra_history"); nhist += nhist_extra; while (nhist_extra > 0) { nhist--; LYFreeDocInfo(&HDOC(nhist)); nhist_extra--; } - trace_history("...clean_extra"); + trace_history("...clean_extra_history"); +} + +/* + * Free the entire history stack, for auditing memory leaks. + */ +#ifdef LY_FIND_LEAKS +PRIVATE void clean_all_history NOARGS +{ + trace_history("clean_all_history"); + clean_extra_history(); + while (nhist > 0) { + nhist--; + LYFreeDocInfo(&HDOC(nhist)); + } + trace_history("...clean_all_history"); } +#endif /* FIXME What is the relationship to are_different() from the mainloop?! */ PRIVATE int are_identical ARGS2( @@ -374,7 +395,13 @@ PUBLIC int LYpush ARGS2( return 1; } - clean_extra(); + clean_extra_history(); +#ifdef LY_FIND_LEAKS + if (!already_registered_clean_all_history) { + already_registered_clean_all_history = 1; + atexit(clean_all_history); + } +#endif /* * OK, push it if we have stack space. @@ -506,7 +533,7 @@ PUBLIC void LYpop ARGS1( DocInfo *, doc) { if (nhist > 0) { - clean_extra(); + clean_extra_history(); nhist--; LYFreeDocInfo(doc); @@ -615,16 +642,8 @@ PUBLIC int showhistory ARGS1( int x = 0; FILE *fp0; - if (LYReuseTempfiles) { - fp0 = LYOpenTempRewrite(tempfile, HTML_SUFFIX, "w"); - } else { - LYRemoveTemp(tempfile); - fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w"); - } - if (fp0 == NULL) { - HTAlert(CANNOT_OPEN_TEMP); + if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0) return(-1); - } LYLocalFileToURL(newfile, tempfile); @@ -791,16 +810,8 @@ PUBLIC int LYShowVisitedLinks ARGS1( if (!cur) return(-1); - if (LYReuseTempfiles) { - fp0 = LYOpenTempRewrite(tempfile, HTML_SUFFIX, "w"); - } else { - LYRemoveTemp(tempfile); - fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w"); - } - if (fp0 == NULL) { - HTAlert(CANNOT_OPEN_TEMP); + if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0) return(-1); - } LYLocalFileToURL(newfile, tempfile); LYRegisterUIPage(*newfile, UIP_VLINKS); @@ -943,9 +954,6 @@ PUBLIC int LYShowVisitedLinks ARGS1( #define STATUSBUFSIZE 40 PRIVATE char * buffstack[STATUSBUFSIZE]; PRIVATE int topOfStack = 0; -#ifdef LY_FIND_LEAKS -PRIVATE int already_registered_free_messages_stack = 0; -#endif #ifdef LY_FIND_LEAKS PRIVATE void free_messages_stack NOARGS diff --git a/src/LYJump.c b/src/LYJump.c index 97a0a072..7d04f27b 100644 --- a/src/LYJump.c +++ b/src/LYJump.c @@ -375,7 +375,7 @@ PRIVATE unsigned LYRead_Jumpfile ARGS1(struct JumpTable *, jtp) char *cp; unsigned i; - if (jtp->file == NULL || *(jtp->file) == '\0') + if (isEmpty(jtp->file)) return 0; CTRACE((tfp, "Read Jumpfile %s\n", jtp->file)); diff --git a/src/LYJump.h b/src/LYJump.h index 3a82b075..25e8d16b 100644 --- a/src/LYJump.h +++ b/src/LYJump.h @@ -27,4 +27,3 @@ extern BOOL LYJumpInit PARAMS((char *config)); extern char *LYJump PARAMS((int key)); #endif /* LYJUMP_H */ - diff --git a/src/LYKeymap.c b/src/LYKeymap.c index 7a51bcfa..a436bc67 100644 --- a/src/LYKeymap.c +++ b/src/LYKeymap.c @@ -1193,12 +1193,12 @@ PUBLIC int LYStringToKeycode ARGS1 ( } else if (len > 2 && !strncasecomp(src, "0x", 2)) { char *dst = 0; key = strtol(src, &dst, 0); - if (dst == 0 || *dst != 0) + if (isEmpty(dst)) key = -1; } else if (len > 6 && !strncasecomp(src, "key-", 4)) { char *dst = 0; key = strtol(src + 4, &dst, 0); - if (dst == 0 || *dst != 0) + if (isEmpty(dst)) key = -1; } if (key < 0) { diff --git a/src/LYLeaks.c b/src/LYLeaks.c index 3f014d33..84ef77f3 100644 --- a/src/LYLeaks.c +++ b/src/LYLeaks.c @@ -2,6 +2,11 @@ ** Copyright (c) 1994, University of Kansas, All Rights Reserved ** ** This code will be used only if LY_FIND_LEAKS is defined. +** +** Revision History: +** 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe +** 10-30-97 modified to handle StrAllocCopy() and +** StrAllocCat(). - KW & FM */ /* @@ -13,15 +18,142 @@ #include <LYexit.h> #include <LYLeaks.h> #include <LYUtils.h> +#include <LYGlobalDefs.h> + +#ifdef LY_FIND_LEAKS PRIVATE AllocationList *ALp_RunTimeAllocations = NULL; -PRIVATE void AddToList PARAMS(( - AllocationList * ALp_new)); -PRIVATE AllocationList *FindInList PARAMS(( - void * vp_find)); -PRIVATE void RemoveFromList PARAMS(( - AllocationList * ALp_del)); +#define LEAK_SUMMARY + +#ifdef LEAK_SUMMARY + +PRIVATE long now_allocated = 0; +PRIVATE long peak_alloced = 0; + +PRIVATE long total_alloced = 0; +PRIVATE long total_freed = 0; + +PRIVATE long count_mallocs = 0; +PRIVATE long count_frees = 0; + +PRIVATE void CountMallocs ARGS1(long, size) +{ + ++count_mallocs; + total_alloced += size; + now_allocated += size; + if (peak_alloced < now_allocated) + peak_alloced = now_allocated; +} + +PRIVATE void CountFrees ARGS1(long, size) +{ + ++count_frees; + total_freed += size; + now_allocated -= size; +} +#else +#define CountMallocs() ++count_mallocs +#define CountFrees() /* nothing */ +#endif + +/* +** Purpose: Add a new allocation item to the list. +** Arguments: ALp_new The new item to add. +** Return Value: void +** Remarks/Portability/Dependencies/Restrictions: +** Static function made to make code reusable in projects beyond +** Lynx (some might ask why not use HTList). +** Revision History: +** 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe +*/ +PRIVATE void AddToList ARGS1( + AllocationList *, ALp_new) +{ + /* + * Just make this the first item in the list. + */ + ALp_new->ALp_Next = ALp_RunTimeAllocations; + ALp_RunTimeAllocations = ALp_new; +} + +/* +** Purpose: Find the place in the list where vp_find is currently +** tracked. +** Arguments: vp_find A pointer to look for in the list. +** Return Value: AllocationList * Either vp_find's place in the +** list or NULL if not found. +** Remarks/Portability/Dependencies/Restrictions: +** Static function made to make code reusable in projects outside +** of Lynx (some might ask why not use HTList). +** Revision History: +** 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe +*/ +PRIVATE AllocationList *FindInList ARGS1( + void *, vp_find) +{ + AllocationList *ALp_find = ALp_RunTimeAllocations; + + /* + * Go through the list of allocated pointers until end of list + * or vp_find is found. + */ + while (ALp_find != NULL) { + if (ALp_find->vp_Alloced == vp_find) { + break; + } + ALp_find = ALp_find->ALp_Next; + } + + return(ALp_find); +} + +/* +** Purpose: Remove the specified item from the list. +** Arguments: ALp_del The item to remove from the list. +** Return Value: void +** Remarks/Portability/Dependencies/Restrictions: +** Static function made to make code reusable in projects outside +** of Lynx (some might ask why not use HTList). +** Revision History: +** 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe +*/ +PRIVATE void RemoveFromList ARGS1( + AllocationList *, ALp_del) +{ + AllocationList *ALp_findbefore = ALp_RunTimeAllocations; + + /* + * There is one special case, where the item to remove is the + * first in the list. + */ + if (ALp_del == ALp_findbefore) { + ALp_RunTimeAllocations = ALp_del->ALp_Next; + return; + } + + /* + * Loop through checking all of the next values, if a match + * don't continue. Always assume the item will be found. + */ + while (ALp_findbefore->ALp_Next != ALp_del) { + ALp_findbefore = ALp_findbefore->ALp_Next; + } + + /* + * We are one item before the one to get rid of. + * Get rid of it. + */ + ALp_findbefore->ALp_Next = ALp_del->ALp_Next; +} + +/* + * Make the malloc-sequence available for debugging/tracing. + */ +PUBLIC long LYLeakSequence NOARGS +{ + return count_mallocs; +} /* ** Purpose: Print a report of all memory left unallocated by @@ -36,10 +168,6 @@ PRIVATE void RemoveFromList PARAMS(( ** in main. ** All output of this function is sent to the file defined in ** the header LYLeaks.h (LEAKAGE_SINK). -** Revision History: -** 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe -** 10-30-97 modified to handle StrAllocCopy() and -** StrAllocCat(). - KW & FM */ PUBLIC void LYLeaks NOARGS { @@ -47,6 +175,9 @@ PUBLIC void LYLeaks NOARGS size_t st_total = (size_t)0; FILE *Fp_leakagesink; + if (LYfind_leaks == FALSE) + return; + /* * Open the leakage sink to take all the output. * Recreate the file each time. @@ -76,6 +207,9 @@ PUBLIC void LYLeaks NOARGS */ fprintf(Fp_leakagesink, "%s.\n", gettext("Invalid pointer detected.")); + fprintf(Fp_leakagesink, "%s\t%ld\n", + gettext("Sequence:"), + ALp_head->st_Sequence); fprintf(Fp_leakagesink, "%s\t%p\n", gettext("Pointer:"), ALp_head->vp_BadRequest); @@ -113,6 +247,9 @@ PUBLIC void LYLeaks NOARGS fprintf(Fp_leakagesink, "%s\n", gettext("Memory leak detected.")); + fprintf(Fp_leakagesink, "%s\t%ld\n", + gettext("Sequence:"), + ALp_head->st_Sequence); fprintf(Fp_leakagesink, "%s\t%p\n", gettext("Pointer:"), ALp_head->vp_Alloced); @@ -166,12 +303,21 @@ PUBLIC void LYLeaks NOARGS * Give a grand total of the leakage. * Close the output file. */ - fprintf(Fp_leakagesink, "\n%s\t%u\n", + fprintf(Fp_leakagesink, "%s\t%u\n", gettext("Total memory leakage this run:"), (unsigned)st_total); +#ifdef LEAK_SUMMARY + fprintf(Fp_leakagesink, "%s\t%ld\n", gettext("Peak allocation"), peak_alloced); + fprintf(Fp_leakagesink, "%s\t%ld\n", gettext("Bytes allocated"), total_alloced); + fprintf(Fp_leakagesink, "%s\t%ld\n", gettext("Total mallocs"), count_mallocs); + fprintf(Fp_leakagesink, "%s\t%ld\n", gettext("Total frees"), count_frees); +#endif fclose(Fp_leakagesink); HTSYS_purge(LEAKAGE_SINK); +#if defined(NCURSES) && defined(HAVE__NC_FREEALL) + _nc_freeall(); +#endif } /* @@ -196,10 +342,16 @@ PUBLIC void *LYLeakMalloc ARGS3( CONST char *, cp_File, CONST short, ssi_Line) { + void *vp_malloc; + + if (LYfind_leaks == FALSE) + return (void *)malloc(st_bytes); + /* * Do the actual allocation. */ - void *vp_malloc = (void *)malloc(st_bytes); + vp_malloc = (void *)malloc(st_bytes); + CountMallocs(st_bytes); /* * Only on successful allocation do we track any information. @@ -219,6 +371,7 @@ PUBLIC void *LYLeakMalloc ARGS3( * There is no need to allocate more memory for the * file name as it is a static string anyhow. */ + ALp_new->st_Sequence = count_mallocs; ALp_new->vp_Alloced = vp_malloc; ALp_new->st_Bytes = st_bytes; ALp_new->SL_memory.cp_FileName = cp_File; @@ -238,7 +391,7 @@ PUBLIC void *LYLeakMalloc ARGS3( ** after a call to malloc or calloc or an equivalent ** function which may or may not have already created ** a list entry. -** Arguments: vp_malloc The pointer to newly allocate memory. +** Arguments: vp_malloc The pointer to newly allocated memory. ** Arguments: st_bytes The size of the allocation requested ** in bytes. ** cp_File The file from which the request for @@ -260,6 +413,10 @@ PUBLIC AllocationList *LYLeak_mark_malloced ARGS4( CONST short, ssi_Line) { AllocationList *ALp_new = NULL; + + if (LYfind_leaks == FALSE) + return NULL; + /* * The actual allocation has already been done! * @@ -324,10 +481,16 @@ PUBLIC void *LYLeakCalloc ARGS4( CONST char *, cp_File, CONST short, ssi_Line) { + void *vp_calloc; + + if (LYfind_leaks == FALSE) + return (void *)calloc(st_number, st_bytes); + /* * Allocate the requested memory. */ - void *vp_calloc = (void *)calloc(st_number, st_bytes); + vp_calloc = (void *)calloc(st_number, st_bytes); + CountMallocs(st_bytes); /* * Only if the allocation was a success do we track information. @@ -348,6 +511,7 @@ PUBLIC void *LYLeakCalloc ARGS4( * There is no need to allocate memory for the file * name as it is a static string anyway. */ + ALp_new->st_Sequence = count_mallocs; ALp_new->vp_Alloced = vp_calloc; ALp_new->st_Bytes = (st_number * st_bytes); ALp_new->SL_memory.cp_FileName = cp_File; @@ -393,6 +557,9 @@ PUBLIC void *LYLeakRealloc ARGS4( void *vp_realloc; AllocationList *ALp_renew; + if (LYfind_leaks == FALSE) + return (void *)realloc(vp_Alloced, st_newBytes); + /* * If we are asked to resize a NULL pointer, this is just a * malloc call. @@ -439,7 +606,11 @@ PUBLIC void *LYLeakRealloc ARGS4( * If not NULL, record the information. */ vp_realloc = (void *)realloc(vp_Alloced, st_newBytes); + CountMallocs(st_newBytes); + CountFrees(ALp_renew->st_Bytes); + if (vp_realloc != NULL) { + ALp_renew->st_Sequence = count_mallocs; ALp_renew->vp_Alloced = vp_realloc; ALp_renew->st_Bytes = st_newBytes; @@ -531,6 +702,11 @@ PUBLIC void LYLeakFree ARGS3( { AllocationList *ALp_free; + if (LYfind_leaks == FALSE) { + free(vp_Alloced); + return; + } + /* * Find the pointer in the allocated list. * If not found, bad pointer. @@ -567,6 +743,7 @@ PUBLIC void LYLeakFree ARGS3( * Free off the memory. * Take entry out of allocation list. */ + CountFrees(ALp_free->st_Bytes); RemoveFromList(ALp_free); FREE(ALp_free); FREE(vp_Alloced); @@ -643,6 +820,7 @@ PUBLIC char * LYLeakSACat ARGS4( } #if defined(LY_FIND_LEAKS) && defined(LY_FIND_LEAKS_EXTENDED) + PUBLIC CONST char * leak_cp_File_hack = __FILE__; PUBLIC short leak_ssi_Line_hack = __LINE__; @@ -702,6 +880,11 @@ PRIVATE char * LYLeakSAVsprintf ARGS6( if (!dest) return NULL; + if (LYfind_leaks == FALSE) { + StrAllocVsprintf(dest, inuse, fmt, ap); + return (*dest); + } + vp_oldAlloced = *dest; if (!vp_oldAlloced) { StrAllocVsprintf(dest, inuse, fmt, ap); @@ -862,94 +1045,9 @@ PUBLIC HTSprintflike *Get_htsprintf0_fn ARGS2( return &LYLeakHTSprintf0; } -#endif /* not LY_FIND_LEAKS and LY_FIND_LEAKS_EXTENDED */ - -/* -** Purpose: Add a new allocation item to the list. -** Arguments: ALp_new The new item to add. -** Return Value: void -** Remarks/Portability/Dependencies/Restrictions: -** Static function made to make code reusable in projects beyond -** Lynx (some might ask why not use HTList). -** Revision History: -** 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe -*/ -PRIVATE void AddToList ARGS1( - AllocationList *, ALp_new) -{ - /* - * Just make this the first item in the list. - */ - ALp_new->ALp_Next = ALp_RunTimeAllocations; - ALp_RunTimeAllocations = ALp_new; -} - -/* -** Purpose: Find the place in the list where vp_find is currently -** tracked. -** Arguments: vp_find A pointer to look for in the list. -** Return Value: AllocationList * Either vp_find's place in the -** list or NULL if not found. -** Remarks/Portability/Dependencies/Restrictions: -** Static function made to make code reusable in projects outside -** of Lynx (some might ask why not use HTList). -** Revision History: -** 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe -*/ -PRIVATE AllocationList *FindInList ARGS1( - void *, vp_find) -{ - AllocationList *ALp_find = ALp_RunTimeAllocations; - - /* - * Go through the list of allocated pointers until end of list - * or vp_find is found. - */ - while (ALp_find != NULL) { - if (ALp_find->vp_Alloced == vp_find) { - break; - } - ALp_find = ALp_find->ALp_Next; - } - - return(ALp_find); -} - -/* -** Purpose: Remove the specified item from the list. -** Arguments: ALp_del The item to remove from the list. -** Return Value: void -** Remarks/Portability/Dependencies/Restrictions: -** Static function made to make code reusable in projects outside -** of Lynx (some might ask why not use HTList). -** Revision History: -** 05-26-94 created Lynx 2-3-1 Garrett Arch Blythe -*/ -PRIVATE void RemoveFromList ARGS1( - AllocationList *, ALp_del) -{ - AllocationList *ALp_findbefore = ALp_RunTimeAllocations; - - /* - * There is one special case, where the item to remove is the - * first in the list. - */ - if (ALp_del == ALp_findbefore) { - ALp_RunTimeAllocations = ALp_del->ALp_Next; - return; - } - - /* - * Loop through checking all of the next values, if a match - * don't continue. Always assume the item will be found. - */ - while (ALp_findbefore->ALp_Next != ALp_del) { - ALp_findbefore = ALp_findbefore->ALp_Next; - } - - /* - * We are one item before the one to get rid of. - * Get rid of it. - */ - ALp_findbefore->ALp_Next = ALp_del->ALp_Next; -} +#endif /* LY_FIND_LEAKS and LY_FIND_LEAKS_EXTENDED */ +#else +/* Standard C forbids an empty file */ +void no_leak_checking NOPARAMS; +void no_leak_checking NOARGS { } +#endif /* LY_FIND_LEAKS */ diff --git a/src/LYList.c b/src/LYList.c index e9777988..724f5689 100644 --- a/src/LYList.c +++ b/src/LYList.c @@ -62,16 +62,8 @@ PUBLIC int showlist ARGS2( return(-1); } - if (LYReuseTempfiles && titles == last_titles) { - fp0 = LYOpenTempRewrite(tempfile, HTML_SUFFIX, "w"); - } else { - LYRemoveTemp(tempfile); - fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w"); - } - if (fp0 == NULL) { - HTUserMsg(CANNOT_OPEN_TEMP); + if ((fp0 = InternalPageFP(tempfile, titles == last_titles)) == 0) return(-1); - } LYLocalFileToURL(&(newdoc->address), tempfile); diff --git a/src/LYLocal.c b/src/LYLocal.c index db733817..94fe9964 100644 --- a/src/LYLocal.c +++ b/src/LYLocal.c @@ -1952,11 +1952,8 @@ PUBLIC int dired_options ARGS2( struct dired_menu *mp; char buf[2048]; - LYRemoveTemp(tempfile); - if ((fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w")) == NULL) { - HTAlert(gettext("Unable to open file management menu file.")); + if ((fp0 = InternalPageFP(tempfile, FALSE)) == 0) return(0); - } /* * Make the tempfile a URL. diff --git a/src/LYMail.c b/src/LYMail.c index 7e8731cb..b0fb8034 100644 --- a/src/LYMail.c +++ b/src/LYMail.c @@ -399,7 +399,9 @@ PRIVATE char *blat_cmd( #if USE_VMS_MAILER PUBLIC BOOLEAN LYMailPMDF(void) { - return !strncasecomp(system_mail, "PMDF SEND", 9); + return (system_mail != 0) + ? !strncasecomp(system_mail, "PMDF SEND", 9) + : FALSE; } /* @@ -456,12 +458,14 @@ PRIVATE void remove_quotes (char * string) PUBLIC FILE *LYPipeToMailer NOARGS { char *buffer = NULL; - FILE *fp; + FILE *fp = NULL; - HTSprintf0(&buffer, "%s %s", system_mail, system_mail_flags); - fp = popen(buffer, "w"); - CTRACE((tfp, "popen(%s) %s\n", buffer, fp != 0 ? "OK" : "FAIL")); - FREE(buffer); + if (LYSystemMail()) { + HTSprintf0(&buffer, "%s %s", system_mail, system_mail_flags); + fp = popen(buffer, "w"); + CTRACE((tfp, "popen(%s) %s\n", buffer, fp != 0 ? "OK" : "FAIL")); + FREE(buffer); + } return fp; } #else /* DOS, Win32, etc. */ @@ -479,6 +483,9 @@ PUBLIC int LYSendMailFile ARGS5( #endif /* __DJGPP__ */ int code; + if (!LYSystemMail()) + return 0; + #if USE_BLAT_MAILER if (mail_is_blat) StrAllocCopy(cmd, @@ -542,10 +549,10 @@ PUBLIC int LYSendMailFile ARGS5( ** mailform() sends form content to the mailto address(es). - FM */ PUBLIC void mailform ARGS4( - CONST char *, mailto_address, - CONST char *, mailto_subject, - CONST char *, mailto_content, - CONST char *, mailto_type) + CONST char *, mailto_address, + CONST char *, mailto_subject, + CONST char *, mailto_content, + CONST char *, mailto_type) { FILE *fd; char *address = NULL; @@ -573,6 +580,9 @@ PUBLIC void mailform ARGS4( NONNULL(mailto_content), NONNULL(mailto_type))); + if (!LYSystemMail()) + return; + if (!mailto_address || !mailto_content) { HTAlert(BAD_FORM_MAILTO); return; @@ -870,9 +880,9 @@ cleanup: */ PUBLIC void mailmsg ARGS4( int, cur, - char *, owner_address, - char *, filename, - char *, linkname) + char *, owner_address, + char *, filename, + char *, linkname) { FILE *fd, *fp; char *address = NULL; @@ -898,6 +908,9 @@ PUBLIC void mailmsg ARGS4( #endif /* VMS */ + if (!LYSystemMail()) + return; + #ifdef ALERTMAIL if (owner_address == NULL) { owner_address = ALERTMAIL; @@ -905,9 +918,8 @@ PUBLIC void mailmsg ARGS4( } #endif - if (owner_address == NULL || *owner_address == '\0') { + if (isEmpty(owner_address)) return; - } if ((cp = (char *)strchr(owner_address,'\n')) != NULL) { #ifdef ALERTMAIL if (skip_parsing) @@ -1097,8 +1109,8 @@ PUBLIC void mailmsg ARGS4( ** a comment from the users to the owner */ PUBLIC void reply_by_mail ARGS4( - char *, mail_address, - char *, filename, + char *, mail_address, + char *, filename, CONST char *, title, CONST char *, refid) { @@ -1143,6 +1155,9 @@ PUBLIC void reply_by_mail ARGS4( term_letter = FALSE; + if (!LYSystemMail()) + return; + if (isEmpty(mail_address)) { HTAlert(NO_ADDRESS_IN_MAILTO_URL); return; @@ -1471,7 +1486,7 @@ PUBLIC void reply_by_mail ARGS4( BOOLEAN is_preparsed = (BOOL) (LYPreparsedSource && HTisDocumentSource()); if (HTConfirm(is_preparsed - ? INC_PREPARSED_MSG_PROMPT + ? INC_PREPARSED_MSG_PROMPT : INC_ORIG_MSG_PROMPT) == YES) { print_wwwfile_to_fd(fd, (BOOL) !is_preparsed); } @@ -1704,7 +1719,7 @@ PUBLIC void reply_by_mail ARGS4( cancelled: HTInfoMsg(CANCELLED); LYCloseTempFP(fd); /* Close the tmpfile. */ - scrollok(LYwin,FALSE); /* Stop scrolling. */ + scrollok(LYwin,FALSE); /* Stop scrolling. */ cleanup: signal(SIGINT, cleanup_sig); term_letter = FALSE; @@ -1729,3 +1744,15 @@ cleanup: FREE(body); return; } + +/* + * Check that we have configured values for system mailer. + */ +PUBLIC BOOLEAN LYSystemMail NOARGS +{ + if (system_mail == 0 || !strcmp(system_mail, "unknown")) { + HTAlert(gettext("No system mailer configured")); + return FALSE; + } + return TRUE; +} diff --git a/src/LYMail.h b/src/LYMail.h index ec887318..9d93d0e1 100644 --- a/src/LYMail.h +++ b/src/LYMail.h @@ -29,6 +29,7 @@ extern BOOLEAN term_letter; +extern BOOLEAN LYSystemMail NOPARAMS; extern BOOLEAN LYMailPMDF NOPARAMS; extern FILE *LYPipeToMailer NOPARAMS; extern int LYSendMailFile PARAMS(( diff --git a/src/LYMain.c b/src/LYMain.c index 0e8733a8..2792bdd9 100644 --- a/src/LYMain.c +++ b/src/LYMain.c @@ -290,6 +290,7 @@ PUBLIC BOOLEAN local_host_only = FALSE; PUBLIC BOOLEAN override_no_download = FALSE; PUBLIC BOOLEAN show_dotfiles = FALSE; /* From rcfile if no_dotfiles is false */ PUBLIC BOOLEAN LYforce_HTML_mode = FALSE; +PUBLIC BOOLEAN LYfind_leaks = TRUE; #ifdef __DJGPP__ PUBLIC BOOLEAN watt_debug = FALSE; /* WATT-32 debugging */ @@ -597,7 +598,7 @@ PRIVATE void reset_break(void) #endif /* __DJGPP__ */ #if defined(WIN_EX) -PUBLIC int is_windows_nt(void) +PRIVATE int is_windows_nt(void) { DWORD version; @@ -1057,7 +1058,11 @@ PUBLIC int main ARGS2( StrAllocCopy(language, PREFERRED_LANGUAGE); StrAllocCopy(pref_charset, PREFERRED_CHARSET); StrAllocCopy(system_mail, SYSTEM_MAIL); +#ifdef SYSTEM_MAIL_FLAGS StrAllocCopy(system_mail_flags, SYSTEM_MAIL_FLAGS); +#else + StrAllocCopy(system_mail_flags, ""); +#endif StrAllocCopy(LYUserAgent, LYNX_NAME); StrAllocCat(LYUserAgent, "/"); StrAllocCat(LYUserAgent, LYNX_VERSION); @@ -2953,7 +2958,7 @@ G)oto's" }, CONST char *value; BOOLEAN found, first; - if (next_arg == 0 || *next_arg == '\0') { + if (isEmpty(next_arg)) { SetOutputMode( O_TEXT ); for (j = 0; j < TABLESIZE(Usage); j++) { printf("%s\n", Usage[j]); @@ -3328,6 +3333,12 @@ keys (may be incompatible with some curses packages)" "include all versions of files in local VMS directory\nlistings" ), #endif +#ifdef LY_FIND_LEAKS + PARSE_SET( + "find_leaks", 4|TOGGLE_ARG, LYfind_leaks, + "toggles memory-leak checking" + ), +#endif PARSE_SET( "force_empty_hrefless_a", 4|SET_ARG, force_empty_hrefless_a, "\nforce HREF-less 'A' elements to be empty (close them as\nsoon as they are seen)" @@ -3424,6 +3435,12 @@ keys (may be incompatible with some curses packages)" "minimal", 4|TOGGLE_ARG, minimal_comments, "toggles minimal versus valid comment parsing" ), +#ifdef EXP_NESTED_TABLES + PARSE_SET( + "nested_tables", 4|TOGGLE_ARG, nested_tables, + "toggles nested-tables logic" + ), +#endif #ifndef DISABLE_NEWS PARSE_FUN( "newschunksize", 4|NEED_FUNCTION_ARG, newschunksize_fun, diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c index 9260f128..e57b882c 100644 --- a/src/LYMainLoop.c +++ b/src/LYMainLoop.c @@ -6941,7 +6941,7 @@ new_cmd: /* s = links[curdoc.link].lname; } else s = curdoc.address; - if (!s && !*s) + if (isEmpty(s)) HTInfoMsg("Current URL is empty."); if (put_clip(s)) HTInfoMsg("Copy to clipboard failed."); diff --git a/src/LYNews.h b/src/LYNews.h index 9eaa8e13..096062d3 100644 --- a/src/LYNews.h +++ b/src/LYNews.h @@ -10,4 +10,3 @@ extern BOOLEAN term_message; extern char *LYNewsPost PARAMS((char *newsgroups, BOOLEAN followup)); #endif /* LYNEWSPOST_H */ - diff --git a/src/LYOptions.c b/src/LYOptions.c index 8f763e1b..0fc62491 100644 --- a/src/LYOptions.c +++ b/src/LYOptions.c @@ -3162,16 +3162,8 @@ PRIVATE int gen_options ARGS1( size_t cset_len = 0; size_t text_len = LYscreenWidth() > 45 ? LYscreenWidth() - 38 : 7; /* cf: PutLabel */ - if (LYReuseTempfiles) { - fp0 = LYOpenTempRewrite(tempfile, HTML_SUFFIX, "w"); - } else { - LYRemoveTemp(tempfile); - fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w"); - } - if (fp0 == NULL) { - HTAlert(UNABLE_TO_OPEN_TEMPFILE); + if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0) return(NOT_FOUND); - } LYLocalFileToURL(newfile, tempfile); diff --git a/src/LYPrint.c b/src/LYPrint.c index 72e96659..9f92ab35 100644 --- a/src/LYPrint.c +++ b/src/LYPrint.c @@ -497,6 +497,9 @@ PRIVATE void send_file_to_mail ARGS3( char *subject = NULL; char user_response[LINESIZE]; + if (!LYSystemMail()) + return; + if (LYPreparsedSource && first_mail_preparsed && HTisDocumentSource()) { if (HTConfirmDefault(CONFIRM_MAIL_SOURCE_PREPARSED, NO) == YES) { @@ -1263,16 +1266,8 @@ PUBLIC int print_options ARGS3( FILE *fp0; lynx_list_item_type *cur_printer; - if (LYReuseTempfiles) { - fp0 = LYOpenTempRewrite(my_temp, HTML_SUFFIX, "w"); - } else { - LYRemoveTemp(my_temp); - fp0 = LYOpenTemp(my_temp, HTML_SUFFIX, "w"); - } - if (fp0 == NULL) { - HTAlert(UNABLE_TO_OPEN_PRINTOP_FILE); + if ((fp0 = InternalPageFP(my_temp, TRUE)) == 0) return(-1); - } LYLocalFileToURL(newfile, my_temp); diff --git a/src/LYPrint.h b/src/LYPrint.h index 622b09f4..249b12b6 100644 --- a/src/LYPrint.h +++ b/src/LYPrint.h @@ -11,4 +11,3 @@ extern int print_options PARAMS((char **newfile, extern char * GetFileName NOPARAMS; #endif /* LYPRINT_H */ - diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c index 0c96100b..b67b08f8 100644 --- a/src/LYReadCFG.c +++ b/src/LYReadCFG.c @@ -239,14 +239,9 @@ PUBLIC int match_item_by_name ARGS3( int default_fg = DEFAULT_COLOR; int default_bg = DEFAULT_COLOR; #else -#ifdef PDCURSES -int default_fg = 15; -int default_bg = COLOR_BLACK; -#else int default_fg = COLOR_WHITE; int default_bg = COLOR_BLACK; #endif -#endif PRIVATE CONST char *Color_Strings[16] = { @@ -1123,7 +1118,7 @@ PRIVATE int parse_html_src_spec ARGS3( * message. */ char* ts2; - if ( !value || !*value) return 0; /* silently ignoring*/ + if (isEmpty(value)) return 0; /* silently ignoring*/ #define BS() html_src_bad_syntax(value,option_name) @@ -1215,7 +1210,7 @@ PRIVATE int read_htmlsrc_tagname_xform ARGS1( char*,str) /* This table is searched ignoring case */ PRIVATE Config_Type Config_Table [] = -{ +{ PARSE_SET(RC_ACCEPT_ALL_COOKIES, LYAcceptAllCookies), PARSE_TIM(RC_ALERTSECS, AlertSecs), PARSE_SET(RC_ALWAYS_RESUBMIT_POSTS, LYresubmit_posts), @@ -1587,35 +1582,31 @@ PRIVATE char *actual_filename ARGS3( char *, parent_filename, char *, dft_filename) { - static char *my_filename; + char *my_filename = NULL; - if (my_filename != 0) { - FREE(my_filename); - } if (!LYisAbsPath(cfg_filename) && !(parent_filename == 0 && LYCanReadFile(cfg_filename))) { if (!strncmp(cfg_filename, "~/", 2)) { HTSprintf0(&my_filename, "%s%s", Home_Dir(), cfg_filename+1); - cfg_filename = my_filename; } else { if (parent_filename != 0) { StrAllocCopy(my_filename, parent_filename); *LYPathLeaf (my_filename) = '\0'; StrAllocCat(my_filename, cfg_filename); } - if (my_filename != 0 && LYCanReadFile(my_filename)) { - cfg_filename = my_filename; - } else { + if (my_filename == 0 || !LYCanReadFile(my_filename)) { StrAllocCopy(my_filename, dft_filename); *LYPathLeaf (my_filename) = '\0'; StrAllocCat(my_filename, cfg_filename); - if (LYCanReadFile(my_filename)) { - cfg_filename = my_filename; + if (!LYCanReadFile(my_filename)) { + StrAllocCopy(my_filename, cfg_filename); } } } + } else { + StrAllocCopy(my_filename, cfg_filename); } - return cfg_filename; + return my_filename; } PUBLIC FILE *LYOpenCFG ARGS3( @@ -1623,9 +1614,14 @@ PUBLIC FILE *LYOpenCFG ARGS3( char *, parent_filename, char *, dft_filename) { - cfg_filename = actual_filename(cfg_filename, parent_filename, dft_filename); - CTRACE((tfp, "opening config file %s\n", cfg_filename)); - return fopen(cfg_filename, TXT_R); + char *my_file = actual_filename(cfg_filename, parent_filename, dft_filename); + FILE *result; + + CTRACE((tfp, "opening config file %s\n", my_file)); + result = fopen(my_file, TXT_R); + FREE(my_file); + + return result; } #define NOPTS_ ( TABLESIZE(Config_Table) - 1 ) @@ -1888,7 +1884,10 @@ PRIVATE void do_read_cfg ARGS5( #ifndef NO_CONFIG_INFO if (fp0 != 0 && !no_lynxcfg_xinfo) { - LYLocalFileToURL(&url, actual_filename(value, cfg_filename, LYNX_CFG_FILE)); + char *my_file = actual_filename(value, cfg_filename, LYNX_CFG_FILE); + + LYLocalFileToURL(&url, my_file); + FREE(my_file); StrAllocCopy(cp1, value); if (strchr(value, '&') || strchr(value, '<')) { LYEntify(&cp1, TRUE); @@ -2033,6 +2032,16 @@ PUBLIC void read_cfg ARGS4( do_read_cfg(cfg_filename, parent_filename, nesting_level, fp0, NULL); } +#ifndef NO_CONFIG_INFO +PRIVATE void extra_cfg_link ARGS3( + FILE *, fp, + char *, href, + char *, name) +{ + fprintf(fp, "<a href=\"%s\">%s</a>", + href, name); +} +#endif /* NO_CONFIG_INFO */ /* * Show rendered lynx.cfg data without comments, LYNXCFG:/ internal page. @@ -2135,17 +2144,9 @@ PUBLIC int lynx_cfg_infopage ARGS1( } if (lynxcfginfo_url == 0) { - if (LYReuseTempfiles) { - fp0 = LYOpenTempRewrite(tempfile, HTML_SUFFIX, "w"); - } else { - if (tempfile[0]) - LYRemoveTemp(tempfile); - fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w"); - } - if (fp0 == NULL) { - HTAlert(CANNOT_OPEN_TEMP); + if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0) return(NOT_FOUND); - } + LYLocalFileToURL(&lynxcfginfo_url, tempfile); LYforce_no_cache = TRUE; /* don't cache this doc */ @@ -2178,14 +2179,34 @@ PUBLIC int lynx_cfg_infopage ARGS1( gettext("for more comments.")); } -#if defined(HAVE_CONFIG_H) && !defined(NO_CONFIG_INFO) - if (!no_compileopts_info) { - fprintf(fp0, "%s <a href=\"%s\">%s</a>\n\n", - SEE_ALSO, - STR_LYNXCFLAGS, - COMPILE_OPT_SEGMENT); - } +#ifndef NO_CONFIG_INFO +#if defined(HAVE_CONFIG_H) && defined(USE_COLOR_STYLE) + if (!no_compileopts_info && !no_lynxcfg_xinfo) { + fprintf(fp0, "%s</pre><ul><li>", SEE_ALSO); + extra_cfg_link(fp0, STR_LYNXCFLAGS, COMPILE_OPT_SEGMENT); + + fprintf(fp0, "<li>"); + LYLocalFileToURL(&temp, lynx_lss_file); + extra_cfg_link(fp0, temp, COLOR_STYLE_SEGMENT); + fprintf(fp0, "</ul><pre>\n"); + } else +#endif + { + fprintf(fp0, "%s ", SEE_ALSO); +#if defined(HAVE_CONFIG_H) + if (!no_compileopts_info) { + extra_cfg_link(fp0, STR_LYNXCFLAGS, COMPILE_OPT_SEGMENT); + } #endif +#if defined(USE_COLOR_STYLE) + if (!no_lynxcfg_xinfo) { + LYLocalFileToURL(&temp, lynx_lss_file); + extra_cfg_link(fp0, temp, COLOR_STYLE_SEGMENT); + } +#endif + fprintf(fp0, "\n\n"); + } +#endif /* NO_CONFIG_INFO */ /** a new experimental link ... **/ if (user_mode == ADVANCED_MODE) @@ -2279,16 +2300,9 @@ PUBLIC int lynx_compile_opts ARGS1( } } if (configinfo_url == NULL) { - if (LYReuseTempfiles) { - fp0 = LYOpenTempRewrite(tempfile, HTML_SUFFIX, "w"); - } else { - LYRemoveTemp(tempfile); - fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w"); - } - if (fp0 == NULL) { - HTAlert(CANNOT_OPEN_TEMP); + if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0) return(NOT_FOUND); - } + LYLocalFileToURL(&configinfo_url, tempfile); BeginInternalPage (fp0, CONFIG_DEF_TITLE, NULL); diff --git a/src/LYShowInfo.c b/src/LYShowInfo.c index 9939a3e5..596e753c 100644 --- a/src/LYShowInfo.c +++ b/src/LYShowInfo.c @@ -281,7 +281,7 @@ PUBLIC int LYShowInfo ARGS4( } else { LYUCcharset * p_in = HTAnchor_getUCInfoStage(HTMainAnchor, UCT_STAGE_PARSER); - if (!p_in || !(p_in->MIMEname) || !*(p_in->MIMEname) || + if (!p_in || isEmpty(p_in->MIMEname) || HTAnchor_getUCLYhndl(HTMainAnchor, UCT_STAGE_PARSER) < 0) { p_in = HTAnchor_getUCInfoStage(HTMainAnchor, UCT_STAGE_MIME); } diff --git a/src/LYShowInfo.h b/src/LYShowInfo.h index f95247fa..623eaf44 100644 --- a/src/LYShowInfo.h +++ b/src/LYShowInfo.h @@ -12,4 +12,3 @@ extern int LYShowInfo PARAMS((DocInfo *doc, int size_of_file, DocInfo *newdoc, char *owner_address)); #endif /* LYSHOWINFO_H */ - diff --git a/src/LYStrings.c b/src/LYStrings.c index 02615488..b981540c 100644 --- a/src/LYStrings.c +++ b/src/LYStrings.c @@ -535,7 +535,7 @@ PRIVATE int set_clicked_link ARGS4( c = LAC_TO_LKC0(LYK_CHANGE_LINK); } else { - if (2*y > LYlines){ /* Bottom Half of the screen */ + if (2*y > LYlines){ /* Bottom Half of the screen */ if (4*y < 3*LYlines){ c = LAC_TO_LKC0(LYK_DOWN_TWO); /* Third quarter */ } else @@ -2144,8 +2144,6 @@ re_read: } #else /* pdcurses version */ - /* _WINDOWS 1997/10/18 (Sat) 19:41:59 */ - #define H_CMD_AREA 6 #define HIST_CMD_2 12 #define V_CMD_AREA 1 @@ -2162,39 +2160,7 @@ re_read: c = -1; mouse_link = -1; - if (system_is_NT) { - /* for Windows NT */ - request_mouse_pos(); - - if (BUTTON_STATUS(1) & BUTTON_PRESSED) { - if (MOUSE_Y_POS > (LYlines - V_CMD_AREA)) { - /* Screen BOTTOM */ - if (MOUSE_X_POS < left) { - c = LTARROW; p = "<-"; - } else if (MOUSE_X_POS < HIST_CMD_2) { - c = RTARROW; p = "->"; - } else if (MOUSE_X_POS > right) { - c = 'z'; p = "Cancel"; - } else { - c = PGDOWN; p = "PGDOWN"; - } - } else if (MOUSE_Y_POS < V_CMD_AREA) { - /* Screen TOP */ - if (MOUSE_X_POS < left) { - c = LTARROW; p = "<-"; - } else if (MOUSE_X_POS < HIST_CMD_2) { - c = RTARROW; p = "->"; - } else if (MOUSE_X_POS > right) { - c = 'z'; p = "Cancel"; - } else { - c = PGUP; p = "PGUP"; - } - } else { - c = set_clicked_link(MOUSE_X_POS, MOUSE_Y_POS, FOR_PANEL, 1); - } - } - } else { - /* for Windows 95 */ + if (!system_is_NT) { tick_count = GetTickCount(); /* Guard Mouse button miss click */ @@ -2204,15 +2170,18 @@ re_read: } else { old_click = tick_count; } - request_mouse_pos(); - if (MOUSE_Y_POS > (LYlines - V_CMD_AREA)) { + } + request_mouse_pos(); + + if (BUTTON_STATUS(1) & BUTTON_PRESSED) { + if (MOUSE_Y_POS > (LYlines - V_CMD_AREA - 1)) { /* Screen BOTTOM */ if (MOUSE_X_POS < left) { c = LTARROW; p = "<-"; } else if (MOUSE_X_POS < HIST_CMD_2) { c = RTARROW; p = "->"; } else if (MOUSE_X_POS > right) { - c = '\b'; p = "History"; + c = 'z'; p = "Cancel"; } else { c = PGDOWN; p = "PGDOWN"; } @@ -2480,16 +2449,19 @@ PUBLIC BOOLEAN LYRemoveNewlines ARGS1( /* * Remove ALL whitespace from a string (including embedded blanks). */ -PUBLIC void LYRemoveBlanks ARGS1( +PUBLIC char * LYRemoveBlanks ARGS1( char *, buffer) { if (buffer != 0) { size_t i, j; - for (i = j = 0; buffer[i]; i++) + for (i = j = 0; buffer[i]; i++) { if (!isspace(UCH((buffer[i])))) buffer[j++] = buffer[i]; + } buffer[j] = 0; + return buffer+j; } + return NULL; } /* @@ -4993,7 +4965,7 @@ PUBLIC char *LYstrsep ARGS2( { char *tmp, *out; - if (!stringp || !*stringp) /* nothing to do? */ + if (isEmpty(stringp)) /* nothing to do? */ return 0; /* then don't fall on our faces */ out = *stringp; /* save the start of the string */ @@ -5746,7 +5718,7 @@ PUBLIC int LYReadCmdKey ARGS1( ++tmp; } if (*tmp != '\0') { - *tmp++ = '\0'; + *tmp++ = '\0'; tmp = LYSkipBlanks(tmp); } CTRACE((tfp, "LYSetConfigValue(%s, %s)\n", src, tmp)); @@ -5757,7 +5729,7 @@ PUBLIC int LYReadCmdKey ARGS1( } if (feof(cmd_script)) { fclose(cmd_script); - cmd_script = 0; + cmd_script = 0; } if (ch >= 0) { LYSleepReplay(); diff --git a/src/LYStrings.h b/src/LYStrings.h index 3fcb443e..6bbff9db 100644 --- a/src/LYStrings.h +++ b/src/LYStrings.h @@ -306,7 +306,7 @@ extern void LYUpperCase PARAMS(( char * buffer)); extern BOOLEAN LYRemoveNewlines PARAMS(( char * buffer)); -extern void LYRemoveBlanks PARAMS(( +extern char * LYRemoveBlanks PARAMS(( char * buffer)); extern char * LYSkipBlanks PARAMS(( char * buffer)); diff --git a/src/LYStyle.c b/src/LYStyle.c index fde9473a..b6d71ea2 100644 --- a/src/LYStyle.c +++ b/src/LYStyle.c @@ -1,6 +1,6 @@ /* character level styles for Lynx * (c) 1996 Rob Partington -- donated to the Lyncei (if they want it :-) - * @Id: LYStyle.c 1.50 Sun, 06 Oct 2002 17:43:28 -0700 dickey @ + * @Id: LYStyle.c 1.51 Wed, 22 Jan 2003 01:43:13 -0800 dickey @ */ #include <HTUtils.h> #include <HTML.h> @@ -192,7 +192,9 @@ PRIVATE void parse_attributes ARGS5( if (fA < MAX_COLOR && bA < MAX_COLOR +#ifdef USE_CURSES_PAIR_0 && (fA != default_fg || bA != default_bg) +#endif && curPair < 255) { if (our_pairs[iBold][iBlink][iFg][iBg] != 0) { curPair = our_pairs[iBold][iBlink][iFg][iBg]; @@ -505,7 +507,7 @@ PRIVATE int style_readFromFileREC ARGS2( int len; CTRACE2(TRACE_STYLE, (tfp, "CSS:Reading styles from file: %s\n", lss_filename ? lss_filename : "?!? empty ?!?")); - if (lss_filename == NULL || *lss_filename == '\0') + if (isEmpty(lss_filename)) return -1; if ((fh = LYOpenCFG(lss_filename, parent_filename, LYNX_LSS_FILE)) == 0) { /* this should probably be an alert or something */ diff --git a/src/LYUpload.c b/src/LYUpload.c index 1667e937..d8b0d10d 100644 --- a/src/LYUpload.c +++ b/src/LYUpload.c @@ -185,16 +185,8 @@ PUBLIC int LYUpload_options ARGS2( static char curloc[LY_MAXPATH]; char *cp; - if (LYReuseTempfiles) { - fp0 = LYOpenTempRewrite(tempfile, HTML_SUFFIX, "w"); - } else { - LYRemoveTemp(tempfile); - fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "w"); - } - if (fp0 == NULL) { - HTAlert(CANNOT_OPEN_TEMP); + if ((fp0 = InternalPageFP(tempfile, TRUE)) == 0) return(-1); - } #ifdef VMS strcpy(curloc, "/sys$login"); diff --git a/src/LYUtils.c b/src/LYUtils.c index 5fbe1965..291751bd 100644 --- a/src/LYUtils.c +++ b/src/LYUtils.c @@ -250,7 +250,7 @@ PUBLIC void LYAddHilite ARGS3( HiliteList *list = &(links[cur].list); HiliteInfo *have = list->hl_info; unsigned need = (list->hl_len - 1); - unsigned want = ++(list->hl_len) * sizeof(HiliteInfo); + unsigned want = (list->hl_len += 1) * sizeof(HiliteInfo); if (have != NULL) { have = realloc(have, want); @@ -1951,7 +1951,7 @@ PUBLIC int LYCheckForProxyURL ARGS1( /* * Don't crash on an empty argument. */ - if (cp == NULL || *cp == '\0') + if (isEmpty(cp)) return(NOT_A_URL_TYPE); /* kill beginning spaces */ @@ -2011,6 +2011,12 @@ static BOOLEAN compare_type ARGS3( return FALSE; } +#define DoubleHtmlSep(s) (LYIsHtmlSep((s)[0]) && LYIsHtmlSep((s)[1])) +#define compare_two(tst,cmp,len,limit) \ + ((len + 2) <= limit \ + && DoubleHtmlSep(tst + len) \ + && compare_type(tst, cmp, len)) + /* ** Must recognize a URL and return the type. ** If recognized, based on a case-insensitive @@ -2029,11 +2035,13 @@ PUBLIC int is_url ARGS1( char *cp = filename; char *cp1; int result = NOT_A_URL_TYPE; + int len; + int limit; /* * Don't crash on an empty argument. */ - if (cp == NULL || *cp == '\0') + if (isEmpty(cp)) return(result); /* @@ -2057,228 +2065,300 @@ PUBLIC int is_url ARGS1( if (*cp == ':' || LYIsHtmlSep(*cp)) { result = NOT_A_URL_TYPE; -#ifndef DISABLE_NEWS - } else if (compare_type(cp, STR_NEWS_URL, LEN_NEWS_URL)) { - result = NEWS_URL_TYPE; - - } else if (compare_type(cp, STR_NNTP_URL, LEN_NNTP_URL)) { - result = NNTP_URL_TYPE; - - } else if (compare_type(cp, STR_SNEWS_URL, LEN_SNEWS_URL)) { - result = SNEWS_URL_TYPE; - - } else if (compare_type(cp, "newspost:", 9)) { - /* - * Special Lynx type to handle news posts. - */ - result = NEWSPOST_URL_TYPE; + } else { + limit = strlen(cp); + switch (*cp) { + case 'L': + case 'l': + /* + * Lynx internal pages ("LYNXfoo:" or "lynxfoo:") + * start with 'l' or 'L', other URLs aren't. + */ + if (compare_type(cp, STR_LYNXEXEC, LEN_LYNXEXEC)) { + /* + * Special External Lynx type to handle execution + * of commands or scripts which require a pause to + * read the screen upon completion. + */ + result = LYNXEXEC_URL_TYPE; - } else if (compare_type(cp, "newsreply:", 10)) { - /* - * Special Lynx type to handle news replies (followups). - */ - result = NEWSREPLY_URL_TYPE; + } else if (compare_type(cp, STR_LYNXPROG, LEN_LYNXPROG)) { + /* + * Special External Lynx type to handle execution + * of commands, scripts or programs with do not + * require a pause to read screen upon completion. + */ + result = LYNXPROG_URL_TYPE; - } else if (compare_type(cp, "snewspost:", 10)) { - /* - * Special Lynx type to handle snews posts. - */ - result = NEWSPOST_URL_TYPE; + } else if (compare_type(cp, STR_LYNXCGI, LEN_LYNXCGI)) { + /* + * Special External Lynx type to handle cgi scripts. + */ + result = LYNXCGI_URL_TYPE; - } else if (compare_type(cp, "snewsreply:", 11)) { - /* - * Special Lynx type to handle snews replies (followups). - */ - result = NEWSREPLY_URL_TYPE; -#endif + } else if (compare_type(cp, STR_LYNXPRINT, LEN_LYNXPRINT)) { + /* + * Special Internal Lynx type. + */ + result = LYNXPRINT_URL_TYPE; - } else if (compare_type(cp, STR_MAILTO_URL, LEN_MAILTO_URL)) { - result = MAILTO_URL_TYPE; + } else if (compare_type(cp, STR_LYNXOPTIONS, LEN_LYNXOPTIONS)) { + /* + * Special Internal Lynx type. + */ + result = LYNXOPTIONS_URL_TYPE; -#ifndef DISABLE_BIBP - } else if (compare_type(cp, STR_BIBP_URL, LEN_BIBP_URL)) { - result = BIBP_URL_TYPE; -#endif + } else if (compare_type(cp, STR_LYNXCFG, LEN_LYNXCFG)) { + /* + * Special Internal Lynx type. + */ + result = LYNXCFG_URL_TYPE; - } else if (compare_type(cp, STR_FILE_URL, LEN_FILE_URL)) { - if (LYisLocalFile(cp)) { - result = FILE_URL_TYPE; - } else if (LYIsHtmlSep(cp[5]) && LYIsHtmlSep(cp[6])) { - result = FTP_URL_TYPE; - } else { - result = NOT_A_URL_TYPE; - } + } else if (compare_type(cp, STR_LYNXMESSAGES, LEN_LYNXMESSAGES)) { + /* + * Special Internal Lynx type. + */ + result = LYNXMESSAGES_URL_TYPE; - } else if (compare_type(cp, "data:", 5)) { - result = DATA_URL_TYPE; + } else if (compare_type(cp, STR_LYNXCFLAGS, LEN_LYNXCFLAGS)) { + /* + * Special Internal Lynx type. + */ + result = LYNXCOMPILE_OPTS_URL_TYPE; - } else if (compare_type(cp, STR_LYNXEXEC, LEN_LYNXEXEC)) { - /* - * Special External Lynx type to handle execution - * of commands or scripts which require a pause to - * read the screen upon completion. - */ - result = LYNXEXEC_URL_TYPE; + } else if (compare_type(cp, STR_LYNXDOWNLOAD, LEN_LYNXDOWNLOAD)) { + /* + * Special Internal Lynx type. + */ + result = LYNXDOWNLOAD_URL_TYPE; - } else if (compare_type(cp, STR_LYNXPROG, LEN_LYNXPROG)) { - /* - * Special External Lynx type to handle execution - * of commands, scripts or programs with do not - * require a pause to read screen upon completion. - */ - result = LYNXPROG_URL_TYPE; + } else if (compare_type(cp, STR_LYNXDIRED, LEN_LYNXDIRED)) { + /* + * Special Internal Lynx type. + */ + result = LYNXDIRED_URL_TYPE; - } else if (compare_type(cp, STR_LYNXCGI, LEN_LYNXCGI)) { - /* - * Special External Lynx type to handle cgi scripts. - */ - result = LYNXCGI_URL_TYPE; + } else if (compare_type(cp, STR_LYNXHIST, LEN_LYNXHIST)) { + /* + * Special Internal Lynx type. + */ + result = LYNXHIST_URL_TYPE; - } else if (compare_type(cp, STR_LYNXPRINT, LEN_LYNXPRINT)) { - /* - * Special Internal Lynx type. - */ - result = LYNXPRINT_URL_TYPE; + } else if (compare_type(cp, STR_LYNXKEYMAP, LEN_LYNXKEYMAP)) { + /* + * Special Internal Lynx type. + */ + result = LYNXKEYMAP_URL_TYPE; - } else if (compare_type(cp, STR_LYNXOPTIONS, LEN_LYNXOPTIONS)) { - /* - * Special Internal Lynx type. - */ - result = LYNXOPTIONS_URL_TYPE; + } else if (compare_type(cp, STR_LYNXIMGMAP, LEN_LYNXIMGMAP)) { + /* + * Special Internal Lynx type. + */ + /* force lower/uppercase of next part */ + (void)is_url(&cp[LEN_LYNXIMGMAP]); + result = LYNXIMGMAP_URL_TYPE; - } else if (compare_type(cp, STR_LYNXCFG, LEN_LYNXCFG)) { - /* - * Special Internal Lynx type. - */ - result = LYNXCFG_URL_TYPE; + } else if (compare_type(cp, STR_LYNXCOOKIE, LEN_LYNXCOOKIE)) { + /* + * Special Internal Lynx type. + */ + result = LYNXCOOKIE_URL_TYPE; + } + break; +#ifndef DISABLE_NEWS + /* + * NEWSfoo: schemes - + */ + case 'N': + case 'n': + if (compare_type(cp, STR_NEWS_URL, LEN_NEWS_URL)) { + result = NEWS_URL_TYPE; - } else if (compare_type(cp, STR_LYNXMESSAGES, LEN_LYNXMESSAGES)) { - /* - * Special Internal Lynx type. - */ - result = LYNXMESSAGES_URL_TYPE; + } else if (compare_type(cp, STR_NNTP_URL, LEN_NNTP_URL)) { + result = NNTP_URL_TYPE; - } else if (compare_type(cp, STR_LYNXCFLAGS, LEN_LYNXCFLAGS)) { - /* - * Special Internal Lynx type. - */ - result = LYNXCOMPILE_OPTS_URL_TYPE; + } else if (compare_type(cp, "newspost:", 9)) { + /* + * Special Lynx type to handle news posts. + */ + result = NEWSPOST_URL_TYPE; - } else if (compare_type(cp, STR_LYNXDOWNLOAD, LEN_LYNXDOWNLOAD)) { - /* - * Special Internal Lynx type. - */ - result = LYNXDOWNLOAD_URL_TYPE; + } else if (compare_type(cp, "newsreply:", 10)) { + /* + * Special Lynx type to handle news replies (followups). + */ + result = NEWSREPLY_URL_TYPE; + } + break; - } else if (compare_type(cp, STR_LYNXDIRED, LEN_LYNXDIRED)) { - /* - * Special Internal Lynx type. - */ - result = LYNXDIRED_URL_TYPE; + /* + * SNEWSfoo: schemes - + */ + case 'S': + case 's': + if (compare_type(cp, STR_SNEWS_URL, LEN_SNEWS_URL)) { + result = SNEWS_URL_TYPE; - } else if (compare_type(cp, STR_LYNXHIST, LEN_LYNXHIST)) { - /* - * Special Internal Lynx type. - */ - result = LYNXHIST_URL_TYPE; + } else if (compare_type(cp, "snewspost:", 10)) { + /* + * Special Lynx type to handle snews posts. + */ + result = NEWSPOST_URL_TYPE; - } else if (compare_type(cp, STR_LYNXKEYMAP, LEN_LYNXKEYMAP)) { - /* - * Special Internal Lynx type. - */ - result = LYNXKEYMAP_URL_TYPE; + } else if (compare_type(cp, "snewsreply:", 11)) { + /* + * Special Lynx type to handle snews replies (followups). + */ + result = NEWSREPLY_URL_TYPE; + } + break; +#endif + case 'M': + case 'm': + if (compare_type(cp, STR_MAILTO_URL, LEN_MAILTO_URL)) { + result = MAILTO_URL_TYPE; + } + break; - } else if (compare_type(cp, STR_LYNXIMGMAP, LEN_LYNXIMGMAP)) { - /* - * Special Internal Lynx type. - */ - (void)is_url(&cp[11]); /* forces lower/uppercase of next part */ - result = LYNXIMGMAP_URL_TYPE; + case 'F': + case 'f': + if (compare_type(cp, STR_FILE_URL, len = LEN_FILE_URL)) { + if (LYisLocalFile(cp)) { + result = FILE_URL_TYPE; + } else if (DoubleHtmlSep(cp + len)) { + result = FTP_URL_TYPE; + } + } +#ifndef DISABLE_FTP + else if (compare_two(cp, STR_FTP_URL, LEN_FTP_URL, limit)) { + result = FTP_URL_TYPE; + } +#endif +#ifndef DISABLE_FINGER + else if (compare_two(cp, STR_FINGER_URL, LEN_FINGER_URL, limit)) { + result = FINGER_URL_TYPE; + } +#endif + break; - } else if (compare_type(cp, STR_LYNXCOOKIE, LEN_LYNXCOOKIE)) { - /* - * Special Internal Lynx type. - */ - result = LYNXCOOKIE_URL_TYPE; + case 'B': + case 'b': +#ifndef DISABLE_BIBP + if (compare_type(cp, STR_BIBP_URL, LEN_BIBP_URL)) { + result = BIBP_URL_TYPE; + } +#endif + break; - } else if (strlen(cp) >= 3 - && strstr((cp+3), "://") == NULL) { - /* - * If it doesn't contain "://", and it's not one of the - * the above, it can't be a URL with a scheme we know, - * so check if it's an unknown scheme for which proxying - * has been set up. - FM - */ - if ((cp1 = strstr(cp, ":")) != NULL - && (cp1 - cp) > 1 /* exclude DOS-style device:/path */ - && LYisAbsPath(cp1+1)) { - result = NCFTP_URL_TYPE; - } else { - result = LYCheckForProxyURL(filename); - } + case 'D': + case 'd': + if (compare_type(cp, "data:", 5)) { + result = DATA_URL_TYPE; + } + break; - } else if (compare_type(cp, STR_HTTP_URL, LEN_HTTP_URL)) { - result = HTTP_URL_TYPE; + default: + if (limit >= 3 + && ((cp1 = strchr(cp + 3, ':')) == NULL + || !DoubleHtmlSep(cp1 + 1))) { + /* + * If it doesn't contain "://", and it's not one of the the + * above, it can't be a URL with a scheme we know, so check if + * it's an unknown scheme for which proxying has been set up. + * - FM + */ + if (cp1 != NULL + && (cp1 - cp) > 1 /* exclude DOS-style device:/path */ + && LYisAbsPath(cp1+1)) { + result = NCFTP_URL_TYPE; + } - } else if (compare_type(cp, STR_HTTPS_URL, LEN_HTTPS_URL)) { - result = HTTPS_URL_TYPE; + } else { + switch (*cp) { + case 'H': + case 'h': + if (compare_type(cp, STR_HTTP_URL, LEN_HTTP_URL)) { + result = HTTP_URL_TYPE; + + } else if (compare_type(cp, STR_HTTPS_URL, LEN_HTTPS_URL)) { + result = HTTPS_URL_TYPE; + } + break; #ifndef DISABLE_GOPHER - } else if (compare_type(cp, STR_GOPHER_URL, LEN_GOPHER_URL)) { - if (strlen(cp) >= 11 - && (cp1 = strchr(cp+11,'/')) != NULL) { - - if (TOUPPER(*(cp1+1)) == 'H' || *(cp1+1) == 'w') - /* if this is a gopher html type */ - result = HTML_GOPHER_URL_TYPE; - else if (*(cp1+1) == 'T' || *(cp1+1) == '8') - result = TELNET_GOPHER_URL_TYPE; - else if (*(cp1+1) == '7') - result = INDEX_GOPHER_URL_TYPE; - else - result = GOPHER_URL_TYPE; - } else { - result = GOPHER_URL_TYPE; - } -#endif - -#ifndef DISABLE_FTP - } else if (compare_type(cp, STR_FTP_URL, LEN_FTP_URL)) { - result = FTP_URL_TYPE; + case 'G': + case 'g': + if (compare_type(cp, STR_GOPHER_URL, LEN_GOPHER_URL)) { + if (strlen(cp) >= 11 + && (cp1 = strchr(cp+11,'/')) != NULL) { + + if (TOUPPER(*(cp1+1)) == 'H' || *(cp1+1) == 'w') + /* if this is a gopher html type */ + result = HTML_GOPHER_URL_TYPE; + else if (*(cp1+1) == 'T' || *(cp1+1) == '8') + result = TELNET_GOPHER_URL_TYPE; + else if (*(cp1+1) == '7') + result = INDEX_GOPHER_URL_TYPE; + else + result = GOPHER_URL_TYPE; + } else { + result = GOPHER_URL_TYPE; + } + } + break; #endif + case 'W': + case 'w': + if (compare_type(cp, STR_WAIS_URL, LEN_WAIS_URL)) { + result = WAIS_URL_TYPE; + } + break; - } else if (compare_type(cp, STR_WAIS_URL, LEN_WAIS_URL)) { - result = WAIS_URL_TYPE; - - } else if (compare_type(cp, STR_TELNET_URL, LEN_TELNET_URL)) { - result = TELNET_URL_TYPE; - - } else if (compare_type(cp, STR_TN3270_URL, LEN_TN3270_URL)) { - result = TN3270_URL_TYPE; - - } else if (compare_type(cp, STR_RLOGIN_URL, LEN_RLOGIN_URL)) { - result = RLOGIN_URL_TYPE; + case 'T': + case 't': + if (compare_type(cp, STR_TELNET_URL, LEN_TELNET_URL)) { + result = TELNET_URL_TYPE; - } else if (compare_type(cp, STR_CSO_URL, LEN_CSO_URL)) { - result = CSO_URL_TYPE; + } else if (compare_type(cp, STR_TN3270_URL, LEN_TN3270_URL)) { + result = TN3270_URL_TYPE; + } + break; -#ifndef DISABLE_FINGER - } else if (compare_type(cp, STR_FINGER_URL, LEN_FINGER_URL)) { - result = FINGER_URL_TYPE; -#endif + case 'R': + case 'r': + if (compare_type(cp, STR_RLOGIN_URL, LEN_RLOGIN_URL)) { + result = RLOGIN_URL_TYPE; + } + break; - } else if (compare_type(cp, "afs:", 4)) { - result = AFS_URL_TYPE; + case 'C': + case 'c': + if (compare_type(cp, STR_CSO_URL, LEN_CSO_URL)) { + result = CSO_URL_TYPE; + } + break; - } else if (compare_type(cp, "prospero:", 9)) { - result = PROSPERO_URL_TYPE; + case 'A': + case 'a': + if (compare_type(cp, "afs:", 4)) { + result = AFS_URL_TYPE; + } + break; - } else { + case 'P': + case 'p': + if (compare_type(cp, "prospero:", 9)) { + result = PROSPERO_URL_TYPE; + } + break; + } + } + } /* - * Check if it's an unknown scheme for which - * proxying has been set up. - FM + * Check if it is an unknown scheme for which proxying has been set up. */ - result = LYCheckForProxyURL(filename); + if (result == NOT_A_URL_TYPE) + result = LYCheckForProxyURL(filename); } return result; } @@ -3680,7 +3760,8 @@ PUBLIC void LYEnsureAbsoluteURL ARGS3( NonNull(name), (name ? " " : ""), *href)); LYConvertToURL(href, fixit); } - if (non_empty(temp = HTParse(*href, "", PARSE_ALL))) + temp = HTParse(*href, "", PARSE_ALL); + if (non_empty(temp)) StrAllocCopy(*href, temp); FREE(temp); } @@ -6585,6 +6666,28 @@ PUBLIC void LYLocalFileToURL ARGS2( StrAllocCat(*target, leaf); } +/* + * Open a temporary file for internal-pages, optionally reusing an existing + * filename. + */ +PUBLIC FILE *InternalPageFP ARGS2( + char *, filename, + int, reuse_flag) +{ + FILE *fp; + + if (LYReuseTempfiles && reuse_flag) { + fp = LYOpenTempRewrite(filename, HTML_SUFFIX, BIN_W); + } else { + LYRemoveTemp(filename); + fp = LYOpenTemp(filename, HTML_SUFFIX, BIN_W); + } + if (fp == NULL) { + HTAlert(CANNOT_OPEN_TEMP); + } + return fp; +} + PUBLIC void BeginInternalPage ARGS3( FILE *, fp0, char*, Title, diff --git a/src/LYUtils.h b/src/LYUtils.h index e1be5c52..9e1ee115 100644 --- a/src/LYUtils.h +++ b/src/LYUtils.h @@ -119,7 +119,9 @@ extern BOOLEAN LYisLocalHost PARAMS((char *filename)); extern BOOLEAN LYisRootPath PARAMS((char *path)); extern BOOLEAN inlocaldomain NOPARAMS; extern CONST char *Home_Dir NOPARAMS; -extern CONST char *index_to_restriction PARAMS(( int inx)); +extern CONST char *index_to_restriction PARAMS((int inx)); +extern CONST char *wwwName PARAMS((CONST char *pathname)); +extern FILE *InternalPageFP PARAMS((char * filename, int reuse_flag)); extern FILE *LYAppendToTxtFile PARAMS((char * name)); extern FILE *LYNewBinFile PARAMS((char * name)); extern FILE *LYNewTxtFile PARAMS((char * name)); @@ -136,7 +138,6 @@ extern char *LYSysShell NOPARAMS; extern char *LYgetXDisplay NOPARAMS; extern char *strip_trailing_slash PARAMS((char * my_dirname)); extern char *trimPoundSelector PARAMS((char * address)); -extern CONST char *wwwName PARAMS((CONST char *pathname)); extern int HTCheckForInterrupt NOPARAMS; extern int LYCheckForProxyURL PARAMS((char *filename)); extern int LYConsoleInputFD PARAMS((BOOLEAN need_selectable)); |