diff options
author | Thomas E. Dickey <dickey@invisible-island.net> | 2024-03-21 08:19:13 +0000 |
---|---|---|
committer | Thomas E. Dickey <dickey@invisible-island.net> | 2024-03-21 08:20:16 +0000 |
commit | 3d3885fb9f3b182a8173a424622a46ac3b9b4a34 (patch) | |
tree | ea31000ebe64e3d62146e0e9e46cac706d9acf3f /src | |
parent | 1743c6cf472c71de8ecbcbcfed7966be34a11743 (diff) | |
download | lynx-snapshots-3d3885fb9f3b182a8173a424622a46ac3b9b4a34.tar.gz |
snapshot of project "lynx", label v2-9-0e
Diffstat (limited to 'src')
-rw-r--r-- | src/GridText.c | 6 | ||||
-rw-r--r-- | src/LYBookmark.c | 267 | ||||
-rw-r--r-- | src/LYIcon.rc | 10 | ||||
-rw-r--r-- | src/chrtrans/README.tables | 2 |
4 files changed, 266 insertions, 19 deletions
diff --git a/src/GridText.c b/src/GridText.c index 806a0533..999afc76 100644 --- a/src/GridText.c +++ b/src/GridText.c @@ -1,5 +1,5 @@ /* - * $LynxId: GridText.c,v 1.347 2024/01/15 19:11:55 Gisle.Vanem Exp $ + * $LynxId: GridText.c,v 1.348 2024/03/18 07:57:58 tom Exp $ * * Character grid hypertext object * =============================== @@ -6002,7 +6002,7 @@ static void HText_trimHightext(HText *text, int final, int stop_before) { - int cur_line, cur_shift; + int cur_line; TextAnchor *anchor_ptr; TextAnchor *prev_a = NULL; HTLine *line_ptr; @@ -6097,7 +6097,6 @@ static void HText_trimHightext(HText *text, anchor_ptr->number, anchor_ptr->extent)); - cur_shift = 0; /* * Strip off any spaces or SpecialAttrChars at the beginning, * if they exist, but only on HYPERTEXT_ANCHORS. @@ -6108,7 +6107,6 @@ static void HText_trimHightext(HText *text, IsSpecialAttrChar(ch)) { anchor_ptr->line_pos++; anchor_ptr->extent--; - cur_shift++; ch = UCH(line_ptr->data[anchor_ptr->line_pos]); } } diff --git a/src/LYBookmark.c b/src/LYBookmark.c index 73416fc1..fd77823c 100644 --- a/src/LYBookmark.c +++ b/src/LYBookmark.c @@ -1,5 +1,5 @@ /* - * $LynxId: LYBookmark.c,v 1.89 2024/03/15 10:04:29 KIHARA.Hideto Exp $ + * $LynxId: LYBookmark.c,v 1.92 2024/03/21 07:34:18 tom Exp $ */ #include <HTUtils.h> #include <HTAlert.h> @@ -202,6 +202,159 @@ static char *title_convert8bit(const char *Title); #define ftruncate(fd, len) _chsize(fd, len) #endif +static const char *visible_char(int ch) +{ + static char result[8]; + + if (ch < 32) { + sprintf(result, "^%c", ch | '@'); + } else if (ch == 32) { + strcpy(result, "SP"); + } else if (ch < 127) { + sprintf(result, "%c", ch); + } else if (ch == 127) { + strcpy(result, "DEL"); + } else { + sprintf(result, "\\%03o", ch & 0xff); + } + return result; +} + +typedef enum { + scanUnknown /* markup which we do not care about */ + ,scanHeadOL + ,scanHeadUL + ,scanTailOL + ,scanTailUL + ,scanTailBody + ,scanTailHtml + ,scanIgnore /* whitespace */ +} SCAN_TRAILING; + +#define SCAN_LEN 10 /* longest interesting tag is 6 characters */ + +/* + * Scan the bookmark file data, looking for a trailing "</ul>" or "</ol>". + * Keep track of "<ul> and "<ol>", and allow for comments. + */ +static int scan_trailing(FILE *ofp, + FILE *ifp, + char chunk[SCAN_LEN], + int *matched, + int *comment, + SCAN_TRAILING * scanned) +{ + /* *INDENT-OFF* */ + static const struct { + SCAN_TRAILING code; + const char name[SCAN_LEN]; + } table[] = { + { scanHeadOL, "<OL>" }, + { scanHeadUL, "<UL>" }, + { scanTailOL, "</OL>" }, + { scanTailUL, "</UL>" }, + { scanTailBody, "</BODY>" }, + { scanTailHtml, "</HTML>" }, + }; + /* *INDENT-ON* */ + + int status = FALSE; + int ch = fgetc(ifp); + + *scanned = scanUnknown; + if (!feof(ifp) && !ferror(ifp)) { + int uc = TOUPPER(ch); + int keep = FALSE; + + if (isspace(UCH(uc))) + *scanned = scanIgnore; + + switch (uc) { + case '<': + if (!*comment) { + *matched = 0; + keep = TRUE; + } + break; + case '!': + if (!*comment && *matched == 1) { + keep = TRUE; + } else + CTRACE((tfp, "...comment %d matched %d\n", *comment, *matched)); + break; + case '-': + if (*comment) { + /* look for "-->" */ + if (*matched == 0 || (*matched == 1 && chunk[0] == '-')) + keep = TRUE; + } else { + /* look for "<!--" */ + if (*matched == 3) { + if (!strncmp(chunk, "<!-", 3)) { + *comment = TRUE; + keep = TRUE; + } + } else if (*matched == 2) { + keep = TRUE; + } + } + break; + case '>': + if (*comment) { + /* look for "-->" */ + if ((*matched == 1 || *matched == 2) && chunk[0] == '-') { + *comment = FALSE; + keep = TRUE; + } + } else { + keep = TRUE; + } + break; + default: + if (isalpha(uc) || uc == '/') { + keep = !*comment; + } else { + keep = FALSE; + } + break; + } + + if (keep) { + if (*matched < (SCAN_LEN - 2)) { + chunk[*matched] = (char) uc; + *matched += 1; + if (uc == '>') { + unsigned n; + + chunk[*matched] = 0; + for (n = 0; n < TABLESIZE(table); ++n) { + if (!strcmp(chunk, table[n].name)) { + *scanned = table[n].code; + CTRACE2(TRACE_SGML, (tfp, "...matched '%s'\n", + chunk)); + break; + } + } + } + } else { + *matched = 0; + } + } else { + *matched = 0; + } + chunk[*matched] = 0; + + CTRACE2(TRACE_SGML, (tfp, "%s %s%s:%d:%s\n", + keep ? "KEEP" : "SKIP", + *comment ? "*" : "", + visible_char(uc), *matched, chunk)); + + fputc(ch, ofp); + status = TRUE; + } + return status; +} + /* * Adds a link to a bookmark file, creating the file if it doesn't already * exist, and making sure that no_cache is set for a pre-existing, cached file, @@ -217,6 +370,7 @@ void save_bookmark_link(const char *address, char filename_buffer[LY_MAXPATH]; char *Address = NULL; char *Title = NULL; + char *trailing_tag = NULL; int i, c; bstring *string_data = NULL; bstring *tmp_data = NULL; @@ -366,30 +520,123 @@ void save_bookmark_link(const char *address, StrAllocCopy(Address, address); LYEntify(&Address, FALSE); + /* + * Copy the existing bookmark file to a temporary file, to allow update. + */ if (!first_time) { BOOLEAN empty_file = TRUE; FILE *bp = tmpfile(); - char *buffer = NULL; + char chunk[SCAN_LEN]; + int ch; + int offset_Chr = 0; + int offset_Tag = 0; + int limit_Edit = -1; + int last_OL = -1; + int last_UL = -1; + int count_OL = 0; + int count_UL = 0; + int matched = 0; + int comment = FALSE; + char found_tag[scanIgnore + 1]; + SCAN_TRAILING scanned = scanUnknown; rewind(fp); - while (LYSafeGets(&buffer, fp)) { + memset(found_tag, 0, sizeof(found_tag)); + while (scan_trailing(bp, fp, chunk, &matched, &comment, &scanned)) { empty_file = FALSE; - if (LYstrstr(buffer, "</ol>")) + + /* remember where the most recent tag starts */ + if (matched == 0) + offset_Tag = offset_Chr; + + found_tag[scanned] = TRUE; + switch (scanned) { + case scanUnknown: + case scanIgnore: + break; + case scanHeadOL: + ++count_OL; + break; + case scanHeadUL: + ++count_UL; + break; + case scanTailOL: + count_OL--; + last_OL = offset_Tag; break; - fprintf(bp, "%s", buffer); + case scanTailUL: + count_UL--; + last_UL = offset_Tag; + break; + case scanTailBody: + case scanTailHtml: + if (limit_Edit < 0) + limit_Edit = offset_Tag; + break; + } + + ++offset_Chr; } fflush(bp); rewind(bp); + /* if no BODY/HTML tag ends the file, treat it as the whole file */ + if (limit_Edit < 0) + limit_Edit = offset_Chr; + + /* if the last UL/OL offsets differ, at least one is valid */ + if (last_UL > last_OL) { + if (limit_Edit > last_UL) + limit_Edit = last_UL; + } else if (last_OL > last_UL) { + if (limit_Edit > last_OL) + limit_Edit = last_OL; + } else { + /* the initial file uses an ordered list; users may edit */ + if (count_UL > count_OL) + StrAllocCopy(trailing_tag, "</ul>"); + else + StrAllocCopy(trailing_tag, "</ol>"); + } + + if (TRACE) { + CTRACE((tfp, "Existing file length %d, insert at %d\n", + offset_Chr, limit_Edit)); + if (limit_Edit == last_UL) { + CTRACE((tfp, "...insert before last </UL>: %d\n", last_UL)); + } else if (limit_Edit == last_OL) { + CTRACE((tfp, "...insert before last </OL>: %d\n", last_OL)); + } else if (trailing_tag != NULL) { + CTRACE((tfp, "...append with %s\n", trailing_tag)); + } + } + rewind(fp); - ftruncate(fileno(fp), 0); + if (ftruncate(fileno(fp), 0) == -1) { + CTRACE((tfp, "%s: %s\n", filename_buffer, strerror(errno))); + } - while (LYSafeGets(&buffer, bp)) { - fprintf(fp, "%s", buffer); + offset_Chr = 0; + while ((ch = fgetc(bp)) != EOF && !ferror(bp)) { + if (offset_Chr <= limit_Edit) + fputc(ch, fp); + else { + char buffer[2]; + + buffer[0] = (char) ch; + buffer[1] = 0; + StrAllocCat(trailing_tag, buffer); + } + ++offset_Chr; } fclose(bp); + if (!found_tag[scanTailBody]) + StrAllocCat(trailing_tag, "</body>"); + if (!found_tag[scanTailHtml]) + StrAllocCat(trailing_tag, "</html>"); + if (empty_file) first_time = TRUE; } @@ -447,8 +694,10 @@ Note: if you edit this file manually\n\ fprintf(fp, "%s %s%s\n", Address, TimeString, Title); } else { fprintf(fp, "<li><a href=\"%s\">%s</a></li>\n", Address, Title); - fprintf(fp, "</ol></body></html>\n"); + if (trailing_tag != NULL) + fputs(trailing_tag, fp); } + free(trailing_tag); LYCloseOutput(fp); SetDefaultMode(O_BINARY); diff --git a/src/LYIcon.rc b/src/LYIcon.rc index 1a817bcb..87ab0efd 100644 --- a/src/LYIcon.rc +++ b/src/LYIcon.rc @@ -1,12 +1,12 @@ -// $LynxId: LYIcon.rc,v 1.61 2024/03/15 22:47:43 tom Exp $ +// $LynxId: LYIcon.rc,v 1.62 2024/03/18 07:49:07 tom Exp $ #include <windows.h> 100 ICON "../samples/lynx.ico" VS_VERSION_INFO VERSIONINFO -FILEVERSION 2,9,0,2004 -PRODUCTVERSION 2,9,0,2004 +FILEVERSION 2,9,0,2005 +PRODUCTVERSION 2,9,0,2005 FILEFLAGSMASK VS_FFI_FILEFLAGSMASK FILEFLAGS 0 FILEOS VOS_NT_WINDOWS32 @@ -19,12 +19,12 @@ BEGIN BEGIN VALUE "CompanyName", "https://invisible-island.net/lynx" VALUE "FileDescription", "Lynx - web browser" - VALUE "FileVersion", "2.9.0.2004" + VALUE "FileVersion", "2.9.0.2005" VALUE "InternalName", "Lynx" VALUE "LegalCopyright", "©1997-2024 Thomas E. Dickey" VALUE "OriginalFilename", "lynx.exe" VALUE "ProductName", "Lynx - web browser" - VALUE "ProductVersion", "2.9.0.2004" + VALUE "ProductVersion", "2.9.0.2005" END END BLOCK "VarFileInfo" diff --git a/src/chrtrans/README.tables b/src/chrtrans/README.tables index 14431dad..911d795a 100644 --- a/src/chrtrans/README.tables +++ b/src/chrtrans/README.tables @@ -71,6 +71,6 @@ Lynx, a `make clean' should not be necessary if you have *only* made changes to the files in src/chrtrans. On VMS, add entries for new tables to build-chrtrans.com, but you can update the particular file with build-header.com, then use the top directory's build.com and -answer 'n' to it's prompts about whether to update the WWWlibrary +answer 'n' to its prompts about whether to update the WWW library and chrtrans modules. |