diff options
Diffstat (limited to 'src')
42 files changed, 1452 insertions, 1739 deletions
diff --git a/src/GridText.c b/src/GridText.c index ad5abbfe..e61ddbd9 100644 --- a/src/GridText.c +++ b/src/GridText.c @@ -33,6 +33,7 @@ #include <LYPrint.h> #include <LYPrettySrc.h> #include <TRSTable.h> +#include <LYHistory.h> #ifdef EXP_CHARTRANS_AUTOSWITCH #include <UCAuto.h> #endif /* EXP_CHARTRANS_AUTOSWITCH */ @@ -60,7 +61,6 @@ unsigned int cached_styles[CACHEH][CACHEW]; #include <LYJustify.h> - #ifdef USE_COLOR_STYLE_UNUSED void LynxClearScreenCache NOARGS { @@ -128,8 +128,8 @@ PUBLIC char * unchecked_box = "[ ]"; PUBLIC char * checked_radio = "(*)"; PUBLIC char * unchecked_radio = "( )"; -PUBLIC BOOLEAN underline_on = OFF; -PUBLIC BOOLEAN bold_on = OFF; +PRIVATE BOOLEAN underline_on = OFF; +PRIVATE BOOLEAN bold_on = OFF; #ifdef SOURCE_CACHE PUBLIC int LYCacheSource = SOURCE_CACHE_NONE; @@ -160,9 +160,6 @@ typedef struct _line { struct _line *prev; unsigned offset; /* Implicit initial spaces */ unsigned size; /* Number of characters */ - BOOL split_after; /* Can we split after? */ - BOOL bullet; /* Do we bullet? */ - BOOL expansion_line; /* TEXTAREA edit new line flag */ #if defined(USE_COLOR_STYLE) HTStyleChange* styles; int numstyles; @@ -294,9 +291,8 @@ void POOL_FREE( pool_type , P* ptr) typedef struct _TextAnchor { struct _TextAnchor * next; int number; /* For user interface */ - int start; /* Characters */ - int line_pos; /* Position in text */ - int extent; /* Characters */ + int line_pos; /* Bytes/chars - extent too */ + int extent; /* (see HText_trimHightext) */ int line_num; /* Place in document */ char * hightext; /* The link text */ char * hightext2; /* A second line*/ @@ -336,11 +332,10 @@ struct _HText { BOOLEAN old_dtd; int keypad_mode; int disp_lines; /* Screen size */ - int disp_cols; + int disp_cols; /* Used for reports only */ #endif HTLine * last_line; int Lines; /* Number of them */ - int chars; /* Number of them */ TextAnchor * first_anchor; /* Singly linked list */ TextAnchor * last_anchor; TextAnchor * last_anchor_before_stbl; @@ -406,7 +401,6 @@ struct _HText { PRIVATE void HText_AddHiddenLink PARAMS((HText *text, TextAnchor *textanchor)); - #ifdef EXP_JUSTIFY_ELTS PUBLIC BOOL can_justify_here; PUBLIC BOOL can_justify_here_saved; @@ -436,10 +430,6 @@ static int ht_num_runs;/*the number of runs filled*/ static ht_run_info ht_runs[MAX_LINE]; static BOOL this_line_was_split; static TextAnchor* last_anchor_of_previous_line; -static int justified_text_map[MAX_LINE]; /* this is a map - for each index i - it tells to which position j=justified_text_map[i] in justified text - i-th character is mapped - it's used for anchor positions fixup and for - color style's positions adjustment. */ static BOOL have_raw_nbsps = FALSE; PUBLIC void ht_justify_cleanup NOARGS @@ -472,6 +462,8 @@ 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 */ @@ -588,7 +580,7 @@ PRIVATE void * LY_check_calloc ARGS2( if (t == HTMainText) t = NULL; /* shouldn't happen */ { - CTRACE((tfp, "\r *** Emergency freeing document %d/%d for '%s'%s!\n", + CTRACE((tfp, "\nBUG *** Emergency freeing document %d/%d for '%s'%s!\n", i + 1, n, ((t && t->node_anchor && t->node_anchor->address) ? @@ -754,7 +746,7 @@ PUBLIC HText * HText_new ARGS1( stylechanges_buffers_free = 0; line->styles = stylechanges_buffers[0]; #endif - self->Lines = self->chars = 0; + self->Lines = 0; self->first_anchor = self->last_anchor = NULL; self->style = &default_style; self->top_of_screen = 0; @@ -1430,7 +1422,7 @@ PRIVATE void display_title ARGS1( char percent[20]; char *cp = NULL; unsigned char *tmp = NULL; - int i = 0, j = 0; + int i = 0, j = 0, toolbar = 0; int limit; /* @@ -1530,9 +1522,26 @@ PRIVATE void display_title ARGS1( #if defined(SH_EX) && defined(KANJI_CODE_OVERRIDE) LYaddstr(str_kcode(last_kcode)); #endif - if (text->top_of_screen > 0 && HText_hasToolbar(text)) { + if (HText_hasToolbar(text)) { LYaddch('#'); + toolbar = 1; } +#ifdef USE_COLOR_STYLE + if (s_forw_backw != NOSTYLE && (nhist || nhist_extra > 1)) { + int c = nhist ? ACS_LARROW : ' '; + + /* turn the FORWBACKW.ARROW style on */ + LynxChangeStyle(s_forw_backw, STACK_ON); + if (nhist) { + LYaddch(c); LYaddch(c); LYaddch(c); + } else + LYmove(0, 3 + toolbar); + if (nhist_extra > 1) { + LYaddch(ACS_RARROW); LYaddch(ACS_RARROW); LYaddch(ACS_RARROW); + } + LynxChangeStyle(s_forw_backw, STACK_OFF); + } +#endif /* USE_COLOR_STYLE */ i = (limit - 1) - strlen(percent) - strlen(title); if (i >= CHAR_WIDTH) { LYmove(0, i); @@ -1844,7 +1853,7 @@ PRIVATE void display_page ARGS3( #ifdef DISP_PARTIAL if (display_partial && text->stbl) { - stop_before_for_anchors = Stbl_getStartLine(text->stbl); + stop_before_for_anchors = Stbl_getStartLineDeep(text->stbl); if (stop_before_for_anchors > line_number+(display_lines)) stop_before_for_anchors = line_number+(display_lines); } else @@ -2337,6 +2346,232 @@ PUBLIC void HText_beginAppend ARGS1( #define CTRACE_SPLITLINE(p) /*nothing*/ #endif +PRIVATE int set_style_by_embedded_chars ARGS4( + char *, s, + char *, e, + unsigned char, start_c, + unsigned char, end_c) +{ + int ret = NO; + + while (--e >= s) { + if (*e == end_c) + break; + if (*e == start_c) { + ret = YES; + break; + } + } + return ret; +} + +PRIVATE void move_anchors_in_region ARGS7( + HTLine *, line, + int, line_number, + TextAnchor **, prev_anchor, + int *, prev_head_processed, + int, sbyte, + int, ebyte, + int, shift) /* Likewise */ +{ + /* + * Update anchor positions for anchors that start on this line. + * Note: we rely on a->line_pos counting bytes, not + * characters. That's one reason why HText_trimHightext + * has to be prevented from acting on these anchors in + * partial display mode before we get a chance to + * deal with them here. + */ + TextAnchor *a; + int head_processed = *prev_head_processed; + + /* We need to know whether (*prev_anchor)->line_pos is "in new + coordinates" or in old ones. If prev_anchor' head was touched + on the previous iteraction, we set head_processed. The tail + may need to be treated now. */ + for (a = *prev_anchor; + a && a->line_num <= line_number; + a = a->next, head_processed = 0) { + /* extent==0 needs to be special-cased; happens if no text for + the anchor was processed yet. */ + /* Subtract one so that the space is not inserted at the end + of the anchor... */ + int last = a->line_pos + (a->extent ? a->extent - 1 : 0); + + /* Include the anchors started on the previous line */ + if (a->line_num < line_number - 1) + continue; + if (a->line_num == line_number - 1) + last -= line->prev->size + 1; /* Fake "\n" "between" lines counted too */ + if (last < sbyte) /* Completely before the start */ + continue; + + if ( !head_processed /* a->line_pos is not edited yet */ + && a->line_num == line_number + && a->line_pos >= ebyte) /* Completely after the end */ + break; + /* Now we know that the anchor context intersects the chunk */ + + /* Fix the start */ + if ( !head_processed && a->line_num == line_number + && a->line_pos >= sbyte ) { + a->line_pos += shift; + a->extent -= shift; + head_processed = 1; + } + /* Fix the end */ + if ( last < ebyte ) + a->extent += shift; + else + break; /* Keep this `a' for the next step */ + } + *prev_anchor = a; + *prev_head_processed = head_processed; +} + +/* + * Given a line and two int arrays of old/now position, this function + * creates a new line where spaces have been inserted/removed + * 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. + * Returns a newly allocated HTLine* if changes were made + * (caller has to free the old one). + * Returns NULL if no changes needed. (Remove-spaces code may be buggy...) + * - kw + */ +PRIVATE HTLine * insert_blanks_in_line ARGS7( + HTLine *, line, + int, line_number, + HText *, text, + TextAnchor *, prev_anchor, + int, ninserts, + int *, oldpos, /* Measured in cells */ + int *, newpos) /* Likewise */ +{ + int ioldc = 0; /* count visible characters */ + int ip; /* count insertion pairs */ +#if defined(USE_COLOR_STYLE) + int istyle = 0; +#endif + int added_chars = 0; + int shift = 0; + int head_processed; + HTLine * mod_line; + char *newdata; + char *s = line->data; + char *copied = line->data, *t; + + if (!(line && line->size && ninserts)) + return NULL; + for (ip = 0; ip < ninserts; ip++) + if (newpos[ip] > oldpos[ip] && + (newpos[ip] - oldpos[ip]) > added_chars) + 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 (!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)); + t = newdata = mod_line->data; + ip = 0; + while (ip <= ninserts) { + /* line->size is in bytes, so it may be larger than needed... */ + int curlim = (ip < ninserts + ? oldpos[ip] + /* Include'em all! */ + : (line->size <= MAX_LINE ? MAX_LINE+1 : line->size+1)); + char *pre = s; + + /* Fast forward to char==curlim or EOL. Stop *before* the + style-change chars. */ + while (*s) { + if ( text && text->T.output_utf8 + && UCH(*s) >= 0x80 && UCH(*s) < 0xC0 ) + pre = s + 1; + else if (!IsSpecialAttrChar(*s)) { /* At a "displayed" char */ + if (ioldc >= curlim) + break; + ioldc++; + pre = s + 1; + } + s++; + } + + /* 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, + &head_processed, + copied - line->data, pre - line->data, + shift); +#if defined(USE_COLOR_STYLE) /* Move styles too */ +#define NStyle mod_line->styles[istyle] + for (; istyle < line->numstyles && NStyle.horizpos < curlim ; istyle++) + /* Should not we include OFF-styles at curlim? */ + NStyle.horizpos += shift; +#endif + while (copied < pre) /* Copy verbatim to byte == pre */ + *t++ = *copied++; + if (ip < ninserts) { /* Insert spaces */ + int delta = newpos[ip] - oldpos[ip] - shift; + + if (delta < 0) { /* Not used yet? */ + while (delta++ < 0 && t > newdata && t[-1] == ' ') + t--, shift--; + } else + shift = newpos[ip] - oldpos[ip]; + while (delta-- > 0) + *t++ = ' '; + } + ip++; + } + /* 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; + *t = '\0'; + mod_line->size = t - newdata; + return mod_line; +} + +#if defined(USE_COLOR_STYLE) +PRIVATE HTStyleChange * skip_matched_and_correct_offsets ARGS3( + HTStyleChange *, end, + HTStyleChange *, start, + unsigned, split_pos) +{ /* Found an OFF change not part of an adjacent matched pair. + * Walk backward looking for the corresponding ON change. + * Move everything after split_pos to be at split_pos. + * This can only work correctly if all changes are correctly + * nested! If this fails, assume it is safer to leave whatever + * comes before the OFF on the previous line alone. */ + int level = 0; + HTStyleChange *tmp = end; + + for (; tmp >= start; tmp--) { + if (tmp->style == end->style) { + if (tmp->direction == STACK_OFF) + level--; + else if (tmp->direction == STACK_ON) { + if (++level == 0) + return tmp; + } else + return 0; + } + if (tmp->horizpos > split_pos) + tmp->horizpos = split_pos; + } + return 0; +} +#endif /* USE_COLOR_STYLE */ + PRIVATE void split_line ARGS2( HText *, text, unsigned, split) @@ -2344,9 +2579,6 @@ PRIVATE void split_line ARGS2( HTStyle * style = text->style; HTLine * temp; int spare; -#if defined(USE_COLOR_STYLE) - int inew; -#endif int indent = text->in_line_1 ? text->style->indent1st : text->style->leftIndent; short alignment; @@ -2355,22 +2587,20 @@ PRIVATE void split_line ARGS2( int HeadTrim = 0; int SpecialAttrChars = 0; int TailTrim = 0; - int s; - - /* - * Make new line. - */ + 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); + + /* + * Make new line. + */ if (line == NULL) outofmem(__FILE__, "split_line_1"); -#if defined(USE_COLOR_STYLE) - line->styles = stylechanges_buffers[stylechanges_buffers_free = (stylechanges_buffers_free + 1) &1]; -#endif 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 = ' '; @@ -2381,6 +2611,7 @@ PRIVATE void split_line ARGS2( #endif cp = previous->data; + /* Float LY_SOFT_NEWLINE to the start */ if (cp[0] == LY_BOLD_START_CHAR || cp[0] == LY_UNDERLINE_START_CHAR) { switch (cp[1]) { @@ -2423,36 +2654,42 @@ PRIVATE void split_line ARGS2( text->permissible_split = 0; /* 12/13/93 */ line->data[0] = '\0'; - /* - * If we are not splitting and need an underline char, add it now. - FM - */ - if ((split < 1) && - !(dump_output_immediately && use_underscore) && underline_on) { + alignment = style->alignment; + + if (split > 0) { /* Restore flags to the value at the splitting point */ + if (!(dump_output_immediately && use_underscore)) + t_underline = set_style_by_embedded_chars( + previous->data, previous->data + split, + LY_UNDERLINE_START_CHAR, LY_UNDERLINE_END_CHAR); + + t_bold = set_style_by_embedded_chars( + previous->data, previous->data + split, + LY_BOLD_START_CHAR, LY_BOLD_END_CHAR); + + } + + if (!(dump_output_immediately && use_underscore) && t_underline) { line->data[line->size++] = LY_UNDERLINE_START_CHAR; line->data[line->size] = '\0'; ctrl_chars_on_this_line++; + SpecialAttrChars++; } - /* - * If we are not splitting and need a bold char, add it now. - FM - */ - if ((split < 1) && bold_on) { + if (t_bold) { line->data[line->size++] = LY_BOLD_START_CHAR; line->data[line->size] = '\0'; ctrl_chars_on_this_line++; + SpecialAttrChars++; } - alignment = style->alignment; /* * Split at required point */ if (split > 0) { /* Delete space at "split" splitting line */ - char *p, *prevdata = previous->data, *linedata = line->data; + char *prevdata = previous->data, *linedata = line->data; unsigned plen; int i; - /* - * Split the line. - FM - */ + /* Split the line. - FM */ prevdata[previous->size] = '\0'; previous->size = split; @@ -2462,160 +2699,76 @@ PRIVATE void split_line ARGS2( */ p = prevdata + split; while (( + (*p == ' ' #ifdef EXP_JUSTIFY_ELTS /* if justification is allowed for prev line, then raw * HT_NON_BREAK_SPACE are still present in data[] (they'll be * substituted at the end of this function with ' ') - VH */ - (*p == ' ' || *p == HT_NON_BREAK_SPACE ) && -#else - (*p == ' ') && -#endif - - (HeadTrim || text->first_anchor || - underline_on || bold_on || - alignment != HT_LEFT || - style->wordWrap || style->freeFormat || - style->spaceBefore || style->spaceAfter)) || + || *p == HT_NON_BREAK_SPACE +#endif + ) + && (HeadTrim || text->first_anchor || + underline_on || bold_on || + alignment != HT_LEFT || + style->wordWrap || style->freeFormat || + style->spaceBefore || style->spaceAfter)) || *p == LY_SOFT_HYPHEN) { p++; HeadTrim++; } - plen = strlen(p); - /* - * Add underline char if needed. - FM - */ - if (!(dump_output_immediately && use_underscore)) { - /* - * Make sure our global flag is correct. - FM - */ - underline_on = NO; - for (i = (split-1); i >= 0; i--) { - if (prevdata[i] == LY_UNDERLINE_END_CHAR) { - break; - } - if (prevdata[i] == LY_UNDERLINE_START_CHAR) { - underline_on = YES; - break; - } - } - /* - * Act on the global flag if set above. - FM - */ - if (underline_on && *p != LY_UNDERLINE_END_CHAR) { - linedata[line->size++] = LY_UNDERLINE_START_CHAR; - linedata[line->size] = '\0'; - ctrl_chars_on_this_line++; - SpecialAttrChars++; - } - if (plen) { - for (i = (plen - 1); i >= 0; i--) { - if (p[i] == LY_UNDERLINE_START_CHAR) { - underline_on = YES; - break; - } - if (p[i] == LY_UNDERLINE_END_CHAR) { - underline_on = NO; - break; - } - } - for (i = (plen - 1); i >= 0; i--) { - if (p[i] == LY_UNDERLINE_START_CHAR || - p[i] == LY_UNDERLINE_END_CHAR) { - ctrl_chars_on_this_line++; - } - } - } - } - - /* - * Add bold char if needed, first making - * sure that our global flag is correct. - FM - */ - bold_on = NO; - for (i = (split - 1); i >= 0; i--) { - if (prevdata[i] == LY_BOLD_END_CHAR) { - break; - } - if (prevdata[i] == LY_BOLD_START_CHAR) { - bold_on = YES; - break; - } - } - /* - * Act on the global flag if set above. - FM - */ - if (bold_on && *p != LY_BOLD_END_CHAR) { - linedata[line->size++] = LY_BOLD_START_CHAR; - linedata[line->size] = '\0'; - ctrl_chars_on_this_line++; - SpecialAttrChars++; - } - if (plen) { - for (i = (plen - 1); i >= 0; i--) { - if (p[i] == LY_BOLD_START_CHAR) { - bold_on = YES; - break; - } - if (p[i] == LY_BOLD_END_CHAR) { - bold_on = NO; - break; - } - } + plen = strlen(p); + if (plen) { /* Count funny characters */ for (i = (plen - 1); i >= 0; i--) { - if (p[i] == LY_BOLD_START_CHAR || + if (p[i] == LY_UNDERLINE_START_CHAR || + p[i] == LY_UNDERLINE_END_CHAR || + p[i] == LY_BOLD_START_CHAR || p[i] == LY_BOLD_END_CHAR || - p[i] == LY_SOFT_HYPHEN) { + p[i] == LY_SOFT_HYPHEN) ctrl_chars_on_this_line++; - } else if (IS_UTF_EXTRA(p[i])) { + else if (IS_UTF_EXTRA(p[i])) utfxtra_on_this_line++; - } - if (p[i] == LY_SOFT_HYPHEN && (int)text->permissible_split < i) { + if (p[i] == LY_SOFT_HYPHEN && (int)text->permissible_split < i) text->permissible_split = i + 1; - } } ctrl_chars_on_this_line += utfxtra_on_this_line; - } - /* - * Add the data to the new line. - FM - */ - strcat(linedata, p); - line->size += plen; + /* Add the data to the new line. - FM */ + strcat(linedata, p); + line->size += plen; + } } /* * Economize on space. */ - while ((previous->size > 0) && + p = previous->data + previous->size - 1; + while (p >= previous->data + && (*p == ' ' #ifdef EXP_JUSTIFY_ELTS /* if justification is allowed for prev line, then raw * HT_NON_BREAK_SPACE are still present in data[] (they'll be * substituted at the end of this function with ' ') - VH */ - ((previous->data[previous->size-1] == ' ') || - (previous->data[previous->size-1] == HT_NON_BREAK_SPACE)) && -#else - (previous->data[previous->size-1] == ' ') && + || *p == HT_NON_BREAK_SPACE #endif + ) #ifdef USE_PRETTYSRC - !psrc_view && /*don't strip trailing whites - since next line can + && !psrc_view /*don't strip trailing whites - since next line can start with LY_SOFT_NEWLINE - so we don't lose spaces when 'p'rinting this text to file -VH */ #endif - (ctrl_chars_on_this_line || HeadTrim || text->first_anchor || - underline_on || bold_on || - alignment != HT_LEFT || - style->wordWrap || style->freeFormat || - style->spaceBefore || style->spaceAfter)) { - /* - * Strip trailers. - */ - previous->data[previous->size-1] = '\0'; - previous->size--; - TailTrim++; - } + && (ctrl_chars_on_this_line || HeadTrim || text->first_anchor || + underline_on || bold_on || + alignment != HT_LEFT || + style->wordWrap || style->freeFormat || + style->spaceBefore || style->spaceAfter)) + p--; /* Strip trailers. */ + TailTrim = previous->data + previous->size - 1 - p; /* Strip trailers. */ + previous->size -= TailTrim; + p[1] = '\0'; + /* * s is the effective split position, given by either a non-zero * value of split or by the size of the previous line before @@ -2626,6 +2779,9 @@ PRIVATE void split_line ARGS2( } else { s = split; } + s_post = s + HeadTrim; + s_pre = s - TailTrim; + #ifdef DEBUG_SPLITLINE #ifdef DEBUG_APPCH if (s != (int)split) @@ -2634,150 +2790,98 @@ PRIVATE void split_line ARGS2( #endif #if defined(USE_COLOR_STYLE) -#define LastStyle (previous->numstyles-1) + line->styles = stylechanges_buffers[stylechanges_buffers_free = (stylechanges_buffers_free + 1) &1]; line->numstyles = 0; - inew = MAX_STYLES_ON_LINE - 1; - /* - * Color style changes after the split position + possible trimmed - * head characters are transferred to the new line. Ditto for changes - * within the trimming region, but we stop when we reach an OFF change. - * The second while loop below may then handle remaining changes. - kw - */ - while (previous->numstyles && inew >= 0) { - if (previous->styles[LastStyle].horizpos > s + HeadTrim) { - line->styles[inew].horizpos = - previous->styles[LastStyle].horizpos - - (s + HeadTrim) + SpecialAttrChars; - line->styles[inew].direction = previous->styles[LastStyle].direction; - line->styles[inew].style = previous->styles[LastStyle].style; - inew --; - line->numstyles ++; - previous->numstyles --; - } else if (previous->styles[LastStyle].horizpos > s - TailTrim && - (previous->styles[LastStyle].direction == STACK_ON || - previous->styles[LastStyle].direction == ABS_ON)) { - line->styles[inew].horizpos = - (previous->styles[LastStyle].horizpos < s) ? - 0 : SpecialAttrChars; - line->styles[inew].direction = previous->styles[LastStyle].direction; - line->styles[inew].style = previous->styles[LastStyle].style; - inew --; - line->numstyles ++; - previous->numstyles --; - } else - break; - } - spare = previous->numstyles; - while (previous->numstyles && inew >= 0) { - if (previous->numstyles >= 2 && - previous->styles[LastStyle].style - == previous->styles[previous->numstyles-2].style && - previous->styles[LastStyle].horizpos - == previous->styles[previous->numstyles-2].horizpos && - ((previous->styles[LastStyle].direction == STACK_OFF && - previous->styles[previous->numstyles-2].direction == STACK_ON) || - (previous->styles[LastStyle].direction == ABS_OFF && - previous->styles[previous->numstyles-2].direction == ABS_ON) || - (previous->styles[LastStyle].direction == ABS_ON && - previous->styles[previous->numstyles-2].direction == ABS_OFF) - )) { - /* - * Discard pairs of ON/OFF for the same color style, but only - * if they appear at the same position. - kw - */ - previous->numstyles -= 2; - if (spare > previous->numstyles) - spare = previous->numstyles; - } else if (spare > 0 && previous->styles[spare - 1].direction && - previous->numstyles < MAX_STYLES_ON_LINE) { - /* - * The index variable spare walks backwards through the - * list of color style changes on the previous line, trying - * to find an ON change which isn't followed by a - * corresponding OFF. When it finds one, the missing OFF - * change is appended to the end, and an ON change is added - * at the beginning of the current line. The OFF change - * appended to the previous line may get removed again in - * the next iteration. - kw - */ - line->styles[inew].horizpos = 0; - line->styles[inew].direction = ON; - line->styles[inew].style = previous->styles[spare - 1].style; - inew --; - line->numstyles ++; - previous->styles[previous->numstyles].style = line->styles[inew + 1].style; - - previous->styles[previous->numstyles].direction = ABS_OFF; - previous->styles[previous->numstyles].horizpos = previous->size; - previous->numstyles++; - spare --; - } else if (spare >= 2 && - previous->styles[spare - 1].style == previous->styles[spare - 2].style && - ((previous->styles[spare - 1].direction == STACK_OFF && - previous->styles[spare - 2].direction == STACK_ON) || - (previous->styles[spare - 1].direction == ABS_OFF && - previous->styles[spare - 2].direction == ABS_ON) || - (previous->styles[spare - 1].direction == STACK_ON && - previous->styles[spare - 2].direction == STACK_OFF) || - (previous->styles[spare - 1].direction == ABS_ON && - previous->styles[spare - 2].direction == ABS_OFF) - )) { - /* - * Skip pairs of adjacent ON/OFF or OFF/ON changes. - */ - spare -= 2; - } else if (spare && !previous->styles[spare - 1].direction) { - /* - * Found an OFF change not part of an adjacent matched pair. - * Walk backward looking for the corresponding ON change. - * If we find it, skip the ON/OFF and everything in between. - * This can only work correctly if all changes are correctly - * nested! If this fails, assume it is safer to leave whatever - * comes before the OFF on the previous line alone. Setting - * spare to 0 ensures that it won't be used in a following - * iteration. - kw + { + HTStyleChange *from = previous->styles + previous->numstyles - 1; + HTStyleChange *to = line->styles + MAX_STYLES_ON_LINE - 1; + HTStyleChange *scan, *at_end; + + /* Color style changes after the split position + * are transferred to the new line. Ditto for changes + * in the trimming region, but we stop when we reach an OFF change. + * The second loop below may then handle remaining changes. - kw */ + while (from >= previous->styles && to >= line->styles) { + *to = *from; + if (to->horizpos > s_post) + to->horizpos += - s_post + SpecialAttrChars; + else if (to->horizpos > s_pre && + (to->direction == STACK_ON || + to->direction == ABS_ON)) + to->horizpos = (to->horizpos < s) ? 0 : SpecialAttrChars; + else + break; + to--; + from--; + } + /* FROM may be invalid, otherwise it is either an ON change at or + before s_pre, or is an OFF change at or before s_post. */ + + scan = from; + at_end = from; + /* Now on the previous line we have a correctly nested but + possibly non-terminated sequence of style changes. + Terminate it, and duplicate unterminated changes at the + beginning of the new line. */ + while (scan >= previous->styles && at_end >= previous->styles) { + /* The algorithm: scan back though the styles on the previous line. + a) If OFF, skip the matched group. + Report a bug on failure. + b) If ON, (try to) cancel the corresponding ON at at_end, + and the corresponding OFF at to; + If not, put the corresponding OFF at at_end, and copy to to; */ - int level=-1; - int itmp; - for (itmp = spare-1; itmp > 0; itmp--) { - if (previous->styles[itmp - 1].style - == previous->styles[spare - 1].style) { - if (previous->styles[itmp - 1].direction == STACK_OFF) { - level--; - } else if (previous->styles[itmp - 1].direction == STACK_ON) { - if (++level == 0) - break; - } else - break; + if (scan->direction == STACK_OFF) { + scan = skip_matched_and_correct_offsets(scan, previous->styles, + s_pre); + if (!scan) { + CTRACE((tfp, "BUG: styles improperly nested.\n")); + break; + } + } else if (scan->direction == STACK_ON) { + if ( at_end->direction == STACK_ON + && at_end->style == scan->style + && at_end->horizpos >= s_pre ) + at_end--; + else if (at_end >= previous->styles + MAX_STYLES_ON_LINE - 1) { + CTRACE((tfp, "BUG: style overflow before split_line.\n")); + break; + } else { + at_end++; + at_end->direction = STACK_OFF; + at_end->style = scan->style; + at_end->horizpos = s_pre; + } + if ( to < line->styles + MAX_STYLES_ON_LINE - 1 + && to[1].direction == STACK_OFF + && to[1].horizpos <= SpecialAttrChars + && to[1].style == scan->style ) + to++; + else if (to >= line->styles) { + *to = *scan; + to->horizpos = SpecialAttrChars; + to--; + } else { + CTRACE((tfp, "BUG: style overflow after split_line.\n")); + break; } } - if (level == 0) - spare = itmp - 1; - else - spare = 0; - } else { - /* - * Nothing applied, so we are done with the loop. - kw - */ - break; + if (scan->horizpos > s_pre) + scan->horizpos = s_pre; + scan--; } - } - if (previous->numstyles > 0 && previous->styles[LastStyle].direction) { + line->numstyles = line->styles + MAX_STYLES_ON_LINE - 1 - to; + if (line->numstyles > 0 && line->numstyles < MAX_STYLES_ON_LINE) { + int n; - CTRACE((tfp, "%s\n%s%s\n", - "........... Too many character styles on line:", - "........... ", previous->data)); - } - if (line->numstyles > 0 && line->numstyles < MAX_STYLES_ON_LINE) { - int n; - inew ++; - for (n = 0; n < line->numstyles; n++) - line->styles[n] = line->styles[n + inew]; - } else if (line->numstyles == 0) { - line->styles[0].horizpos = ~0; + for (n = 0; n < line->numstyles; n++) + line->styles[n] = to[n + 1]; + } else if (line->numstyles == 0) + line->styles[0].horizpos = ~0; /* ?!!! */ + previous->numstyles = at_end - previous->styles + 1; + if (previous->numstyles == 0) + previous->styles[0].horizpos = ~0; /* ?!!! */ } - if (previous->numstyles == 0) - previous->styles[0].horizpos = ~0; #endif /*USE_COLOR_STYLE*/ temp = (HTLine *)LY_CALLOC(1, LINE_SIZE(previous->size)); @@ -2907,7 +3011,6 @@ PRIVATE void split_line ARGS2( break; } /* switch */ - text->chars = text->chars + previous->size + 1; /* 1 for the line */ text->in_line_1 = NO; /* unless caller sets it otherwise */ /* @@ -2915,126 +3018,73 @@ PRIVATE void split_line ARGS2( * structure values for the new line. - FM */ - if (split > 0 || s > 0) { /* if not completely empty */ + if (s > 0) { /* if not completely empty */ TextAnchor * prev_a = NULL; + int moved = 0; + + /* In the algorithm below we move or not move anchors between + lines using some heuristic criteria. However, it is + desirable not to have two consequent anchors on different + lines *in a wrong order*! (How can this happen?) + So when the "reasonable choice" is not unique, we use the + MOVED flag to choose one. + */ + /* Our operations can make a non-empty all-whitespace link + empty. So what? */ for (a = text->first_anchor; a; prev_a = a, a = a->next) { if (a->line_num == CurLine) { - int old_e = a->extent; - int a0 = a->line_pos, a1 = a->line_pos + a->extent; - int S, d, new_pos, new_ext; - if (a->link_type == INPUT_ANCHOR) { - if (a->line_pos >= s) { - a->start += (1 + SpecialAttrChars - HeadTrim - TailTrim); - a->line_pos -= (s - SpecialAttrChars + HeadTrim); - a->line_num = text->Lines; + int len = a->extent, n = a->number, start = a->line_pos; + int end = start + len; + + /* Which anchors do we leave on the previous line? + a) empty finished (We need a cut-off value. + "Just because": those before s; + this is the only case when we use s, not s_pre/s_post); + b) Those which start before s_pre; + */ + if (start < s_pre) { + if (end <= s_pre) + continue; /* No problem */ + + CTRACE_SPLITLINE((tfp, "anchor %d: no relocation", n)); + if (end > s_post) { + CTRACE_SPLITLINE((tfp, " of the start.\n")); + a->extent += -(TailTrim + HeadTrim) - SpecialAttrChars; + } else { + CTRACE_SPLITLINE((tfp, ", cut the end.\n")); + a->extent = s_pre - start; } continue; + } else if (start < s && !len + && (!n || (a->show_anchor && !moved))) { + CTRACE_SPLITLINE((tfp, "anchor %d: no relocation, empty-finished", + n)); + a->line_pos = s_pre; /* Leave at the end of line */ + continue; } - if (a0 < s - TailTrim && a1 <= s - TailTrim) { - continue; /* unaffected, leave it where it is. */ - } - S = s + a->start - a->line_pos; - d = S - s; /* == a->start - a->line_pos */ - new_ext = old_e = a->extent; - - if (!old_e && - (!a->number || a->show_anchor) && - a0 <= s + HeadTrim) { - CTRACE_SPLITLINE((tfp, "anchor %d case %d: ", a->number,1)); - /* - * It is meant to be empty, and/or endAnchor - * has seen it and recognized it as empty. - */ - new_pos = (a0 <= s) ? s - TailTrim : - s - TailTrim + 1; - if (prev_a && new_pos + d < prev_a->start) { - if (prev_a->start <= S - TailTrim + 1 + SpecialAttrChars) - new_pos = prev_a->start - d; - else - new_pos = s - TailTrim + 1 + SpecialAttrChars; - } - } else if (old_e && - a0 >= s - TailTrim && a0 <= s + HeadTrim && - a1 <= s + HeadTrim) { - CTRACE_SPLITLINE((tfp, "anchor %d case %d: ", a->number,2)); - /* - * endAnchor has seen it, it is effectively empty - * after our trimming, but endAnchor has for some - * reason not recognized this. In other words, - * this should not happen. - * Should we not adjust the extent and let it "leak" - * into the new line? - */ - new_pos = (a0 < s) ? s - TailTrim : - s - TailTrim + 1; - if (prev_a && new_pos + d < prev_a->start) { - if (prev_a->start <= S - TailTrim + 1 + SpecialAttrChars) - new_pos = prev_a->start - d; - else - new_pos = s - TailTrim + 1 + SpecialAttrChars; - } - new_ext = 0; - } else if (a0 >= s + HeadTrim) { - CTRACE_SPLITLINE((tfp, "anchor %d case %d: ", a->number,3)); - /* - * Completely after split, just shift. - */ - new_pos = a0 - TailTrim + 1 - HeadTrim + SpecialAttrChars; - } else if (!old_e) { - CTRACE_SPLITLINE((tfp, "anchor %d case %d: ", a->number,4)); - /* - * No extent set, we may still be growing it. - */ - new_pos = s - TailTrim + 1 + SpecialAttrChars; - /* - * Ok, it's neither empty, nor is it completely - * before or after the split region (including trimmed - * stuff). So the anchor is either being split in - * the middle, with stuff remaining on both lines, - * or something is being nibbled off, either at - * the end (anchor stays on previous line) or at - * the beginning (anchor is on new line). Let's - * try in that order. - */ - } else if (a0 < s - TailTrim && - a1 > s + HeadTrim) { - CTRACE_SPLITLINE((tfp, "anchor %d case %d: ", a->number,5)); - new_pos = a0; - new_ext = old_e - TailTrim - HeadTrim + SpecialAttrChars; - } else if (a0 < s - TailTrim) { - CTRACE_SPLITLINE((tfp, "anchor %d case %d: ", a->number,6)); - new_pos = a0; - new_ext = s - TailTrim - a0; - } else if (a1 > s + HeadTrim) { - CTRACE_SPLITLINE((tfp, "anchor %d case %d: ", a->number,7)); - new_pos = s - TailTrim + 1 + SpecialAttrChars; - new_ext = old_e - (s + HeadTrim - a0); - } else { - CTRACE((tfp, "split_line anchor %d line %d: This should not happen!\n", - a->number, a->line_num)); - CTRACE((tfp, - "anchor %d: (T,H,S)=(%d,%d,%d); (line,start,pos,ext):(%d,%d,%d,%d)!\n", - a->number, - TailTrim,HeadTrim,SpecialAttrChars, - a->line_num,a->start,a->line_pos,a->extent)); - continue; + /* The rest we relocate */ + moved = 1; + a->line_num++; + CTRACE_SPLITLINE((tfp, "anchor %d: (T,H,S)=(%d,%d,%d); (line,pos,ext):(%d,%d,%d), ", + n, TailTrim,HeadTrim,SpecialAttrChars, + a->line_num,a->line_pos,a->extent)); + if (end < s_post) { /* Move the end to s_post */ + CTRACE_SPLITLINE((tfp, "Move end +%d, ", s_post - end)); + len += s_post - end; } - CTRACE_SPLITLINE((tfp, "(T,H,S)=(%d,%d,%d); (line,start,pos,ext):(%d,%d,%d,%d", - TailTrim,HeadTrim,SpecialAttrChars, - a->line_num,a->start,a->line_pos,a->extent)); - if (new_pos != a->line_pos) - a->start = new_pos + d; - if (new_pos > s - TailTrim) { - new_pos -= s - TailTrim + 1; - a->line_num = text->Lines; + if (start < s_post) { /* Move the start to s_post */ + CTRACE_SPLITLINE((tfp, "Move start +%d, ", s_post - start)); + len -= s_post - start; + start = s_post; } - a->line_pos = new_pos; - a->extent = new_ext; + a->line_pos = start - s_post + SpecialAttrChars; + a->extent = len; - CTRACE_SPLITLINE((tfp, "))->(%d,%d,%d,%d)\n", - a->line_num,a->start,a->line_pos,a->extent)); - } + CTRACE_SPLITLINE((tfp, "->(%d,%d,%d)\n", + a->line_num,a->line_pos,a->extent)); + } else if (a->line_num > CurLine) + break; } } @@ -3043,6 +3093,7 @@ PRIVATE void split_line ARGS2( if (this_line_was_split && spare + && !text->stbl /* We don't inform TRST on the cell width change yet */ && justify_max_void_percent > 0 && justify_max_void_percent <= 100 && justify_max_void_percent >= ((100*spare) @@ -3055,10 +3106,8 @@ PRIVATE void split_line ARGS2( ht_run_info* r = ht_runs; char c; int total_byte_len = 0, total_cell_len = 0; - int d_, r_, i, j, cur_byte_num, *m; + int d_, r_; HTLine * jline; - char *jdata; - char *prevdata = previous->data; ht_num_runs = 0; r->byte_len = r->cell_len = 0; @@ -3106,183 +3155,46 @@ PRIVATE void split_line ARGS2( ++ht_num_runs; if (ht_num_runs != 1) { + int *oldpos = (int*)malloc(sizeof(int)*2*(ht_num_runs - 1)); + int *newpos = oldpos + ht_num_runs - 1; + int i = 1; - jline = allocHTLine(previous->size+spare); - if (jline == NULL) - outofmem(__FILE__, "split_line_1"); -#if defined(USE_COLOR_STYLE) - jline->styles = previous->styles; -#endif - jdata = jline->data; + if (oldpos == NULL) + outofmem(__FILE__, "split_line_3"); - /* - * we have to spread num_spaces among (ht_num_runs-1) runs - we - * fill justified_text_map in order to apply changes caused by - * justification to anchor data and color styles, and justify - * original string on the fly - */ d_ = spare/(ht_num_runs-1); r_ = spare % (ht_num_runs-1); - m = justified_text_map; - for(jp = previous->data, i = 0; i < justify_start_position; ++i) { - *m++ = i; - *jdata++ = ( *prevdata == HT_NON_BREAK_SPACE ? ' ' : *prevdata); - ++prevdata; - } - - cur_byte_num = i; - - for (r = ht_runs; r < ht_runs + ht_num_runs; ++r ) { + /* The first run is not moved, proceed to the second one */ + oldpos[0] = justify_start_position + ht_runs[0].cell_len + 1; + newpos[0] = oldpos[0] + ( d_ + ( r_-- > 0 ) ); + while (i < ht_num_runs - 1) { + int delta = ht_runs[i].cell_len + 1; - /* copy the reference to run content */ - for(i=0; i < r->byte_len; ++i) { - *m++ = cur_byte_num++; - *jdata++ = *prevdata++; - } - if ( r - ht_runs == ht_num_runs - 1 ) { /* nop on last run */ - *jdata++ = '\0'; - break; - } - - /* the space that was in original string */ - *m++ = cur_byte_num++; - *jdata++ = ' '; - prevdata++;/* skip that space */ - - cur_byte_num += j=( d_ + ( r_-- > 0 ) ); - for (i=0; i<j; ++i) - *jdata++ = ' '; + oldpos[i] = oldpos[i-1] + delta; + newpos[i] = newpos[i-1] + delta + ( d_ + ( r_-- > 0 ) ); + i++; } - *m++ = previous->size + spare; /*map the end */ - - text->chars += spare; - - jline->offset = previous->offset; - jline->size = previous->size + spare; - jline->split_after = previous->split_after; - jline->bullet = previous->bullet; - jline->expansion_line = previous->expansion_line; - - jline->prev = previous->prev; - jline->next = previous->next; + jline = insert_blanks_in_line(previous, CurLine, text, + last_anchor_of_previous_line, + ht_num_runs - 1, oldpos, newpos); + free((char*)oldpos); + if (jline == NULL) + outofmem(__FILE__, "split_line_4"); previous->next->prev = jline; previous->prev->next = jline; -#if defined(USE_COLOR_STYLE) - jline->numstyles = previous->numstyles; - - /* now copy and fix colorstyles */ - for(i = 0; i < jline->numstyles; ++i) { - int hpos = previous->styles[i].horizpos; - - jline->styles[i].style = previous->styles[i].style; - jline->styles[i].direction = previous->styles[i].direction; - /*there are stylechanges with hpos > line length */ - jline->styles[i].horizpos = (hpos > previous->size) - ? previous->size + spare - : justified_text_map[hpos]; - } -#endif - /* we have to fix anchors*/ - { - /*a2 is the last anchor on the line preceding 'previous'*/ - TextAnchor* a2 = last_anchor_of_previous_line; - - if (!a2) - a2 = text->first_anchor; - else if (a2 == text->last_anchor) - a2 = NULL; - else - a2 = a2->next; /*1st anchor on line we justify */ - - if (a2) { - for (; a2 /*&& a2->line_num == text->Lines-1*/; - last_anchor_of_previous_line = a2, a2 = a2->next) { - int oldpos = a2->line_pos, - newpos = justified_text_map[a2->line_pos], - shift = newpos - oldpos; - - if (a2->line_num == text->Lines) - break;/*new line not yet completed*/ - - if (a2->line_num == text->Lines-1) { - a2->line_pos = newpos; - a2->start += shift; - - if (!a2->extent && a2->number && - (a2->link_type & HYPERTEXT_ANCHOR) && - !a2->show_anchor && - a2->number == text->last_anchor_number) - /* seems endAnchor wasn't called for it */ { - a2 = a2->next; /*don't allow .start to be incremented - by 'spare' once more */ - break; - } - - if ( a2->extent + oldpos > (int) previous->size) - /*anchor content wrapped to new line */ - a2->extent += (jline->size - newpos) - - (previous->size - oldpos); - else - a2->extent = justified_text_map[oldpos+a2->extent] - - newpos; - - } else { - /* This is the anchor that was started on previous - * line. Its .line_pos and .start were updated. - * So we have to update only extent. If anchor - * text is longer than two lines, we don't bother - * setting it to correct value. - */ - if (a2->line_num != text->Lines-2) - continue; /* don't bother */ - if (!a2->extent && a2->number && - (a2->link_type & HYPERTEXT_ANCHOR) && - !a2->show_anchor && - a2->number == text->last_anchor_number) - /* seems endAnchor wasn't called for it */ - continue; - /* anchor is started at text->Lines-2, and there - * are two cases - either it was wrapped to newline - * or it ended in previous text->Lines-1. - */ - { - int p2sz = previous->prev->size, - p1sz = previous->size, - onp2sz = p2sz - a2->line_pos, - onp1sz = a2->extent - 1 - onp2sz; - - if (onp1sz >= p1sz) - /* this anchor will be skipped at the next - * split_line here, since its line_num will - * be text->Lines-3 - */ - a2->extent += spare; - else if (onp2sz < a2->extent) - a2->extent += justified_text_map[onp1sz-1] - - onp1sz + 1; - } - - } - - } - - /* iterate on anchors in the last line */ - for (; a2; a2 = a2->next) - a2->start += spare; - } - } - FREE(previous); - } else { /* (ht_num_runs==1) */ + 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* p = previous->data; - for( ; p < previous->data + justify_start_position; ++p) - *p = (*p == HT_NON_BREAK_SPACE ? ' ' : *p); + char* p2 = previous->data; + for( ; p2 < previous->data + justify_start_position; ++p2) + *p2 = (*p2 == HT_NON_BREAK_SPACE ? ' ' : *p2); } if (!a2) @@ -3298,23 +3210,23 @@ PRIVATE void split_line ARGS2( } } else { if (REALLY_CAN_JUSTIFY(text) ) { - char* p; + char* p2; /* it was permitted to justify line, but this function was called * to end paragraph - we must substitute HT_NON_BREAK_SPACEs with * spaces in previous line */ - if (line->size) { - CTRACE((tfp,"justification: shouldn't happen - new line is not empty!\n")); + if (line->size && !text->stbl) { + CTRACE((tfp,"BUG: justification: shouldn't happen - new line is not empty!\n")); } - for (p=previous->data;*p;++p) - if (*p == HT_NON_BREAK_SPACE) - *p = ' '; + for (p2=previous->data;*p2;++p2) + if (*p2 == HT_NON_BREAK_SPACE) + *p2 = ' '; } else if (have_raw_nbsps) { /* this is very rare case, that can happen in forms placed in table cells*/ - int i; + unsigned i; for (i = 0; i< previous->size; ++i) if (previous->data[i] == HT_NON_BREAK_SPACE) @@ -3349,6 +3261,13 @@ PRIVATE void blank_lines ARGS2( if (!HText_LastLineSize(text, IgnoreSpaces)) { /* No text on current line */ HTLine * line = text->last_line->prev; + +#ifdef USE_COLOR_STYLE + /* Style-change petty requests at the start of the document: */ + if (line == text->last_line && newlines == 1) + return; /* Do not add a blank line at start */ +#endif + while ((line != text->last_line) && (HText_TrueLineSize(line, text, IgnoreSpaces) == 0)) { if (newlines == 0) @@ -4411,9 +4330,9 @@ PUBLIC void _internal_HTC ARGS3(HText *,text, int,style, int,dir) line = text->last_line; if (line->numstyles > 0 && dir == 0 && - line->styles[line->numstyles].direction && - line->styles[line->numstyles].style == style && - (int) line->styles[line->numstyles].horizpos + line->styles[line->numstyles-1].direction && + line->styles[line->numstyles-1].style == style && + (int) line->styles[line->numstyles-1].horizpos == (int)line->size - ctrl_chars_on_this_line) { /* * If this is an OFF change directly preceded by an @@ -4483,138 +4402,6 @@ PUBLIC void HText_setIgnoreExcess ARGS2( */ /* - * Given a line and two int arrays of old/now position, this function - * does the actual work of creating a new line where spaces have been - * inserted 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. - * Returns a newly allocated HTLine* if changes were made - * (caller has to free the old one). - * Returns NULL if no changes needed. - * - kw - */ -PRIVATE HTLine * insert_blanks_in_line ARGS6( - HTLine *, line, - int, line_number, - HText *, text, - int, ninserts, - int *, oldpos, - int *, newpos) -{ - int i; - int ioldb, inewb; /* count bytes */ - int ioldc = 0, inewc = 0; /* count visible characters (positions) */ - int ip = 0; /* count oldpos,newpos insertion pairs */ - int acurshift, ashift = 0; /* for shifting of anchors in this line */ -#if defined(USE_COLOR_STYLE) - int stcurshift, stshift = 0; /* for shifting of styles in this line */ - int istyle; -#endif - int added_chars = 0; - HTLine * mod_line; - char * newdata; - TextAnchor * a; - if (!(line && line->size && ninserts)) - return NULL; - for (i = 0; i < ninserts; i++) - if (newpos[i] > oldpos[i] && - (newpos[i] - oldpos[i]) > added_chars) - added_chars = newpos[i] - oldpos[i]; - 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 (!mod_line) - return NULL; - memcpy(mod_line, line, LINE_SIZE(1)); - newdata = mod_line->data; - for (ioldb = 0, inewb = 0; ioldb < (int)line->size; ioldb++) { - if ((line->data[ioldb] == LY_BOLD_START_CHAR || - line->data[ioldb] == LY_UNDERLINE_START_CHAR || - !IsSpecialAttrChar(line->data[ioldb])) && - (!(text && text->T.output_utf8) || - UCH(line->data[ioldb]) < 128 || - (UCH((line->data[ioldb] & 0xc0)) == 0xc0))) { - /* - * A new displayable character starts here. Time to check - * whether this is a position to insert spaces. - */ - while (ip < ninserts && oldpos[ip] <= ioldc) { - if (inewc < newpos[ip]) { - /* - * Yup, spaces to insert. We also have to update - * anchor positions for anchors that start on the - * same line, this is a pain. Let's do it first. - * Note: we rely on a->line_pos counting bytes, not - * characters. That's one reason why HText_trimHightext - * has to be prevented from acting on these anchors in - * partial display mode before we get a chance to - * deal with them here. - */ - acurshift = 0; - for (a = text->last_anchor_before_stbl ? - text->last_anchor_before_stbl->next : - text->first_anchor; - a && a->line_num <= line_number; a = a->next) { - if (a->line_num == line_number) - if (a->line_pos - ashift >= ioldb) { - acurshift = newpos[ip] - inewc; - a->line_pos += acurshift; - a->start += acurshift; - } - } - ashift += acurshift; - - /* doing something for color styles here. - * we rely on horizpos counting characters - * (display positions), not bytes. */ -#if defined(USE_COLOR_STYLE) -#define NStyle mod_line->styles[istyle] - stcurshift = 0; - for (istyle = 0; istyle < line->numstyles; - istyle++) { - if (NStyle.horizpos - stshift >= ioldc) { - stcurshift = newpos[ip] - inewc; - NStyle.horizpos += stcurshift; - } - } - stshift += stcurshift; -#endif - /* - * Now insert the spaces. - */ - for (; inewc < newpos[ip]; inewc++) { - newdata[inewb++] = ' '; - } - } - ip++; /* done with this oldpos[ip],newpos[ip] pair. */ - } - /* - * Copy character data over, advance position pointers. - */ - newdata[inewb++] = line->data[ioldb]; - if (!(line->data[ioldb] == LY_BOLD_START_CHAR || - line->data[ioldb] == LY_UNDERLINE_START_CHAR)) { - ioldc++; - inewc++; - } - } else { - /* - * Just copy special attribute chars and utf-8 additional - * bytes over, don't advance position pointers. - */ - newdata[inewb++] = line->data[ioldb]; - } - } - newdata[inewb] = '\0'; - mod_line->size = inewb; - return mod_line; -} - -/* * HText_insertBlanksInStblLines fixes up table lines when simple table * processing is closed, by calling insert_blanks_in_line for lines * that need fixup. Also recalculates alignment for those lines, @@ -4636,7 +4423,6 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2( int last_nonempty = -1; #endif int added_chars_before = 0; - TextAnchor * a; int lines_changed = 0; int max_width = 0, indent, spare, table_offset; HTStyle *style; @@ -4662,14 +4448,6 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2( } first_lineno_pass2 = last_lineno = me->Lines; for (; line && lineno <= last_lineno; line = line->next, lineno++) { - if (added_chars_before) { - for (a = me->last_anchor_before_stbl ? - me->last_anchor_before_stbl->next : me->first_anchor; - a && a->line_num <= lineno; a = a->next) { - if (a->line_num == lineno) - a->start += added_chars_before; - } - } ninserts = Stbl_getFixupPositions(me->stbl, lineno, oldpos, newpos); if (ninserts < 0) continue; @@ -4712,12 +4490,12 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2( continue; } mod_line = insert_blanks_in_line(line, lineno, me, + me->last_anchor_before_stbl, ninserts, oldpos, newpos); if (mod_line) { if (line == me->last_line) { me->last_line = mod_line; } else { - me->chars += (mod_line->size - line->size); added_chars_before += (mod_line->size - line->size); } line->prev->next = mod_line; @@ -4807,7 +4585,7 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2( * Still not enough. Something went wrong. Try the best we * can do. */ - CTRACE((tfp, "insertBlanks: resulting table too wide by %d positions!", + CTRACE((tfp, "BUG: insertBlanks: resulting table too wide by %d positions!\n", -spare)); indent = spare = 0; } @@ -4848,11 +4626,11 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2( CTRACE((tfp, " %d:%d", lineno, table_offset - line->offset)); line->offset = table_offset; } + } #ifdef EXP_NESTED_TABLES - if (max_width) - Stbl_update_enclosing(me->stbl, max_width, last_nonempty); + if (max_width) + Stbl_update_enclosing(me->stbl, max_width, last_nonempty); #endif - } CTRACE((tfp, " %d:done\n", lineno)); free(oldpos); return lines_changed; @@ -4867,20 +4645,20 @@ PRIVATE int HText_insertBlanksInStblLines ARGS2( PUBLIC void HText_cancelStbl ARGS1( HText *, me) { - STable_info *stbl; - if (!me || !me->stbl) { CTRACE((tfp, "cancelStbl: ignored.\n")); return; } CTRACE((tfp, "cancelStbl: ok, will do.\n")); #ifdef EXP_NESTED_TABLES - stbl = me->stbl; + { + STable_info *stbl = me->stbl; while (stbl) { STable_info *enclosing = Stbl_get_enclosing(stbl); Stbl_free(stbl); stbl = enclosing; } + } #else Stbl_free(me->stbl); #endif @@ -5012,7 +4790,7 @@ PUBLIC void HText_endStblTD ARGS1( { if (!me || !me->stbl) return; - if (Stbl_finishCellInTable(me->stbl, YES, + if (Stbl_finishCellInTable(me->stbl, TRST_ENDCELL_ENDTD, me->Lines, HText_LastLineSize(me,FALSE)) < 0) HText_cancelStbl(me); /* give up */ } @@ -5079,7 +4857,6 @@ PUBLIC int HText_beginAnchor ARGS3( outofmem(__FILE__, "HText_beginAnchor"); a->hightext = NULL; a->hightext2 = NULL; - a->start = text->chars + text->last_line->size; a->inUnderline = underline; a->line_num = text->Lines; @@ -5122,7 +4899,6 @@ PUBLIC int HText_beginAnchor ARGS3( HText_appendText(text, marker); if (saved_linenum && text->Lines && saved_lastchar != ' ') text->LastChar = ']'; /* if marker not after space caused split */ - a->start = text->chars + text->last_line->size; a->line_num = text->Lines; a->line_pos = text->last_line->size; } @@ -5130,15 +4906,11 @@ PUBLIC int HText_beginAnchor ARGS3( return(a->number); } -/* - This returns whether the given anchor has blank content. Shamelessly copied - from HText_endAnchor. The values returned are meaningful only for "normal" - links - like ones produced by <a href=".">foo</a>, no inputs, etc. - VH -*/ -#ifdef MARK_HIDDEN_LINKS -PUBLIC BOOL HText_isAnchorBlank ARGS2( +/* If !really, report whether the anchor is empty. */ +PRIVATE int HText_endAnchor0 ARGS3( HText *, text, - int, number) + int, number, + int, really) { TextAnchor *a; @@ -5170,7 +4942,7 @@ PUBLIC BOOL HText_isAnchorBlank ARGS2( } } - CTRACE((tfp, "GridText:HText_isAnchorBlank: number:%d link_type:%d\n", + CTRACE((tfp, "GridText:HText_endAnchor0: number:%d link_type:%d\n", a->number, a->link_type)); if (a->link_type == INPUT_ANCHOR) { /* @@ -5178,188 +4950,8 @@ PUBLIC BOOL HText_isAnchorBlank ARGS2( */ CTRACE((tfp, - "HText_isAnchorBlank: internal error: last anchor was input field!\n")); - return 0; - } - if (a->number) { - /* - * If it goes somewhere... - */ - int i, j, k; - HTLine *last = text->last_line; - HTLine *prev = text->last_line->prev; - HTLine *start = last; - int CurBlankExtent = 0; - int BlankExtent = 0; - - int extent_adjust = (text->chars + last->size) - a->start - - (text->Lines - a->line_num); - - /* - * Check if the anchor content has only - * white and special characters, starting - * with the content on the last line. - FM - */ - a->extent += extent_adjust; - if (a->extent > (int)last->size) { - /* - * The anchor extends over more than one line, - * so set up to check the entire last line. - FM - */ - i = last->size; - } else { - /* - * The anchor is restricted to the last line, - * so check from the start of the anchor. - FM - */ - i = a->extent; - } - k = j = (last->size - i); - while (j < (int)last->size) { - if (!IsSpecialAttrChar(last->data[j]) && - !isspace(UCH(last->data[j])) && - last->data[j] != HT_NON_BREAK_SPACE && - last->data[j] != HT_EN_SPACE) - break; - i--; - j++; - } - if (i == 0) { - if (a->extent > (int)last->size) { - /* - * The anchor starts on a preceding line, and - * the last line has only white and special - * characters, so declare the entire extent - * of the last line as blank. - FM - */ - CurBlankExtent = BlankExtent = last->size; - } else { - /* - * The anchor starts on the last line, and - * has only white or special characters, so - * declare the anchor's extent as blank. - FM - */ - CurBlankExtent = BlankExtent = a->extent; - } - } - /* - * While the anchor starts on a line preceding - * the one we just checked, and the one we just - * checked has only white and special characters, - * check whether the anchor's content on the - * immediately preceding line also has only - * white and special characters. - FM - */ - while (i == 0 && - (a->extent > CurBlankExtent || - (a->extent == CurBlankExtent && - k == 0 && - prev != text->last_line && - (prev->size == 0 || - prev->data[prev->size - 1] == ']')))) { - start = prev; - k = j = prev->size - a->extent + CurBlankExtent; - if (j < 0) { - /* - * The anchor starts on a preceding line, - * so check all of this line. - FM - */ - j = 0; - i = prev->size; - } else { - /* - * The anchor starts on this line. - FM - */ - i = a->extent - CurBlankExtent; - } - while (j < (int)prev->size) { - if (!IsSpecialAttrChar(prev->data[j]) && - !isspace(UCH(prev->data[j])) && - prev->data[j] != HT_NON_BREAK_SPACE && - prev->data[j] != HT_EN_SPACE) - break; - i--; - j++; - } - if (i == 0) { - if (a->extent > (CurBlankExtent + (int)prev->size) || - (a->extent == CurBlankExtent + (int)prev->size && - k == 0 && - prev->prev != text->last_line && - (prev->prev->size == 0 || - prev->prev->data[prev->prev->size - 1] == ']'))) { - /* - * This line has only white and special - * characters, so treat its entire extent - * as blank, and decrement the pointer for - * the line to be analyzed. - FM - */ - CurBlankExtent += prev->size; - BlankExtent = CurBlankExtent; - prev = prev->prev; - } else { - /* - * The anchor starts on this line, and it - * has only white or special characters, so - * declare the anchor's extent as blank. - FM - */ - BlankExtent = a->extent; - break; - } - } - } - a->extent -= extent_adjust; - return i==0; - } else + "BUG: HText_endAnchor0: internal error: last anchor was input field!\n")); return 0; -} -#endif /* MARK_HIDDEN_LINKS */ - - -PUBLIC void HText_endAnchor ARGS2( - HText *, text, - int, number) -{ - TextAnchor *a; - - /* - * The number argument is set to 0 in HTML.c and - * LYCharUtils.c when we want to end the anchor - * for the immediately preceding HText_beginAnchor() - * call. If it's greater than 0, we want to handle - * a particular anchor. This allows us to set links - * for positions indicated by NAME or ID attributes, - * without needing to close any anchor with an HREF - * within which that link might be embedded. - FM - */ - if (number <= 0 || number == text->last_anchor->number) { - a = text->last_anchor; - } else { - for (a = text->first_anchor; a; a = a->next) { - if (a->number == number) { - break; - } - } - if (a == NULL) { - /* - * There's no anchor with that number, - * so we'll default to the last anchor, - * and cross our fingers. - FM - */ - a = text->last_anchor; - } - } - - CTRACE((tfp, "GridText:HText_endAnchor: number:%d link_type:%d\n", - a->number, a->link_type)); - if (a->link_type == INPUT_ANCHOR) { - /* - * Shouldn't happen, but put test here anyway to be safe. - LE - */ - - CTRACE((tfp, - "HText_endAnchor: internal error: last anchor was input field!\n")); - return; } if (a->number) { /* @@ -5379,14 +4971,25 @@ PUBLIC void HText_endAnchor ARGS2( HTLine *start = last; int CurBlankExtent = 0; int BlankExtent = 0; + int extent_adjust = 0; + + /* Find the length taken by the anchor */ + l = text->Lines; /* lineno of last */ + while (l > a->line_num) { + extent_adjust += start->size; + start = start->prev; + l--; + } + /* Now start is the start line of the anchor */ + extent_adjust += start->size - a->line_pos; + start = last; /* Used later */ /* * Check if the anchor content has only * white and special characters, starting * with the content on the last line. - FM */ - a->extent += (text->chars + last->size) - a->start - - (text->Lines - a->line_num); + a->extent += extent_adjust; if (a->extent > (int)last->size) { /* * The anchor extends over more than one line, @@ -5494,6 +5097,10 @@ PUBLIC void HText_endAnchor ARGS2( } } } + if (!really) { /* Just report whether it is empty */ + a->extent -= extent_adjust; + return i==0; + } if (i == 0) { /* * It's an invisible anchor probably from an ALT="" @@ -5503,8 +5110,8 @@ PUBLIC void HText_endAnchor ARGS2( a->show_anchor = NO; CTRACE((tfp, - "HText_endAnchor: hidden (line,start,pos,ext,BlankExtent):(%d,%d,%d,%d,%d)", - a->line_num,a->start,a->line_pos,a->extent, + "HText_endAnchor0: hidden (line,pos,ext,BlankExtent):(%d,%d,%d,%d)", + a->line_num,a->line_pos,a->extent, BlankExtent)); /* @@ -5579,10 +5186,7 @@ PUBLIC void HText_endAnchor ARGS2( k = j + NumSize; while (k < (int)start->size) start->data[j++] = start->data[k++]; - if (start != last) - text->chars -= NumSize; for (anc = a; anc; anc = anc->next) { - anc->start -= NumSize; if (anc->line_num == a->line_num && anc->line_pos >= NumSize) { anc->line_pos -= NumSize; @@ -5617,10 +5221,6 @@ PUBLIC void HText_endAnchor ARGS2( l = (i - j); while (i < (int)prev->size) prev->data[j++] = prev->data[i++]; - text->chars -= l; - for (anc = a; anc; anc = anc->next) { - anc->start -= l; - } prev->size = j; prev->data[j] = '\0'; while (j < i) @@ -5635,10 +5235,7 @@ PUBLIC void HText_endAnchor ARGS2( i = k; while (k < (int)start->size) start->data[j++] = start->data[k++]; - if (start != last) - text->chars -= i; for (anc = a; anc; anc = anc->next) { - anc->start -= i; if (anc->line_num == a->line_num && anc->line_pos >= i) { anc->line_pos -= i; @@ -5694,10 +5291,6 @@ PUBLIC void HText_endAnchor ARGS2( k = j + NumSize; while (k < (int)prev->size) prev->data[j++] = prev->data[k++]; - text->chars -= NumSize; - for (anc = a; anc; anc = anc->next) { - anc->start -= NumSize; - } prev->size = j; prev->data[j++] = '\0'; while (j < k) @@ -5733,8 +5326,8 @@ PUBLIC void HText_endAnchor ARGS2( a->show_anchor = YES; if (BlankExtent) { CTRACE((tfp, - "HText_endAnchor: blanks (line,start,pos,ext,BlankExtent):(%d,%d,%d,%d,%d)", - a->line_num,a->start,a->line_pos,a->extent, + "HText_endAnchor0: blanks (line,pos,ext,BlankExtent):(%d,%d,%d,%d)", + a->line_num,a->line_pos,a->extent, BlankExtent)); } } @@ -5764,12 +5357,14 @@ PUBLIC void HText_endAnchor ARGS2( } if (BlankExtent || a->extent <= 0 || a->number <= 0) { CTRACE((tfp, - "->[%d](%d,%d,%d,%d,%d)\n", + "->[%d](%d,%d,%d,%d)\n", a->number, - a->line_num,a->start,a->line_pos,a->extent, + a->line_num,a->line_pos,a->extent, BlankExtent)); } } else { + if (!really) /* Just report whether it is empty */ + return 0; /* * It's a named anchor without an HREF, so it * should be registered but not shown as a @@ -5778,8 +5373,29 @@ PUBLIC void HText_endAnchor ARGS2( a->show_anchor = NO; a->extent = 0; } + return 0; +} + +PUBLIC void HText_endAnchor ARGS2( + HText *, text, + int, number) +{ + HText_endAnchor0(text, number, 1); } +/* + This returns whether the given anchor has blank content. Shamelessly copied + from HText_endAnchor. The values returned are meaningful only for "normal" + links - like ones produced by <a href=".">foo</a>, no inputs, etc. - VH +*/ +#ifdef MARK_HIDDEN_LINKS +PUBLIC BOOL HText_isAnchorBlank ARGS2( + HText *, text, + int, number) +{ + return HText_endAnchor0(text, number, 0); +} +#endif /* MARK_HIDDEN_LINKS */ PUBLIC void HText_appendText ARGS2( HText *, text, @@ -5921,7 +5537,7 @@ PUBLIC void HText_trimHightext ARGS3( BOOLEAN, final, int, stop_before) { - int cur_line, cur_char, cur_shift; + int cur_line, cur_shift; TextAnchor *anchor_ptr; TextAnchor *prev_a = NULL; HTLine *line_ptr; @@ -5944,7 +5560,6 @@ PUBLIC void HText_trimHightext ARGS3( * Get the first line. */ line_ptr = text->last_line->next; - cur_char = line_ptr->size; cur_line = 0; /* @@ -5959,10 +5574,8 @@ re_parse: /* * Find the right line. */ - for (; anchor_ptr->start > cur_char; - line_ptr = line_ptr->next, - cur_char += line_ptr->size+1, - cur_line++) { + for (; anchor_ptr->line_num > cur_line; + line_ptr = line_ptr->next, cur_line++) { ; /* null body */ } @@ -5974,7 +5587,8 @@ re_parse: */ if (cur_line >= stop_before) break; - if (anchor_ptr->start >= text->chars - 1) + if ( anchor_ptr->line_num >= text->Lines - 1 + && anchor_ptr->line_pos >= (int) text->last_line->prev->size ) break; /* * Also skip this anchor if it looks like HText_endAnchor @@ -5995,14 +5609,10 @@ re_parse: if (anchor_ptr->hightext) continue; - if (anchor_ptr->start == cur_char) { + if (anchor_ptr->line_pos > (int) line_ptr->size) { anchor_ptr->line_pos = line_ptr->size; - } else { - anchor_ptr->line_pos = anchor_ptr->start - - (cur_char - line_ptr->size); } if (anchor_ptr->line_pos < 0) { - anchor_ptr->start -= anchor_ptr->line_pos; anchor_ptr->line_pos = 0; anchor_ptr->line_num = cur_line; } @@ -6029,7 +5639,6 @@ re_parse: if (anchor_ptr->extent < 0) { anchor_ptr->extent = 0; } - anchor_ptr->start += cur_shift; CTRACE((tfp, "anchor text: '%s'\n", line_ptr->data)); /* @@ -6043,8 +5652,10 @@ re_parse: if (cur_line < text->Lines && (anchor_ptr->extent || anchor_ptr->line_pos != (int)line_ptr->size || - (prev_a && prev_a->start > anchor_ptr->start))) { - anchor_ptr->start++; + (prev_a && /* How could this happen? */ + (prev_a->line_num > anchor_ptr->line_num)))) { + anchor_ptr->line_num++; + anchor_ptr->line_pos = 0; CTRACE((tfp, "found anchor at end of line\n")); goto re_parse; } else { @@ -6369,8 +5980,8 @@ PUBLIC int HTGetLinkInfo ARGS6( * and don't count towards nlinks. - KW */ if ((a->show_anchor) && - (a->link_type != INPUT_ANCHOR || - a->input_field->type != F_HIDDEN_TYPE)) { + !(a->link_type == INPUT_ANCHOR + && a->input_field->type == F_HIDDEN_TYPE)) { if (a->line_num == prev_anchor_line) { anchors_this_line++; } else { @@ -6645,8 +6256,8 @@ PUBLIC int HTGetLinkOrFieldStart ARGS5( * and don't count towards nlinks. - KW */ if ((a->show_anchor) && - (a->link_type != INPUT_ANCHOR || - a->input_field->type != F_HIDDEN_TYPE)) { + !(a->link_type == INPUT_ANCHOR + && a->input_field->type == F_HIDDEN_TYPE)) { if (a->line_num == prev_anchor_line) { anchors_this_line++; } else { @@ -7141,7 +6752,7 @@ PUBLIC void HText_pageDisplay ARGS2( ** Multiple calls of HText_trimHightext works without problem now. */ if (HTMainText && HTMainText->stbl) - stop_before = Stbl_getStartLine(HTMainText->stbl); + stop_before = Stbl_getStartLineDeep(HTMainText->stbl); HText_trimHightext(HTMainText, FALSE, stop_before); } #endif @@ -7197,8 +6808,8 @@ PUBLIC int HText_LinksInLines ARGS3( if (Anchor_ptr->line_num >= start && Anchor_ptr->line_num < end && Anchor_ptr->show_anchor && - (Anchor_ptr->link_type != INPUT_ANCHOR || - Anchor_ptr->input_field->type != F_HIDDEN_TYPE)) + !(Anchor_ptr->link_type == INPUT_ANCHOR + && Anchor_ptr->input_field->type == F_HIDDEN_TYPE)) ++total; if (Anchor_ptr == text->last_anchor) break; @@ -7273,22 +6884,6 @@ PUBLIC void HText_scrollBottom ARGS1( /* Bring to front and highlight it */ -PRIVATE int line_for_char ARGS2( - HText *, text, - int, char_num) -{ - int line_number = 0; - int characters = 0; - HTLine * line = text->last_line->next; - for (;;) { - if (line == text->last_line) return 0; /* Invalid */ - characters = characters + line->size + 1; - if (characters > char_num) return line_number; - line_number ++; - line = line->next; - } -} - PUBLIC BOOL HText_select ARGS1( HText *, text) { @@ -7400,8 +6995,8 @@ PUBLIC BOOL HTFindPoundSelector ARGS1( www_search_result = a->line_num+1; CTRACE((tfp, - "HText: Selecting anchor [%d] at character %d, line %d\n", - a->number, a->start, www_search_result)); + "HText: Selecting anchor [%d] at line %d\n", + a->number, www_search_result)); if (!strcmp(selector, LYToolbarName)) { --www_search_result; } @@ -7440,10 +7035,10 @@ PUBLIC BOOL HText_selectAnchor ARGS2( } { - int l = line_for_char(text, a->start); + int l = a->line_num; CTRACE((tfp, - "HText: Selecting anchor [%d] at character %d, line %d\n", - a->number, a->start, l)); + "HText: Selecting anchor [%d] at line %d\n", + a->number, l)); if ( !text->stale && (l >= text->top_of_screen) && @@ -8119,8 +7714,8 @@ PRIVATE int www_user_search_internals ARGS8( for (;;) { while ((a != NULL) && a->line_num == (*count - 1)) { if (a->show_anchor && - (a->link_type != INPUT_ANCHOR || - a->input_field->type != F_HIDDEN_TYPE)) { + !(a->link_type == INPUT_ANCHOR + && a->input_field->type == F_HIDDEN_TYPE)) { if (((a->hightext != NULL && case_sensitive == TRUE) && LYno_attr_char_strstr(a->hightext, target)) || ((a->hightext != NULL && case_sensitive == FALSE) && @@ -8491,7 +8086,7 @@ PUBLIC BOOLEAN HTreparse_document NOARGS } CTRACE((tfp, " Content type is \"%s\"\n", format->name)); - fp = fopen(HTMainAnchor->source_cache_file, "r"); + fp = fopen(HTMainAnchor->source_cache_file, TXT_R); if (!fp) { CTRACE((tfp, " Cannot read file %s\n", HTMainAnchor->source_cache_file)); LYRemoveTemp(HTMainAnchor->source_cache_file); @@ -8873,8 +8468,6 @@ PUBLIC void HText_RemovePreviousLine ARGS1( previous = line->prev; previous->next = text->last_line; text->last_line->prev = previous; - text->chars -= ((data && *data == '\0') ? - 1 : strlen(line->data) + 1); text->Lines--; FREE(line); } @@ -9486,7 +9079,7 @@ PUBLIC char * HText_setLastOptionValue ARGS7( cp[j] = '\0'; if (HTCJK != NOCJK) { if (cp && - (tmp = (unsigned char *)calloc(1, strlen(cp)+1))) { + (tmp = typecallocn(unsigned char, strlen(cp)+1)) != 0) { #ifdef SH_EX if (tmp == NULL) outofmem(__FILE__, "HText_setLastOptionValue"); @@ -9608,27 +9201,6 @@ PUBLIC char * HText_setLastOptionValue ARGS7( } /* - * Count the number of anchors on the current line so we can allow for the - * length of numbered fields. - */ -PRIVATE int AnchorsOnThisLine ARGS2( - HText *, txt, - TextAnchor *, ank) -{ - TextAnchor *chk = txt->first_anchor; - int count = 1; - - while (chk != 0 - && chk != txt->last_anchor - && chk != ank) { - if (chk->line_num == ank->line_num) - count++; - chk = chk->next; - } - return count; -} - -/* * Assign a form input anchor. * Returns the number of characters to leave * blank so that the input field can fit. @@ -9650,7 +9222,6 @@ PUBLIC int HText_beginInput ARGS3( if (a == NULL || f == NULL) outofmem(__FILE__, "HText_beginInput"); - a->start = text->chars + text->last_line->size; a->inUnderline = underline; a->line_num = text->Lines; a->line_pos = text->last_line->size; @@ -9728,11 +9299,7 @@ PUBLIC int HText_beginInput ARGS3( if (I->value) StrAllocCopy(IValue, I->value); if (IValue && HTCJK != NOCJK) { - if ((tmp = (unsigned char *)calloc(1, (strlen(IValue) + 1)))) { -#ifdef SH_EX - if (tmp == NULL) - outofmem(__FILE__, "HText_beginInput"); -#endif + if ((tmp = typecallocn(unsigned char, strlen(IValue) + 1)) != 0) { if (kanji_code == EUC) { TO_EUC((unsigned char *)IValue, tmp); I->value_cs = current_char_set; @@ -10018,7 +9585,6 @@ PUBLIC int HText_beginInput ARGS3( * Add option list designation char. */ HText_appendCharacter(text, '['); - a->start = text->chars + text->last_line->size; a->line_num = text->Lines; a->line_pos = text->last_line->size; } @@ -10047,12 +9613,14 @@ PUBLIC int HText_beginInput ARGS3( (int)text->style->leftIndent - (int)text->style->rightIndent; - /* - * If we are numbering form links, take that into - * account as well. - FM - */ + /* If we are numbering form links, place is taken by [nn] */ if (keypad_mode == LINKS_AND_FIELDS_ARE_NUMBERED) - MaximumSize -= AnchorsOnThisLine(text, a) / 10 + 3; + MaximumSize -= (a->number >= 10 /*Buggy if 1e6 links, sowhat?*/ + ? (a->number >= 100 + ? (a->number >= 1000 + ? (a->number >= 10000 + ? (a->number >= 100000 + ? 6 : 5) : 4) : 3) : 2) : 1) + 2; if (f->size > MaximumSize) f->size = MaximumSize; @@ -10858,7 +10426,7 @@ PUBLIC int HText_SubmitForm ARGS4( escaped1 = HTEscapeSP(name_used, URL_XALPHAS); } - if ((fd = fopen(val_used, "rb")) == 0) { + if ((fd = fopen(val_used, BIN_R)) == 0) { /* We can't open the file, what do we do? */ HTAlert(gettext("Can't open file for uploading")); goto exit_disgracefully; @@ -12189,7 +11757,6 @@ PRIVATE void insert_new_textarea_anchor ARGS2( /* [anything "special" needed based on ->show_anchor value ?] */ a->next = anchor->next; a->number = anchor->number; - a->start = anchor->start + anchor->input_field->size + 1; a->line_pos = anchor->line_pos; a->extent = anchor->extent; a->line_num = anchor->line_num + 1; @@ -12220,9 +11787,6 @@ PRIVATE void insert_new_textarea_anchor ARGS2( l->prev = htline; l->offset = htline->offset; l->size = htline->size; - l->split_after = htline->split_after; - l->bullet = htline->bullet; - l->expansion_line = TRUE; #if defined(USE_COLOR_STYLE) /* dup styles[] if needed [no need in TEXTAREA (?); leave 0's] */ l->numstyles = htline->numstyles; @@ -12276,13 +11840,12 @@ PRIVATE void insert_new_textarea_anchor ARGS2( PRIVATE void update_subsequent_anchors ARGS4( int, n, TextAnchor *, start_anchor, - HTLine *, start_htline, + HTLine *, start_htline, int, start_tag) { TextAnchor *anchor; HTLine *htline = start_htline; - int form_chars_added = (start_anchor->input_field->size + 1) * n; int line_adj = 0; int tag_adj = 0; int lx = 0; @@ -12306,7 +11869,6 @@ PRIVATE void update_subsequent_anchors ARGS4( (anchor->number != 0)) anchor->number += n; anchor->line_num += n; - anchor->start += form_chars_added; anchor = anchor->next; } @@ -12395,7 +11957,6 @@ finish: nlinks += n; HTMainText->Lines += n; HTMainText->last_anchor_number += n; - HTMainText->chars += (form_chars_added + tag_adj); more = HText_canScrollDown(); @@ -12456,7 +12017,7 @@ PUBLIC int HText_ExtEditForm ARGS1( char *line; char *lp; char *cp; - int match_tag = 0; + int match_tag = 0; int newlines = 0; int len, len0, len_in; int wanted_fieldlen_wrap = -1; /* not yet asked; 0 means don't. */ @@ -12596,7 +12157,7 @@ PUBLIC int HText_ExtEditForm ARGS1( return 0; } - fp = fopen (ed_temp, "r"); + fp = fopen (ed_temp, TXT_R); size = fread (ebuf, 1, size, fp); LYCloseInput (fp); ebuf[size] = '\0'; /* Terminate! - kw */ @@ -12801,7 +12362,7 @@ PUBLIC int HText_ExtEditForm ARGS1( */ PUBLIC void HText_ExpandTextarea ARGS2( struct link *, form_link, - int, newlines) + int, newlines) { TextAnchor *anchor_ptr; TextAnchor *end_anchor = NULL; @@ -12986,7 +12547,7 @@ PUBLIC int HText_InsertFile ARGS1( */ LYGetFileInfo(fn, 0, 0, 0, 0, 0, &file_cs); - fp = fopen (fn, "r"); + fp = fopen (fn, TXT_R); if (!fp) { free(fbuf); free(fn); @@ -13059,7 +12620,6 @@ PUBLIC int HText_InsertFile ARGS1( /* [anything "special" needed based on ->show_anchor value ?] */ a->next = anchor_ptr; a->number = anchor_ptr->number; - a->start = anchor_ptr->start; a->line_pos = anchor_ptr->line_pos; a->extent = anchor_ptr->extent; a->line_num = anchor_ptr->line_num; @@ -13088,9 +12648,6 @@ PUBLIC int HText_InsertFile ARGS1( /* Init all the fields in the new HTLine (but see the #if). */ l->offset = htline->offset; l->size = htline->size; - l->split_after = htline->split_after; - l->bullet = htline->bullet; - l->expansion_line = TRUE; #if defined(USE_COLOR_STYLE) /* dup styles[] if needed [no need in TEXTAREA (?); leave 0's] */ l->numstyles = htline->numstyles; @@ -13112,11 +12669,11 @@ PUBLIC int HText_InsertFile ARGS1( if (prev_anchor) prev_anchor->next = a; - htline = htline->prev; - l->next = htline->next; - l->prev = htline; - htline->next->prev = l; - htline->next = l; + htline = htline->prev; + l->next = htline->next; + l->prev = htline; + htline->next->prev = l; + htline->next = l; /* * update_subsequent_anchors() expects htline to point to 1st potential diff --git a/src/HTFWriter.c b/src/HTFWriter.c index ff75c6e0..3afa76db 100644 --- a/src/HTFWriter.c +++ b/src/HTFWriter.c @@ -570,7 +570,7 @@ PRIVATE char *mailcap_substitute ARGS3( } } if (pass == 0) { - if ((result = malloc(need)) == 0) + if ((result = malloc(need + 1)) == 0) outofmem(__FILE__, "mailcap_substitute"); *result = 0; } @@ -667,7 +667,7 @@ PUBLIC HTStream* HTSaveAndExecute ARGS3( * not being able to find the fp. The ".bin" suffix is expected * to not be used, it's only for fallback in unusual error cases. - kw */ - me->fp = LYOpenTempRewrite(fnam, ".bin", "wb"); + me->fp = LYOpenTempRewrite(fnam, ".bin", BIN_W); } else { #if defined(WIN_EX) && !defined(__CYGWIN__) /* 1998/01/04 (Sun) */ if (!strncmp(anchor->address,"file://localhost",16)) { @@ -730,7 +730,7 @@ PUBLIC HTStream* HTSaveAndExecute ARGS3( { suffix = HTML_SUFFIX; } - me->fp = LYOpenTemp(fnam, suffix, "wb"); + me->fp = LYOpenTemp(fnam, suffix, BIN_W); } if (!me->fp) { @@ -862,7 +862,7 @@ PUBLIC HTStream* HTSaveToFile ARGS3( * not being able to find the fp. The ".bin" suffix is expected * to not be used, it's only for fallback in unusual error cases. - kw */ - ret_obj->fp = LYOpenTempRewrite(fnam, ".bin", "wb"); + ret_obj->fp = LYOpenTempRewrite(fnam, ".bin", BIN_W); } else { /* * Check for a suffix. @@ -880,7 +880,7 @@ PUBLIC HTStream* HTSaveToFile ARGS3( || *suffix != '.') { suffix = HTML_SUFFIX; } - ret_obj->fp = LYOpenTemp(fnam, suffix, "wb"); + ret_obj->fp = LYOpenTemp(fnam, suffix, BIN_W); } if (!ret_obj->fp) { @@ -1173,7 +1173,7 @@ PUBLIC HTStream* HTCompressed ARGS3( /* * Open the file for receiving the compressed input stream. - FM */ - me->fp = LYOpenTemp (fnam, temp, "wb"); + me->fp = LYOpenTemp (fnam, temp, BIN_W); if (!me->fp) { HTAlert(CANNOT_OPEN_TEMP); FREE(uncompress_mask); diff --git a/src/HTML.c b/src/HTML.c index 8973cab0..4175b026 100644 --- a/src/HTML.c +++ b/src/HTML.c @@ -8178,7 +8178,7 @@ PUBLIC HTStructured* HTML_new ARGS3( exit_immediately (EXIT_FAILURE); } - me = (HTStructured*) calloc(sizeof(*me),1); + me = typecalloc(HTStructured); if (me == NULL) outofmem(__FILE__, "HTML_new"); @@ -8631,7 +8631,7 @@ PRIVATE HTStream* CacheThru_new ARGS2( * don't get munged; this way, the file should (knock on wood) * contain exactly what came in from the network. */ - if (!(stream->fp = LYOpenTemp(filename, HTML_SUFFIX, "wb"))) { + if (!(stream->fp = LYOpenTemp(filename, HTML_SUFFIX, BIN_W))) { CTRACE((tfp, "SourceCacheWriter: Cannot open source cache file for URL %s\n", HTAnchor_address((HTAnchor *)anchor))); FREE(stream); diff --git a/src/LYBookmark.c b/src/LYBookmark.c index db2e0271..cfe8c837 100644 --- a/src/LYBookmark.c +++ b/src/LYBookmark.c @@ -328,7 +328,7 @@ PUBLIC void save_bookmark_link ARGS2( } CTRACE((tfp, "\nsave_bookmark_link: SEEKING %s\n AS %s\n\n", BookmarkPage, filename_buffer)); - if ((fp = fopen(filename_buffer, (first_time ? "w" : "a+"))) == NULL) { + if ((fp = fopen(filename_buffer, (first_time ? TXT_W : TXT_A))) == NULL) { LYMBM_statusline(BOOKMARK_OPEN_FAILED); LYSleepAlert(); FREE(Title); diff --git a/src/LYCharUtils.c b/src/LYCharUtils.c index 6bb34184..3a15f269 100644 --- a/src/LYCharUtils.c +++ b/src/LYCharUtils.c @@ -111,8 +111,8 @@ PUBLIC void LYEntify ARGS2( /* * Allocate space and convert. - FM */ - q = (char *)calloc(1, - (strlen(*str) + (4 * amps) + (3 * lts) + (3 * gts) + 1)); + q = typecallocn(char, + (strlen(*str) + (4 * amps) + (3 * lts) + (3 * gts) + 1)); if ((cp = q) == NULL) outofmem(__FILE__, "LYEntify"); for (p = *str; *p; p++) { @@ -3623,11 +3623,10 @@ PUBLIC int LYLegitimizeHREF ARGS4( : me->node_anchor->address[4]) == 's') { str = "s"; } - if (TRACE) { - CTRACE((tfp, "LYLegitimizeHREF: Bad value '%s' for http%s URL.\n", - *href, str);) - CTRACE((tfp, " Stripping lead dots.\n")); - } else if (!me->inBadHREF) { + CTRACE((tfp, "LYLegitimizeHREF: Bad value '%s' for http%s URL.\n", + *href, str)); + CTRACE((tfp, " Stripping lead dots.\n")); + if (!me->inBadHREF) { HTUserMsg(BAD_PARTIAL_REFERENCE); me->inBadHREF = TRUE; } diff --git a/src/LYCookie.c b/src/LYCookie.c index ec9ab39d..df847365 100644 --- a/src/LYCookie.c +++ b/src/LYCookie.c @@ -132,7 +132,7 @@ PRIVATE void MemAllocCopy ARGS3( return; } - temp = (char *)calloc(1, ((end - start) + 1)); + temp = typecallocn(char, (end - start) + 1); if (temp == NULL) outofmem(__FILE__, "MemAllocCopy"); LYstrncpy(temp, start, (end - start)); @@ -1031,7 +1031,7 @@ PRIVATE void LYProcessSetCookies ARGS6( if (value_len > max_cookies_buffer) { value_len = max_cookies_buffer; } - value = (char *)calloc(1, value_len + 1); + value = typecallocn(char, value_len + 1); if (value == NULL) outofmem(__FILE__, "LYProcessSetCookies"); LYstrncpy(value, value_start, value_len); @@ -1551,7 +1551,7 @@ PRIVATE void LYProcessSetCookies ARGS6( if (value_len > max_cookies_buffer) { value_len = max_cookies_buffer; } - value = (char *)calloc(1, value_len + 1); + value = typecallocn(char, value_len + 1); if (value == NULL) outofmem(__FILE__, "LYProcessSetCookies"); LYstrncpy(value, value_start, value_len); diff --git a/src/LYCurses.c b/src/LYCurses.c index fe9642b6..49d48567 100644 --- a/src/LYCurses.c +++ b/src/LYCurses.c @@ -769,7 +769,6 @@ static WINDOW *LYscreen = NULL; PUBLIC void start_curses NOARGS { - int keypad_on = 0; #ifdef USE_SLANG static int slinit; @@ -882,10 +881,10 @@ PUBLIC void start_curses NOARGS signal(SIGINT, cleanup_sig); #endif /* !VMS */ - lynx_enable_mouse (1); + lynx_enable_mouse (1); #else /* USE_SLANG; Now using curses: */ - + int keypad_on = 0; #ifdef VMS /* @@ -1152,6 +1151,56 @@ PUBLIC void lynx_enable_mouse ARGS1(int,state) #endif /* USE_MOUSE */ } +/* + * SVr4 curses (and ncurses) initialize the terminal I/O to raw mode, and + * simulate other modes in the library. This means that when running, it + * simulates the OCRNL setting. Normally that is not a problem. However, when + * spawning a subprocess (e.g., xli), the subprocess may write to the screen. + * Fine so far - curses resets the terminal I/O to the normal state on exit. + * But the subprocess's messages can still be coming to the screen when lynx + * returns to the screen mode. This function delays restoring OCRNL until + * after the first getch() call. + * + * The OCRNL setting is controlled by nl()/nonl() of course - but we do not + * want to give up that optimization since it would be a bit slower. (Note - + * slang does not use this optimization; if it did, the same screen glitch + * would occur). + * + * FIXME: for simplicity, only ncurses is implemented here - the TTY and + * SET_TTY definitions are ncurses-specific. The same effect could be done for + * other curses implementations, since the "cur_term->Nttyb" part is common to + * SVr4 curses. + */ +PUBLIC void lynx_nl2crlf ARGS1(int, normal GCC_UNUSED) +{ + +#if defined(NCURSES_VERSION) && defined(SET_TTY) && defined(TERMIOS) && defined(ONLCR) + static TTY saved_tty; + static int did_save = FALSE; + static int waiting = FALSE; + + if (!did_save) { + saved_tty = cur_term->Nttyb; + did_save = TRUE; + } + if (normal) { + if (!waiting) { + cur_term->Nttyb.c_oflag |= ONLCR; + waiting = TRUE; + nonl(); + } + } else { + if (waiting) { + cur_term->Nttyb = saved_tty; + SET_TTY(fileno(stdout), &saved_tty); + waiting = FALSE; + nl(); + LYrefresh(); + } + } +#endif +} + PUBLIC void stop_curses NOARGS { if (LYCursesON) @@ -1172,6 +1221,7 @@ PUBLIC void stop_curses NOARGS * 05-28-94 Lynx 2-3-1 Garrett Arch Blythe */ if(LYCursesON == TRUE) { + lynx_nl2crlf(TRUE); lynx_enable_mouse (0); #if (!defined(WIN_EX) || defined(__CYGWIN__)) /* @@@ */ if(LYscreen) { @@ -1293,10 +1343,10 @@ PUBLIC BOOLEAN setup ARGS1( char *buffer = NULL; char *cp; - /* - * If the display was not set by a command line option then - * see if it is available from the environment . - */ + /* + * If the display was not set by a command line option then + * see if it is available from the environment . + */ if ((cp = LYgetXDisplay()) != NULL) { StrAllocCopy(x_display, cp); } else { @@ -1350,7 +1400,7 @@ PUBLIC BOOLEAN setup ARGS1( * the current link is indistinguishable from all other links. * The workaround here is to disable the 'rev' capability. */ - if ((strncmp(ttytype, "sun", 3) == 0)) { + if ((strncmp((CONST char *)ttytype, "sun", 3) == 0)) { LYnoVideo(2); } #endif /* HAVE_TTYTYPE */ @@ -2090,6 +2140,19 @@ PUBLIC void LYrefresh NOARGS { #ifdef USE_CURSES_PADS if (LYwin != stdscr) { + /* + * Workaround for special case where lynx is prompting for a mailto, + * and has a subject line that is wider than the screen. The + * wnoutrefresh() call resets newscr's position to match stdscr's, + * which happens to be the window's origin because we were not updating + * that, and other stray wmove's in lynx fail because the coordinate + * is on/after the right margin. Force things to look ok here. + */ + int y, x; + getyx(LYwin, y, x); + if (x >= LYcols) x = LYcols-1; + wmove(stdscr, y, x); + wnoutrefresh(stdscr); pnoutrefresh(LYwin, 0, LYshiftWin, 0, 0, LYlines, LYscreenWidth()-1); doupdate(); @@ -2199,16 +2262,16 @@ PUBLIC void lynx_stop_link_color ARGS2( PUBLIC void lynx_stop_target_color NOARGS { - stop_underline(); - stop_reverse(); - stop_bold(); + stop_underline(); + stop_reverse(); + stop_bold(); } PUBLIC void lynx_start_target_color NOARGS { - start_bold(); - start_reverse(); - start_underline(); + start_bold(); + start_reverse(); + start_underline(); } @@ -2234,41 +2297,41 @@ PUBLIC void lynx_stop_status_color NOARGS PUBLIC void lynx_start_h1_color NOARGS { - if (bold_H1 || bold_headers) - start_bold(); + if (bold_H1 || bold_headers) + start_bold(); } PUBLIC void lynx_stop_h1_color NOARGS { - if (bold_H1 || bold_headers) - stop_bold(); + if (bold_H1 || bold_headers) + stop_bold(); } PUBLIC void lynx_start_prompt_color NOARGS { - start_reverse (); + start_reverse (); } PUBLIC void lynx_stop_prompt_color NOARGS { - stop_reverse (); + stop_reverse (); } PUBLIC void lynx_start_radio_color NOARGS { - start_bold (); + start_bold (); } PUBLIC void lynx_stop_radio_color NOARGS { - stop_bold (); + stop_bold (); } PUBLIC void lynx_stop_all_colors NOARGS { - stop_underline (); - stop_reverse (); - stop_bold (); + stop_underline (); + stop_reverse (); + stop_bold (); } /* diff --git a/src/LYCurses.h b/src/LYCurses.h index c872758e..f4be459f 100644 --- a/src/LYCurses.h +++ b/src/LYCurses.h @@ -66,6 +66,14 @@ typedef struct { #define ACS_DARROW SLSMG_DARROW_CHAR #endif +#ifndef ACS_LARROW +#define ACS_LARROW SLSMG_LARROW_CHAR +#endif + +#ifndef ACS_RARROW +#define ACS_RARROW SLSMG_RARROW_CHAR +#endif + #ifndef ACS_CKBOARD #define ACS_CKBOARD SLSMG_CKBRD_CHAR #endif @@ -542,6 +550,7 @@ FANCY_CURSES. Check your config.log to see why the FANCY_CURSES test failed. extern void lynx_enable_mouse PARAMS((int)); extern void lynx_force_repaint NOPARAMS; +extern void lynx_nl2crlf PARAMS((int normal)); extern void lynx_start_title_color NOPARAMS; extern void lynx_stop_title_color NOPARAMS; extern void lynx_start_link_color PARAMS((int flag, int pending)); diff --git a/src/LYDownload.c b/src/LYDownload.c index 839af32b..03a9ea5f 100644 --- a/src/LYDownload.c +++ b/src/LYDownload.c @@ -34,7 +34,7 @@ PUBLIC void LYDownload ARGS1( char buffer[LY_MAXPATH]; char command[LY_MAXPATH]; char *cp; - lynx_html_item_type *download_command = 0; + lynx_list_item_type *download_command = 0; int ch, recall; int FnameTotal; int FnameNum; @@ -62,7 +62,7 @@ PUBLIC void LYDownload ARGS1( /* * Parse out the File, sug_file, and the Method. */ - if ((file = (char *)strstr(Line, "/File=")) == NULL) + if ((file = strstr(Line, "/File=")) == NULL) goto failed; *file = '\0'; /* @@ -70,7 +70,7 @@ PUBLIC void LYDownload ARGS1( */ file += 6; - if ((sug_file = (char *)strstr(file + 1, "/SugFile=")) != NULL) { + if ((sug_file = strstr(file + 1, "/SugFile=")) != NULL) { *sug_file = '\0'; /* * Go past "SugFile=". @@ -110,7 +110,7 @@ PUBLIC void LYDownload ARGS1( #endif /* _WINDOWS */ #endif /* DIRED_SUPPORT */ - if ((method = (char *)strstr(Line, "Method=")) == NULL) + if ((method = strstr(Line, "Method=")) == NULL) goto failed; /* * Go past "Method=". @@ -485,7 +485,7 @@ PUBLIC int LYdownload_options ARGS2( char *downloaded_url = NULL; char *sug_filename = NULL; FILE *fp0; - lynx_html_item_type *cur_download; + lynx_list_item_type *cur_download; int count; /* @@ -495,10 +495,10 @@ PUBLIC int LYdownload_options ARGS2( change_sug_filename(sug_filename); if (LYReuseTempfiles) { - fp0 = LYOpenTempRewrite(tempfile, HTML_SUFFIX, "wb"); + fp0 = LYOpenTempRewrite(tempfile, HTML_SUFFIX, BIN_W); } else { LYRemoveTemp(tempfile); - fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, "wb"); + fp0 = LYOpenTemp(tempfile, HTML_SUFFIX, BIN_W); } if (fp0 == NULL) { HTAlert(CANNOT_OPEN_TEMP); diff --git a/src/LYEdit.c b/src/LYEdit.c index 37b182db..453cab0b 100644 --- a/src/LYEdit.c +++ b/src/LYEdit.c @@ -129,7 +129,7 @@ PUBLIC int edit_current_file ARGS3( /* * Don't allow editing if user lacks append access. */ - if ((fp = fopen(filename, "a")) == NULL) + if ((fp = fopen(filename, TXT_A)) == NULL) { HTUserMsg(NOAUTH_TO_EDIT_FILE); goto done; diff --git a/src/LYExtern.c b/src/LYExtern.c index 8cecb422..4f341bb7 100644 --- a/src/LYExtern.c +++ b/src/LYExtern.c @@ -24,9 +24,9 @@ #include <LYExtern.h> #include <LYLeaks.h> #include <LYCurses.h> +#include <LYReadCFG.h> #include <LYStrings.h> - #ifdef WIN_EX /* 1997/10/15 (Wed) 17:39:50 */ @@ -126,254 +126,297 @@ PUBLIC char * quote_pathname ARGS1( } #endif /* WIN_EX */ -#if 0 /* old version */ -void run_external_ ARGS1(char *, cmd) + +PRIVATE void format ARGS3( + char **, result, + char *, fmt, + char *, parm) { - char *the_command = 0; - lynx_html_item_type *ext = 0; + *result = NULL; + HTAddParam(result, fmt, 1, parm); + HTEndParam(result, fmt, 1); +} - for (ext = externals; ext != NULL; ext = ext->next) { +/* + * Format the given command into a buffer, returning the resulting string. + * + * It is too dangerous to leave any URL that may come along unquoted. They + * often contain '&', ';', and '?' chars, and who knows what else may occur. + * Prevent spoofing of the shell. Dunno how this needs to be modified for VMS + * or DOS. - kw + */ +PRIVATE char *format_command ARGS2( + char *, command, + char *, param) +{ +#ifdef WIN_EX + char pram_string[PATH_MAX]; +#endif + char *cmdbuf = NULL; - if (ext->command != 0 - && !strncasecomp(ext->name, cmd, strlen(ext->name))) { +#if (defined(VMS) || defined(DOSPATH) || defined(__EMX__)) && !defined(WIN_EX) + format(&cmdbuf, command, param); +#else /* Unix or DOS/Win: */ +#if defined(WIN_EX) + if (*param != '\"' && strchr(param, ' ') != NULL) { + char *cp = quote_pathname(param); + format(&cmdbuf, command, cp); + FREE(cp); + } else { + LYstrncpy(pram_string, param, sizeof(pram_string)-1); + decode_string(pram_string); + param = pram_string; + + if (strnicmp("mailto:", param, 7) == 0) { + format(&cmdbuf, command, param + 7); + } else if (strnicmp("telnet://", param, 9) == 0) { + char host[sizeof(pram_string)]; + int last_pos; + + strcpy(host, param + 9); + last_pos = strlen(host) - 1; + if (last_pos > 1 && host[last_pos] == '/') + host[last_pos] = '\0'; + + format(&cmdbuf, command, host); + } else if (strnicmp("file://localhost/", param, 17) == 0) { + char e_buff[PATH_MAX], *p; + + p = param + 17; + *e_buff = 0; + if (strchr(p, ':') == NULL) { + sprintf(e_buff, "%.3s/", windows_drive); + } + strncat(e_buff, p, sizeof(e_buff) - strlen(e_buff) - 1); + p = strrchr(e_buff, '.'); + if (p) { + p = strchr(p, '#'); + if (p) { + *p = '\0'; + } + } + if (*e_buff != '\"' && strchr(e_buff, ' ') != NULL) { + p = quote_pathname(e_buff); + LYstrncpy(e_buff, p, sizeof(e_buff)-1); + FREE(p); + } - if (no_externals && !ext->always_enabled) { - HTUserMsg(EXTERNALS_DISABLED); + /* Less ==> short filename, + * less ==> long filename + */ + if (isupper(command[0])) { + format(&cmdbuf, + command, HTDOS_short_name(e_buff)); } else { - - HTAddParam(&the_command, ext->command, 1, cmd); - HTEndParam(&the_command, ext->command, 1); - - HTUserMsg(the_command); - - stop_curses(); - LYSystem(the_command); - FREE(the_command); - start_curses(); + format(&cmdbuf, command, e_buff); } - - break; + } else { + format(&cmdbuf, command, param); } } - - return; -} +#else /* Unix */ + { + format(&cmdbuf, command, param); + } #endif +#endif /* VMS */ + return cmdbuf; +} -PRIVATE void format ARGS3( - char **, result, - char *, fmt, - char *, parm) +/* + * Find the EXTERNAL command which matches the given name 'param'. If there is + * more than one possibility, make a popup menu of the matching commands and + * allow the user to select one. Return the selected command. + */ +PRIVATE char *lookup_external ARGS2( + char *, param, + BOOL, only_overriders) { - *result = NULL; - HTAddParam(result, fmt, 1, parm); - HTEndParam(result, fmt, 1); + int pass, num_disabled, num_matched, num_choices, cur_choice; + int length = 0; + char *cmdbuf = NULL; + char **choices = 0; + lynx_list_item_type *ptr = 0; + + for (pass = 0; pass < 2; pass++) { + num_disabled = 0; + num_matched = 0; + num_choices = 0; + for (ptr = externals; ptr != 0; ptr = ptr->next) { + + if (match_item_by_name(ptr, param, only_overriders)) { + ++num_matched; + CTRACE((tfp, "EXTERNAL: '%s' <==> '%s'\n", ptr->name, param)); + if (no_externals && !ptr->always_enabled && !only_overriders) { + ++num_disabled; + } else { + if (pass == 0) { + length++; + } else if (pass != 0) { + cmdbuf = format_command(ptr->command, param); + if (length > 1) + choices[num_choices] = cmdbuf; + } + num_choices++; + } + } + } + if (length > 1) { + if (pass == 0) { + choices = typecallocn(char *, length + 1); + } else { + choices[num_choices] = 0; + } + } + } + + if (num_disabled != 0 + && num_disabled == num_matched) { + HTUserMsg(EXTERNALS_DISABLED); + } else if (num_choices > 1) { + int old_y, old_x; +#ifdef USE_SLANG + old_y = SLsmg_get_row(); + old_x = SLsmg_get_column(); +#else + getyx(LYwin, old_y, old_x); +#endif + cur_choice = LYhandlePopupList( + -1, + 0, + old_x, + (CONST char **)choices, + -1, + -1, + FALSE, + TRUE, + FALSE); +#ifdef USE_SLANG + SLsmg_gotorc(old_y, old_x); +#else + wmove(LYwin, old_y, old_x); +#endif + CTRACE((tfp, "selected choice %d of %d\n", cur_choice, num_choices)); + if (cur_choice < 0) { + HTInfoMsg(CANCELLED); + cmdbuf = 0; + } + for (pass = 0; choices[pass] != 0; pass++) { + if (pass == cur_choice) { + cmdbuf = choices[pass]; + } else { + FREE(choices[pass]); + } + } + FREE(choices); + } + return cmdbuf; } BOOL run_external ARGS2( - char *, c, + char *, param, BOOL, only_overriders) { #ifdef WIN_EX - HANDLE handle; int status; - int confirmed; - char pram_string[PATH_MAX]; - int redraw_flag; extern int xsystem(char *cmd); #endif + int redraw_flag = TRUE; char *cmdbuf = NULL; - lynx_html_item_type *externals2 = 0; int found = 0; + int confirmed = TRUE; if (externals == NULL) return 0; #ifdef WIN_EX /* 1998/01/26 (Mon) 09:16:13 */ - if (c == NULL) { + if (param == NULL) { HTInfoMsg("External command is null"); return 0; } #endif - for (externals2 = externals; externals2 != NULL; - externals2 = externals2->next) { - -#ifdef WIN_EX - handle = GetForegroundWindow(); - CTRACE((tfp, "EXTERNAL: '%s' <==> '%s'\n", externals2->name, c)); -#endif - if (externals2->command != 0 - && !strncasecomp(externals2->name, c, strlen(externals2->name)) - && (only_overriders ? externals2->override_primary_action : 1)) - { - if (no_externals && !externals2->always_enabled && !only_overriders) { - HTUserMsg(EXTERNALS_DISABLED); - break; - } - ++found; - /* Too dangerous to leave any URL that may come along unquoted. - * They often contain '&', ';', and '?' chars, and who knows - * what else may occur. - * Prevent spoofing of the shell. - * Dunno how this needs to be modified for VMS or DOS. - kw - */ -#if (defined(VMS) || defined(DOSPATH) || defined(__EMX__)) && !defined(WIN_EX) - format(&cmdbuf, externals2->command, c); -#else /* Unix or DOS/Win: */ -#if defined(WIN_EX) - if (*c != '\"' && strchr(c, ' ') != NULL) { - char *cp = quote_pathname(c); - format(&cmdbuf, externals2->command, cp); - FREE(cp); - } else { - LYstrncpy(pram_string, c, sizeof(pram_string)-1); - decode_string(pram_string); - c = pram_string; - - if (strnicmp("mailto:", c, 7) == 0) { - format(&cmdbuf, externals2->command, c + 7); - } else if (strnicmp("telnet://", c, 9) == 0) { - char host[sizeof(pram_string)]; - int last_pos; - - strcpy(host, c + 9); - last_pos = strlen(host) - 1; - if (last_pos > 1 && host[last_pos] == '/') - host[last_pos] = '\0'; - - format(&cmdbuf, externals2->command, host); - } else if (strnicmp("file://localhost/", c, 17) == 0) { - char e_buff[PATH_MAX], *p; - - p = c + 17; - *e_buff = 0; - if (strchr(p, ':') == NULL) { - sprintf(e_buff, "%.3s/", windows_drive); - } - strncat(e_buff, p, sizeof(e_buff) - strlen(e_buff) - 1); - p = strrchr(e_buff, '.'); - if (p) { - p = strchr(p, '#'); - if (p) { - *p = '\0'; - } - } - if (*e_buff != '\"' && strchr(e_buff, ' ') != NULL) { - p = quote_pathname(e_buff); - LYstrncpy(e_buff, p, sizeof(e_buff)-1); - FREE(p); - } - - /* Less ==> short filename, - * less ==> long filename - */ - if (isupper(externals2->command[0])) { - format(&cmdbuf, - externals2->command, HTDOS_short_name(e_buff)); - } else { - format(&cmdbuf, externals2->command, e_buff); - } - } else { - format(&cmdbuf, externals2->command, c); - } - } -#else /* Unix */ - { - format(&cmdbuf, externals2->command, c); - } -#endif -#endif /* VMS */ - - if (cmdbuf != 0 && *cmdbuf != '\0') { + cmdbuf = lookup_external(param, only_overriders); + if (cmdbuf != 0 && *cmdbuf != '\0') { #ifdef WIN_EX /* 1997/10/17 (Fri) 14:07:50 */ - int len; - char buff[PATH_MAX]; + int len; + char buff[PATH_MAX]; - CTRACE((tfp, "Lynx EXTERNAL: '%s'\n", cmdbuf)); + CTRACE((tfp, "Lynx EXTERNAL: '%s'\n", cmdbuf)); #ifdef WIN_GUI /* 1997/11/06 (Thu) 14:17:15 */ - confirmed = MessageBox(handle, cmdbuf, - "Lynx (EXTERNAL COMMAND EXEC)", - MB_ICONQUESTION | MB_SETFOREGROUND | MB_OKCANCEL) - == IDCANCEL; + confirmed = MessageBox(GetForegroundWindow(), cmdbuf, + "Lynx (EXTERNAL COMMAND EXEC)", + MB_ICONQUESTION | MB_SETFOREGROUND | MB_OKCANCEL) + != IDCANCEL; #else - confirmed = HTConfirm(string_short(cmdbuf, 40)) == NO; + confirmed = HTConfirm(string_short(cmdbuf, 40)) != NO; #endif - if (confirmed) - break; - - len = strlen(cmdbuf); - if (len > 255) { - sprintf(buff, "Lynx: command line too long (%d > 255)", len); + if (confirmed) { + len = strlen(cmdbuf); + if (len > 255) { + sprintf(buff, "Lynx: command line too long (%d > 255)", len); #ifdef WIN_GUI /* 1997/11/06 (Thu) 14:17:02 */ - MessageBox(handle, buff, - "Lynx (EXTERNAL COMMAND EXEC)", - MB_ICONEXCLAMATION | MB_SETFOREGROUND | MB_OK); - SetConsoleTitle("Lynx for Win32"); + MessageBox(GetForegroundWindow(), buff, + "Lynx (EXTERNAL COMMAND EXEC)", + MB_ICONEXCLAMATION | MB_SETFOREGROUND | MB_OK); + SetConsoleTitle("Lynx for Win32"); #else - HTConfirm(string_short(buff, 40)); + HTConfirm(string_short(buff, 40)); #endif - break; - } else { - SetConsoleTitle(cmdbuf); - } - - if (strnicmp(cmdbuf, "start ", 6) == 0) - redraw_flag = FALSE; - else - redraw_flag = TRUE; + confirmed = FALSE; + } else { + SetConsoleTitle(cmdbuf); + } + } - if (redraw_flag) { - stop_curses(); - fflush(stdout); - } + if (strnicmp(cmdbuf, "start ", 6) == 0) + redraw_flag = FALSE; + else + redraw_flag = TRUE; #else - HTUserMsg(cmdbuf); - stop_curses(); + HTUserMsg(cmdbuf); #endif + found = TRUE; + if (confirmed) { + if (redraw_flag) { + stop_curses(); + fflush(stdout); + } - /* command running. */ + /* command running. */ #ifdef WIN_EX /* 1997/10/17 (Fri) 14:07:50 */ #ifdef __CYGWIN__ - status = system(cmdbuf); + status = system(cmdbuf); #else - status = xsystem(cmdbuf); + status = xsystem(cmdbuf); #endif - if (status != 0) { - sprintf(buff, - "EXEC code = %04x (%2d, %2d)\r\n" - "'%s'", - status, (status / 256), (status & 0xff), - cmdbuf); + if (status != 0) { + sprintf(buff, + "EXEC code = %04x (%2d, %2d)\r\n" + "'%s'", + status, (status / 256), (status & 0xff), + cmdbuf); #ifdef SH_EX /* WIN_GUI for ERROR only */ - MessageBox(handle, buff, - "Lynx (EXTERNAL COMMAND EXEC)", - MB_ICONSTOP | MB_SETFOREGROUND | MB_OK); + MessageBox(GetForegroundWindow(), buff, + "Lynx (EXTERNAL COMMAND EXEC)", + MB_ICONSTOP | MB_SETFOREGROUND | MB_OK); #else - HTConfirm(string_short(buff, 40)); -#endif /* 1 */ - } + HTConfirm(string_short(buff, 40)); +#endif /* 1 */ + } #else /* Not WIN_EX */ - LYSystem(cmdbuf); + LYSystem(cmdbuf); #endif /* WIN_EX */ #if defined(WIN_EX) - SetConsoleTitle("Lynx for Win32"); + SetConsoleTitle("Lynx for Win32"); #endif - -#ifdef WIN_EX - if (redraw_flag) { - fflush(stdout); - start_curses(); - } -#else + if (redraw_flag) { fflush(stdout); start_curses(); -#endif } - break; - } /* end if */ - } /* end-for */ + } + } FREE(cmdbuf); return found; diff --git a/src/LYForms.c b/src/LYForms.c index cc5ccf1e..cdf84fc6 100644 --- a/src/LYForms.c +++ b/src/LYForms.c @@ -232,9 +232,9 @@ PUBLIC int change_form_link_ex ARGS8( if (form->disabled == YES && (c == '\r' || c == '\n' || immediate_submit)) { if (peek_mouse_link() >= 0) - c = lookup_keymap(LYK_ACTIVATE); + c = LAC_TO_LKC0(LYK_ACTIVATE); else - c = '\t'; + c = '\t'; break; } /* diff --git a/src/LYGlobalDefs.h b/src/LYGlobalDefs.h index 3f754c7c..c7cdd705 100644 --- a/src/LYGlobalDefs.h +++ b/src/LYGlobalDefs.h @@ -15,7 +15,7 @@ be removed (at least): CURRENT_KEYMAP_HELP */ -#ifdef HAVE_CONFIG_H +#if defined(HAVE_CONFIG_H) && defined(HAVE_LYHELP_H) #include <LYHelp.h> #else #define ALT_EDIT_HELP "keystrokes/alt_edit_help.html" @@ -446,10 +446,10 @@ extern BOOLEAN with_backspaces; #endif #ifndef NO_LYNX_TRACE -extern BOOLEAN LYUseTraceLog; /* Use a TRACE log? */ extern FILE *LYTraceLogFP; /* Pointer for TRACE log */ extern char *LYTraceLogPath; /* Path for TRACE log */ #endif +extern BOOLEAN LYUseTraceLog; /* Use a TRACE log? */ extern BOOL force_empty_hrefless_a; extern int connect_timeout; diff --git a/src/LYHash.h b/src/LYHash.h index b6453fc8..72039a04 100644 --- a/src/LYHash.h +++ b/src/LYHash.h @@ -41,6 +41,7 @@ extern int s_aedit_sel; extern int s_alert; extern int s_alink; extern int s_curedit; +extern int s_forw_backw; extern int s_normal; extern int s_prompt_edit; extern int s_prompt_edit_arr; diff --git a/src/LYHistory.c b/src/LYHistory.c index 31d39c92..26ac340b 100644 --- a/src/LYHistory.c +++ b/src/LYHistory.c @@ -38,7 +38,7 @@ PRIVATE VisitedLink *Latest_tree; PRIVATE VisitedLink *First_tree; PRIVATE VisitedLink *Last_by_first; -PRIVATE int nhist_extra; +int nhist_extra; #ifdef LY_FIND_LEAKS /* diff --git a/src/LYHistory.h b/src/LYHistory.h index fecb67f9..5d061a24 100644 --- a/src/LYHistory.h +++ b/src/LYHistory.h @@ -20,4 +20,6 @@ extern void LYstatusline_messages_on_exit PARAMS((char **buf)); extern void LYstore_message PARAMS((CONST char *message)); extern void LYstore_message2 PARAMS((CONST char *message, CONST char *argument)); +extern int nhist_extra; + #endif /* LYHISTORY_H */ diff --git a/src/LYJump.c b/src/LYJump.c index b198f3df..6f426153 100644 --- a/src/LYJump.c +++ b/src/LYJump.c @@ -378,7 +378,7 @@ PRIVATE unsigned LYRead_Jumpfile ARGS1(struct JumpTable *,jtp) } /* allocate storage to read entire file */ - if ((mp=(char *)calloc(1, st.st_size + 1)) == NULL) { + if ((mp= typecallocn(char, st.st_size + 1)) == NULL) { HTAlert(OUTOF_MEM_FOR_JUMP_FILE); return 0; } @@ -387,7 +387,7 @@ PRIVATE unsigned LYRead_Jumpfile ARGS1(struct JumpTable *,jtp) if (st.st_fab_rfm != (char)FAB$C_STMLF) { /** It's a record-oriented file. **/ IsStream_LF = FALSE; - if ((fp = fopen(jtp->file, "r", "mbc=32")) == NULL) { + if ((fp = fopen(jtp->file, TXT_R, "mbc=32")) == NULL) { HTAlert(CANNOT_OPEN_JUMP_FILE); FREE(mp); return 0; diff --git a/src/LYKeymap.c b/src/LYKeymap.c index 75549f98..8f20e7e3 100644 --- a/src/LYKeymap.c +++ b/src/LYKeymap.c @@ -104,7 +104,7 @@ LYK_LAST_LINK, 0, 0, LYK_HISTORICAL, LYK_UP_HALF, LYK_DOWN_HALF, LYK_IMAGE_TOGGLE, LYK_NEXT_PAGE, /* ( */ /* ) */ /* * */ /* + */ -LYK_NEXT_PAGE, LYK_PREV_PAGE, LYK_EXTERN, LYK_WHEREIS, +LYK_EXTERN_PAGE, LYK_PREV_PAGE, LYK_EXTERN_LINK, LYK_WHEREIS, /* , */ /* - */ /* . */ /* / */ LYK_F_LINK_NUM, LYK_1, LYK_2, LYK_3, @@ -898,8 +898,11 @@ PRIVATE Kcmd revmap[] = { #endif #ifdef USE_EXTERNALS DATA( - LYK_EXTERN, "EXTERN", - "run external program with url" ), + LYK_EXTERN_LINK, "EXTERN_LINK", + "run external program with current link" ), + DATA( + LYK_EXTERN_PAGE, "EXTERN_PAGE", + "run external program with current page" ), #endif #ifdef VMS DATA( @@ -1319,7 +1322,7 @@ PUBLIC int lacname_to_lac ARGS1( { Kcmd *mp = LYStringToKcmd(func); - return (mp != 0) ? mp->code : -1; + return (mp != 0) ? (int) mp->code : -1; } /* @@ -1488,7 +1491,7 @@ PUBLIC int remap ARGS3( else #endif keymap[c+1] = mp->code; - return (c ? c : LAC_TO_LKC0(mp->code)); /* don't return 0, successful */ + return (c ? c : (int) LAC_TO_LKC0(mp->code)); /* don't return 0, successful */ } return 0; } @@ -1614,19 +1617,6 @@ PUBLIC void reset_numbers_as_arrows NOARGS did_number_keys = FALSE; } -PUBLIC int lookup_keymap ARGS1( - int, func) -{ - size_t i; - - for (i = 1; i < KEYMAP_SIZE; i++) { - if (LYisNonAlnumKeyname(i, func)) { - return i; - } - } - return -1; -} - PUBLIC char *key_for_func ARGS1 ( int, func) { diff --git a/src/LYKeymap.h b/src/LYKeymap.h index 8d783f7f..166df535 100644 --- a/src/LYKeymap.h +++ b/src/LYKeymap.h @@ -16,7 +16,6 @@ extern int LYStringToKeycode PARAMS((char *src)); extern int lacname_to_lac PARAMS((CONST char *func)); extern int lecname_to_lec PARAMS((CONST char *func)); extern int lkcstring_to_lkc PARAMS((CONST char *src)); -extern int lookup_keymap PARAMS((int code)); extern int remap PARAMS((char *key, char *func, BOOLEAN for_dired)); extern void print_keymap PARAMS((char **newfile)); extern void reset_emacs_keys NOPARAMS; @@ -213,9 +212,11 @@ typedef enum { #endif #ifdef USE_EXTERNALS - , LYK_EXTERN + , LYK_EXTERN_LINK + , LYK_EXTERN_PAGE #else -#define LYK_EXTERN LYK_UNKNOWN +#define LYK_EXTERN_LINK LYK_UNKNOWN +#define LYK_EXTERN_PAGE LYK_UNKNOWN #endif /* !defined(USE_EXTERNALS) */ #if defined(VMS) || defined(DIRED_SUPPORT) diff --git a/src/LYLeaks.c b/src/LYLeaks.c index 87a11666..6f188ebe 100644 --- a/src/LYLeaks.c +++ b/src/LYLeaks.c @@ -209,8 +209,7 @@ PUBLIC void *LYLeakMalloc ARGS3( * Further allocate memory to store the information. * Just return on failure to allocate more. */ - AllocationList *ALp_new = - (AllocationList *)calloc(1, sizeof(AllocationList)); + AllocationList *ALp_new = typecalloc(AllocationList); if (ALp_new == NULL) { return(vp_malloc); @@ -242,7 +241,7 @@ PUBLIC void *LYLeakMalloc ARGS3( ** Arguments: vp_malloc The pointer to newly allocate memory. ** Arguments: st_bytes The size of the allocation requested ** in bytes. -** cp_File The file from which the request for +** cp_File The file from which the request for ** allocation came from. ** ssi_Line The line number in cp_File where the ** allocation request came from. @@ -256,7 +255,7 @@ PUBLIC void *LYLeakMalloc ARGS3( */ PUBLIC AllocationList *LYLeak_mark_malloced ARGS4( void *, vp_malloced, - size_t, st_bytes, + size_t, st_bytes, CONST char *, cp_File, CONST short, ssi_Line) { @@ -276,12 +275,12 @@ PUBLIC AllocationList *LYLeak_mark_malloced ARGS4( ALp_new->SL_memory.cp_FileName = cp_File; ALp_new->SL_memory.ssi_LineNumber = ssi_Line; return(ALp_new); - } + } /* * Further allocate memory to store the information. * Just return on failure to allocate more. */ - ALp_new = (AllocationList *)calloc(1, sizeof(AllocationList)); + ALp_new = typecalloc(AllocationList); if (ALp_new == NULL) { return(NULL); @@ -338,8 +337,7 @@ PUBLIC void *LYLeakCalloc ARGS4( * Allocate memory for the item to be in the list. * If unable, just return. */ - AllocationList *ALp_new = - (AllocationList *)calloc(1, sizeof(AllocationList)); + AllocationList *ALp_new = typecalloc(AllocationList); if (ALp_new == NULL) { return(vp_calloc); @@ -413,9 +411,7 @@ PUBLIC void *LYLeakRealloc ARGS4( * Track the invalid pointer value and then exit. * If unable to allocate, just exit. */ - auto AllocationList *ALp_new = - (AllocationList *)calloc(1, - sizeof(AllocationList)); + auto AllocationList *ALp_new = typecalloc(AllocationList); if (ALp_new == NULL) { exit(EXIT_FAILURE); @@ -463,15 +459,15 @@ PUBLIC void *LYLeakRealloc ARGS4( ** after a call to realloc or an equivalent ** function which has not already created or updated ** a list entry. -** Arguments: ALp_old List entry for previously allocated +** Arguments: ALp_old List entry for previously allocated ** block of memory to resize. If NULL, ** mark_realloced works just like ** mark_malloced. ** vp_realloced The new pointer, after resizing. ** st_newBytes The new size of the chunk of memory. -** cp_File The file to record. +** cp_File The file to record. ** ssi_Line The line to record. -** Return Value: Pointer to new or updated list entry +** Return Value: Pointer to new or updated list entry ** for this memory block. ** NULL on allocation error. ** Revision History: @@ -480,8 +476,8 @@ PUBLIC void *LYLeakRealloc ARGS4( #if defined(LY_FIND_LEAKS) && defined(LY_FIND_LEAKS_EXTENDED) PRIVATE AllocationList *mark_realloced ARGS5( AllocationList *, ALp_old, - void *, vp_realloced, - size_t, st_newBytes, + void *, vp_realloced, + size_t, st_newBytes, CONST char *, cp_File, CONST short, ssi_Line) { @@ -546,9 +542,7 @@ PUBLIC void LYLeakFree ARGS3( * Create the final entry before exiting marking this error. * If unable to allocate more memory just exit. */ - AllocationList *ALp_new = - (AllocationList *)calloc(1, - sizeof(AllocationList)); + AllocationList *ALp_new = typecalloc(AllocationList); if (ALp_new == NULL) { exit(EXIT_FAILURE); @@ -701,7 +695,7 @@ PRIVATE char * LYLeakSAVsprintf ARGS6( { AllocationList *ALp_old; void *vp_oldAlloced; - + CONST char * old_cp_File = __FILE__; short old_ssi_Line = __LINE__; @@ -721,9 +715,7 @@ PRIVATE char * LYLeakSAVsprintf ARGS6( * Track the invalid pointer value and then exit. * If unable to allocate, just exit. */ - auto AllocationList *ALp_new = - (AllocationList *)calloc(1, - sizeof(AllocationList)); + auto AllocationList *ALp_new = typecalloc(AllocationList); if (ALp_new == NULL) { exit(EXIT_FAILURE); diff --git a/src/LYLocal.c b/src/LYLocal.c index 175c8ef9..ae5e5701 100644 --- a/src/LYLocal.c +++ b/src/LYLocal.c @@ -69,7 +69,7 @@ PRIVATE int LYExecv PARAMS(( char * path, - char ** argv, + char ** argv, char * msg)); #ifdef DIRED_SUPPORT @@ -91,7 +91,7 @@ PRIVATE char *get_filename PARAMS(( PRIVATE BOOLEAN permit_location PARAMS(( char * destpath, char * srcpath, - char ** newpath)); + char ** newpath)); #endif /* OK_PERMIT */ PRIVATE char *render_item PARAMS(( @@ -100,7 +100,7 @@ PRIVATE char *render_item PARAMS(( CONST char * dir, char * buf, int bufsize, - BOOLEAN url_syntax)); + BOOLEAN url_syntax)); PRIVATE struct dired_menu *menu_head = NULL; struct dired_menu { @@ -240,7 +240,7 @@ struct dired_menu { #ifdef OK_GZIP { DE_FILE, "", "Compress", - "(using gzip)", "LYNXDIRED://GZIP%p", NULL }, + "(using gzip)", "LYNXDIRED://GZIP%p", NULL }, #endif /* OK_GZIP */ #ifdef OK_ZIP @@ -263,7 +263,7 @@ struct dired_menu { "", "LYNXDIRED://CLEAR_TAGGED", NULL }, { 0, NULL, NULL, - NULL, NULL, NULL } + NULL, NULL, NULL } }; PRIVATE BOOLEAN cannot_stat ARGS1(CONST char *, name) @@ -451,7 +451,7 @@ PRIVATE BOOLEAN remove_tagged NOARGS * uid with Lynx & dired can do the same thing. */ PRIVATE BOOLEAN modify_tagged ARGS1( - char *, testpath) + char *, testpath) { char *cp; dev_t dev; @@ -607,7 +607,7 @@ PRIVATE BOOLEAN modify_tagged ARGS1( * Modify the name of the specified item. */ PRIVATE BOOLEAN modify_name ARGS1( - char *, testpath) + char *, testpath) { char *cp; char tmpbuf[DIRED_MAXBUF]; @@ -662,7 +662,7 @@ PRIVATE BOOLEAN modify_name ARGS1( * Change the location of a file or directory. */ PRIVATE BOOLEAN modify_location ARGS1( - char *, testpath) + char *, testpath) { char *cp; dev_t dev; @@ -822,7 +822,7 @@ PUBLIC BOOLEAN local_modify ARGS2( * Create a new empty file in the current directory. */ PRIVATE BOOLEAN create_file ARGS1( - char *, current_location) + char *, current_location) { int code = FALSE; char tmpbuf[DIRED_MAXBUF]; @@ -871,7 +871,7 @@ PRIVATE BOOLEAN create_file ARGS1( * Create a new directory in the current directory. */ PRIVATE BOOLEAN create_directory ARGS1( - char *, current_location) + char *, current_location) { int code = FALSE; char tmpbuf[DIRED_MAXBUF]; @@ -947,7 +947,7 @@ PUBLIC BOOLEAN local_create ARGS1( * Remove a single file or directory. */ PRIVATE BOOLEAN remove_single ARGS1( - char *, testpath) + char *, testpath) { int code = 0; char *cp; @@ -1079,8 +1079,8 @@ PRIVATE char LYValidPermitFile[LY_MAXPATH] = "\0"; * Handle DIRED permissions. */ PRIVATE BOOLEAN permit_location ARGS3( - char *, destpath, - char *, srcpath, + char *, destpath, + char *, srcpath, char **, newpath) { #ifndef UNIX @@ -1479,7 +1479,7 @@ PUBLIC int local_dired ARGS1( StrAllocCopy(line, line_url); HTUnEscape(line); /* _file_ (not URL) syntax, for those functions that need it. Don't forget to FREE it. */ - if ((arg = match_op("CHDIR", line)) != 0) { + if ((arg = match_op("CHDIR", line)) != 0) { #ifdef SUPPORT_CHDIR handle_LYK_CHDIR(); do_pop_doc = FALSE; @@ -1717,7 +1717,7 @@ PUBLIC int dired_options ARGS2( static char tempfile[LY_MAXPATH]; char *path; char *dir; - lynx_html_item_type *nxt; + lynx_list_item_type *nxt; struct stat dir_info; FILE *fp0; char *dir_url; @@ -1870,9 +1870,9 @@ PUBLIC int dired_options ARGS2( * Check DIRED filename. */ PRIVATE char *get_filename ARGS3( - char *, prompt, - char *, buf, - size_t, bufsize) + char *, prompt, + char *, buf, + size_t, bufsize) { char *cp; @@ -1904,7 +1904,7 @@ PRIVATE char *get_filename ARGS3( #define LYEXECV_MAX_ARGC 15 /* these are quasi-constant once they have been allocated: */ static char ** install_argp = NULL; /* args for execv install */ -static char * install_path = NULL; /* auxiliary */ +static char * install_path = NULL; /* auxiliary */ #ifdef LY_FIND_LEAKS PRIVATE void clear_install_path NOARGS { @@ -1936,7 +1936,7 @@ PRIVATE int fill_argv_for_execv ARGS5( char **args; char *cp; if (*argvp == NULL) { - *argvp = (char **)calloc(LYEXECV_MAX_ARGC+1, sizeof(char *)); + *argvp = typecallocn(char *, LYEXECV_MAX_ARGC+1); if (!*argvp) return(-1); #ifdef LY_FIND_LEAKS @@ -1969,8 +1969,8 @@ PRIVATE int fill_argv_for_execv ARGS5( * Install the specified file or directory. */ PUBLIC BOOLEAN local_install ARGS3( - char *, destpath, - char *, srcpath, + char *, destpath, + char *, srcpath, char **, newpath) { char *tmpbuf = NULL; @@ -2159,7 +2159,7 @@ PUBLIC void clear_tags NOARGS * Handle DIRED menu item. */ PUBLIC void add_menu_item ARGS1( - char *, str) + char *, str) { struct dired_menu *new, *mp; char *cp; @@ -2171,7 +2171,7 @@ PUBLIC void add_menu_item ARGS1( if (menu_head == defmenu) menu_head = NULL; - new = (struct dired_menu *)calloc(1, sizeof(*new)); + new = typecalloc(struct dired_menu); if (new == NULL) outofmem(__FILE__, "add_menu_item"); @@ -2240,10 +2240,10 @@ PUBLIC void reset_dired_menu NOARGS * Create URL for DIRED HREF value. */ PRIVATE char * render_item ARGS6( - CONST char *, s, - CONST char *, path, - CONST char *, dir, - char *, buf, + CONST char *, s, + CONST char *, path, + CONST char *, dir, + char *, buf, int, bufsize, BOOLEAN, url_syntax) { @@ -2338,18 +2338,18 @@ PRIVATE char * render_item ARGS6( * Execute DIRED command, return -1 or 0 on failure, 1 success. */ PRIVATE int LYExecv ARGS3( - char *, path, + char *, path, char **, argv, - char *, msg) + char *, msg) { + int rc = 0; #if defined(VMS) CTRACE((tfp, "LYExecv: Called inappropriately!\n")); - return(0); #else #if defined(_WINDOWS) if (!strcmp(path, TOUCH_PATH)) { -#if defined(__BORLANDC__) || defined(__MINGW32__) - int fd = _creat(argv[1], S_IREAD | S_IWRITE); +#if defined(__BORLANDC__) || defined(__MINGW32__) + int fd = _creat(argv[1], S_IREAD | S_IWRITE); #else /* Visual C++ */ int fd = _creat(argv[1], _S_IREAD | _S_IWRITE); #endif @@ -2358,12 +2358,11 @@ PRIVATE int LYExecv ARGS3( return(1); } } else if (!strcmp(path, RM_PATH)) { - return remove(argv[2]); + rc = remove(argv[2]); + } else { + CTRACE((tfp, "LYExecv: Called inappropriately! (path=%s)\n", path)); } - CTRACE((tfp, "LYExecv: Called inappropriately! (path=%s)\n", path)); - return(0); #else - int rc; int n; char *tmpbuf = 0; #ifdef __DJGPP__ @@ -2390,11 +2389,13 @@ PRIVATE int LYExecv ARGS3( rc = 1; /* It will work */ stop_curses(); pid = fork(); /* fork and execute command */ + switch (pid) { case -1: HTSprintf0(&tmpbuf, gettext("Unable to %s due to system error!"), msg); rc = 0; break; /* don't fall thru! - KW */ + case 0: /* child */ #ifdef USE_EXECVP execvp(path, argv); /* this uses our $PATH */ @@ -2402,6 +2403,8 @@ PRIVATE int LYExecv ARGS3( execv(path, argv); #endif exit(EXIT_FAILURE); /* execv failed, give wait() something to look at */ + /*NOTREACHED*/ + default: /* parent */ #if !HAVE_WAITPID while (wait(&wstatus) != pid) @@ -2442,7 +2445,7 @@ PRIVATE int LYExecv ARGS3( FREE(tmpbuf); } - return(rc); #endif /* _WINDOWS */ #endif /* VMS */ + return(rc); } diff --git a/src/LYMain.c b/src/LYMain.c index 371bc591..bf63a8ed 100644 --- a/src/LYMain.c +++ b/src/LYMain.c @@ -146,15 +146,15 @@ PUBLIC char *empty_string = "\0"; PUBLIC int display_lines; /* number of lines in display */ PUBLIC int www_search_result= -1; /* linked list of printers */ -PUBLIC lynx_printer_item_type *printers = NULL; +PUBLIC lynx_list_item_type *printers = NULL; /* linked list of download options */ -PUBLIC lynx_html_item_type *downloaders = NULL; +PUBLIC lynx_list_item_type *downloaders = NULL; /* linked list of upload options */ #ifdef USE_EXTERNALS -PUBLIC lynx_html_item_type *externals = NULL; +PUBLIC lynx_list_item_type *externals = NULL; /* linked list of external options */ #endif -PUBLIC lynx_html_item_type *uploaders = NULL; +PUBLIC lynx_list_item_type *uploaders = NULL; PUBLIC int port_syntax = 1; PUBLIC int LYShowColor = SHOW_COLOR_UNKNOWN; /* to show or not to show */ PUBLIC int LYChosenShowColor = SHOW_COLOR_UNKNOWN; /* whether to show and save */ @@ -436,18 +436,22 @@ BOOLEAN persistent_cookies = FALSE; /* disabled by default! */ PUBLIC char *LYCookieFile = NULL; /* cookie read file */ PUBLIC char *LYCookieSaveFile = NULL; /* cookie save file */ #endif /* EXP_PERSISTENT_COOKIES */ + PUBLIC int LYTransferRate = rateEtaKB_maybe; PUBLIC char *XLoadImageCommand = NULL; /* Default image viewer for X */ PUBLIC BOOLEAN LYNoISMAPifUSEMAP = FALSE; /* Omit ISMAP link if MAP present? */ PUBLIC int LYHiddenLinks = HIDDENLINKS_SEPARATE; /* Show hidden links? */ PUBLIC BOOL Old_DTD = NO; + +#ifndef NO_LYNX_TRACE PUBLIC FILE *LYTraceLogFP = NULL; /* Pointer for TRACE log */ +#endif PUBLIC char *LYTraceLogPath = NULL; /* Path for TRACE log */ PUBLIC BOOLEAN LYUseTraceLog = USE_TRACE_LOG; /* Use a TRACE log? */ + PUBLIC BOOLEAN LYSeekFragMAPinCur = TRUE; PUBLIC BOOLEAN LYSeekFragAREAinCur = TRUE; - PUBLIC BOOLEAN LYStripDotDotURLs = TRUE; /* Try to fix ../ in some URLs? */ PUBLIC BOOLEAN LYForceSSLCookiesSecure = FALSE; PUBLIC BOOLEAN LYNoCc = FALSE; @@ -2139,7 +2143,7 @@ PUBLIC void reload_read_cfg NOARGS * no_option_save restriction may thus be unnecessarily restrictive, * but the check is currently still left in place. - kw */ - tempfile = calloc(1, LY_MAXPATH); + tempfile = typecallocn(char, LY_MAXPATH); if (!tempfile) { HTAlwaysAlert(NULL, NOT_ENOUGH_MEMORY); return; @@ -2196,7 +2200,7 @@ PUBLIC void reload_read_cfg NOARGS /* * Process the temporary RC file. */ - rcfp = fopen(tempfile, "r"); + rcfp = fopen(tempfile, TXT_R); read_rc(rcfp); LYRemoveTemp(tempfile); FREE(tempfile); /* done with it - kw */ diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c index 434d804d..fd5ae994 100644 --- a/src/LYMainLoop.c +++ b/src/LYMainLoop.c @@ -2683,7 +2683,7 @@ PRIVATE int handle_LYK_ELGOTO ARGS5( } #ifdef USE_EXTERNALS -PRIVATE void handle_LYK_EXTERN ARGS1( +PRIVATE void handle_LYK_EXTERN_LINK ARGS1( BOOLEAN *, refresh_screen) { if ((nlinks > 0) && (links[curdoc.link].lname != NULL)) @@ -2692,6 +2692,16 @@ PRIVATE void handle_LYK_EXTERN ARGS1( *refresh_screen = TRUE; } } + +PRIVATE void handle_LYK_EXTERN_PAGE ARGS1( + BOOLEAN *, refresh_screen) +{ + if (curdoc.address != NULL) + { + run_external(curdoc.address, FALSE); + *refresh_screen = TRUE; + } +} #endif PRIVATE BOOLEAN handle_LYK_FASTBACKW_LINK ARGS3( @@ -7300,8 +7310,11 @@ new_cmd: /* #endif /* DIRED_SUPPORT || VMS*/ #ifdef USE_EXTERNALS - case LYK_EXTERN: /* use external program on url */ - handle_LYK_EXTERN(&refresh_screen); + case LYK_EXTERN_LINK: /* use external program on url */ + handle_LYK_EXTERN_LINK(&refresh_screen); + break; + case LYK_EXTERN_PAGE: /* use external program on current page */ + handle_LYK_EXTERN_PAGE(&refresh_screen); break; #endif /* USE_EXTERNALS */ diff --git a/src/LYNews.c b/src/LYNews.c index c9b13506..72309078 100644 --- a/src/LYNews.c +++ b/src/LYNews.c @@ -35,7 +35,7 @@ PRIVATE BOOLEAN message_has_content ARGS2( *nonspaces = FALSE; - if (!filename || (fp = fopen(filename, "r")) == NULL) { + if (!filename || (fp = fopen(filename, TXT_R)) == NULL) { CTRACE((tfp, "Failed to open file %s for reading!\n", NONNULL(filename))); return FALSE; @@ -136,7 +136,7 @@ PUBLIC char *LYNewsPost ARGS2( * and message body. - FM */ #ifdef __DJGPP__ - if ((fd = LYOpenTemp(my_tempfile, HTML_SUFFIX, "wb")) == NULL) + if ((fd = LYOpenTemp(my_tempfile, HTML_SUFFIX, BIN_W)) == NULL) #else if ((fd = LYOpenTemp(my_tempfile, HTML_SUFFIX, "w")) == NULL) #endif /* __DJGPP__ */ @@ -240,11 +240,11 @@ PUBLIC char *LYNewsPost ARGS2( CJKinput[0] = '\0'; switch(kanji_code) { case EUC: - TO_EUC((CONST unsigned char *)kp, CJKinput); + TO_EUC((CONST unsigned char *)kp, (unsigned char *)CJKinput); kp = CJKinput; break; case SJIS: - TO_SJIS((CONST unsigned char *)kp, CJKinput); + TO_SJIS((CONST unsigned char *)kp, (unsigned char *)CJKinput); kp = CJKinput; break; default: @@ -280,7 +280,7 @@ PUBLIC char *LYNewsPost ARGS2( StrAllocCat(cp, org); } #ifdef UNIX - else if ((fp = fopen("/etc/organization", "r")) != NULL) { + else if ((fp = fopen("/etc/organization", TXT_R)) != NULL) { char *buffer = 0; if (LYSafeGets(&buffer, fp) != NULL) { if ((org = strchr(buffer, '\n')) != NULL) { diff --git a/src/LYOptions.c b/src/LYOptions.c index 0ef88dec..230d380c 100644 --- a/src/LYOptions.c +++ b/src/LYOptions.c @@ -2438,7 +2438,7 @@ PRIVATE PostPair * break_data ARGS1( CTRACE((tfp, "break_data %s\n", data)); - q = calloc(sizeof(PostPair), 1); + q = typecalloc(PostPair); if (q==NULL) outofmem(__FILE__, "break_data(calloc)"); diff --git a/src/LYPrint.c b/src/LYPrint.c index 6a95f962..12bf6605 100644 --- a/src/LYPrint.c +++ b/src/LYPrint.c @@ -805,7 +805,7 @@ PRIVATE void send_file_to_printer ARGS4( char my_file[LY_MAXPATH]; char my_temp[LY_MAXPATH]; int FnameTotal, FnameNum = -1; - lynx_printer_item_type *cur_printer; + lynx_list_item_type *cur_printer; outfile_fp = LYOpenTemp(my_temp, (HTisDocumentSource()) @@ -1115,7 +1115,7 @@ PUBLIC int printfile ARGS1( /* * Get the number of lines in the file. */ - if ((cp = (char *)strstr(link_info, "lines=")) != NULL) { + if ((cp = strstr(link_info, "lines=")) != NULL) { /* * Terminate prev string here. */ @@ -1143,12 +1143,12 @@ PUBLIC int printfile ARGS1( } else if (strstr(link_info, "PRINTER")) { type = PRINTER; - if ((cp = (char *)strstr(link_info, "number=")) != NULL) { + if ((cp = strstr(link_info, "number=")) != NULL) { /* number of characters in "number=" */ cp += 7; printer_number = atoi(cp); } - if ((cp = (char *)strstr(link_info, "pagelen=")) != NULL) { + if ((cp = strstr(link_info, "pagelen=")) != NULL) { /* number of characters in "pagelen=" */ cp += 8; pagelen = atoi(cp); @@ -1271,7 +1271,7 @@ PUBLIC int print_options ARGS3( int count; int pages; FILE *fp0; - lynx_printer_item_type *cur_printer; + lynx_list_item_type *cur_printer; if (LYReuseTempfiles) { fp0 = LYOpenTempRewrite(my_temp, HTML_SUFFIX, "w"); @@ -1464,7 +1464,7 @@ check_recall: * "invalid pointer" reported in the Lynx.leaks file (if compiled * with --enable-find-leaks turned on. Dumb.] */ - if ((fn = (char *) calloc (1, (strlen (tbuf) + 1))) == NULL) + if ((fn = typecallocn(char, strlen (tbuf) + 1)) == NULL) outofmem(__FILE__, "GetFileName"); return (strcpy (fn, tbuf)); diff --git a/src/LYReadCFG.c b/src/LYReadCFG.c index 1369a8df..5ba10be4 100644 --- a/src/LYReadCFG.c +++ b/src/LYReadCFG.c @@ -78,15 +78,12 @@ PRIVATE char *find_colon ARGS1( return NULL; } -/* - * Function for freeing the DOWNLOADER and UPLOADER menus list. - FM - */ -PRIVATE void free_item_list NOARGS +PRIVATE void free_item_list ARGS1( + lynx_list_item_type **, ptr) { - lynx_html_item_type *cur; - lynx_html_item_type *next; + lynx_list_item_type *cur = *ptr; + lynx_list_item_type *next; - cur = downloaders; while (cur) { next = cur->next; FREE(cur->name); @@ -94,30 +91,22 @@ PRIVATE void free_item_list NOARGS FREE(cur); cur = next; } - downloaders = NULL; + *ptr = NULL; +} +/* + * Function for freeing the DOWNLOADER and UPLOADER menus list. - FM + */ +PRIVATE void free_all_item_lists NOARGS +{ + free_item_list(&printers); + free_item_list(&downloaders); #ifdef DIRED_SUPPORT - cur = uploaders; - while (cur) { - next = cur->next; - FREE(cur->name); - FREE(cur->command); - FREE(cur); - cur = next; - } - uploaders = NULL; + free_item_list(&uploaders); #endif /* DIRED_SUPPORT */ #ifdef USE_EXTERNALS - cur = externals; - while (cur) { - next = cur->next; - FREE(cur->name); - FREE(cur->command); - FREE(cur); - cur = next; - } - externals = NULL; + free_item_list(&externals); #endif /* USE_EXTERNALS */ return; @@ -126,12 +115,13 @@ PRIVATE void free_item_list NOARGS /* * Process string buffer fields for DOWNLOADER or UPLOADER menus. */ -PRIVATE void add_item_to_list ARGS2( +PRIVATE void add_item_to_list ARGS3( char *, buffer, - lynx_html_item_type **, list_ptr) + lynx_list_item_type **, list_ptr, + int, special) { char *colon, *next_colon; - lynx_html_item_type *cur_item, *prev_item; + lynx_list_item_type *cur_item, *prev_item; /* * Make a linked list @@ -140,12 +130,12 @@ PRIVATE void add_item_to_list ARGS2( /* * First item. */ - cur_item = typecalloc(lynx_html_item_type); + cur_item = typecalloc(lynx_list_item_type); if (cur_item == NULL) outofmem(__FILE__, "read_cfg"); *list_ptr = cur_item; #ifdef LY_FIND_LEAKS - atexit(free_item_list); + atexit(free_all_item_lists); #endif } else { /* @@ -155,7 +145,7 @@ PRIVATE void add_item_to_list ARGS2( prev_item->next != NULL; prev_item = prev_item->next) ; /* null body */ - cur_item = typecalloc(lynx_html_item_type); + cur_item = typecalloc(lynx_list_item_type); if (cur_item == NULL) outofmem(__FILE__, "read_cfg"); else @@ -166,6 +156,7 @@ PRIVATE void add_item_to_list ARGS2( cur_item->command = NULL; cur_item->always_enabled = FALSE; cur_item->override_primary_action = FALSE; + cur_item->pagelen = 66; /* * Find first unescaped colon and process fields @@ -174,7 +165,7 @@ PRIVATE void add_item_to_list ARGS2( /* * Process name field */ - cur_item->name = typecallocn(char,colon-buffer+1); + cur_item->name = typecallocn(char, colon-buffer+1); if (cur_item->name == NULL) outofmem(__FILE__, "read_cfg"); LYstrncpy(cur_item->name, buffer, (int)(colon-buffer)); @@ -202,113 +193,36 @@ PRIVATE void add_item_to_list ARGS2( *next_colon++ = '\0'; cur_item->always_enabled = is_true(colon); if (next_colon) { - cur_item->override_primary_action = is_true(next_colon); + if (special) { + cur_item->pagelen = atoi(next_colon); + } else { + cur_item->override_primary_action = is_true(next_colon); + } } } } } - -/* - * Function for freeing the PRINTER menus list. - FM - */ -PRIVATE void free_printer_item_list NOARGS +PUBLIC lynx_list_item_type *find_item_by_number ARGS2( + lynx_list_item_type *, list_ptr, + char *, number) { - lynx_printer_item_type *cur = printers; - lynx_printer_item_type *next; - - while (cur) { - next = cur->next; - FREE(cur->name); - FREE(cur->command); - FREE(cur); - cur = next; + int value = atoi(number); + while (value-- >= 0 && list_ptr != 0) { + list_ptr = list_ptr->next; } - printers = NULL; - - return; + return list_ptr; } -/* - * Process string buffer fields for PRINTER menus. - */ -PRIVATE void add_printer_to_list ARGS2( - char *, buffer, - lynx_printer_item_type **, list_ptr) +PUBLIC int match_item_by_name ARGS3( + lynx_list_item_type *, ptr, + char *, name, + BOOLEAN, only_overriders) { - char *colon, *next_colon; - lynx_printer_item_type *cur_item, *prev_item; - - /* - * Make a linked list. - */ - if (*list_ptr == NULL) { - /* - * First item. - */ - cur_item = typecalloc(lynx_printer_item_type); - if (cur_item == NULL) - outofmem(__FILE__, "read_cfg"); - *list_ptr = cur_item; -#ifdef LY_FIND_LEAKS - atexit(free_printer_item_list); -#endif - } else { - /* - * Find the last item. - */ - for (prev_item = *list_ptr; - prev_item->next != NULL; - prev_item = prev_item->next) - ; /* null body */ - - cur_item = typecalloc(lynx_printer_item_type); - if (cur_item == NULL) - outofmem(__FILE__, "read_cfg"); - else - prev_item->next = cur_item; - } - cur_item->next = NULL; - cur_item->name = NULL; - cur_item->command = NULL; - cur_item->always_enabled = FALSE; - - /* - * Find first unescaped colon and process fields. - */ - if ((colon = find_colon(buffer)) != NULL) { - /* - * Process name field. - */ - cur_item->name = typecallocn(char, colon-buffer+1); - if (cur_item->name == NULL) - outofmem(__FILE__, "read_cfg"); - LYstrncpy(cur_item->name, buffer, (int)(colon-buffer)); - remove_backslashes(cur_item->name); - - /* - * Process TRUE/FALSE field. - */ - if ((next_colon = find_colon(colon+1)) != NULL) { - cur_item->command = typecallocn(char, next_colon-colon); - if (cur_item->command == NULL) - outofmem(__FILE__, "read_cfg"); - LYstrncpy(cur_item->command, colon+1, (int)(next_colon-(colon+1))); - remove_backslashes(cur_item->command); - cur_item->always_enabled = is_true(next_colon+1); - } - - /* - * Process pagelen field. - */ - if (next_colon != NULL - && (next_colon = find_colon(next_colon+1)) != NULL) { - cur_item->pagelen = atoi(next_colon+1); - } else { - /* default to 66 lines */ - cur_item->pagelen = 66; - } - } + return + (ptr->command != 0 + && !strncasecomp(ptr->name, name, strlen(ptr->name)) + && (only_overriders ? ptr->override_primary_action : 1)); } #if defined(USE_COLOR_STYLE) || defined(USE_COLOR_TABLE) @@ -483,7 +397,7 @@ PRIVATE void parse_color ARGS1( typedef int (*ParseFunc) PARAMS((char *)); typedef union { - lynx_html_item_type ** add_value; + lynx_list_item_type ** add_value; BOOLEAN * set_value; int * int_value; char ** str_value; @@ -493,7 +407,7 @@ typedef union { #ifdef PARSE_DEBUG #define ParseData \ - lynx_html_item_type** add_value; \ + lynx_list_item_type** add_value; \ BOOLEAN *set_value; \ int *int_value; \ char **str_value; \ @@ -971,7 +885,7 @@ static int cern_rulesfile_fun ARGS1( static int printer_fun ARGS1( char *, value) { - add_printer_to_list(value, &printers); + add_item_to_list(value, &printers, TRUE); return 0; } @@ -1710,8 +1624,7 @@ PUBLIC void free_lynx_cfg NOARGS break; } } - free_item_list(); - free_printer_item_list(); + free_all_item_lists(); #ifdef DIRED_SUPPORT reset_dired_menu(); /* frees and resets dired menu items - kw */ #endif @@ -1739,6 +1652,60 @@ PRIVATE Config_Type *lookup_config ARGS1( return tbl; } +/* + * If the given value is an absolute path (by syntax), or we can read it, use + * the value as given. Otherwise, assume it must be in the same place we read + * the parent configuration file from. + * + * Note: only read files from the current directory if there's no parent + * filename, otherwise it leads to user surprise. + */ +PRIVATE char *actual_filename ARGS3( + char *, cfg_filename, + char *, parent_filename, + char *, dft_filename) +{ + static char *my_filename; + + 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 { + StrAllocCopy(my_filename, dft_filename); + *LYPathLeaf (my_filename) = '\0'; + StrAllocCat(my_filename, cfg_filename); + if (LYCanReadFile(my_filename)) { + cfg_filename = my_filename; + } + } + } + } + return cfg_filename; +} + +PUBLIC FILE *LYOpenCFG ARGS3( + char *, cfg_filename, + 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); +} + #define NOPTS_ ( TABLESIZE(Config_Table) - 1 ) typedef BOOL (optidx_set_t) [ NOPTS_ ]; /* if element is FALSE, then it's allowed in the current file*/ @@ -1765,7 +1732,6 @@ PRIVATE void do_read_cfg ARGS5( FILE *, fp0, optidx_set_t*, allowed) { - static char *mypath = NULL; FILE *fp; char *buffer = 0; @@ -1790,11 +1756,7 @@ PRIVATE void do_read_cfg ARGS5( CTRACE((tfp,"No filename following -cfg switch!\n")); return; } - if (!strncmp(cfg_filename, "~/", 2)) { - HTSprintf0(&mypath, "%s%s", Home_Dir(), cfg_filename+1); - cfg_filename = mypath; - } - if ((fp = fopen(cfg_filename, TXT_R)) == 0) { + if ((fp = LYOpenCFG(cfg_filename, parent_filename, LYNX_CFG_FILE)) == 0) { CTRACE((tfp, "lynx.cfg file not found as '%s'\n", cfg_filename)); return; } @@ -1954,7 +1916,7 @@ PRIVATE void do_read_cfg ARGS5( #ifndef NO_CONFIG_INFO if (fp0 != 0 && !no_lynxcfg_xinfo) { - LYLocalFileToURL(&url, value); + LYLocalFileToURL(&url, actual_filename(value, cfg_filename, LYNX_CFG_FILE)); StrAllocCopy(cp1, value); if (strchr(value, '&') || strchr(value, '<')) { LYEntify(&cp1, TRUE); @@ -2043,7 +2005,7 @@ PRIVATE void do_read_cfg ARGS5( case CONF_ADD_ITEM: if (q->add_value != 0) - add_item_to_list (value, q->add_value); + add_item_to_list (value, q->add_value, FALSE); break; #if defined(EXEC_LINKS) || defined(LYNXCGI_LINKS) @@ -2076,7 +2038,7 @@ PRIVATE void do_read_cfg ARGS5( * with those always_enabled options still available. - FM */ if (downloaders != 0) { - lynx_html_item_type *cur_download; + lynx_list_item_type *cur_download; cur_download = downloaders; while (cur_download != 0) { diff --git a/src/LYReadCFG.h b/src/LYReadCFG.h index 2fc893ad..b6349cc0 100644 --- a/src/LYReadCFG.h +++ b/src/LYReadCFG.h @@ -53,8 +53,11 @@ extern void read_cfg PARAMS((char *cfg_filename, char *parent_filename, int nest extern void free_lynx_cfg NOPARAMS; extern BOOLEAN have_read_cfg; +extern FILE *LYOpenCFG PARAMS((char *cfg_filename, char *parent_filename, char *dft_filename)); extern int lynx_cfg_infopage PARAMS((document *newdoc)); extern int lynx_compile_opts PARAMS((document *newdoc)); +extern int match_item_by_name PARAMS((lynx_list_item_type * ptr, char * name, BOOLEAN only_overriders)); +extern lynx_list_item_type *find_item_by_number PARAMS((lynx_list_item_type * list_ptr, char * number)); extern void reload_read_cfg NOPARAMS; /* implemented in LYMain.c */ #endif /* LYREADCFG_H */ diff --git a/src/LYStrings.c b/src/LYStrings.c index 7ea81384..0f6685de 100644 --- a/src/LYStrings.c +++ b/src/LYStrings.c @@ -364,16 +364,45 @@ PRIVATE int set_clicked_link ARGS4( int i; int c = -1; - if (y == (LYlines-1)) { - mouse_link = -2; - if (x < left) c = (code==FOR_PROMPT) ? LTARROW : LTARROW; - else if (x > right) c = (code==FOR_PROMPT) ? RTARROW : '\b'; - else c = PGDOWN; - } else if (y == 0) { + if (y == (LYlines-1) || y == 0) { /* First or last row */ + /* XXXX In fact # is not always at x==0? KANJI_CODE_OVERRIDE? */ + int toolbar = (y == 0 && HText_hasToolbar(HTMainText)); + mouse_link = -2; - if (x < left) c = LTARROW; - else if (x > right) c = '\b'; - else c = PGUP; + if (x == 0 && toolbar) /* On '#' */ + c = LAC_TO_LKC0(LYK_TOOLBAR); + else if (clicks > 1) { + if (x < left + toolbar) + c = (code==FOR_PROMPT && y) + ? HOME : LAC_TO_LKC0(LYK_MAIN_MENU); + else if (x > right) + c = (code==FOR_PROMPT && y) + ? END_KEY : LAC_TO_LKC0(LYK_VLINKS); + else if (y) /* Last row */ + c = LAC_TO_LKC0(LYK_END); + else /* First row */ + c = LAC_TO_LKC0(LYK_HOME); + } else { + if (x < left + toolbar) + c = (code==FOR_PROMPT && y) + ? LTARROW + : ( +#ifdef USE_COLOR_STYLE + (s_forw_backw != NOSTYLE && x - toolbar >= 3) + ? LAC_TO_LKC0(LYK_NEXT_DOC) + : LAC_TO_LKC0(LYK_PREV_DOC) +#else + LAC_TO_LKC0(LYK_NEXT_DOC) +#endif + ); + else if (x > right) + c = (code==FOR_PROMPT && y) + ? RTARROW : LAC_TO_LKC0(LYK_HISTORY); + else if (y) /* Last row */ + c = LAC_TO_LKC0(LYK_NEXT_PAGE); + else /* First row */ + c = LAC_TO_LKC0(LYK_PREV_PAGE); + } #ifdef USE_SCROLLBAR } else if (x == LYcols - 1 && LYsb && LYsb_begin >= 0) { int h = display_lines - 2*(LYsb_arrow != 0); @@ -499,9 +528,9 @@ PRIVATE int set_clicked_link ARGS4( if (mouse_link >= 0) { if (mouse_err == 0) { if (c == -1) - c = lookup_keymap(LYK_ACTIVATE); + c = LAC_TO_LKC0(LYK_ACTIVATE); } else if (mouse_err >= 0) - c = lookup_keymap(LYK_CHANGE_LINK); + c = LAC_TO_LKC0(LYK_CHANGE_LINK); } } return c; @@ -1213,18 +1242,16 @@ PRIVATE int read_keymap_file NOARGS char *line = NULL; FILE *fp; char file[LY_MAXPATH]; - int ret; int linenum; size_t n; LYAddPathToHome(file, sizeof(file), FNAME_LYNX_KEYMAPS); - if ((fp = fopen (file, "r")) == 0) + if ((fp = fopen (file, TXT_R)) == 0) return 0; linenum = 0; - ret = 0; - while (LYSafeGets(&line, fp) != 0 && (ret == 0)) { + while (LYSafeGets(&line, fp) != 0) { char *s = LYSkipBlanks(line); linenum++; @@ -1234,23 +1261,15 @@ PRIVATE int read_keymap_file NOARGS for (n = 0; n < TABLESIZE(table); n++) { size_t len = strlen(table[n].name); - if (strlen(s) > len - && !strncmp(s, table[n].name, len)) { - if ((*(table[n].func))(LYSkipBlanks(s+len)) < 0) { - ret = -1; - break; - } - } + + if ( strlen(s) > len && !strncmp(s, table[n].name, len) + && (*(table[n].func))(LYSkipBlanks(s+len)) < 0 ) + fprintf (stderr, FAILED_READING_KEYMAP, linenum, file); } } FREE(line); - LYCloseInput (fp); - - if (ret == -1) - fprintf (stderr, FAILED_READING_KEYMAP, linenum, file); - - return ret; + return 0; } PRIVATE void setup_vtXXX_keymap NOARGS @@ -1547,9 +1566,11 @@ re_read: #endif /* !USE_SLANG */ #if !defined(USE_SLANG) || defined(VMS) || defined(DJGPP_KEYHANDLER) c = GetChar(); + lynx_nl2crlf(FALSE); #else if (LYCursesON) { c = GetChar(); + lynx_nl2crlf(FALSE); } else { c = getchar(); if (c == EOF && errno == EINTR) /* Ctrl-Z causes EINTR in getchar() */ @@ -1595,7 +1616,7 @@ re_read: if (new_fd >= 0) { FILE *frp; close(new_fd); - freopen(term_name, "r", stdin); + freopen(term_name, TXT_R, stdin); CTRACE((tfp, "nozap: freopen(%s,\"r\",stdin) returned %p, stdin is now %p with fd %d.\n", term_name, frp, stdin, fileno(stdin))); @@ -2077,23 +2098,7 @@ re_read: c = set_clicked_link(event.x, event.y, code, 1); } else if (event.bstate & BUTTON1_DOUBLE_CLICKED) { c = set_clicked_link(event.x, event.y, code, 2); - if (c == PGDOWN) - c = END_KEY; - else if (c == PGUP) - c = HOME; - else if (c == REMOVE_KEY) - c = END_KEY; - else if (c == INSERT_KEY) - c = HOME; - else if (c == RTARROW) - c = END_KEY; - else if (c == LTARROW && code == FOR_PROMPT) - c = HOME; - else if (c == LTARROW) - c = LYReverseKeymap(LYK_MAIN_MENU); - else if (c == '\b' && (code == FOR_PANEL || code == FOR_INPUT)) - c = LAC_TO_LKC0(LYK_VLINKS); - else if (c == LAC_TO_LKC0(LYK_SUBMIT) && code == FOR_INPUT) + if (c == LAC_TO_LKC0(LYK_SUBMIT) && code == FOR_INPUT) lac = LYK_SUBMIT; } else if (event.bstate & BUTTON3_CLICKED) { c = LAC_TO_LKC0(LYK_PREV_DOC); @@ -2110,7 +2115,7 @@ re_read: int atlink; c = set_clicked_link(event.x, event.y, code, 1); - atlink = (c == LYReverseKeymap(LYK_ACTIVATE)); + atlink = (c == LAC_TO_LKC0(LYK_ACTIVATE)); if (!atlink) mouse_link = -1; /* Forget about approx stuff. */ @@ -2695,7 +2700,8 @@ PUBLIC int LYEditInsert ARGS5( if (map < 0) map = map_active; if (map && LYCharSet_UC[current_char_set].enc == UCT_ENC_UTF8) { - unsigned char *e = s + len, *t = Buf + Pos; + int off = Pos; + unsigned char *e = s + len; char *tail = 0; while (s < e) { @@ -2712,30 +2718,30 @@ PUBLIC int LYEditInsert ARGS5( remains -= l - 1; if (remains < 0) { if (tail) - strcpy(t, tail); + strcpy(Buf + off, tail); FREE(tail); - len = (char*)t - Buf; + len = off; overflow = 1; goto finish; } if (l > 1 && !tail) - StrAllocCopy((char*)tail, Buf + Pos + len); + StrAllocCopy(tail, Buf + Pos + len); } else utfbuf[0] = '?'; } else utfbuf[0] = UCH(ucode); } - strncpy(t, utfbuf, l); + strncpy(Buf + off, utfbuf, l); edited = 1; - t += l; + off += l; s++; } if (tail) - strcpy(t, tail); - len = (char*)t - (Buf + Pos); + strcpy(Buf + off, tail); + len = off - Pos; FREE(tail); } else if (map) { - unsigned char *e = s + len, *t = Buf + Pos; + unsigned char *e = s + len, *t = (unsigned char *)Buf + Pos; while (s < e) { int ch; @@ -3556,7 +3562,7 @@ PRIVATE char **sortedList ARGS2( unsigned count = HTList_count(list); unsigned j = 0; unsigned k, jk; - char **result = calloc(count + 1, sizeof(char *)); + char **result = typecallocn(char *, count + 1); if (result == 0) outofmem(__FILE__, "sortedList"); @@ -3695,7 +3701,7 @@ PUBLIC int LYhandlePopupList ARGS9( BOOLEAN, numbered) { int c = 0, cmd = 0, i = 0, j = 0, rel = 0; - int orig_choice = cur_choice; + int orig_choice; WINDOW * form_window; int num_choices = 0; int max_choices = 0; @@ -3719,6 +3725,10 @@ PUBLIC int LYhandlePopupList ARGS9( char *popup_status_msg = NULL; CONST char **Cptr = NULL; + orig_choice = cur_choice; + if (cur_choice < 0) + cur_choice = 0; + /* * Initialize the search string buffer. - FM */ @@ -5341,7 +5351,7 @@ PUBLIC char * SNACopy ARGS3( { FREE(*dest); if (src) { - *dest = (char *)calloc(1, n + 1); + *dest = typecallocn(char, n + 1); if (*dest == NULL) { CTRACE((tfp, "Tried to calloc %d bytes\n", n)); outofmem(__FILE__, "SNACopy"); @@ -5369,7 +5379,7 @@ PUBLIC char * SNACat ARGS3( strncpy(*dest + length, src, n); *(*dest + length + n) = '\0'; /* terminate */ } else { - *dest = (char *)calloc(1, n + 1); + *dest = typecallocn(char, n + 1); if (*dest == NULL) outofmem(__FILE__, "SNACat"); memcpy(*dest, src, n); @@ -5692,7 +5702,7 @@ PUBLIC BOOL LYHaveCmdScript NOARGS PUBLIC void LYOpenCmdScript NOARGS { if (lynx_cmd_script != 0) { - cmd_script = fopen(lynx_cmd_script, "r"); + cmd_script = fopen(lynx_cmd_script, TXT_R); CTRACE((tfp, "LYOpenCmdScript(%s) %s\n", lynx_cmd_script, cmd_script != 0 ? "SUCCESS" : "FAIL")); diff --git a/src/LYStrings.h b/src/LYStrings.h index 3c1f0898..af6e4fb2 100644 --- a/src/LYStrings.h +++ b/src/LYStrings.h @@ -139,10 +139,10 @@ extern void base64_encode PARAMS((char * dest, char * src, int len)); have to be changed/reviewed, AS WELL AS the lineedit binding tables in LYEditmap.c ! - KEYMAP_SIZE, defined in LYKeymap.h, may need to be changed ! - - See also table funckey[] in LYKeymap.c for 'pretty' strings + - See also table named_keys[] in LYKeymap.c for 'pretty' strings for the keys with codes >= 256 (to appear on the 'K'eymap page). New keycodes should probably be assigned consecutively, so their - key names can be easily added to funckey[] (but see next point). + key names can be easily added to named_keys[] (but see next point). They should also be documented in lynx.cfg. - The DOS port uses its own native codes for some keys, unless they are remapped by the code in LYgetch(). See *.key files diff --git a/src/LYStructs.h b/src/LYStructs.h index 2471c59c..90020afd 100644 --- a/src/LYStructs.h +++ b/src/LYStructs.h @@ -80,14 +80,15 @@ typedef struct _VisitedLink { extern histstruct history[MAXHIST]; extern int nhist; -typedef struct _lynx_html_item_type { - struct _lynx_html_item_type *next; /* the next item in the linked list */ +typedef struct _lynx_list_item_type { + struct _lynx_list_item_type *next; /* the next item in the linked list */ char *name; /* a description of the item */ char *command; /* the command to execute */ int always_enabled; /* a constant to tell whether or * not to disable the printer * when the no_print option is on */ + /* HTML lists: */ BOOL override_primary_action; /* whether primary action will be * overridden by this - e.g. this allows * invoking user's MUA when mailto: link @@ -95,32 +96,23 @@ typedef struct _lynx_html_item_type { * command. This field is only examined * by code that handles EXTERNAL command. */ -} lynx_html_item_type; + /* PRINTER lists: */ + int pagelen; /* an integer to store the printer's + * page length + */ +} lynx_list_item_type; -/* for printer commands */ -typedef struct _lynx_printer_item_type { - struct _lynx_printer_item_type *next; /* next item in the linked list */ - char *name; /* a description of the item */ - char *command; /* the command to execute */ - int always_enabled; /* a constant to tell whether or - * not to disable the printer - * when the no_print option is on - */ - int pagelen; /* an integer to store the printer's - * page length - */ -} lynx_printer_item_type; -extern lynx_printer_item_type *printers; +extern lynx_list_item_type *printers; /* for download commands */ -extern lynx_html_item_type *downloaders; +extern lynx_list_item_type *downloaders; /* for upload commands */ -extern lynx_html_item_type *uploaders; +extern lynx_list_item_type *uploaders; #ifdef USE_EXTERNALS /* for external commands */ -extern lynx_html_item_type *externals; +extern lynx_list_item_type *externals; #endif #endif /* LYSTRUCTS_H */ diff --git a/src/LYStyle.c b/src/LYStyle.c index b2b40e69..6477b42f 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.43 Mon, 26 Feb 2001 18:41:57 -0800 dickey @ + * @Id: LYStyle.c 1.44 Sun, 01 Apr 2001 17:51:46 -0700 dickey @ */ #include <HTUtils.h> #include <HTML.h> @@ -58,6 +58,7 @@ PUBLIC int s_aedit_sel = NOSTYLE; PUBLIC int s_alert = NOSTYLE; PUBLIC int s_alink = NOSTYLE; PUBLIC int s_curedit = NOSTYLE; +PUBLIC int s_forw_backw = NOSTYLE; PUBLIC int s_normal = NOSTYLE; PUBLIC int s_prompt_edit = NOSTYLE; PUBLIC int s_prompt_edit_arr = NOSTYLE; @@ -207,6 +208,7 @@ PRIVATE void parse_style ARGS1(char*,buffer) { "edit.prompt.arrow", DSTYLE_ELEMENTS, &s_prompt_edit_arr }, { "edit.prompt.marked", DSTYLE_ELEMENTS, &s_prompt_sel }, { "edit.prompt", DSTYLE_ELEMENTS, &s_prompt_edit }, + { "forwbackw.arrow", DSTYLE_ELEMENTS, &s_forw_backw }, }; unsigned n; BOOL found = FALSE; @@ -434,24 +436,24 @@ PUBLIC void style_deleteStyleList NOARGS lss_styles = NULL; } -PRIVATE int style_readFromFileREC ARGS2(char*, file, int, toplevel) +PRIVATE int style_readFromFileREC ARGS2( + char *, lss_filename, + char *, parent_filename) { FILE *fh; char *buffer = NULL; int len; - CTRACE2(TRACE_STYLE, (tfp, "CSS:Reading styles from file: %s\n", file ? file : "?!? empty ?!?")); - if (file == NULL || *file == '\0') + CTRACE2(TRACE_STYLE, (tfp, "CSS:Reading styles from file: %s\n", lss_filename ? lss_filename : "?!? empty ?!?")); + if (lss_filename == NULL || *lss_filename == '\0') return -1; - fh = fopen(file, TXT_R); - if (!fh) - { + if ((fh = LYOpenCFG(lss_filename, parent_filename, LYNX_LSS_FILE)) == 0) { /* this should probably be an alert or something */ - CTRACE2(TRACE_STYLE, (tfp, "CSS:Can't open style file '%s', using defaults\n", file)); + CTRACE2(TRACE_STYLE, (tfp, "CSS:Can't open style file '%s', using defaults\n", lss_filename)); return -1; } - if (toplevel) { + if (parent_filename == 0) { style_initialiseHashTable(); style_deleteStyleList(); } @@ -461,20 +463,20 @@ PRIVATE int style_readFromFileREC ARGS2(char*, file, int, toplevel) LYTrimTail(buffer); LYTrimHead(buffer); if (!strncasecomp(buffer,"include:",8)) - style_readFromFileREC(buffer+8, 0); + style_readFromFileREC(buffer+8, lss_filename); else if (buffer[0] != '#' && (len = strlen(buffer)) > 0) HStyle_addStyle(buffer); } LYCloseInput (fh); - if (toplevel && LYCursesON) + if ((parent_filename == 0) && LYCursesON) parse_userstyles(); return 0; } -PUBLIC int style_readFromFile ARGS1(char*, file) +PUBLIC int style_readFromFile ARGS1(char*, filename) { - return style_readFromFileREC(file, 1); + return style_readFromFileREC(filename, (char *)0); } /* Used in HTStructured methods: - kw */ diff --git a/src/LYUpload.c b/src/LYUpload.c index 63ab40d4..a78018fa 100644 --- a/src/LYUpload.c +++ b/src/LYUpload.c @@ -47,19 +47,19 @@ PUBLIC int LYUpload ARGS1( char *the_upload = 0; char tmpbuf[LY_MAXPATH]; char *filename = NULL; - lynx_html_item_type *upload_command = 0; + lynx_list_item_type *upload_command = 0; char *the_command = 0; /* * Use configured upload commands. */ - if((directory = (char *)strstr(line, "TO=")) == NULL) + if((directory = strstr(line, "TO=")) == NULL) goto failed; *(directory - 1) = '\0'; /* go past "Directory=" */ directory += 3; - if((method = (char *)strstr(line, "UPLOAD=")) == NULL) + if((method = strstr(line, "UPLOAD=")) == NULL) goto failed; /* * Go past "Method=". @@ -180,7 +180,7 @@ PUBLIC int LYUpload_options ARGS2( { static char tempfile[LY_MAXPATH]; FILE *fp0; - lynx_html_item_type *cur_upload; + lynx_list_item_type *cur_upload; int count; static char curloc[LY_MAXPATH]; char *cp; diff --git a/src/LYUtils.c b/src/LYUtils.c index 5b754ddf..24494fc2 100644 --- a/src/LYUtils.c +++ b/src/LYUtils.c @@ -2514,7 +2514,7 @@ PUBLIC int HTCheckForInterrupt NOARGS * references a directory. */ PUBLIC BOOLEAN LYisAbsPath ARGS1( - char *, path) + CONST char *, path) { #ifdef VMS return TRUE; @@ -3231,7 +3231,7 @@ PUBLIC BOOLEAN LYCloseOutput ARGS1( PUBLIC BOOLEAN LYCanWriteFile ARGS1( CONST char*, filename) { - if (LYCloseOutput(fopen(filename, "w"))) { + if (LYCloseOutput(fopen(filename, TXT_W))) { remove(filename); return TRUE; } else { @@ -3248,7 +3248,7 @@ PUBLIC BOOLEAN LYCanReadFile ARGS1( { FILE *fp; - if ((fp = fopen(filename, "r")) != 0) { + if ((fp = fopen(filename, TXT_R)) != 0) { return LYCloseInput(fp); } return FALSE; @@ -3293,7 +3293,7 @@ PUBLIC BOOLEAN inlocaldomain NOARGS if ((cp = ttyname(0))) mytty = strrchr(cp, '/'); - if (mytty && (fp = fopen(UTMP_FILE, "r")) != NULL) { + if (mytty && (fp = fopen(UTMP_FILE, TXT_R)) != NULL) { mytty++; do { n = fread((char *) &me, sizeof(struct utmp), 1, fp); @@ -3506,6 +3506,15 @@ PUBLIC void size_change ARGS1( recent_sizechange = TRUE; CTRACE((tfp, "Window size changed from (%d,%d) to (%d,%d)\n", old_lines, old_cols, LYlines, LYcols)); +#if defined(CAN_SWITCH_DISPLAY_CHARSET) && defined(CAN_AUTODETECT_DISPLAY_CHARSET) + /* May need to reload the font due to different char-box size */ + if (current_char_set != auto_display_charset) { + int old = current_char_set; + + Switch_Display_Charset(auto_display_charset, 1); + Switch_Display_Charset(old, 1); + } +#endif } #ifdef SIGWINCH LYExtSignal (SIGWINCH, size_change); @@ -6388,6 +6397,7 @@ PRIVATE FILE *OpenHiddenFile ARGS2(char *, name, char *, mode) { FILE *fp = 0; struct stat data; + BOOLEAN binary = strchr(mode, 'b') != 0; #if defined(O_CREAT) && defined(O_EXCL) /* we have fcntl.h or kindred? */ /* @@ -6405,7 +6415,7 @@ PRIVATE FILE *OpenHiddenFile ARGS2(char *, name, char *, mode) } if (fd >= 0) { #if defined(O_BINARY) && defined(__CYGWIN__) - if (mode[1] == 'b') + if (binary) setmode(fd, O_BINARY); #endif fp = fdopen(fd, mode); @@ -6418,7 +6428,7 @@ PRIVATE FILE *OpenHiddenFile ARGS2(char *, name, char *, mode) && chmod(name, HIDE_CHMOD) == 0) fp = fopen(name, mode); else if (lstat(name, &data) != 0) - fp = OpenHiddenFile(name, "w"); + fp = OpenHiddenFile(name, binary ? BIN_W : TXT_W); /* * This is less stringent, but reasonably portable. For new files, the * umask will suffice; however if the file already exists we'll change @@ -6445,10 +6455,10 @@ PRIVATE FILE *OpenHiddenFile ARGS2(char *, name, char *, mode) PUBLIC FILE *LYNewBinFile ARGS1(char *, name) { #ifdef VMS - FILE *fp = fopen (name, "wb", "mbc=32"); + FILE *fp = fopen (name, BIN_W, "mbc=32"); chmod(name, HIDE_CHMOD); #else - FILE *fp = OpenHiddenFile(name, "wb"); + FILE *fp = OpenHiddenFile(name, BIN_W); #endif return fp; } @@ -6458,12 +6468,12 @@ PUBLIC FILE *LYNewTxtFile ARGS1(char *, name) FILE *fp; #ifdef VMS - fp = fopen (name, "w", "shr=get"); + fp = fopen (name, TXT_W, "shr=get"); chmod(name, HIDE_CHMOD); #else SetDefaultMode(O_TEXT); - fp = OpenHiddenFile(name, "w"); + fp = OpenHiddenFile(name, TXT_W); SetDefaultMode(O_BINARY); #endif @@ -6476,12 +6486,12 @@ PUBLIC FILE *LYAppendToTxtFile ARGS1(char *, name) FILE *fp; #ifdef VMS - fp = fopen (name, "a+", "shr=get"); + fp = fopen (name, TXT_A, "shr=get"); chmod(name, HIDE_CHMOD); #else SetDefaultMode(O_TEXT); - fp = OpenHiddenFile(name, "a+"); + fp = OpenHiddenFile(name, TXT_A); SetDefaultMode(O_BINARY); #endif @@ -7321,6 +7331,11 @@ PUBLIC void LYLocalFileToURL ARGS2( leaf = wwwName(source); + if (!LYisAbsPath(source)) { + char temp[LY_MAXPATH]; + Current_Dir(temp); + StrAllocCat(*target, temp); + } if (!LYIsHtmlSep(*leaf)) LYAddHtmlSep(target); StrAllocCat(*target, leaf); @@ -7529,8 +7544,8 @@ PUBLIC int LYCopyFile ARGS2( int len; code = EOF; - if ((fin = fopen(src, "rb")) != 0) { - if ((fout = fopen(dst, "wb")) != 0) { + if ((fin = fopen(src, BIN_R)) != 0) { + if ((fout = fopen(dst, BIN_W)) != 0) { code = 0; while ((len = fread(buff, 1, BUF_SIZE, fin)) > 0) { fwrite(buff, 1, len, fout); diff --git a/src/LYUtils.h b/src/LYUtils.h index bc6ee44d..a9b990e5 100644 --- a/src/LYUtils.h +++ b/src/LYUtils.h @@ -75,7 +75,7 @@ extern BOOLEAN LYExpandHostForURL PARAMS((char **AllocatedString, char *prefix_l extern BOOLEAN LYFixCursesOnForAccess PARAMS((CONST char* addr, CONST char* physical)); extern BOOLEAN LYPathOffHomeOK PARAMS((char *fbuffer, size_t fbuffer_size)); extern BOOLEAN LYValidateFilename PARAMS((char * result, char * given)); -extern BOOLEAN LYisAbsPath PARAMS((char *path)); +extern BOOLEAN LYisAbsPath PARAMS((CONST char *path)); extern BOOLEAN LYisLocalAlias PARAMS((char *filename)); extern BOOLEAN LYisLocalFile PARAMS((char *filename)); extern BOOLEAN LYisLocalHost PARAMS((char *filename)); @@ -312,4 +312,8 @@ extern void LYCloselog NOPARAMS; #define TXT_A "a+" #endif +#define BIN_R "rb" +#define BIN_W "wb" +#define BIN_A "ab+" + #endif /* LYUTILS_H */ diff --git a/src/TRSTable.c b/src/TRSTable.c index 8b752135..cb3980dc 100644 --- a/src/TRSTable.c +++ b/src/TRSTable.c @@ -74,6 +74,12 @@ typedef struct _STable_cellinfo { or RESERVEDCELL */ } STable_cellinfo; +enum ended_state { + ROW_not_ended, + ROW_ended_by_endtr, + ROW_ended_by_splitline +}; + typedef struct _STable_rowinfo { /* Each row may be displayed on many display lines, but we fix up positions of cells on this display line only: */ @@ -103,6 +109,7 @@ typedef struct _STable_rowinfo { reset to the line of icell_core. */ BOOL fixed_line; /* if we have a 'core' line of cells */ + BOOL ended; /* if we saw </tr> */ int allocated; /* number of table cells allocated */ STable_cellinfo * cells; short alignment; /* global align attribute for this row */ @@ -620,7 +627,7 @@ PRIVATE int Stbl_finishCellInRow ARGS5( cellstate_s(s->prev_state), cellstate_s(s->state))); if (multiline) { - if (!end_td) { /* processing line-break */ + if ((end_td & TRST_ENDCELL_MASK) == TRST_ENDCELL_LINEBREAK) { switch (s->state) { case CS_invalid: newstate = empty ? CS_invalid : CS__cbc; @@ -862,7 +869,7 @@ PRIVATE int Stbl_finishCellInRow ARGS5( } } } else { /* (!multiline) */ - if (!end_td) { /* processing line-break */ + if ((end_td & TRST_ENDCELL_MASK) == TRST_ENDCELL_LINEBREAK) { switch (s->state) { case CS_invalid: case CS__0new: @@ -1218,6 +1225,7 @@ PUBLIC int Stbl_addRowToTable ARGS3( me->pending_colgroup_next = 0; } me->rows[me->nrows].Line = -1; /* not yet used */ + me->rows[me->nrows].ended = ROW_not_ended; /* No </tr> yet */ return (me->nrows - 1); } @@ -1236,6 +1244,7 @@ PRIVATE int Stbl_finishRowInTable ARGS1( return -1; /* no row started! */ lastrow = me->rows + (me->nrows - 1); ncells = lastrow->ncells; + lastrow->ended = ROW_ended_by_endtr; if (lastrow->ncells > 0) { if (s->pending_len > 0) lastrow->cells[lastrow->ncells - 1].len = s->pending_len; @@ -1366,7 +1375,7 @@ PRIVATE int Stbl_fakeFinishCellInTable ARGS4( int cs = lastrow->cells[lastrow->ncells - 1].colspan; int rs = 1; /* XXXX How to find rowspan? */ int ih = 0; /* XXXX How to find is_header? */ - int end_td = 1; + int end_td = (TRST_ENDCELL_ENDTD | TRST_FAKING_CELLS); int need_reserved = 0; int prev_reserved_last = -1; STable_rowinfo *prev_row; @@ -1421,6 +1430,7 @@ PRIVATE int Stbl_fakeFinishCellInTable ARGS4( (me->allocated_rows + 1) * sizeof(STable_rowinfo)); int need_cells = prev_reserved_last + 1; + int n; if (!rows) return -1; /* ignore silently, no free memory, may be recoverable */ @@ -1433,8 +1443,8 @@ PRIVATE int Stbl_fakeFinishCellInTable ARGS4( me->allocated_rows++; /* Insert a duplicate row after lastrow */ - memmove(lastrow+1, lastrow, - sizeof(STable_rowinfo)*(me->allocated_rows - me->nrows)); + for (n = me->allocated_rows - me->nrows - 1; n >= 0; --n) + lastrow[n + 1] = lastrow[n]; /* Ignore cells, they belong to the next row now */ lastrow->allocated = 0; @@ -1515,7 +1525,9 @@ PUBLIC int Stbl_addCellToTable ARGS7( if (!me->rows || !me->nrows) return -1; /* no row started! */ /* ##850_fail_if_fail?? */ - Stbl_finishCellInTable(me, YES, lineno, pos); + if (me->rows[me->nrows - 1].ended) + Stbl_addRowToTable(me, alignment, lineno); + Stbl_finishCellInTable(me, TRST_ENDCELL_ENDTD, lineno, pos); lastrow = me->rows + (me->nrows - 1); #ifdef EXP_NESTED_TABLES @@ -1650,12 +1662,14 @@ PUBLIC int Stbl_finishCellInTable ARGS4( icell = lastrow->ncells - 1; if (icell < 0) return icell; - if (s->x_td == -1) - return end_td ? -1 : 0; + if (s->x_td == -1) { /* Stray </TD> or safety-call */ + if ((end_td & TRST_ENDCELL_MASK) == TRST_ENDCELL_LINEBREAK) + lastrow->ended = ROW_ended_by_splitline; + return 0; + } #ifdef EXP_NESTED_TABLES - /* This check for pos saves us from infinite recursion... */ - if (!NO_AGGRESSIVE_NEWROW && pos) { + if (!NO_AGGRESSIVE_NEWROW && !(end_td & TRST_FAKING_CELLS)) { int rc = Stbl_fakeFinishCellInTable(me, lastrow, lineno, 1); if (rc) { @@ -1670,7 +1684,7 @@ PUBLIC int Stbl_finishCellInTable ARGS4( if (len == -1) return len; xlen = (len > 0) ? len : s->pending_len; /* ##890 use xlen if fixed_line?: */ - if (lastrow->fixed_line && lastrow->Line == lineno) + if (lastrow->Line == lineno) len = xlen; if (lastrow->cells[icell].colspan > 1) { /* @@ -1758,7 +1772,12 @@ PUBLIC int Stbl_finishCellInTable ARGS4( } #endif -#ifndef EXP_NESTED_TABLES /* maxlen may already include contribution of a cell in this column */ + if ((end_td & TRST_ENDCELL_MASK) == TRST_ENDCELL_LINEBREAK) + lastrow->ended = ROW_ended_by_splitline; +#ifdef EXP_NESTED_TABLES /* maxlen may already include contribution of a cell in this column */ + if (me->maxlen > MAX_STBL_POS) + return -1; +#else if (me->maxlen + (xlen - len) > MAX_STBL_POS) return -1; #endif @@ -1996,6 +2015,16 @@ PUBLIC int Stbl_getStartLine ARGS1( #ifdef EXP_NESTED_TABLES +PUBLIC int Stbl_getStartLineDeep ARGS1( + STable_info *, me) +{ + if (!me) + return -1; + while (me->enclosing) + me = me->enclosing; + return me->startline; +} + PUBLIC void Stbl_update_enclosing ARGS3( STable_info *, me, int, max_width, @@ -2009,7 +2038,7 @@ PUBLIC void Stbl_update_enclosing ARGS3( max_width, me->startline, last_lineno)); for (l = me->startline; l <= last_lineno; l++) { /* Fake <BR> in appropriate positions */ - if (Stbl_finishCellInTable(me->enclosing, 0, l, max_width) < 0) { + if (Stbl_finishCellInTable(me->enclosing, TRST_ENDCELL_LINEBREAK, l, max_width) < 0) { /* It is not handy to let the caller delete me->enclosing, and it does not buy us anything. Do it directly. */ STable_info *stbl = me->enclosing; diff --git a/src/TRSTable.h b/src/TRSTable.h index 5eb48ce5..02463640 100644 --- a/src/TRSTable.h +++ b/src/TRSTable.h @@ -15,7 +15,13 @@ extern int Stbl_finishCellInTable PARAMS((STable_info *, BOOL, int, int)); extern int Stbl_addColInfo PARAMS((STable_info *, int, short, BOOL)); extern int Stbl_finishColGroup PARAMS((STable_info *)); extern int Stbl_addRowGroup PARAMS((STable_info *, short)); -#define Stbl_lineBreak(stbl,l,pos) Stbl_finishCellInTable(stbl, NO, l, pos) + +#define TRST_ENDCELL_ENDTD 1 +#define TRST_ENDCELL_LINEBREAK 0 +#define TRST_ENDCELL_MASK 1 +#define TRST_FAKING_CELLS 2 +#define Stbl_lineBreak(stbl,l,pos) Stbl_finishCellInTable(stbl, TRST_ENDCELL_LINEBREAK, l, pos) + extern int Stbl_getStartLine PARAMS((STable_info *)); extern int Stbl_getFixupPositions PARAMS(( STable_info * me, @@ -35,6 +41,9 @@ extern void Stbl_set_enclosing PARAMS(( STable_info *me, struct _TextAnchor *last_anchor)); extern STable_info * Stbl_get_enclosing PARAMS((STable_info * me)); extern struct _TextAnchor * Stbl_get_last_anchor_before PARAMS((STable_info * me)); +extern int Stbl_getStartLineDeep PARAMS((STable_info *)); +#else +#define Stbl_getStartLineDeep(t) Stbl_getStartLine(t) #endif #endif /* TRSTABLE_H */ diff --git a/src/UCAuto.c b/src/UCAuto.c index e37944ff..fec1b052 100644 --- a/src/UCAuto.c +++ b/src/UCAuto.c @@ -210,10 +210,10 @@ PUBLIC void UCChangeTerminalCodepage ARGS2( } else if (lastcs < 0 && old_umap == 0 && old_font == 0) { FILE * fp1; FILE * fp2 = NULL; - if ((old_font = calloc(1, LY_MAXPATH))) - old_umap = calloc(1, LY_MAXPATH); - if ((fp1 = LYOpenTemp(old_font, ".fnt", "wb"))) - fp2 = LYOpenTemp(old_umap, ".uni", "wb"); + if ((old_font = typecallocn(char, LY_MAXPATH))) + old_umap = typecallocn(char, LY_MAXPATH); + if ((fp1 = LYOpenTemp(old_font, ".fnt", BIN_W))) + fp2 = LYOpenTemp(old_umap, ".uni", BIN_W); if (fp1 && fp2) { size_t nlen; char *rp; @@ -543,7 +543,7 @@ PRIVATE int _Switch_Display_Charset ARGS2 (int, ord, int, really) { CONST char *name; unsigned short cp; - static int font_loaded_for = -1; + static int font_loaded_for = -1, old_h, old_w; int rc, ord1; UCHAR msgbuf[MAXPATHLEN + 80]; @@ -581,10 +581,7 @@ PRIVATE int _Switch_Display_Charset ARGS2 (int, ord, int, really) } /* Not a "prepared" codepage. Need to load the user font. */ - if (ord1 == font_loaded_for) { /* The same as the previous font */ - if ((rc = VioSetCp(0, -1, 0))) /* -1: User font */ - goto err; - } else if (charsets_directory) { + if (charsets_directory) { TIB *tib; /* Can't load font in a windowed-VIO */ PIB *pib; VIOFONTINFO f[2]; @@ -597,7 +594,8 @@ PRIVATE int _Switch_Display_Charset ARGS2 (int, ord, int, really) long i, j; /* 0 means a FS protected-mode session */ - if (DosGetInfoBlocks(&tib, &pib) || pib->pib_ultype != 0) { + if ( font_loaded_for == -1 /* Did not try it yet */ + && (DosGetInfoBlocks(&tib, &pib) || pib->pib_ultype != 0) ) { ord = ord1 = auto_display_charset; goto retry; } @@ -619,9 +617,16 @@ PRIVATE int _Switch_Display_Charset ARGS2 (int, ord, int, really) ord = ord1 = auto_display_charset; goto retry; } + if ( ord1 == font_loaded_for + && old_h == font->cyCell && old_w == font->cxCell ) { + /* The same as the previous font */ + if ((rc = VioSetCp(0, -1, 0))) /* -1: User font */ + goto err; + goto report; + } sprintf(fnamebuf, "%s/%dx%d/%s.fnt", charsets_directory, font->cyCell, font->cxCell, name); - file = fopen(fnamebuf,"rb"); + file = fopen(fnamebuf, BIN_R); if (!file) { sprintf(msgbuf, "Can't open font file '%s'", fnamebuf); HTInfoMsg(msgbuf); @@ -645,9 +650,12 @@ PRIVATE int _Switch_Display_Charset ARGS2 (int, ord, int, really) sprintf(msgbuf, "Can't set font: err=%#lx=%ld", rc, rc); HTInfoMsg(msgbuf); ord = ord1 = auto_display_charset; + font_loaded_for = -1; goto retry; } font_loaded_for = ord1; + old_h = font->cyCell; + old_w = font->cxCell; } report: CTRACE((tfp, "Display font set to '%s'.\n", name)); diff --git a/src/Xsystem.c b/src/Xsystem.c index 56cac70d..969f90d5 100644 --- a/src/Xsystem.c +++ b/src/Xsystem.c @@ -1,4 +1,4 @@ -/* @Id: Xsystem.c 1.9 Mon, 26 Feb 2001 18:41:57 -0800 dickey @ +/* @Id: Xsystem.c 1.10 Sun, 01 Apr 2001 17:51:46 -0700 dickey @ * like system("cmd") but return with exit code of "cmd" * for Turbo-C/MS-C/LSI-C * This code is in the public domain. @@ -86,7 +86,7 @@ xmalloc(size_t n) { char *bp; - if ((bp = calloc(1, n)) == (char *) 0) { + if ((bp = typecallocn(char, n)) == 0) { write(2, "xsystem: Out of memory.!\n", 25); exit(1); } diff --git a/src/chrtrans/makefile.in b/src/chrtrans/makefile.in index 52cf5524..d399a0e5 100644 --- a/src/chrtrans/makefile.in +++ b/src/chrtrans/makefile.in @@ -29,6 +29,7 @@ SITE_DEFS = # FIXME: set in parent makefile CC = @CC@ CPP = @CPP@ CFLAGS = @CFLAGS@ +_O = .o CPP_OPTS = @DEFS@ @CPPFLAGS@ \ -I$(top_builddir) \ @@ -93,14 +94,14 @@ default: $(FONTMAP_INC) tables: $(TABLES) -makeuctb$x: makeuctb.o - $(CC) $(CC_OPTS) $(LDFLAGS) -o $@ makeuctb.o $(INTLLIB) $(LIBS) +makeuctb$x: makeuctb$(_O) + $(CC) $(CC_OPTS) $(LDFLAGS) -o $@ makeuctb$(_O) $(INTLLIB) $(LIBS) -makeuctb.o: $(srcdir)/UCkd.h $(srcdir)/makeuctb.c +makeuctb$(_O): $(srcdir)/UCkd.h $(srcdir)/makeuctb.c -.SUFFIXES : .tbl .i +.SUFFIXES : $(_O) .tbl .i -.c.o: +.c$(_O): @RULE_CC@ @ECHO_CC@$(CC) $(CC_OPTS) -c $(srcdir)/$*.c @@ -155,7 +156,7 @@ utf8_uni.h: $(srcdir)/utf8_uni.tbl makeuctb$x viscii_uni.h: $(srcdir)/viscii_uni.tbl makeuctb$x clean: - rm -f makeuctb$x *.o *uni.h *uni2.h + rm -f makeuctb$x *$(_O) *uni.h *uni2.h distclean: clean -rm -rf obsolete diff --git a/src/makefile.dos b/src/makefile.dos index 7c29b2c2..880c151a 100644 --- a/src/makefile.dos +++ b/src/makefile.dos @@ -22,9 +22,7 @@ DIRED_DEFS = \ # Use this option to enable optional and *experimental* color style. #ENABLE_COLOR_STYLE = \ - -DUSE_COLOR_STYLE \ - -DUSE_HASH \ - -DLINKEDSTYLES + -DUSE_COLOR_STYLE CC = gcc diff --git a/src/makefile.in b/src/makefile.in index f76c6bef..36bdb424 100644 --- a/src/makefile.in +++ b/src/makefile.in @@ -24,6 +24,7 @@ CFLAGS = @CFLAGS@ DEFS = @DEFS@ CHARSET_DEFS = @CHARSET_DEFS@ CPPFLAGS = @CPPFLAGS@ +_O = .o LIBS = @LIBS@ $(RESOLVLIB) $(WAISLIB) $(SITE_LIBS) LDFLAGS = @LDFLAGS@ @@ -58,24 +59,26 @@ LINTOPTS = COMPRESS_PROG =@COMPRESS_PROG@ COMPRESS_EXT =@COMPRESS_EXT@ -CHARTRANS_OBJS=UCdomap.o UCAux.o UCAuto.o -OBJS= LYClean.o LYShowInfo.o LYEdit.o LYStrings.o \ -LYMail.o HTAlert.o GridText.o LYGetFile.o \ -LYMain.o LYMainLoop.o LYCurses.o LYBookmark.o LYUtils.o \ -LYOptions.o LYReadCFG.o LYSearch.o LYHistory.o \ -LYForms.o LYPrint.o LYrcFile.o LYDownload.o LYNews.o LYKeymap.o \ -HTML.o HTFWriter.o HTInit.o DefaultStyle.o LYUpload.o \ -LYLeaks.o LYexit.o LYJump.o LYList.o LYCgi.o LYTraversal.o \ -LYEditmap.o LYCharSets.o LYCharUtils.o LYMap.o LYCookie.o \ -LYStyle.o LYHash.o LYPrettySrc.o TRSTable.o $(CHARTRANS_OBJS) @LIBOBJS@ - -C_SRC = $(OBJS:.o=.c) +CHARTRANS_OBJS = UCdomap$(_O) UCAux$(_O) UCAuto$(_O) +OBJS = \ + LYClean$(_O) LYShowInfo$(_O) LYEdit$(_O) LYStrings$(_O) LYMail$(_O) \ + HTAlert$(_O) GridText$(_O) LYGetFile$(_O) LYMain$(_O) LYMainLoop$(_O) \ + LYCurses$(_O) LYBookmark$(_O) LYUtils$(_O) LYOptions$(_O) \ + LYReadCFG$(_O) LYSearch$(_O) LYHistory$(_O) LYForms$(_O) LYPrint$(_O) \ + LYrcFile$(_O) LYDownload$(_O) LYNews$(_O) LYKeymap$(_O) HTML$(_O) \ + HTFWriter$(_O) HTInit$(_O) DefaultStyle$(_O) LYUpload$(_O) \ + LYLeaks$(_O) LYexit$(_O) LYJump$(_O) LYList$(_O) LYCgi$(_O) \ + LYTraversal$(_O) LYEditmap$(_O) LYCharSets$(_O) LYCharUtils$(_O) \ + LYMap$(_O) LYCookie$(_O) LYStyle$(_O) LYHash$(_O) LYPrettySrc$(_O) \ + TRSTable$(_O) $(CHARTRANS_OBJS) @LIBOBJS@ + +C_SRC = $(OBJS:$(_O)=.c) all: lynx$x -.SUFFIXES : .i +.SUFFIXES : $(_O) .i -.c.o: +.c$(_O): @RULE_CC@ @ECHO_CC@$(CC) $(CC_OPTS) -c $(srcdir)/$*.c @@ -112,21 +115,21 @@ distclean: clean CMN=$(top_srcdir)/WWW/Library/Implementation/ -HTFWriter.o: $(top_srcdir)/userdefs.h -HTInit.o: $(top_srcdir)/userdefs.h -LYCharSets.o: $(top_srcdir)/userdefs.h -LYGetFile.o: $(top_srcdir)/userdefs.h -LYKeymap.o: $(top_srcdir)/userdefs.h -LYMail.o: $(top_srcdir)/userdefs.h -LYMain.o: $(top_srcdir)/userdefs.h $(top_builddir)/lynx_cfg.h -LYMainLoop.o: $(top_srcdir)/userdefs.h -LYOptions.o: $(top_srcdir)/userdefs.h -LYReadCFG.o: $(top_srcdir)/userdefs.h -LYShowInfo.o: $(top_builddir)/cfg_defs.h -LYTraversal.o: $(top_srcdir)/userdefs.h -LYUtils.o: $(top_srcdir)/userdefs.h -LYrcFile.o: $(top_srcdir)/userdefs.h -LYLeaks.o: $(CMN)LYLeaks.h $(CMN)HTString.h +HTFWriter$(_O): $(top_srcdir)/userdefs.h +HTInit$(_O): $(top_srcdir)/userdefs.h +LYCharSets$(_O): $(top_srcdir)/userdefs.h +LYGetFile$(_O): $(top_srcdir)/userdefs.h +LYKeymap$(_O): $(top_srcdir)/userdefs.h +LYMail$(_O): $(top_srcdir)/userdefs.h +LYMain$(_O): $(top_srcdir)/userdefs.h $(top_builddir)/lynx_cfg.h +LYMainLoop$(_O): $(top_srcdir)/userdefs.h +LYOptions$(_O): $(top_srcdir)/userdefs.h +LYReadCFG$(_O): $(top_srcdir)/userdefs.h +LYShowInfo$(_O): $(top_builddir)/cfg_defs.h +LYTraversal$(_O): $(top_srcdir)/userdefs.h +LYUtils$(_O): $(top_srcdir)/userdefs.h +LYrcFile$(_O): $(top_srcdir)/userdefs.h +LYLeaks$(_O): $(CMN)LYLeaks.h $(CMN)HTString.h CHRTR= chrtrans/ @@ -173,14 +176,14 @@ TABLES= \ $(TABLES): -cd chrtrans && $(MAKE) tables -UCdomap.o: UCdomap.c chrtrans/UCkd.h chrtrans/makeuctb$x chrtrans/makeuctb.c \ +UCdomap$(_O): UCdomap.c chrtrans/UCkd.h chrtrans/makeuctb$x chrtrans/makeuctb.c \ UCdomap.h $(CMN)UCMap.h $(TABLES) $(top_srcdir)/userdefs.h chrtrans/makeuctb$x: cd chrtrans; make makeuctb$x -UCAux.o : UCAux.c $(CMN)UCAux.h $(CMN)UCDefs.h -LYCookie.o: $(top_srcdir)/userdefs.h +UCAux$(_O) : UCAux.c $(CMN)UCAux.h $(CMN)UCDefs.h +LYCookie$(_O): $(top_srcdir)/userdefs.h depend : $(TABLES) makedepend -fmakefile -- $(CC_OPTS) -- $(C_SRC) |