mirror of
https://github.com/rkd77/elinks.git
synced 2024-11-04 08:17:17 -05:00
Merge with http://elinks.cz/elinks.git
This commit is contained in:
commit
9deceafa0b
@ -294,7 +294,7 @@ b.Xi ISOgrk4 0x039E # GREEK CAPITAL LETTER XI
|
||||
b.alpha ISOgrk4 0x03B1 # GREEK SMALL LETTER ALPHA
|
||||
b.beta ISOgrk4 0x03B2 # GREEK SMALL LETTER BETA
|
||||
b.chi ISOgrk4 0x03C7 # GREEK SMALL LETTER CHI
|
||||
b.delta ? 0x03B3 # GREEK SMALL LETTER GAMMA
|
||||
b.delta ISOgrk4 0x03B4 # GREEK SMALL LETTER DELTA
|
||||
b.epsi ISOgrk4 0x03B5 # GREEK SMALL LETTER EPSILON
|
||||
b.epsis ISOgrk4 0x03B5 # GREEK SMALL LETTER EPSILON
|
||||
b.epsiv ISOgrk4 0x03B5 # GREEK SMALL LETTER EPSILON
|
||||
|
30
doc/Makefile
30
doc/Makefile
@ -49,6 +49,11 @@ ELINKS = $(top_builddir)/src/elinks
|
||||
KBDBIND = $(top_srcdir)/src/config/kbdbind.c
|
||||
FEATURES = $(top_srcdir)/features.conf
|
||||
|
||||
### Locale env vars to override system one to ensure commands
|
||||
# using elinks binary will generate texts in english
|
||||
#
|
||||
LOCALES = LC_ALL=C LANGUAGE=en
|
||||
|
||||
### Scripts
|
||||
#
|
||||
|
||||
@ -59,7 +64,7 @@ MAKE_ELINKS_MANPAGE = $(top_srcdir)/doc/tools/make-elinks-manpage
|
||||
MAKE_ELINKSKEYS_MANPAGE = $(top_srcdir)/doc/tools/make-elinkskeys-manpage
|
||||
|
||||
HTML_DOCS-$(CONFIG_ASCIIDOC) += \
|
||||
api/dom-sgml-parser.html \
|
||||
api/dom.html \
|
||||
elinks.1.html \
|
||||
elinkskeys.5.html \
|
||||
hacking.html \
|
||||
@ -109,10 +114,10 @@ $(TXT_DIR)/import-features.conf.txt: $(FEATURES) $(IMPORT_FEATURES_CONF)
|
||||
$(IMPORT_FEATURES_CONF) > $@
|
||||
|
||||
$(TXT_DIR)/elinks.1.%.txt: $(MAKE_ELINKS_MANPAGE) $(ELINKS)
|
||||
$(MAKE_ELINKS_MANPAGE) $@ $(ELINKS) $(HELP2DOC) > $@
|
||||
$(LOCALES) $(MAKE_ELINKS_MANPAGE) $@ $(ELINKS) $(HELP2DOC) > $@
|
||||
|
||||
$(TXT_DIR)/elinkskeys.5.%.txt: $(MAKE_ELINKSKEYS_MANPAGE) $(KBDBIND)
|
||||
$(MAKE_ELINKSKEYS_MANPAGE) $@ $(KBDBIND) > $@
|
||||
$(LOCALES) $(MAKE_ELINKSKEYS_MANPAGE) $@ $(KBDBIND) > $@
|
||||
|
||||
|
||||
# Man Pages
|
||||
@ -122,15 +127,19 @@ $(XML_DIR)/%.man.xml: $(TXT_DIR)/%.man.txt
|
||||
|
||||
$(MAN_DIR)/man1/elinks.1.in: $(XML_DIR)/elinks.1.man.xml
|
||||
$(XMLTO) -o $(MAN_DIR)/man1 man $<
|
||||
mv $(MAN_DIR)/man1/elinks.1 $@
|
||||
sed 's/^\.TH "ELINKS" 1 .*/.TH "ELINKS" 1 "The ELinks text-browser" "$(shell date -I)" "The ELinks text-browser"/' \
|
||||
< $(MAN_DIR)/man1/elinks.1 > $@
|
||||
rm $(MAN_DIR)/man1/elinks.1
|
||||
|
||||
$(MAN_DIR)/man5/elinkskeys.5: $(XML_DIR)/elinkskeys.5.man.xml
|
||||
$(XMLTO) -o $(MAN_DIR)/man5 man $<
|
||||
sed -e 's/\\fI\\fR'\''/\\fI\\'\''\\fR/' < $@ > $@.tmp
|
||||
mv $@.tmp $@
|
||||
sed 's/^\.TH "ELINKSKEYS" 5 .*/.TH "ELINKSKEYS" 5 "ELinks keybindings" "$(shell date -I)" "ELinks keybindings"/' \
|
||||
< $@.tmp > $@
|
||||
rm $@.tmp
|
||||
|
||||
$(MAN_DIR)/man5/elinks.conf.5: $(ELINKS)
|
||||
$(HELP2DOC) --elinks=$(ELINKS) --elinksconf > $@
|
||||
$(LOCALES) $(HELP2DOC) --elinks=$(ELINKS) --elinksconf > $@
|
||||
|
||||
# XHTML/CSS Man Pages
|
||||
|
||||
@ -171,7 +180,12 @@ $(HTML_DIR)/perl-hooks.html: $(top_srcdir)/contrib/perl/hooks.pl
|
||||
## API Docs
|
||||
#
|
||||
|
||||
$(HTML_DIR)/api/dom-sgml-parser.html: $(top_srcdir)/src/dom/sgml/parser.h
|
||||
$(CODE2DOC) $< | $(ASCIIDOC) -f code2doc.conf -b xhtml11 -d book -o $@ -n -
|
||||
DOM_API = \
|
||||
$(top_srcdir)/src/dom/scanner.h \
|
||||
$(top_srcdir)/src/dom/stack.h \
|
||||
$(top_srcdir)/src/dom/sgml/parser.h
|
||||
|
||||
$(HTML_DIR)/api/dom.html: $(DOM_API)
|
||||
$(CODE2DOC) $(DOM_API) | $(ASCIIDOC) -f code2doc.conf -b xhtml11 -d book -o $@ -n -
|
||||
|
||||
include $(top_srcdir)/Makefile.lib
|
||||
|
@ -6,16 +6,19 @@ monospacedwords=\basciidoc\(1\)
|
||||
<a id="{0}" href="#{0}">{0}</a>
|
||||
|
||||
[enum-inlinemacro]
|
||||
<a id="{0}" href="#{0}">enum {0}</a>
|
||||
<a id="{target}">enum {target}: {0}</a>
|
||||
|
||||
[func-inlinemacro]
|
||||
<a id="{0}" href="#{0}">{0}()</a>
|
||||
<a id="{target}">{target}(): {0}</a>
|
||||
|
||||
[struct-inlinemacro]
|
||||
<a id="{0}" href="#{0}">struct {0}</a>
|
||||
<a id="{target}">struct {target}: {0}</a>
|
||||
|
||||
[callback-inlinemacro]
|
||||
<a id="{0}" href="#{0}">callback {0}</a>
|
||||
[macro-inlinemacro]
|
||||
<a id="{target}">struct {target}: {0}</a>
|
||||
|
||||
[typedef-inlinemacro]
|
||||
<a id="{target}">typedef {target}: {0}</a>
|
||||
|
||||
[ref-inlinemacro]
|
||||
<a href="{target}#{0}">{0}</a>
|
||||
|
@ -17,7 +17,7 @@
|
||||
.el .ne 3
|
||||
.IP "\\$1" \\$2
|
||||
..
|
||||
.TH "ELINKS" 1 "" "" ""
|
||||
.TH "ELINKS" 1 "The ELinks text-browser" "2006-01-10" "The ELinks text-browser"
|
||||
.SH NAME
|
||||
elinks \- lynx-like alternative character mode WWW browser
|
||||
.SH "SYNOPSIS"
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\" elinks.conf.5
|
||||
.\"
|
||||
.\" Generated by help2doc (Revision: 1.19) on 03 January 06 using output from ELinks version 0.12.GIT.
|
||||
.\" Generated by help2doc (Revision: 1.19) on 2006-01-10 using output from ELinks version 0.12.GIT.
|
||||
.\"
|
||||
.\" Copyleft (c) 2002-2004 The ELinks project
|
||||
.\"
|
||||
@ -8,7 +8,7 @@
|
||||
.\" General Public License. <www.gnu.org/licenses/gpl.html>
|
||||
.\"
|
||||
.\" Process this file with groff -man -Tascii elinks.conf.5
|
||||
.TH ELINKS.CONF 5 \"03 January 06\"
|
||||
.TH ELINKS.CONF 5 "ELinks configuration file" "2006-01-10" "ELinks configuration file"
|
||||
|
||||
.SH NAME
|
||||
elinks.conf \- ELinks configuration file
|
||||
@ -50,7 +50,7 @@ set document.browse.margin_width = 3
|
||||
# Default document codepage.
|
||||
set document.codepage.assume = "ISO-8859-1"
|
||||
# User defined protocol handlers
|
||||
set protocol.user.mailto.unix = "mutt %h -s \"%s\""
|
||||
set protocol.user.mailto.unix = "mutt %h -s \e\*(lq%s\e\*(rq"
|
||||
|
||||
.SH OPTIONS
|
||||
.SS Bookmarks (bookmarks)
|
||||
@ -784,8 +784,6 @@ in dump output.
|
||||
.TP
|
||||
\f3document.dump.separator\f2 <str>\f1 (document.dump.separator <str> (default: ")
|
||||
.TP
|
||||
\f3String\f2 Swhich\f1 (String which separates two dumps.)
|
||||
.TP
|
||||
\f3document.dump.width\f2 <num>\f1 (default: 80)
|
||||
Width of screen in characters when dumping documents.
|
||||
.PD
|
||||
@ -2162,8 +2160,6 @@ Keep the session active even if the last terminal exits.
|
||||
Automatically save a snapshot of all tabs periodically.
|
||||
This will periodically bookmark the tabs of each terminal in a separate folder
|
||||
for recovery after a crash.
|
||||
.TP
|
||||
\f3This\f2 Tfeature\f1 (This feature requires bookmark support.)
|
||||
.SS Window tabs (ui.tabs)
|
||||
Window tabs settings.
|
||||
.TP
|
||||
@ -2246,7 +2242,7 @@ in an xterm-like terminal. This way the document's title is
|
||||
shown on the window titlebar.
|
||||
.SH "DOCUMENT INFO"
|
||||
.PP
|
||||
Generated by help2doc (Revision: 1.19) on 03 January 06 using output from ELinks version 0.12.GIT.
|
||||
Generated by help2doc (Revision: 1.19) on 2006-01-10 using output from ELinks version 0.12.GIT.
|
||||
help2doc is distributed with ELinks under the terms of the GPL.
|
||||
.SH "SEE ALSO"
|
||||
.BR elinks (1),
|
||||
|
@ -17,7 +17,7 @@
|
||||
.el .ne 3
|
||||
.IP "\\$1" \\$2
|
||||
..
|
||||
.TH "ELINKSKEYS" 5 "" "" ""
|
||||
.TH "ELINKSKEYS" 5 "ELinks keybindings" "2006-01-10" "ELinks keybindings"
|
||||
.SH NAME
|
||||
elinkskeys \- keybindings for ELinks
|
||||
.SH "SYNOPSIS"
|
||||
|
@ -2,45 +2,111 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
use diagnostics;
|
||||
use Getopt::Std;
|
||||
|
||||
print "Usage: $0 [FILE]\n\tParses [FILE], outputing the result to stdout.\n"
|
||||
and exit if not @ARGV;
|
||||
my $HELP = "Usage: $0 [FILE]...
|
||||
Parses [FILE], outputing the result to stdout.";
|
||||
|
||||
my ($input) = @ARGV;
|
||||
my ($found, $start, $first, $gotone, $idpath);
|
||||
print "Copyleft© 2006, Russ Rowan (See `COPYING')\n" and exit if $input eq '-v';
|
||||
open FILEIN, "<$input" or print "File `$input' was not found.\n" and exit;
|
||||
$idpath = '';
|
||||
while (<FILEIN>)
|
||||
{
|
||||
if ($found)
|
||||
{
|
||||
if ($_ =~ /^\s+\*\s$/) { next if $first; $_ =~ s/\s\*// if not $first; }
|
||||
if ($_ =~ /^\s\*+\/$/ or $_ !~ /^\s/) { $found = undef; next; }
|
||||
$_ =~ s/^(\s*)\s\*\s/$1/;
|
||||
$found = 'sorta' if $_ =~ s/\s*\*\/$/\n/; $first = undef;
|
||||
}
|
||||
elsif ($_ =~ /^\s*\/\*\*\s(.*)/)
|
||||
{
|
||||
$_ = $1; $first = 1;
|
||||
print STDOUT "\n\n" if $start;
|
||||
if ($_ =~ s/\s*\*\/$//) { $found = 'sorta'; } else { $found = $.; }
|
||||
if ($_ =~ /struct:[[]([^\]]+)[\]]/) { $idpath = "$1."; } else { $idpath = ''; }
|
||||
if ($_ =~ /::/) { $_ = "$_\n\n"; }
|
||||
else
|
||||
{
|
||||
my $dash; for (my $x = 0; $x < length($_); $x++) { $dash .= '-'; }
|
||||
$_ = "$_\n$dash\n\n";
|
||||
}
|
||||
}
|
||||
elsif ($_ =~ /^(\s|[^\s=]+)*[\s*]([A-Za-z0-9_]+)(\s+=\s+[^,;]+)?[,;]\s*\/\*::\s*(.*)\s+\*\/$/)
|
||||
{
|
||||
print STDOUT "\n" if $gotone;
|
||||
$_ = "\nid:[$idpath$2]::\n\t$4\n";
|
||||
$found = 'sorta'; $gotone = $.;
|
||||
}
|
||||
print STDOUT "\n" and $gotone = undef if $gotone and $gotone < $.;
|
||||
next if not $found; $found = undef if $found eq 'sorta';
|
||||
print STDOUT $_ and $start = 1;
|
||||
sub usage {
|
||||
print "@_\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
our($opt_h, $opt_v, $title, $body, $indent, $idpath, $inblock);
|
||||
|
||||
getopts("hv") or usage($HELP);
|
||||
$opt_v and usage("Copyleft (c) 2006, Russ Rowan (See `COPYING')");
|
||||
usage($HELP) if $opt_h or @ARGV < 1;
|
||||
|
||||
sub put_section {
|
||||
if ($title) {
|
||||
print "\n$title\n";
|
||||
$_ = $title;
|
||||
s/[^-]/-/g;
|
||||
print "$_\n" if not $indent;
|
||||
}
|
||||
if ($body) {
|
||||
$_ = $body;
|
||||
s/#newline#/$indent/g;
|
||||
print "$_\n";
|
||||
}
|
||||
$title = $body = undef;
|
||||
}
|
||||
|
||||
$idpath = $title = $body = "";
|
||||
while (<>)
|
||||
{
|
||||
my $end = s/\s*\*+\//\n/ ? 'yes' : undef;
|
||||
|
||||
if ($end and /[^=]*[\s*](\w+)[\s:,;].*\/\*:\s*(.*)/) {
|
||||
# Implicit id for enum values and struct members.
|
||||
print "\nid:[$idpath$1]::\n\t$2\n";
|
||||
|
||||
} elsif ($inblock) {
|
||||
# Redo the indentation, preserve empty lines.
|
||||
s/^(\s|\*)*//;
|
||||
s/^$/\n/;
|
||||
$body .= "#newline#" . $_;
|
||||
|
||||
} elsif (s/\s*\/\*\*+\s*(.*)/$1/) {
|
||||
# Found magic header; flush, record title and set indentation.
|
||||
put_section;
|
||||
$title = "$1";
|
||||
$indent = /::/ ? "\t" : "";
|
||||
|
||||
} else {
|
||||
next if not ($title or $body) or /^\s$/;
|
||||
|
||||
my $orig_title = $title;
|
||||
|
||||
if (not /^#define\s/) {
|
||||
while (not /(struct|enum|typedef|[^=])*[\s*](\w+).*[\[:,;{]/) {
|
||||
$_ .= <>;
|
||||
}
|
||||
}
|
||||
|
||||
if (/struct\s+(\w+)\s*{/) {
|
||||
$title = "struct:$1" . "[$title]";
|
||||
$idpath = "$1.";
|
||||
|
||||
} elsif (/enum\s+(\w+)\s*{/) {
|
||||
$title = "enum:$1" . "[$title]";
|
||||
$idpath = "";
|
||||
|
||||
} elsif (/#define\s+(\w+)[(]/) {
|
||||
$title = "func:$1" . "[$title]";
|
||||
$idpath = "";
|
||||
|
||||
} elsif (/#define\s+(\w+)/) {
|
||||
$title = "macro:$1" . "[$title]";
|
||||
$idpath = "";
|
||||
|
||||
} else {
|
||||
if (/typedef/) {
|
||||
if (/.*\(\*(\w+)\)\(/) {
|
||||
$title = "typedef:$1" . "[$title]";
|
||||
} elsif (/typedef.*\s(\w+);/) {
|
||||
$title = "typedef:$1" . "[$title]";
|
||||
}
|
||||
$idpath = "";
|
||||
} else {
|
||||
if (/.*[\s*](\w+)\(/) {
|
||||
$title = "func:$1" . "[$title]";
|
||||
$idpath = "";
|
||||
} elsif (/.*\(\*(\w+)\)\(/) {
|
||||
$body = "#newline#" . $title if not $body;
|
||||
$title = "id:[$idpath$1]::";
|
||||
$indent = "\t";
|
||||
} elsif (/[^=]*[\s*](\w+)[\[\s,:;]/) {
|
||||
$body = "#newline#" . $title if not $body;
|
||||
$title = "id:[$idpath$1]::";
|
||||
$indent = "\t";
|
||||
}
|
||||
}
|
||||
}
|
||||
put_section if $orig_title ne $title;
|
||||
next;
|
||||
}
|
||||
|
||||
$inblock = $end ? undef : 'yes';
|
||||
}
|
||||
close FILEIN;
|
||||
|
@ -67,7 +67,7 @@ then
|
||||
usage "No backend defined"
|
||||
fi
|
||||
|
||||
date_string=`date +"%d %B %y"`
|
||||
date_string=`date -I`
|
||||
script_version=`echo "\\$Revision: 1.19 $" | sed -e 's/\\$\(.*\) \\$/\1/'`
|
||||
elinks_version="`$elinks -version | head -n 1 | sed -e 's/ELinks \([0-9][^ ]*\).*/\1/'`"
|
||||
script_info="Generated by `basename $0` ($script_version) on $date_string"
|
||||
@ -171,7 +171,7 @@ print_elinksconf_header()
|
||||
.\" General Public License. <www.gnu.org/licenses/gpl.html>
|
||||
.\"
|
||||
.\" Process this file with groff -man -Tascii elinks.conf.5
|
||||
.TH ELINKS.CONF 5 \"$date_string\"
|
||||
.TH ELINKS.CONF 5 "ELinks configuration file" "$date_string" "ELinks configuration file"
|
||||
|
||||
.SH NAME
|
||||
elinks.conf \- ELinks configuration file
|
||||
@ -213,7 +213,7 @@ set document.browse.margin_width = 3
|
||||
# Default document codepage.
|
||||
set document.codepage.assume = "ISO-8859-1"
|
||||
# User defined protocol handlers
|
||||
set protocol.user.mailto.unix = "mutt %h -s \"%s\""
|
||||
set protocol.user.mailto.unix = "mutt %h -s \e\*(lq%s\e\*(rq"
|
||||
|
||||
.SH OPTIONS
|
||||
__END__
|
||||
|
@ -855,6 +855,16 @@ render_rss_item(struct dom_renderer *renderer, struct dom_node *item)
|
||||
struct dom_string *date = get_rss_text(item, RSS_ELEMENT_PUBDATE);
|
||||
|
||||
if (title && is_dom_string_set(title)) {
|
||||
if (item == renderer->channel) {
|
||||
unsigned char *str;
|
||||
|
||||
str = convert_string(renderer->convert_table,
|
||||
title->string, title->length,
|
||||
renderer->document->options.cp,
|
||||
CSM_DEFAULT, NULL, NULL, NULL);
|
||||
if (str)
|
||||
renderer->document->title = str;
|
||||
}
|
||||
render_dom_text(renderer, &renderer->styles[DOM_NODE_ELEMENT],
|
||||
title->string, title->length);
|
||||
}
|
||||
|
@ -114,9 +114,10 @@ struct html_context {
|
||||
void *(*special_f)(struct html_context *, enum html_special_type, ...);
|
||||
};
|
||||
|
||||
#define format (((struct html_element *) html_context->stack.next)->attr)
|
||||
#define par_format (((struct html_element *) html_context->stack.next)->parattr)
|
||||
#define html_top (*(struct html_element *) html_context->stack.next)
|
||||
#define html_top ((struct html_element *) html_context->stack.next)
|
||||
#define html_bottom ((struct html_element *) html_context->stack.prev)
|
||||
#define format (html_top->attr)
|
||||
#define par_format (html_top->parattr)
|
||||
|
||||
#define html_is_preformatted() (format.style.attr & AT_PREFORMATTED)
|
||||
|
||||
|
@ -93,7 +93,7 @@ get_target(struct document_options *options, unsigned char *a)
|
||||
void
|
||||
ln_break(struct html_context *html_context, int n)
|
||||
{
|
||||
if (!n || html_top.invisible) return;
|
||||
if (!n || html_top->invisible) return;
|
||||
while (n > html_context->line_breax) {
|
||||
html_context->line_breax++;
|
||||
html_context->line_break_f(html_context);
|
||||
@ -108,7 +108,7 @@ put_chrs(struct html_context *html_context, unsigned char *start, int len)
|
||||
if (html_is_preformatted())
|
||||
html_context->putsp = HTML_SPACE_NORMAL;
|
||||
|
||||
if (!len || html_top.invisible)
|
||||
if (!len || html_top->invisible)
|
||||
return;
|
||||
|
||||
switch (html_context->putsp) {
|
||||
@ -258,8 +258,8 @@ html_focusable(struct html_context *html_context, unsigned char *a)
|
||||
void
|
||||
html_skip(struct html_context *html_context, unsigned char *a)
|
||||
{
|
||||
html_top.invisible = 1;
|
||||
html_top.type = ELEMENT_DONT_KILL;
|
||||
html_top->invisible = 1;
|
||||
html_top->type = ELEMENT_DONT_KILL;
|
||||
}
|
||||
|
||||
void
|
||||
@ -663,10 +663,7 @@ init_html_parser_state(struct html_context *html_context,
|
||||
enum html_element_type type,
|
||||
int align, int margin, int width)
|
||||
{
|
||||
struct html_element *element;
|
||||
|
||||
html_stack_dup(html_context, type);
|
||||
element = &html_top;
|
||||
|
||||
par_format.align = align;
|
||||
|
||||
@ -677,10 +674,10 @@ init_html_parser_state(struct html_context *html_context,
|
||||
par_format.list_level = 0;
|
||||
par_format.list_number = 0;
|
||||
par_format.dd_margin = 0;
|
||||
html_top.namelen = 0;
|
||||
html_top->namelen = 0;
|
||||
}
|
||||
|
||||
return element;
|
||||
return html_top;
|
||||
}
|
||||
|
||||
|
||||
@ -691,20 +688,20 @@ done_html_parser_state(struct html_context *html_context,
|
||||
{
|
||||
html_context->line_breax = 1;
|
||||
|
||||
while (&html_top != element) {
|
||||
kill_html_stack_item(html_context, &html_top);
|
||||
while (html_top != element) {
|
||||
pop_html_element(html_context);
|
||||
#if 0
|
||||
/* I've preserved this bit to show an example of the Old Code
|
||||
* of the Mikulas days (I _HOPE_ it's by Mikulas, at least ;-).
|
||||
* I think this assert() can never fail, for one. --pasky */
|
||||
assertm(&html_top && (void *) &html_top != (void *) &html_stack,
|
||||
assertm(html_top && (void *) html_top != (void *) &html_stack,
|
||||
"html stack trashed");
|
||||
if_assert_failed break;
|
||||
#endif
|
||||
}
|
||||
|
||||
html_top.type = ELEMENT_KILLABLE;
|
||||
kill_html_stack_item(html_context, &html_top);
|
||||
html_top->type = ELEMENT_KILLABLE;
|
||||
pop_html_element(html_context);
|
||||
|
||||
}
|
||||
|
||||
@ -777,12 +774,12 @@ init_html_parser(struct uri *uri, struct document_options *options,
|
||||
|
||||
par_format.bgcolor = options->default_bg;
|
||||
|
||||
html_top.invisible = 0;
|
||||
html_top.name = NULL;
|
||||
html_top.namelen = 0;
|
||||
html_top.options = NULL;
|
||||
html_top.linebreak = 1;
|
||||
html_top.type = ELEMENT_DONT_KILL;
|
||||
html_top->invisible = 0;
|
||||
html_top->name = NULL;
|
||||
html_top->namelen = 0;
|
||||
html_top->options = NULL;
|
||||
html_top->linebreak = 1;
|
||||
html_top->type = ELEMENT_DONT_KILL;
|
||||
|
||||
html_context->has_link_lines = 0;
|
||||
html_context->table_level = 0;
|
||||
|
@ -254,7 +254,7 @@ html_input_format(struct html_context *html_context, unsigned char *a,
|
||||
case FC_HIDDEN:
|
||||
INTERNAL("bad control type");
|
||||
}
|
||||
kill_html_stack_item(html_context, &html_top);
|
||||
pop_html_element(html_context);
|
||||
put_chrs(html_context, " ", 1);
|
||||
}
|
||||
|
||||
@ -498,7 +498,7 @@ end_parse:
|
||||
for (i = 0; i < max_width; i++)
|
||||
put_chrs(html_context, "_", 1);
|
||||
|
||||
kill_html_stack_item(html_context, &html_top);
|
||||
pop_html_element(html_context);
|
||||
put_chrs(html_context, "]", 1);
|
||||
html_context->special_f(html_context, SP_CONTROL, fc);
|
||||
}
|
||||
@ -513,7 +513,7 @@ do_html_select_multiple(struct html_context *html_context, unsigned char *a,
|
||||
|
||||
if (!al) return;
|
||||
html_focusable(html_context, a);
|
||||
html_top.type = ELEMENT_DONT_KILL;
|
||||
html_top->type = ELEMENT_DONT_KILL;
|
||||
mem_free_set(&format.select, al);
|
||||
format.select_disabled = has_attr(a, "disabled", html_context->options)
|
||||
? FORM_MODE_DISABLED
|
||||
@ -603,7 +603,7 @@ end_parse:
|
||||
format.form = fc;
|
||||
format.style.attr |= AT_BOLD;
|
||||
put_chrs(html_context, "[ ]", 3);
|
||||
kill_html_stack_item(html_context, &html_top);
|
||||
pop_html_element(html_context);
|
||||
put_chrs(html_context, " ", 1);
|
||||
html_context->special_f(html_context, SP_CONTROL, fc);
|
||||
}
|
||||
@ -709,7 +709,7 @@ pp:
|
||||
ln_break(html_context, 1);
|
||||
}
|
||||
|
||||
kill_html_stack_item(html_context, &html_top);
|
||||
pop_html_element(html_context);
|
||||
if (rows > 1)
|
||||
ln_break(html_context, 1);
|
||||
else
|
||||
|
@ -141,14 +141,14 @@ html_apply_canvas_bgcolor(struct html_context *html_context)
|
||||
/* If there are any CSS twaks regarding bgcolor, make sure we will get
|
||||
* it _and_ prefer it over bgcolor attribute. */
|
||||
if (html_context->options->css_enable)
|
||||
css_apply(html_context, &html_top, &html_context->css_styles,
|
||||
css_apply(html_context, html_top, &html_context->css_styles,
|
||||
&html_context->stack);
|
||||
#endif
|
||||
|
||||
if (par_format.bgcolor != format.style.bg) {
|
||||
/* Modify the root HTML element - format_html_part() will take
|
||||
* this from there. */
|
||||
struct html_element *e = html_context->stack.prev;
|
||||
struct html_element *e = html_bottom;
|
||||
|
||||
html_context->was_body_background = 1;
|
||||
e->parattr.bgcolor = e->attr.style.bg = par_format.bgcolor = format.style.bg;
|
||||
@ -195,7 +195,7 @@ html_script(struct html_context *html_context, unsigned char *a,
|
||||
mem_free(type);
|
||||
not_processed:
|
||||
/* Permit nested scripts and retreat. */
|
||||
html_top.invisible++;
|
||||
html_top->invisible++;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -364,7 +364,7 @@ html_html(struct html_context *html_context, unsigned char *a,
|
||||
|
||||
/* Modify the root HTML element - format_html_part() will take
|
||||
* this from there. */
|
||||
struct html_element *e = html_context->stack.prev;
|
||||
struct html_element *e = html_bottom;
|
||||
|
||||
if (par_format.bgcolor != format.style.bg)
|
||||
e->parattr.bgcolor = e->attr.style.bg = par_format.bgcolor = format.style.bg;
|
||||
@ -403,8 +403,8 @@ void
|
||||
html_title(struct html_context *html_context, unsigned char *a,
|
||||
unsigned char *xxx3, unsigned char *xxx4, unsigned char **xxx5)
|
||||
{
|
||||
html_top.invisible = 1;
|
||||
html_top.type = ELEMENT_WEAK;
|
||||
html_top->invisible = 1;
|
||||
html_top->type = ELEMENT_WEAK;
|
||||
}
|
||||
|
||||
void
|
||||
@ -586,7 +586,7 @@ html_hr(struct html_context *html_context, unsigned char *a,
|
||||
}
|
||||
html_context->special_f(html_context, SP_NOWRAP, 0);
|
||||
ln_break(html_context, 2);
|
||||
kill_html_stack_item(html_context, &html_top);
|
||||
pop_html_element(html_context);
|
||||
}
|
||||
|
||||
void
|
||||
@ -690,7 +690,7 @@ html_ul(struct html_context *html_context, unsigned char *a,
|
||||
int_upper_bound(&par_format.leftmargin, par_format.width / 2);
|
||||
|
||||
par_format.align = ALIGN_LEFT;
|
||||
html_top.type = ELEMENT_DONT_KILL;
|
||||
html_top->type = ELEMENT_DONT_KILL;
|
||||
}
|
||||
|
||||
void
|
||||
@ -725,7 +725,7 @@ html_ol(struct html_context *html_context, unsigned char *a,
|
||||
int_upper_bound(&par_format.leftmargin, par_format.width / 2);
|
||||
|
||||
par_format.align = ALIGN_LEFT;
|
||||
html_top.type = ELEMENT_DONT_KILL;
|
||||
html_top->type = ELEMENT_DONT_KILL;
|
||||
}
|
||||
|
||||
static struct {
|
||||
@ -873,10 +873,10 @@ html_dl(struct html_context *html_context, unsigned char *a,
|
||||
par_format.list_number = 0;
|
||||
par_format.align = ALIGN_LEFT;
|
||||
par_format.dd_margin = par_format.leftmargin;
|
||||
html_top.type = ELEMENT_DONT_KILL;
|
||||
html_top->type = ELEMENT_DONT_KILL;
|
||||
if (!(par_format.flags & P_COMPACT)) {
|
||||
ln_break(html_context, 2);
|
||||
html_top.linebreak = 2;
|
||||
html_top->linebreak = 2;
|
||||
}
|
||||
}
|
||||
|
||||
@ -948,14 +948,14 @@ html_frame(struct html_context *html_context, unsigned char *a,
|
||||
}
|
||||
if (!name) return;
|
||||
|
||||
if (!html_context->options->frames || !html_top.frameset) {
|
||||
if (!html_context->options->frames || !html_top->frameset) {
|
||||
html_focusable(html_context, a);
|
||||
put_link_line("Frame: ", name, url, "", html_context);
|
||||
|
||||
} else {
|
||||
if (html_context->special_f(html_context, SP_USED, NULL)) {
|
||||
html_context->special_f(html_context, SP_FRAME,
|
||||
html_top.frameset, name, url);
|
||||
html_top->frameset, name, url);
|
||||
}
|
||||
}
|
||||
|
||||
@ -997,12 +997,12 @@ html_frameset(struct html_context *html_context, unsigned char *a,
|
||||
}
|
||||
}
|
||||
|
||||
if (!html_top.frameset) {
|
||||
if (!html_top->frameset) {
|
||||
width = html_context->options->box.width;
|
||||
height = html_context->options->box.height;
|
||||
html_context->options->needs_height = 1;
|
||||
} else {
|
||||
struct frameset_desc *frameset_desc = html_top.frameset;
|
||||
struct frameset_desc *frameset_desc = html_top->frameset;
|
||||
int offset;
|
||||
|
||||
if (frameset_desc->box.y >= frameset_desc->box.height)
|
||||
@ -1020,9 +1020,9 @@ html_frameset(struct html_context *html_context, unsigned char *a,
|
||||
parse_frame_widths(rows, height, HTML_FRAME_CHAR_HEIGHT,
|
||||
&fp.height, &fp.y);
|
||||
|
||||
fp.parent = html_top.frameset;
|
||||
fp.parent = html_top->frameset;
|
||||
if (fp.x && fp.y) {
|
||||
html_top.frameset = html_context->special_f(html_context, SP_FRAMESET, &fp);
|
||||
html_top->frameset = html_context->special_f(html_context, SP_FRAMESET, &fp);
|
||||
}
|
||||
mem_free_if(fp.width);
|
||||
mem_free_if(fp.height);
|
||||
|
@ -67,20 +67,20 @@ html_a(struct html_context *html_context, unsigned char *a,
|
||||
#ifdef CONFIG_GLOBHIST
|
||||
} else if (get_global_history_item(format.link)) {
|
||||
format.style.fg = format.vlink;
|
||||
html_top.pseudo_class &= ~ELEMENT_LINK;
|
||||
html_top.pseudo_class |= ELEMENT_VISITED;
|
||||
html_top->pseudo_class &= ~ELEMENT_LINK;
|
||||
html_top->pseudo_class |= ELEMENT_VISITED;
|
||||
#endif
|
||||
#ifdef CONFIG_BOOKMARKS
|
||||
} else if (get_bookmark(format.link)) {
|
||||
format.style.fg = format.bookmark_link;
|
||||
html_top.pseudo_class &= ~ELEMENT_VISITED;
|
||||
html_top->pseudo_class &= ~ELEMENT_VISITED;
|
||||
/* XXX: Really set ELEMENT_LINK? --pasky */
|
||||
html_top.pseudo_class |= ELEMENT_LINK;
|
||||
html_top->pseudo_class |= ELEMENT_LINK;
|
||||
#endif
|
||||
} else {
|
||||
format.style.fg = format.clink;
|
||||
html_top.pseudo_class &= ~ELEMENT_VISITED;
|
||||
html_top.pseudo_class |= ELEMENT_LINK;
|
||||
html_top->pseudo_class &= ~ELEMENT_VISITED;
|
||||
html_top->pseudo_class |= ELEMENT_LINK;
|
||||
}
|
||||
|
||||
mem_free_set(&format.title,
|
||||
@ -89,7 +89,7 @@ html_a(struct html_context *html_context, unsigned char *a,
|
||||
html_focusable(html_context, a);
|
||||
|
||||
} else {
|
||||
kill_html_stack_item(html_context, &html_top);
|
||||
pop_html_element(html_context);
|
||||
}
|
||||
|
||||
set_fragment_identifier(html_context, a, "name");
|
||||
@ -269,7 +269,7 @@ html_img_do(unsigned char *a, unsigned char *object_src,
|
||||
* If not, just exit now. */
|
||||
if (!options->images && !format.link) {
|
||||
mem_free_if(src);
|
||||
if (usemap) kill_html_stack_item(html_context, &html_top);
|
||||
if (usemap) pop_html_element(html_context);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -332,7 +332,7 @@ html_img_do(unsigned char *a, unsigned char *object_src,
|
||||
|
||||
put_image_label(a, label, html_context);
|
||||
|
||||
if (ismap) kill_html_stack_item(html_context, &html_top);
|
||||
if (ismap) pop_html_element(html_context);
|
||||
mem_free_set(&format.image, NULL);
|
||||
mem_free_set(&format.title, NULL);
|
||||
}
|
||||
@ -341,7 +341,7 @@ html_img_do(unsigned char *a, unsigned char *object_src,
|
||||
}
|
||||
|
||||
mem_free_if(src);
|
||||
if (usemap) kill_html_stack_item(html_context, &html_top);
|
||||
if (usemap) pop_html_element(html_context);
|
||||
}
|
||||
|
||||
void
|
||||
@ -369,7 +369,7 @@ put_link_line(unsigned char *prefix, unsigned char *linkname,
|
||||
format.style.fg = format.clink;
|
||||
put_chrs(html_context, linkname, strlen(linkname));
|
||||
ln_break(html_context, 1);
|
||||
kill_html_stack_item(html_context, &html_top);
|
||||
pop_html_element(html_context);
|
||||
}
|
||||
|
||||
|
||||
|
@ -714,7 +714,7 @@ next_break:
|
||||
|
||||
element:
|
||||
endingtag = *name == '/'; name += endingtag; namelen -= endingtag;
|
||||
if (!endingtag && html_context->putsp == HTML_SPACE_ADD && !html_top.invisible)
|
||||
if (!endingtag && html_context->putsp == HTML_SPACE_ADD && !html_top->invisible)
|
||||
put_chrs(html_context, " ", 1);
|
||||
put_chrs(html_context, base_pos, html - base_pos);
|
||||
if (!html_is_preformatted() && !endingtag && html_context->putsp == HTML_SPACE_NORMAL) {
|
||||
@ -766,14 +766,14 @@ start_element(struct element_info *ei,
|
||||
struct css_selector *selector = NULL;
|
||||
#endif
|
||||
|
||||
if (html_top.type == ELEMENT_WEAK) {
|
||||
kill_html_stack_item(html_context, &html_top);
|
||||
if (html_top->type == ELEMENT_WEAK) {
|
||||
pop_html_element(html_context);
|
||||
}
|
||||
|
||||
/* We try to process nested <script> if we didn't process the parent
|
||||
* one. */
|
||||
if (html_top.invisible
|
||||
&& (ei->func != html_script || html_top.invisible < 2)) {
|
||||
if (html_top->invisible
|
||||
&& (ei->func != html_script || html_top->invisible < 2)) {
|
||||
ELEMENT_RENDER_PROLOGUE
|
||||
return html;
|
||||
}
|
||||
@ -803,11 +803,14 @@ start_element(struct element_info *ei,
|
||||
if (e->type < ELEMENT_KILLABLE) break;
|
||||
if (is_block_element(e) || is_inline_element(ei)) break;
|
||||
}
|
||||
} else foreach (e, html_context->stack) {
|
||||
if (is_block_element(e) && is_inline_element(ei)) break;
|
||||
if (e->type < ELEMENT_KILLABLE) break;
|
||||
if (!strlcasecmp(e->name, e->namelen, name, namelen)) break;
|
||||
} else {
|
||||
foreach (e, html_context->stack) {
|
||||
if (is_block_element(e) && is_inline_element(ei)) break;
|
||||
if (e->type < ELEMENT_KILLABLE) break;
|
||||
if (!strlcasecmp(e->name, e->namelen, name, namelen)) break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strlcasecmp(e->name, e->namelen, name, namelen)) {
|
||||
while (e->prev != (void *) &html_context->stack)
|
||||
kill_html_stack_item(html_context, e->prev);
|
||||
@ -819,10 +822,10 @@ start_element(struct element_info *ei,
|
||||
|
||||
if (ei->type != ELEMENT_TYPE_NON_PAIRABLE) {
|
||||
html_stack_dup(html_context, ELEMENT_KILLABLE);
|
||||
html_top.name = name;
|
||||
html_top.namelen = namelen;
|
||||
html_top.options = attr;
|
||||
html_top.linebreak = ei->linebreak;
|
||||
html_top->name = name;
|
||||
html_top->namelen = namelen;
|
||||
html_top->options = attr;
|
||||
html_top->linebreak = ei->linebreak;
|
||||
|
||||
#ifdef CONFIG_ECMASCRIPT
|
||||
if (has_attr(attr, "onClick", html_context->options)) {
|
||||
@ -830,7 +833,7 @@ start_element(struct element_info *ei,
|
||||
mem_free_set(&format.link, stracpy("javascript:void(0);"));
|
||||
mem_free_set(&format.target, stracpy(html_context->base_target));
|
||||
format.style.fg = format.clink;
|
||||
html_top.pseudo_class = ELEMENT_LINK;
|
||||
html_top->pseudo_class = ELEMENT_LINK;
|
||||
mem_free_set(&format.title, stracpy("onClick placeholder"));
|
||||
/* Er. I know. Well, double html_focusable()s shouldn't
|
||||
* really hurt. */
|
||||
@ -840,7 +843,7 @@ start_element(struct element_info *ei,
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CSS
|
||||
if (html_top.options && html_context->options->css_enable) {
|
||||
if (html_top->options && html_context->options->css_enable) {
|
||||
/* XXX: We should apply CSS otherwise as well, but that'll need
|
||||
* some deeper changes in order to have options filled etc.
|
||||
* Probably just applying CSS from more places, since we
|
||||
@ -852,12 +855,12 @@ start_element(struct element_info *ei,
|
||||
/* FIXME: The caching of the CSS selector is broken, since t can
|
||||
* lead to wrong styles being applied to following elements, so
|
||||
* disabled for now. */
|
||||
selector = get_css_selector_for_element(html_context, &html_top,
|
||||
selector = get_css_selector_for_element(html_context, html_top,
|
||||
&html_context->css_styles,
|
||||
&html_context->stack);
|
||||
|
||||
if (selector) {
|
||||
apply_css_selector_style(html_context, &html_top, selector);
|
||||
apply_css_selector_style(html_context, html_top, selector);
|
||||
done_css_selector(selector);
|
||||
}
|
||||
}
|
||||
@ -868,14 +871,14 @@ start_element(struct element_info *ei,
|
||||
ELEMENT_RENDER_PROLOGUE
|
||||
if (ei->func) ei->func(html_context, attr, html, eof, &html);
|
||||
#ifdef CONFIG_CSS
|
||||
if (selector && html_top.options) {
|
||||
if (selector && html_top->options) {
|
||||
/* Call it now to override default colors of the elements. */
|
||||
selector = get_css_selector_for_element(html_context, &html_top,
|
||||
selector = get_css_selector_for_element(html_context, html_top,
|
||||
&html_context->css_styles,
|
||||
&html_context->stack);
|
||||
|
||||
if (selector) {
|
||||
apply_css_selector_style(html_context, &html_top, selector);
|
||||
apply_css_selector_style(html_context, html_top, selector);
|
||||
done_css_selector(selector);
|
||||
}
|
||||
}
|
||||
@ -909,7 +912,7 @@ end_element(struct element_info *ei,
|
||||
|
||||
/* Apply background color from the <HTML> element. (bug 696) */
|
||||
if (ei->func == html_html
|
||||
&& html_top.type >= ELEMENT_KILLABLE
|
||||
&& html_top->type >= ELEMENT_KILLABLE
|
||||
&& !html_context->was_body_background)
|
||||
html_apply_canvas_bgcolor(html_context);
|
||||
|
||||
|
@ -60,7 +60,7 @@ search_html_stack(struct html_context *html_context, unsigned char *name)
|
||||
#endif
|
||||
|
||||
foreach (element, html_context->stack) {
|
||||
if (element == &html_top)
|
||||
if (element == html_top)
|
||||
continue; /* skip the top element */
|
||||
if (strlcasecmp(element->name, element->namelen, name, namelen))
|
||||
continue;
|
||||
@ -189,7 +189,7 @@ kill_element(struct html_context *html_context, int ls, struct html_element *e)
|
||||
void
|
||||
kill_html_stack_until(struct html_context *html_context, int ls, ...)
|
||||
{
|
||||
struct html_element *e = &html_top;
|
||||
struct html_element *e = html_top;
|
||||
|
||||
if (ls) e = e->next;
|
||||
|
||||
|
@ -14,6 +14,8 @@ void html_stack_dup(struct html_context *html_context,
|
||||
|
||||
void kill_html_stack_item(struct html_context *html_context,
|
||||
struct html_element *e);
|
||||
#define pop_html_element(html_context) \
|
||||
kill_html_stack_item(html_context, html_top)
|
||||
void kill_html_stack_until(struct html_context *html_context, int ls, ...);
|
||||
|
||||
/* void dump_html_stack(struct html_context *html_context); */
|
||||
|
@ -7,30 +7,32 @@
|
||||
/* Define if you want a talking scanner */
|
||||
/* #define DEBUG_DOM_SCANNER */
|
||||
|
||||
/* The {struct dom_scanner_token} describes one scanner state. There are two
|
||||
* kinds of tokens: char and non-char tokens. Char tokens contains only one
|
||||
* char and simply have their char value as type. They are tokens having
|
||||
* special control meaning in the code, like ':', ';', '{', '}' and '*'. Non
|
||||
* char tokens has one or more chars and contain stuff like number or
|
||||
* indentifier strings. */
|
||||
/** DOM scanner token
|
||||
*
|
||||
* This struct describes one scanner state. There are two kinds of tokens: char
|
||||
* and non-char tokens. Char tokens contains only one char and simply have
|
||||
* their char value as type. They are tokens having special control meaning in
|
||||
* the code, like ':', ';', '{', '}' and '*'. Non-char tokens have one or more
|
||||
* chars and contain stuff like number or indentifier strings. */
|
||||
struct dom_scanner_token {
|
||||
/* The type the token */
|
||||
/** The type the token. */
|
||||
int type;
|
||||
|
||||
/* Some precedence value */
|
||||
/** Some precedence value. */
|
||||
int precedence;
|
||||
|
||||
/* The line number; used for error tokens */
|
||||
/** The line number; used for error tokens. */
|
||||
unsigned int lineno;
|
||||
|
||||
/* The start of the token string and the token length */
|
||||
/** The start of the token string and the token length. */
|
||||
struct dom_string string;
|
||||
};
|
||||
|
||||
/** Skip the first charector of a token */
|
||||
#define skip_dom_scanner_token_char(token) \
|
||||
do { (token)->string.string++; (token)->string.length--; } while (0)
|
||||
|
||||
/* Compare the string of @token with the "static" string in @str. */
|
||||
/** Compare the token string to a "static" string */
|
||||
#define dom_scanner_token_contains(token, str) \
|
||||
((token)->string.length == (sizeof(str) - 1) \
|
||||
&& !strncasecmp((token)->string.string, str, sizeof(str) - 1))
|
||||
@ -70,55 +72,72 @@ struct dom_scanner_string_mapping {
|
||||
|
||||
struct dom_scanner;
|
||||
|
||||
/** DOM scanner info
|
||||
*
|
||||
* Backend-specific information used during the actual scanning and
|
||||
* by the front end to fill the token table on-demand, etc.
|
||||
*/
|
||||
struct dom_scanner_info {
|
||||
/* Table containing how to map strings to token types */
|
||||
/** Table containing how to map strings to token types */
|
||||
const struct dom_scanner_string_mapping *mappings;
|
||||
|
||||
/* Information for how to initialize the scanner table */
|
||||
/** Information for how to initialize the scanner table */
|
||||
const struct dom_scan_table_info *scan_table_info;
|
||||
|
||||
/* Fills the scanner with tokens. Already scanned tokens which have not
|
||||
/**
|
||||
* Fills the scanner with tokens. Already scanned tokens which have not
|
||||
* been requested remain and are moved to the start of the scanners
|
||||
* token table. */
|
||||
/* Returns the current token or NULL if there are none. */
|
||||
* token table. Returns the current token or NULL if there are none. */
|
||||
struct dom_scanner_token *(*scan)(struct dom_scanner *scanner);
|
||||
|
||||
/* The scanner table */
|
||||
/* Contains bitmaps for the various characters groups.
|
||||
* Idea sync'ed from mozilla browser. */
|
||||
/**
|
||||
* The scanner table. Contains bitmaps for the various characters
|
||||
* groups. Idea sync'ed from mozilla browser. */
|
||||
int scan_table[DOM_SCAN_TABLE_SIZE];
|
||||
|
||||
/* Has the scanner info been initialized? */
|
||||
/** Has the scanner info been initialized? */
|
||||
unsigned int initialized:1;
|
||||
};
|
||||
|
||||
|
||||
/* Initializes the scanner. */
|
||||
/** Initializes a DOM scanner
|
||||
*
|
||||
* See struct ref:[dom_scanner] for a description of the `int` flags. */
|
||||
void init_dom_scanner(struct dom_scanner *scanner, struct dom_scanner_info *scanner_info,
|
||||
struct dom_string *string, int state, int count_lines, int complete,
|
||||
int check_complete, int detect_error);
|
||||
|
||||
/* The number of tokens in the scanners token table:
|
||||
/** The number of tokens in the scanners token table
|
||||
*
|
||||
* At best it should be big enough to contain properties with space separated
|
||||
* values and function calls with up to 3 variables like rgb(). At worst it
|
||||
* should be no less than 2 in order to be able to peek at the next token in
|
||||
* the scanner. */
|
||||
#define DOM_SCANNER_TOKENS 10
|
||||
|
||||
/* The {struct dom_scanner} describes the current state of the scanner. */
|
||||
/** DOM scanner
|
||||
*
|
||||
* Holds the current state of the scanner. */
|
||||
struct dom_scanner {
|
||||
/* The very start of the scanned string, the position in the string
|
||||
* where to scan next and the end of the string. If position is NULL it
|
||||
* means that no more tokens can be retrieved from the string. */
|
||||
unsigned char *string, *position, *end;
|
||||
/** The start of the scanned string. */
|
||||
unsigned char *string;
|
||||
/** The end of the scanned string. */
|
||||
unsigned char *end;
|
||||
/**
|
||||
* The position in the string where to scan next and the end of the
|
||||
* string. If position is NULL it means that no more tokens can be
|
||||
* retrieved from the string. */
|
||||
unsigned char *position;
|
||||
|
||||
/* The current token and number of scanned tokens in the table.
|
||||
* If the number of scanned tokens is less than DOM_SCANNER_TOKENS it
|
||||
* is because there are no more tokens in the string. */
|
||||
/**
|
||||
* The current token. If the number of scanned tokens is less than
|
||||
* ref:[DOM_SCANNER_TOKENS] it is because there are no more tokens in
|
||||
* the string. */
|
||||
struct dom_scanner_token *current;
|
||||
/** The number of scanned tokens left in the table. */
|
||||
int tokens;
|
||||
|
||||
/* The 'meta' scanner information */
|
||||
/** The 'meta' scanner information */
|
||||
struct dom_scanner_info *info;
|
||||
|
||||
#ifdef DEBUG_SCANNER
|
||||
@ -130,25 +149,27 @@ struct dom_scanner {
|
||||
/* The following two flags are used when parsing is incremental and
|
||||
* the scanner must ensure that only tokens that are complete are
|
||||
* generated. */
|
||||
unsigned int check_complete:1; /* Only generate complete tokens */
|
||||
unsigned int incomplete:1; /* The scanned string is incomplete */
|
||||
unsigned int check_complete:1; /*: Only generate complete tokens */
|
||||
unsigned int incomplete:1; /*: The scanned string is incomplete */
|
||||
|
||||
unsigned int detect_errors:1; /* Check for markup errors */
|
||||
unsigned int found_error; /* Did we already report this error? */
|
||||
unsigned int detect_errors:1; /*: Check for markup errors */
|
||||
unsigned int found_error; /*: Did we already report this error? */
|
||||
|
||||
unsigned int count_lines:1; /* Is line counting enbaled? */
|
||||
unsigned int lineno; /* Line # of the last scanned token */
|
||||
unsigned int count_lines:1; /*: Is line counting enbaled? */
|
||||
unsigned int lineno; /*: Line # of the last scanned token */
|
||||
|
||||
/* Some state indicator only meaningful to the scanner internals */
|
||||
/** Some state indicator only meaningful to the scanner internals */
|
||||
int state;
|
||||
|
||||
/* The table contain already scanned tokens. It is maintained in
|
||||
/**
|
||||
* The table contain already scanned tokens. It is maintained in
|
||||
* order to optimize the scanning a bit and make it possible to look
|
||||
* ahead at the next token. You should always use the accessors
|
||||
* (defined below) for getting tokens from the scanner. */
|
||||
struct dom_scanner_token table[DOM_SCANNER_TOKENS];
|
||||
};
|
||||
|
||||
/** Check if there are more tokens */
|
||||
#define dom_scanner_has_tokens(scanner) \
|
||||
((scanner)->tokens > 0 && (scanner)->current < (scanner)->table + (scanner)->tokens)
|
||||
|
||||
@ -162,22 +183,24 @@ struct dom_scanner {
|
||||
|
||||
/* Scanner table accessors and mutators */
|
||||
|
||||
/* Checks the type of the next token */
|
||||
/** Check the type of the next token */
|
||||
#define check_next_dom_scanner_token(scanner, token_type) \
|
||||
(scanner_has_tokens(scanner) \
|
||||
&& ((scanner)->current + 1 < (scanner)->table + (scanner)->tokens) \
|
||||
&& (scanner)->current[1].type == (token_type))
|
||||
|
||||
/* Access current and next token. Getting the next token might cause
|
||||
* a rescan so any token pointers that has been stored in a local variable
|
||||
* might not be valid after the call. */
|
||||
/** Get the current token */
|
||||
static inline struct dom_scanner_token *
|
||||
get_dom_scanner_token(struct dom_scanner *scanner)
|
||||
{
|
||||
return dom_scanner_has_tokens(scanner) ? scanner->current : NULL;
|
||||
}
|
||||
|
||||
/* Do a scanning if we do not have also have access to next token. */
|
||||
/** Get the next token
|
||||
*
|
||||
* Getting the next token might cause a rescan so any token pointers that has
|
||||
* been stored in a local variable might not be valid after the call. */
|
||||
/* Do a scanning if we do not also have access to next token. */
|
||||
static inline struct dom_scanner_token *
|
||||
get_next_dom_scanner_token(struct dom_scanner *scanner)
|
||||
{
|
||||
@ -186,16 +209,20 @@ get_next_dom_scanner_token(struct dom_scanner *scanner)
|
||||
? scanner->info->scan(scanner) : get_dom_scanner_token(scanner));
|
||||
}
|
||||
|
||||
/* This should just make the code more understandable .. hopefully */
|
||||
/** Skip the current token */
|
||||
#define skip_dom_scanner_token(scanner) get_next_dom_scanner_token(scanner)
|
||||
|
||||
/* Removes tokens from the scanner until it meets a token of the given type.
|
||||
/** Conditionally skip tokens
|
||||
*
|
||||
* Removes tokens from the scanner until it meets a token of the given type.
|
||||
* This token will then also be skipped. */
|
||||
struct dom_scanner_token *
|
||||
skip_dom_scanner_tokens(struct dom_scanner *scanner, int skipto, int precedence);
|
||||
|
||||
/* Looks up the string from @ident to @end to in the scanners string mapping
|
||||
* table */
|
||||
/** Map a string to internal ID
|
||||
*
|
||||
* Looks up the string from @ident to @end to in the scanners string mapping
|
||||
* table. */
|
||||
int
|
||||
map_dom_scanner_string(struct dom_scanner *scanner,
|
||||
unsigned char *ident, unsigned char *end, int base_type);
|
||||
|
@ -11,12 +11,12 @@ struct sgml_parser;
|
||||
struct string;
|
||||
struct uri;
|
||||
|
||||
/** enum:[sgml_parser_type]: SGML parser type
|
||||
/** SGML parser type
|
||||
*
|
||||
* There are two kinds of parser types: One that optimises one-time access to
|
||||
* the DOM tree and one that creates a persistent DOM tree. */
|
||||
enum sgml_parser_type {
|
||||
/** id:[SGML_PARSER_STREAM]::
|
||||
/**
|
||||
* The first one will simply push nodes on the stack, not building a
|
||||
* DOM tree. This interface is similar to that of SAX (Simple API for
|
||||
* XML) where events are fired when nodes are entered and exited. It is
|
||||
@ -24,7 +24,7 @@ enum sgml_parser_type {
|
||||
* do all processing in a stream-like manner, such as when highlighting
|
||||
* HTML code. */
|
||||
SGML_PARSER_STREAM,
|
||||
/** id:[SGML_PARSER_TREE]::
|
||||
/**
|
||||
* The second one is a DOM tree builder, that builds a persistent DOM
|
||||
* tree. When using this type, it is possible to do even more
|
||||
* (pre)processing than for parser streams. For example you can sort
|
||||
@ -33,49 +33,48 @@ enum sgml_parser_type {
|
||||
SGML_PARSER_TREE,
|
||||
};
|
||||
|
||||
/** enum:[sgml_parser_flag]: SGML parser flags
|
||||
/** SGML parser flags
|
||||
*
|
||||
* These flags control how the parser behaves.
|
||||
*/
|
||||
enum sgml_parser_flag {
|
||||
SGML_PARSER_COUNT_LINES = 1, /*:: Make line numbers available. */
|
||||
SGML_PARSER_COMPLETE = 2, /*:: Used internally when incremental. */
|
||||
SGML_PARSER_INCREMENTAL = 4, /*:: Parse chunks of input. */
|
||||
SGML_PARSER_DETECT_ERRORS = 8, /*:: Report errors. */
|
||||
SGML_PARSER_COUNT_LINES = 1, /*: Make line numbers available. */
|
||||
SGML_PARSER_COMPLETE = 2, /*: Used internally when incremental. */
|
||||
SGML_PARSER_INCREMENTAL = 4, /*: Parse chunks of input. */
|
||||
SGML_PARSER_DETECT_ERRORS = 8, /*: Report errors. */
|
||||
};
|
||||
|
||||
/** struct:[sgml_parser_state]: SGML parser state
|
||||
/** SGML parser state
|
||||
*
|
||||
* The SGML parser has only little state.
|
||||
*/
|
||||
struct sgml_parser_state {
|
||||
/** id:[sgml_parser_state.info]::
|
||||
/**
|
||||
* Info about the properties of the node contained by state.
|
||||
* This is only meaningful to element and attribute nodes. For
|
||||
* unknown nodes it points to the common 'unknown node' info. */
|
||||
struct sgml_node_info *info;
|
||||
/** id:[sgml_parser_state.end_token]::
|
||||
/**
|
||||
* This is used by the DOM source renderer for highlighting the
|
||||
* end-tag of an element. */
|
||||
struct dom_scanner_token end_token;
|
||||
};
|
||||
|
||||
/** enum:[sgml_parser_code]: (Error) codes for the SGML parser
|
||||
/** (Error) codes for the SGML parser
|
||||
*
|
||||
* These enum values are used for return codes.
|
||||
*/
|
||||
enum sgml_parser_code {
|
||||
SGML_PARSER_CODE_OK, /*:: The parsing was successful */
|
||||
SGML_PARSER_CODE_INCOMPLETE, /*:: The parsing could not be completed */
|
||||
SGML_PARSER_CODE_MEM_ALLOC, /*:: Failed to allocate memory */
|
||||
|
||||
/** id:[SGML_PARSER_CODE_ERROR]::
|
||||
SGML_PARSER_CODE_OK, /*: The parsing was successful */
|
||||
SGML_PARSER_CODE_INCOMPLETE, /*: The parsing could not be completed */
|
||||
SGML_PARSER_CODE_MEM_ALLOC, /*: Failed to allocate memory */
|
||||
/**
|
||||
* FIXME: For when we will add support for requiring stricter parsing
|
||||
* or even a validator. */
|
||||
SGML_PARSER_CODE_ERROR,
|
||||
};
|
||||
|
||||
/** callback:[sgml_error_T]: SGML error callback
|
||||
/** SGML error callback
|
||||
*
|
||||
* Called by the SGML parser when a parsing error has occurred.
|
||||
*
|
||||
@ -85,28 +84,29 @@ typedef enum sgml_parser_code
|
||||
(*sgml_error_T)(struct sgml_parser *, struct dom_string *, unsigned int);
|
||||
|
||||
|
||||
/** struct:[sgml_parser]: The SGML parser
|
||||
/** The SGML parser
|
||||
*
|
||||
* This struct hold info used while parsing SGML data.
|
||||
*
|
||||
* NOTE: The only variable the user should set is ref:[error_func]. */
|
||||
* NOTE: The only variable the user should set is ref:[sgml_parser.error_func].
|
||||
*/
|
||||
struct sgml_parser {
|
||||
enum sgml_parser_type type; /*:: Stream or tree */
|
||||
enum sgml_parser_flag flags; /*:: Flags that control the behaviour */
|
||||
enum sgml_parser_type type; /*: Stream or tree */
|
||||
enum sgml_parser_flag flags; /*: Flags that control the behaviour */
|
||||
|
||||
struct sgml_info *info; /*:: Backend dependent info */
|
||||
struct sgml_info *info; /*: Backend dependent info */
|
||||
|
||||
struct dom_string uri; /*:: The URI of the DOM document */
|
||||
struct dom_node *root; /*:: The document root node */
|
||||
struct dom_string uri; /*: The URI of the DOM document */
|
||||
struct dom_node *root; /*: The document root node */
|
||||
|
||||
sgml_error_T error_func; /*:: Called for detected errors */
|
||||
sgml_error_T error_func; /*: Called for detected errors */
|
||||
|
||||
struct dom_stack stack; /*:: A stack for tracking parsed nodes */
|
||||
struct dom_stack parsing; /*:: Used for tracking parsing states */
|
||||
struct dom_stack stack; /*: A stack for tracking parsed nodes */
|
||||
struct dom_stack parsing; /*: Used for tracking parsing states */
|
||||
};
|
||||
|
||||
|
||||
/** func:[init_sgml_parser]: Initialise an SGML parser
|
||||
/** Initialise an SGML parser
|
||||
*
|
||||
* Initialise an SGML parser with the given properties.
|
||||
*
|
||||
@ -121,7 +121,7 @@ struct sgml_parser *
|
||||
init_sgml_parser(enum sgml_parser_type type, enum sgml_document_type doctype,
|
||||
struct dom_string *uri, enum sgml_parser_flag flags);
|
||||
|
||||
/** func:[done_sgml_parser]: Release an SGML parser
|
||||
/** Release an SGML parser
|
||||
*
|
||||
* Deallocates all resources, _expect_ the root node.
|
||||
*
|
||||
@ -129,7 +129,7 @@ init_sgml_parser(enum sgml_parser_type type, enum sgml_document_type doctype,
|
||||
*/
|
||||
void done_sgml_parser(struct sgml_parser *parser);
|
||||
|
||||
/** func:[parse_sgml]: Parse a chunk of SGML source
|
||||
/** Parse a chunk of SGML source
|
||||
*
|
||||
* Parses the given `buffer`. For incremental rendering the last buffer can be
|
||||
* signals through the `complete` parameter.
|
||||
@ -144,12 +144,12 @@ void done_sgml_parser(struct sgml_parser *parser);
|
||||
enum sgml_parser_code
|
||||
parse_sgml(struct sgml_parser *parser, struct dom_string *buffer, int complete);
|
||||
|
||||
/** func:[get_sgml_parser_line_number]: Get the line position in the source
|
||||
/** Get the line position in the source
|
||||
*
|
||||
* Returns what line number the parser is currently at or zero if there has
|
||||
* been no parsing yet.
|
||||
*
|
||||
* NOTE: Line numbers are recoderded in the scanner tokens.
|
||||
* NOTE: Line numbers are recorded in the scanner tokens.
|
||||
*/
|
||||
unsigned int get_sgml_parser_line_number(struct sgml_parser *parser);
|
||||
|
||||
|
193
src/dom/stack.h
193
src/dom/stack.h
@ -7,75 +7,110 @@
|
||||
|
||||
struct dom_stack;
|
||||
|
||||
/** DOM stack callback
|
||||
*
|
||||
* Used by contexts, for 'hooking' into the node traversing. */
|
||||
typedef void (*dom_stack_callback_T)(struct dom_stack *, struct dom_node *, void *);
|
||||
|
||||
#define DOM_STACK_MAX_DEPTH 4096
|
||||
|
||||
/** DOM stack state
|
||||
*
|
||||
* This state records what node and where it is placed. */
|
||||
struct dom_stack_state {
|
||||
/** The node assiciated with the state */
|
||||
struct dom_node *node;
|
||||
|
||||
/* The depth of the state in the stack. This is amongst other things
|
||||
/**
|
||||
* The depth of the state in the stack. This is amongst other things
|
||||
* used to get the state object data. */
|
||||
unsigned int depth;
|
||||
|
||||
/* Wether this stack state can be popped with pop_dom_*() family. */
|
||||
/** Whether this stack state can be popped with pop_dom_*() family. */
|
||||
unsigned int immutable:1;
|
||||
};
|
||||
|
||||
/** DOM stack context info
|
||||
*
|
||||
* To add a DOM stack context define this struct either statically or on the
|
||||
* stack. */
|
||||
struct dom_stack_context_info {
|
||||
/* The @object_size member tells whether the stack should allocate
|
||||
* objects for each state to be assigned to the state's @data member.
|
||||
* Zero means no state data should be allocated. */
|
||||
/**
|
||||
* This member tells whether the stack should allocate objects for each
|
||||
* state to be assigned to the state's @data member. Zero means no
|
||||
* state data should be allocated. */
|
||||
size_t object_size;
|
||||
|
||||
/* Callbacks to be called when pushing and popping nodes. */
|
||||
/** Callbacks to be called when pushing nodes. */
|
||||
dom_stack_callback_T push[DOM_NODES];
|
||||
/** Callbacks to be called when popping nodes. */
|
||||
dom_stack_callback_T pop[DOM_NODES];
|
||||
};
|
||||
|
||||
/** DOM stack context
|
||||
*
|
||||
* This holds 'runtime' data for the stack context. */
|
||||
struct dom_stack_context {
|
||||
/* Data specific to the context. */
|
||||
/** Data specific to the context. */
|
||||
void *data;
|
||||
|
||||
/* This is one big array of context specific objects. */
|
||||
/* For the SGML parser this holds DTD-oriented info about the node
|
||||
* (recorded in struct sgml_node_info). E.g. whether an element node
|
||||
* is optional. */
|
||||
/**
|
||||
* This is one big array of context specific objects. For the SGML
|
||||
* parser this holds DTD-oriented info about the node (recorded in
|
||||
* struct sgml_node_info). E.g. whether an element node is optional.
|
||||
*/
|
||||
unsigned char *state_objects;
|
||||
|
||||
/* Info about node callbacks and such. */
|
||||
/** Info about node callbacks and such. */
|
||||
struct dom_stack_context_info *info;
|
||||
};
|
||||
|
||||
/** Flags for controlling the DOM stack */
|
||||
enum dom_stack_flag {
|
||||
/** No flag needed. */
|
||||
DOM_STACK_FLAG_NONE = 0,
|
||||
|
||||
/* Free nodes when popping them by calling done_dom_node(). */
|
||||
/** Free nodes when popping by calling ref:[done_dom_node]. */
|
||||
DOM_STACK_FLAG_FREE_NODES = 1,
|
||||
};
|
||||
|
||||
/* The DOM stack is a convenient way to traverse DOM trees. Also it
|
||||
/** The DOM stack
|
||||
*
|
||||
* The DOM stack is a convenient way to traverse DOM trees. Also it
|
||||
* maintains needed state info and is therefore also a holder of the current
|
||||
* context since the stack is used to when the DOM tree is manipulated. */
|
||||
struct dom_stack {
|
||||
/* The stack of nodes */
|
||||
/** The states currently on the stack. */
|
||||
struct dom_stack_state *states;
|
||||
/** The depth of the stack. */
|
||||
size_t depth;
|
||||
|
||||
/** Flags given to ref:[init_dom_stack]. */
|
||||
enum dom_stack_flag flags;
|
||||
|
||||
/* Contexts for the pushed and popped nodes. */
|
||||
/** Contexts for the pushed and popped nodes. */
|
||||
struct dom_stack_context **contexts;
|
||||
/** The number of active contexts. */
|
||||
size_t contexts_size;
|
||||
|
||||
/* The current context. */
|
||||
/* XXX: Only meaningful within dom_stack_callback_T functions. */
|
||||
/**
|
||||
* The current context. Only meaningful within
|
||||
* ref:[dom_stack_callback_T] functions. */
|
||||
struct dom_stack_context *current;
|
||||
};
|
||||
|
||||
/** Check whether stack is empty or not
|
||||
*
|
||||
* stack:: The stack to check.
|
||||
*
|
||||
* Returns non-zero if stack is empty. */
|
||||
#define dom_stack_is_empty(stack) \
|
||||
(!(stack)->states || (stack)->depth == 0)
|
||||
|
||||
/** Access state by offset from top
|
||||
*
|
||||
* stack:: The stack to fetch the state from.
|
||||
* top_offset:: The offset from the stack top, zero is the top.
|
||||
*
|
||||
* Returns the requested state. */
|
||||
static inline struct dom_stack_state *
|
||||
get_dom_stack_state(struct dom_stack *stack, int top_offset)
|
||||
{
|
||||
@ -84,8 +119,24 @@ get_dom_stack_state(struct dom_stack *stack, int top_offset)
|
||||
return &stack->states[stack->depth - 1 - top_offset];
|
||||
}
|
||||
|
||||
#define get_dom_stack_top(stack) get_dom_stack_state(stack, 0)
|
||||
/** Access the stack top
|
||||
*
|
||||
* stack:: The stack to get the top state from.
|
||||
*
|
||||
* Returns the top state. */
|
||||
#define get_dom_stack_top(stack) \
|
||||
get_dom_stack_state(stack, 0)
|
||||
|
||||
/** Access context specific state data
|
||||
*
|
||||
* Similar to ref:[get_dom_stack_state], this will fetch the data
|
||||
* associated with the state for the given context.
|
||||
*
|
||||
* context:: The context to get data from.
|
||||
* state:: The stack state to get data from.
|
||||
*
|
||||
* Returns the state data or NULL if ref:[dom_stack_context_info.object_size]
|
||||
* was zero. */
|
||||
static inline void *
|
||||
get_dom_stack_state_data(struct dom_stack_context *context,
|
||||
struct dom_stack_state *state)
|
||||
@ -99,25 +150,36 @@ get_dom_stack_state_data(struct dom_stack_context *context,
|
||||
return (void *) &context->state_objects[state->depth * object_size];
|
||||
}
|
||||
|
||||
/* Define to have debug info about the nodes added printed to the log.
|
||||
* Run as: ELINKS_LOG=/tmp/dom-dump.txt ./elinks -no-connect <url>
|
||||
* to have the debug dumped into a file. */
|
||||
/*#define DOM_STACK_TRACE*/
|
||||
|
||||
#ifdef DOM_STACK_TRACE
|
||||
extern struct dom_stack_context_info dom_stack_trace_context_info;
|
||||
/** Get debug info from the DOM stack
|
||||
*
|
||||
* Define `DOM_STACK_TRACE` to have debug info about the nodes added printed to
|
||||
* the log. It will define add_dom_stack_tracer() to not be a no-op.
|
||||
*
|
||||
* Run as:
|
||||
*
|
||||
* ELINKS_LOG=/tmp/dom-dump.txt ./elinks -no-connect <url>
|
||||
*
|
||||
* to have the debug dumped into a file. */
|
||||
#define add_dom_stack_tracer(stack, name) \
|
||||
add_dom_stack_context(stack, name, &dom_stack_trace_context_info)
|
||||
#else
|
||||
#define add_dom_stack_tracer(stack, name) /* Nada */
|
||||
#endif
|
||||
|
||||
/* The state iterators do not include the bottom state */
|
||||
/** The state iterators
|
||||
*
|
||||
* To safely iterate through the stack state iterators. */
|
||||
|
||||
/** Iterate the stack from bottom to top. */
|
||||
#define foreach_dom_stack_state(stack, state, pos) \
|
||||
for ((pos) = 0; (pos) < (stack)->depth; (pos)++) \
|
||||
if (((state) = &(stack)->states[(pos)]))
|
||||
|
||||
/** Iterate the stack from top to bottom. */
|
||||
#define foreachback_dom_stack_state(stack, state, pos) \
|
||||
for ((pos) = (stack)->depth - 1; (pos) >= 0; (pos)--) \
|
||||
if (((state) = &(stack)->states[(pos)]))
|
||||
@ -125,41 +187,96 @@ extern struct dom_stack_context_info dom_stack_trace_context_info;
|
||||
|
||||
/* Life cycle functions. */
|
||||
|
||||
/** Initialise a DOM stack
|
||||
* stack:: Pointer to a (preallocated) stack.
|
||||
* flags:: Any flags needed for controlling the behaviour of the stack.
|
||||
*/
|
||||
void init_dom_stack(struct dom_stack *stack, enum dom_stack_flag flags);
|
||||
/** Release a DOM stack
|
||||
*
|
||||
* Free all resources collected by the stack.
|
||||
*
|
||||
* stack:: The stack to release. */
|
||||
void done_dom_stack(struct dom_stack *stack);
|
||||
|
||||
/* Add a context to the stack. This is needed if either you want to have the
|
||||
* stack allocated objects for created states and/or if you want to install
|
||||
* callbacks for pushing or popping. . */
|
||||
/** Add a context to the stack
|
||||
*
|
||||
* This is needed if either you want to have the stack allocated objects for
|
||||
* created states and/or if you want to install callbacks for pushing or
|
||||
* popping.
|
||||
*
|
||||
* stack:: The stack where the context should be created.
|
||||
* data:: Private data to be stored in ref:[dom_stack_context.data].
|
||||
* context_info:: Information about state objects and node callbacks.
|
||||
*
|
||||
* Returns a pointer to the newly created context or NULL. */
|
||||
struct dom_stack_context *
|
||||
add_dom_stack_context(struct dom_stack *stack, void *data,
|
||||
struct dom_stack_context_info *context_info);
|
||||
|
||||
/* Unregister a stack @context. This should be done especially for temporary
|
||||
* stack contexts (without any callbacks) so that they do not increasing the
|
||||
* memory usage. */
|
||||
/** Unregister a stack context
|
||||
* This should be done especially for temporary stack contexts (without any
|
||||
* callbacks) so that they do not increasing the memory usage. */
|
||||
void done_dom_stack_context(struct dom_stack *stack, struct dom_stack_context *context);
|
||||
|
||||
/* Decends down to the given node making it the current parent */
|
||||
/* If an error occurs the node is free()d and NULL is returned */
|
||||
/** Push a node onto the stack
|
||||
*
|
||||
* Makes the pushed node the new top of the stack.
|
||||
*
|
||||
* stack:: The stack to push onto.
|
||||
* node:: The node to push onto the stack.
|
||||
*
|
||||
* If an error occurs the node is released with ref:[done_dom_node] and NULL is
|
||||
* returned. Else the pushed node is returned. */
|
||||
struct dom_node *push_dom_node(struct dom_stack *stack, struct dom_node *node);
|
||||
|
||||
/* Ascends the stack to the current parent */
|
||||
/** Pop the top stack state
|
||||
*
|
||||
* stack:: The stack to pop from. */
|
||||
void pop_dom_node(struct dom_stack *stack);
|
||||
|
||||
/* Ascends the stack looking for specific parent */
|
||||
/** Conditionally pop the stack states
|
||||
*
|
||||
* Searches the stack (using ref:[search_dom_stack]) for a specific node and
|
||||
* pops all states until that particular state is met.
|
||||
*
|
||||
* NOTE: The popping is stopped if an immutable state is encountered. */
|
||||
void pop_dom_nodes(struct dom_stack *stack, enum dom_node_type type,
|
||||
struct dom_string *string);
|
||||
|
||||
/* Pop all stack states until a specific state is reached. */
|
||||
/** Pop all states until target state
|
||||
*
|
||||
* Pop all stack states until a specific state is reached. The target state
|
||||
* is also popped.
|
||||
*
|
||||
* stack:: The stack to pop from.
|
||||
* target:: The state to pop until and including. */
|
||||
void pop_dom_state(struct dom_stack *stack, struct dom_stack_state *target);
|
||||
|
||||
/* Dive through the stack states in search for the specified match. */
|
||||
/** Search the stack states
|
||||
*
|
||||
* The string comparison is done against the ref:[dom_node.string] member of
|
||||
* the of the state nodes.
|
||||
*
|
||||
* stack:: The stack to search in.
|
||||
* type:: The type of node to match against.
|
||||
* string:: The string to match against.
|
||||
*
|
||||
* Returns a state that matched the type and string or NULL. */
|
||||
struct dom_stack_state *
|
||||
search_dom_stack(struct dom_stack *stack, enum dom_node_type type,
|
||||
struct dom_string *string);
|
||||
|
||||
/* Visit each node in the tree rooted at @root pre-order */
|
||||
/** Walk all nodes reachable from a given node
|
||||
*
|
||||
* Visits each node in the DOM tree rooted at a given node, pre-order style.
|
||||
*
|
||||
* stack:: The stack to use for walking the nodes.
|
||||
* root:: The root node to start from.
|
||||
*
|
||||
* It is assummed that the given stack has been initialised with
|
||||
* ref:[init_dom_stack] and that the caller already added one or more
|
||||
* context to the stack. */
|
||||
void walk_dom_nodes(struct dom_stack *stack, struct dom_node *root);
|
||||
|
||||
#endif
|
||||
|
@ -259,7 +259,7 @@ struct entity { char *s; unicode_val_T c; } entities [1002] = {
|
||||
{ "b.alpha", 0x03B1 }, /* GREEK SMALL LETTER ALPHA */
|
||||
{ "b.beta", 0x03B2 }, /* GREEK SMALL LETTER BETA */
|
||||
{ "b.chi", 0x03C7 }, /* GREEK SMALL LETTER CHI */
|
||||
{ "b.delta", 0x03B3 }, /* GREEK SMALL LETTER GAMMA */
|
||||
{ "b.delta", 0x03B4 }, /* GREEK SMALL LETTER DELTA */
|
||||
{ "b.epsi", 0x03B5 }, /* GREEK SMALL LETTER EPSILON */
|
||||
{ "b.epsis", 0x03B5 }, /* GREEK SMALL LETTER EPSILON */
|
||||
{ "b.epsiv", 0x03B5 }, /* GREEK SMALL LETTER EPSILON */
|
||||
@ -1005,4 +1005,4 @@ struct entity { char *s; unicode_val_T c; } entities [1002] = {
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
#define N_ENTITIES 1001
|
||||
#define N_ENTITIES 1001
|
||||
|
@ -110,7 +110,8 @@ init_response_digest(md5_digest_hex_T response, struct auth_entry *entry,
|
||||
MD5_Init(&MD5Ctx);
|
||||
MD5_Update(&MD5Ctx, ha1, sizeof(ha1));
|
||||
MD5_Update(&MD5Ctx, ":", 1);
|
||||
MD5_Update(&MD5Ctx, entry->nonce, strlen(entry->nonce));
|
||||
if (entry->nonce)
|
||||
MD5_Update(&MD5Ctx, entry->nonce, strlen(entry->nonce));
|
||||
MD5_Update(&MD5Ctx, ":", 1);
|
||||
MD5_Update(&MD5Ctx, "00000001", 8);
|
||||
MD5_Update(&MD5Ctx, ":", 1);
|
||||
@ -142,10 +143,12 @@ get_http_auth_digest_response(struct auth_entry *entry, struct uri *uri)
|
||||
add_to_string(&string, entry->user);
|
||||
add_to_string(&string, "\", ");
|
||||
add_to_string(&string, "realm=\"");
|
||||
add_to_string(&string, entry->realm);
|
||||
if (entry->realm)
|
||||
add_to_string(&string, entry->realm);
|
||||
add_to_string(&string, "\", ");
|
||||
add_to_string(&string, "nonce=\"");
|
||||
add_to_string(&string, entry->nonce);
|
||||
if (entry->nonce)
|
||||
add_to_string(&string, entry->nonce);
|
||||
add_to_string(&string, "\", ");
|
||||
add_to_string(&string, "uri=\"/");
|
||||
add_bytes_to_string(&string, uri->data, uri->datalen);
|
||||
|
@ -140,7 +140,7 @@ get_gopher_entity_info(enum gopher_entity type)
|
||||
{
|
||||
int entry;
|
||||
|
||||
for (entry = 0; entry < sizeof(gopher_entity_info) - 1; entry++)
|
||||
for (entry = 0; entry < sizeof_array(gopher_entity_info) - 1; entry++)
|
||||
if (gopher_entity_info[entry].type == type)
|
||||
return &gopher_entity_info[entry];
|
||||
|
||||
@ -282,7 +282,7 @@ init_gopher_connection_info(struct connection *conn)
|
||||
|
||||
/* Get entity type, and selector string. */
|
||||
/* Pick up gopher_entity */
|
||||
if (selectorlen > 0) {
|
||||
if (selectorlen > 1 && selector[1] == '/') {
|
||||
entity = *selector++;
|
||||
selectorlen--;
|
||||
}
|
||||
@ -296,7 +296,7 @@ init_gopher_connection_info(struct connection *conn)
|
||||
* _after_ the Gopher entity. If the <entity-char> '/' combo is not
|
||||
* found assume that the whole URI data part is the selector. */
|
||||
entity_info = get_gopher_entity_info(entity);
|
||||
if (entity_info->type == GOPHER_UNKNOWN) {
|
||||
if (entity_info->type == GOPHER_UNKNOWN && entity != GOPHER_UNKNOWN) {
|
||||
selector--;
|
||||
selectorlen++;
|
||||
}
|
||||
@ -518,7 +518,8 @@ add_gopher_menu_line(struct string *buffer, unsigned char *line)
|
||||
default:
|
||||
{
|
||||
struct string address;
|
||||
unsigned char *format = *selector ? "%s://%s@%s/" : "%s://%s%s/";
|
||||
unsigned char *format = selector && *selector
|
||||
? "%s://%s@%s/" : "%s://%s%s/";
|
||||
|
||||
/* If port is defined it means that both @selector and @host
|
||||
* was correctly parsed. */
|
||||
|
@ -10,10 +10,6 @@
|
||||
* Ie. MIN(a+b, c+d) will do 3 additions...
|
||||
* Please prefer to use int_min() and int_max() if possible. */
|
||||
|
||||
#ifdef HAVE_SYS_PARAM_H
|
||||
#include <sys/param.h> /* MIN/MAX may be defined in this header. */
|
||||
#endif
|
||||
|
||||
/* FreeBSD needs this. */
|
||||
#ifdef MIN
|
||||
#undef MIN
|
||||
|
Loading…
Reference in New Issue
Block a user