mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
Merge commit 'pasky.or.cz/elinks-0.12' into elinks-0.13
This commit is contained in:
commit
ab9e0821d6
3
NEWS
3
NEWS
@ -71,6 +71,7 @@ Miscellaneous:
|
||||
* gzip_read: always call gzclearerr
|
||||
* bug 816: convert entity references in input/@value only once
|
||||
* bug 916: if a mailcap entry has no %s, provide the file as stdin
|
||||
* bug 744: don't change ``//'' to ``/'' in URIs
|
||||
* bug 766: speed up CSS
|
||||
* bug 355: add documents displayed via ``What to do'' dialog to the
|
||||
global history
|
||||
@ -125,7 +126,7 @@ Build system and compile-time errors (ignore if you don't build ELinks):
|
||||
* enhancement: avoid compilation of vernum.c in 'make install'
|
||||
* enhancement: make uninstall
|
||||
* experimental enhancements: --with-python=DIRECTORY, --with-gc=DIRECTORY
|
||||
* experimental enhancement: native Win32 port
|
||||
* experimental enhancement: Win32 port (build with MinGW MSYS)
|
||||
|
||||
Changes in the experimental ECMAScript support:
|
||||
|
||||
|
@ -21,7 +21,8 @@ echo timestamp > stamp-h.in
|
||||
echo autoconf...
|
||||
autoconf
|
||||
|
||||
echo config.cache...
|
||||
echo config.cache, autom4te.cache...
|
||||
rm -f config.cache
|
||||
rm -rf autom4te.cache
|
||||
|
||||
echo done
|
||||
|
@ -14,7 +14,7 @@ AC_DEFUN([EL_CONFIG_OS_WIN32],
|
||||
EL_RESTORE_FLAGS
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS(windows.h)
|
||||
AC_CHECK_HEADERS(windows.h ws2tcpip.h)
|
||||
|
||||
# TODO: Check this?
|
||||
# TODO: Check -lws2_32 for IPv6 support
|
||||
|
174
contrib/mkdist
Normal file → Executable file
174
contrib/mkdist
Normal file → Executable file
@ -2,11 +2,21 @@
|
||||
#
|
||||
# This script can be used by a cron to generate snapshots.
|
||||
# For example, use:
|
||||
# 35 0 * * * mkdist elinks-0.11 0.11 >>mkdist.log 2>&1
|
||||
# 40 0 * * * mkdist HEAD 0.12 >>mkdist.log 2>&1
|
||||
# 35 0 * * * mkdist -r elinks-0.11 -l 0.11 -s >>mkdist.log 2>&1
|
||||
# 40 0 * * * mkdist -r HEAD -l 0.12 -s >>mkdist.log 2>&1
|
||||
#
|
||||
# To generate a release (which doesn't have a date in the
|
||||
# top-level directory) also pass -r as the third parameter.
|
||||
# Options:
|
||||
# -g GIT_DIR Git repository from which this script exports ELinks.
|
||||
# May be given in the environment instead.
|
||||
# -r REVISION Git revision to be exported from the repository.
|
||||
# -l LABEL User-friendly name of the branch or release.
|
||||
# This ends up in the name of the tar file, and in the
|
||||
# name of the directory it contains.
|
||||
# -s Generate a snapshot (which has a date in the top-level
|
||||
# directory).
|
||||
# -d DOCDIR Copy prebuilt documentation from DOCDIR.
|
||||
# -o OUTDIR Place the output files in OUTDIR. Defaults to the
|
||||
# current directory.
|
||||
|
||||
# set -x
|
||||
|
||||
@ -15,64 +25,118 @@ echo "Date: $(date)"
|
||||
echo "Args: $*"
|
||||
echo "-------------------------------------------------"
|
||||
|
||||
ub=$1
|
||||
lb=$2
|
||||
# Variables used in this script:
|
||||
# $GIT_DIR = option -g GIT_DIR; passed in environment to Git
|
||||
# $OPTARG = Bash special: argument of the option being parsed
|
||||
# $OPTIND = Bash special: index of argument to be parsed next
|
||||
# $commit = commit ID corresponding to $rev
|
||||
# $docdir = option -d DOCDIR
|
||||
# $label = option -l LABEL
|
||||
# $opt = option letter being parsed, or '?' on error
|
||||
# $outdir = option -o OUTDIR
|
||||
# $rev = option -r REVISION
|
||||
# $snap = option -s
|
||||
# $tarbasename = name of the tar file without .tar.* extensions
|
||||
# $tartopdir = name of the top directory within the tar file
|
||||
# $tmpdir = temporary directory created by this script
|
||||
|
||||
GIT_DIR="elinks-repo-directory"
|
||||
DOC_DIR="" # Leave empty for no doc dir
|
||||
TMP_DIR="/tmp/elinks-git.$$"
|
||||
TAR_DIR="elinks-snapshot-directory"
|
||||
rev=
|
||||
label=
|
||||
snap=
|
||||
docdir=
|
||||
outdir=.
|
||||
while getopts "g:r:l:sd:o:" opt
|
||||
do
|
||||
case "$opt" in
|
||||
(g) GIT_DIR=$OPTARG ;;
|
||||
(r) rev=$OPTARG ;;
|
||||
(l) label=$OPTARG ;;
|
||||
(s) snap=1 ;;
|
||||
(d) docdir=$OPTARG ;;
|
||||
(o) outdir=$OPTARG ;;
|
||||
("?") exit 1 ;;
|
||||
(*) echo >&2 "$0:$LINENO: bug found"
|
||||
exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ "$ub" ] || exit 1
|
||||
[ "$lb" ] || exit 1
|
||||
|
||||
if [ "$3" != "-r" ]; then
|
||||
ver=$lb-`date +%Y%m%d`
|
||||
c="-current";
|
||||
else
|
||||
ver=$lb;
|
||||
c="";
|
||||
if [ $OPTIND -le $# ]
|
||||
then
|
||||
echo >&2 "$0: too many non-option arguments"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir "$TMP_DIR
|
||||
cd "$TMP_DIR"
|
||||
|
||||
GIT_DIR="$GIT_DIR" cg-export -r "$ub" "$TMP_DIR"/elinks"
|
||||
|
||||
cd elinks
|
||||
|
||||
./autogen.sh
|
||||
./configure
|
||||
|
||||
if [ "$ub" = "REL_0_10" ]; then
|
||||
make dist
|
||||
tar xfz elinks-$lb*.tar.gz
|
||||
cd elinks-$ub*
|
||||
else
|
||||
make -C po
|
||||
if [ -z "$GIT_DIR" ]
|
||||
then
|
||||
echo >&2 "$0: Must specify -g GIT_DIR option"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$outdir" ]
|
||||
then
|
||||
echo >&2 "$0: Must specify -o OUTDIR option"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$rev" ]
|
||||
then
|
||||
echo >&2 "$0: Must specify -r REVISION option"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z "$label" ]
|
||||
then
|
||||
label=$rev
|
||||
fi
|
||||
|
||||
if test -n "$DOC_DIR"; then
|
||||
mkdir doc/html
|
||||
cp -r "$DOC_DIR"/*.html* doc/html
|
||||
commit=$(GIT_DIR=$GIT_DIR cg-object-id -c "$rev") || exit 1
|
||||
|
||||
if [ "$snap" ]
|
||||
then
|
||||
tartopdir=elinks-$label-$(date +%Y%m%d)
|
||||
tarbasename=elinks-current-$label
|
||||
else
|
||||
tartopdir=elinks-$label
|
||||
tarbasename=elinks-$label
|
||||
fi
|
||||
|
||||
tmpdir=$(mktemp -d -t elinks-dist-XXXXXXXX) || exit 1
|
||||
|
||||
# To make it easier to compare build logs, put the source first in an
|
||||
# "elinks" directory, and only move to "$tartopdir" when finished.
|
||||
|
||||
GIT_DIR=$GIT_DIR cg-export -r "$rev" -- "$tmpdir/elinks"
|
||||
mkdir -- "$tmpdir/elinks/.git"
|
||||
printf "%s\n" "$commit" > "$tmpdir/elinks/.git/HEAD"
|
||||
|
||||
(set -e
|
||||
cd -- "$tmpdir/elinks"
|
||||
./autogen.sh
|
||||
mkdir build
|
||||
cd build
|
||||
../configure
|
||||
make -C po
|
||||
mv po/*.gmo ../po/
|
||||
mv contrib/elinks.spec ../contrib/
|
||||
) || exit 1
|
||||
|
||||
if [ -n "$docdir" ]; then
|
||||
mkdir -- "$tmpdir/elinks/doc/html"
|
||||
cp -r -- "$docdir"/*.html* "$tmpdir/elinks/doc/html/"
|
||||
# mkdir doc/pdf
|
||||
# cp "$DOC_DIR"/*.pdf doc/pdf
|
||||
# cp "$docdir"/*.pdf doc/pdf
|
||||
fi
|
||||
|
||||
cd ..
|
||||
rm -rf -- "$tmpdir/elinks/build"
|
||||
mv -- "$tmpdir/elinks" "$tmpdir/$tartopdir"
|
||||
|
||||
if [ "$c" ]; then
|
||||
dir=`ls .`
|
||||
mv $dir elinks-$ver
|
||||
fi
|
||||
|
||||
|
||||
tar cfz elinks$c-$lb.tar.gz elinks-$ver && \
|
||||
mv elinks$c-$lb.tar.gz "$TAR_DIR" && \
|
||||
(cd "$TAR_DIR" && md5sum elinks$c-$lb.tar.gz > elinks$c-$lb.tar.gz.md5)
|
||||
|
||||
tar cfj elinks$c-$lb.tar.bz2 elinks-$ver && \
|
||||
mv elinks$c-$lb.tar.bz2 "$TAR_DIR" && \
|
||||
(cd "$TAR_DIR" && md5sum elinks$c-$lb.tar.bz2 > elinks$c-$lb.tar.gz.md5)
|
||||
|
||||
rm -rf "$TMP_DIR"
|
||||
(set -e
|
||||
cd -- "$tmpdir"
|
||||
tar cf "$tarbasename.tar" "$tartopdir"
|
||||
md5sum --binary -- "$tarbasename.tar" > "$tarbasename.md5"
|
||||
bzip2 --keep -- "$tarbasename.tar"
|
||||
gzip -9 -- "$tarbasename.tar"
|
||||
md5sum --binary -- "$tarbasename.tar.gz" "$tarbasename.tar.bz2" >> "$tarbasename.md5"
|
||||
) || exit 1
|
||||
|
||||
mv -- "$tmpdir/$tarbasename.tar.gz" "$outdir"
|
||||
mv -- "$tmpdir/$tarbasename.tar.bz2" "$outdir"
|
||||
mv -- "$tmpdir/$tarbasename.md5" "$outdir"
|
||||
rm -rf -- "$tmpdir"
|
||||
|
3
contrib/proxy/.gitignore
vendored
Normal file
3
contrib/proxy/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
gen
|
||||
proxy.py
|
||||
*.http
|
@ -121,10 +121,10 @@ dicts(FILE *f)
|
||||
|
||||
fprintf(f, "slownik = {\n");
|
||||
for (i = 0; i < counter - 1; i++) {
|
||||
fprintf(f, "\t'http://%s%s' : '%d.txt',\n", tab[i].host, tab[i].string, i);
|
||||
fprintf(f, "\t'http://%s%s' : '%d.http',\n", tab[i].host, tab[i].string, i);
|
||||
}
|
||||
for (; i < counter; i++) {
|
||||
fprintf(f, "\t'http://%s%s' : '%d.txt'\n", tab[i].host, tab[i].string, i);
|
||||
fprintf(f, "\t'http://%s%s' : '%d.http'\n", tab[i].host, tab[i].string, i);
|
||||
}
|
||||
fprintf(f, "}\n\n");
|
||||
}
|
||||
@ -138,7 +138,7 @@ save(void)
|
||||
for (i = 0; i < counter; i++) {
|
||||
char buf[12];
|
||||
|
||||
snprintf(buf, 12, "%d.txt", i);
|
||||
snprintf(buf, 12, "%d.http", i);
|
||||
f = fopen(buf, "w");
|
||||
if (!f)
|
||||
return;
|
||||
|
15
doc/Makefile
15
doc/Makefile
@ -4,7 +4,7 @@ include $(top_builddir)/Makefile.config
|
||||
SUBDIRS = man
|
||||
|
||||
# A little trick to simplify some of the rules.
|
||||
VPATH = $(builddir):$(srcdir):$(top_srcdir)/contrib/perl:$(top_srcdir)/po/perl
|
||||
VPATH = $(builddir):$(srcdir):$(top_srcdir)/contrib/perl
|
||||
|
||||
docdir = $(datadir)/doc
|
||||
|
||||
@ -43,11 +43,9 @@ HTML_DOCS-$(CONFIG_POD2HTML) += \
|
||||
perl.html \
|
||||
perl-hooks.html
|
||||
|
||||
# Don't install these documents, because the corresponding scripts
|
||||
# are not installed either. However, generating them may be useful.
|
||||
HTML_DOCS_NOINSTALL-$(CONFIG_POD2HTML) += \
|
||||
perl-check-accelerator-conflicts.html \
|
||||
perl-gather-accelerator-contexts.html
|
||||
# We don't nowadays run pod2html on the po/perl/ scripts, because
|
||||
# "make install" does not install them and they do not have the .pl
|
||||
# suffix expected by the pod2html rule below.
|
||||
|
||||
MAN_DOCS-$(CONFIG_XMLTO) += \
|
||||
elinks.1 \
|
||||
@ -64,11 +62,10 @@ PDF_DOCS-$(CONFIG_JW) += \
|
||||
|
||||
MAN_DOCS = $(MAN_DOCS-yes)
|
||||
HTML_DOCS = $(HTML_DOCS-yes)
|
||||
HTML_DOCS_NOINSTALL = $(HTML_DOCS_NOINSTALL-yes)
|
||||
PDF_DOCS = $(PDF_DOCS-yes)
|
||||
|
||||
txt: $(TXT_DOCS_NOINSTALL)
|
||||
html: txt $(HTML_DOCS) $(HTML_DOCS_NOINSTALL)
|
||||
html: txt $(HTML_DOCS)
|
||||
pdf: txt $(PDF_DOCS)
|
||||
man: txt $(MAN_DOCS)
|
||||
|
||||
@ -97,7 +94,7 @@ update-man: man
|
||||
$(call ncmd,installdata,elinks.conf.5,$(srcdir)man/man5/))
|
||||
|
||||
clean-local:
|
||||
@$(RM) -r api $(TXT_DOCS_NOINSTALL) $(MAN_DOCS) $(HTML_DOCS) $(HTML_DOCS_NOINSTALL) $(PDF_DOCS) *.tmp *.xml
|
||||
@$(RM) -r api $(TXT_DOCS_NOINSTALL) $(MAN_DOCS) $(HTML_DOCS) $(PDF_DOCS) *.tmp *.xml
|
||||
|
||||
# TODO: perl.pod should be pod2ized during make install. --pasky
|
||||
install-local:
|
||||
|
@ -53,7 +53,7 @@ $(srcdir)$(POTFILES_ABS_LIST): $(POTFILES_REL)
|
||||
find src/ -type f -name '*.[ch]' -o -name options.inc -o -name 'actions-*.inc' | sort ) \
|
||||
> $(srcdir)$(POTFILES_ABS_LIST)
|
||||
|
||||
$(srcdir)$(PACKAGE).pot: $(srcdir)$(POTFILES_ABS_LIST) $(srcdir)perl/gather-accelerator-contexts.pl
|
||||
$(srcdir)$(PACKAGE).pot: $(srcdir)$(POTFILES_ABS_LIST) $(srcdir)perl/msgaccel-prepare
|
||||
$(XGETTEXT) --default-domain=$(PACKAGE) \
|
||||
--directory=$(top_srcdir) \
|
||||
--add-comments --language=C \
|
||||
@ -77,7 +77,7 @@ $(srcdir)$(PACKAGE).pot: $(srcdir)$(POTFILES_ABS_LIST) $(srcdir)perl/gather-acce
|
||||
--flag=N__:1:pass-c-format \
|
||||
-f $(srcdir)$(POTFILES_ABS_LIST) \
|
||||
&& test -f $(PACKAGE).po \
|
||||
&& $(PERL) -I"$(srcdir)perl" $(srcdir)perl/gather-accelerator-contexts.pl -S"$(top_srcdir)" $(PACKAGE).po \
|
||||
&& $(PERL) -I"$(srcdir)perl" $(srcdir)perl/msgaccel-prepare -S"$(top_srcdir)" $(PACKAGE).po \
|
||||
&& mv -f $(PACKAGE).po $(srcdir)$(PACKAGE).pot
|
||||
|
||||
|
||||
@ -111,7 +111,7 @@ check-po:
|
||||
@-$(foreach lang,$(basename $(if $(strip $(PO)),$(PO),$(GMOFILES))), \
|
||||
echo -n "$(lang): "; \
|
||||
$(GMSGFMT) --check --check-accelerators="~" --verbose --statistics -o /dev/null $(srcdir)$(lang).po; \
|
||||
$(PERL) -I"$(srcdir)perl" $(srcdir)perl/check-accelerator-conflicts.pl $(srcdir)$(lang).po; \
|
||||
$(PERL) -I"$(srcdir)perl" $(srcdir)perl/msgaccel-check $(srcdir)$(lang).po; \
|
||||
)
|
||||
|
||||
### Installation and distribution
|
||||
|
127
po/README
127
po/README
@ -166,131 +166,8 @@ well, especially Last-Translator and PO-Revision-Date fields.
|
||||
--------------------
|
||||
|
||||
First set Plural-Forms: header (msgid "" at top of .po file) to some correct
|
||||
value, depending on language.
|
||||
|
||||
To help you in this, here is an excerpt from GNU gettext documentation:
|
||||
|
||||
Only one form:
|
||||
Some languages only require one single form. There is no distinction
|
||||
between the singular and plural form. An appropriate header entry
|
||||
would look like this:
|
||||
|
||||
Plural-Forms: nplurals=1; plural=0;
|
||||
|
||||
Languages with this property include:
|
||||
|
||||
Finno-Ugric family
|
||||
Hungarian
|
||||
Asian family
|
||||
Japanese, Korean
|
||||
Turkic/Altaic family
|
||||
Turkish
|
||||
|
||||
Two forms, singular used for one only:
|
||||
This is the form used in most existing programs since it is what English
|
||||
is using. A header entry would look like this:
|
||||
|
||||
Plural-Forms: nplurals=2; plural=n != 1;
|
||||
|
||||
(Note: this uses the feature of C expressions that boolean expressions
|
||||
have to value zero or one.)
|
||||
|
||||
Languages with this property include:
|
||||
|
||||
Germanic family
|
||||
Danish, Dutch, English, German, Norwegian, Swedish
|
||||
Finno-Ugric family
|
||||
Estonian, Finnish
|
||||
Latin/Greek family
|
||||
Greek
|
||||
Semitic family
|
||||
Hebrew
|
||||
Romanic family
|
||||
Italian, Portuguese, Spanish
|
||||
Artificial
|
||||
Esperanto
|
||||
|
||||
Two forms, singular used for zero and one:
|
||||
Exceptional case in the language family. The header entry would be:
|
||||
|
||||
Plural-Forms: nplurals=2; plural=n>1;
|
||||
|
||||
Languages with this property include:
|
||||
|
||||
Romanic family
|
||||
French, Brazilian Portuguese
|
||||
|
||||
Three forms, special case for zero:
|
||||
The header entry would be:
|
||||
|
||||
Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2;
|
||||
|
||||
Languages with this property include:
|
||||
|
||||
Baltic family
|
||||
Latvian
|
||||
|
||||
Three forms, special cases for one and two:
|
||||
The header entry would be:
|
||||
|
||||
Plural-Forms: nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;
|
||||
|
||||
Languages with this property include:
|
||||
|
||||
Celtic
|
||||
Gaeilge (Irish)
|
||||
|
||||
Three forms, special case for numbers ending in 1[2-9]:
|
||||
The header entry would look like this:
|
||||
|
||||
Plural-Forms: nplurals=3; \
|
||||
plural=n%10==1 && n%100!=11 ? 0 : \
|
||||
n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2;
|
||||
|
||||
Languages with this property include:
|
||||
|
||||
Baltic family
|
||||
Lithuanian
|
||||
|
||||
Three forms, special cases for numbers ending in 1 and 2, 3, 4,
|
||||
except those ending in 1[1-4]:
|
||||
The header entry would look like this:
|
||||
|
||||
Plural-Forms: nplurals=3; \
|
||||
plural=n%10==1 && n%100!=11 ? 0 : \
|
||||
n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
|
||||
|
||||
Languages with this property include:
|
||||
|
||||
Slavic family
|
||||
Croatian, Czech, Russian, Slovak, Ukrainian
|
||||
|
||||
Three forms, special case for one and some numbers ending in 2, 3, or 4:
|
||||
The header entry would look like this:
|
||||
|
||||
Plural-Forms: nplurals=3; \
|
||||
plural=n==1 ? 0 : \
|
||||
n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;
|
||||
|
||||
Languages with this property include:
|
||||
|
||||
Slavic family
|
||||
Polish
|
||||
|
||||
Four forms, special case for one and all numbers ending in 02, 03, or 04:
|
||||
The header entry would look like this:
|
||||
|
||||
Plural-Forms: nplurals=4; \
|
||||
plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;
|
||||
|
||||
Languages with this property include:
|
||||
|
||||
Slavic family
|
||||
Slovenian
|
||||
|
||||
|
||||
More info at http://www.gnu.org/software/gettext
|
||||
|
||||
value, depending on language. See GNU gettext documentation for details, at
|
||||
http://www.gnu.org/software/gettext
|
||||
|
||||
Plural forms will appear like this in .po file:
|
||||
|
||||
|
@ -21,21 +21,21 @@ When a programmer adds a translatable string to the C source code of
|
||||
ELinks, and the string contains an accelerator, he should also add a
|
||||
special "gettext_accelerator_context" comment that names the menu or
|
||||
dialog box in which the string will be used. See the documentation of
|
||||
gather-accelerator-contexts.pl for the details.
|
||||
msgaccel-prepare for the details.
|
||||
|
||||
When a programmer or translator runs "make update-po" in the
|
||||
elinks/po directory, gather-accelerator-contexts.pl reads the
|
||||
"gettext_accelerator_context" comments in the source files and
|
||||
generates "accelerator_context" comments in elinks.pot. Then,
|
||||
msgmerge copies them from elinks.pot to *.po.
|
||||
When a programmer or translator runs "make update-po" in the elinks/po
|
||||
directory, msgaccel-prepare reads the "gettext_accelerator_context"
|
||||
comments in the source files and generates "accelerator_context"
|
||||
comments in elinks.pot. Then, msgmerge copies them from elinks.pot to
|
||||
*.po.
|
||||
|
||||
When a translator edits a *.po file, she does not alter the
|
||||
"accelerator_context" comments.
|
||||
|
||||
When a translator runs "make check-po" in the elinks/po directory,
|
||||
check-accelerator-conflicts.pl reads the "accelerator_context"
|
||||
comments in the *.po file, checks the accelerators in the
|
||||
translations, and displays any conflicts it finds.
|
||||
msgaccel-check reads the "accelerator_context" comments in the *.po
|
||||
file, checks the accelerators in the translations, and displays any
|
||||
conflicts it finds.
|
||||
|
||||
|
||||
FILES
|
||||
@ -43,12 +43,12 @@ FILES
|
||||
|
||||
See each file for copying conditions.
|
||||
|
||||
gather-accelerator-contexts.pl reads elinks.pot and the source files
|
||||
to which it refers, and writes a new elinks.pot with information from
|
||||
msgaccel-prepare reads elinks.pot and the source files to which it
|
||||
refers, and writes a new elinks.pot with information from
|
||||
"gettext_accelerator_context" comments.
|
||||
|
||||
check-accelerator-conflicts.pl reads just one *.po file and scans it
|
||||
for conflicts. It does not access the C source files.
|
||||
msgaccel-check reads just one *.po file and scans it for conflicts.
|
||||
It does not access the C source files.
|
||||
|
||||
Locale/PO.pm was originally imported from Locale-PO-0.16 on CPAN, and
|
||||
has since been patched to make it more suitable for these scripts.
|
||||
|
@ -7,11 +7,11 @@ use Locale::PO qw();
|
||||
use Getopt::Long qw(GetOptions :config bundling gnu_compat);
|
||||
use autouse 'Pod::Usage' => qw(pod2usage);
|
||||
|
||||
my $VERSION = "1.5";
|
||||
my $VERSION = "1.6";
|
||||
|
||||
sub show_version
|
||||
{
|
||||
print "check-accelerator-conflicts.pl $VERSION\n";
|
||||
print "msgaccel-check $VERSION\n";
|
||||
pod2usage({-verbose => 99, -sections => "COPYRIGHT AND LICENSE",
|
||||
-exitval => 0});
|
||||
}
|
||||
@ -208,32 +208,31 @@ __END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
check-accelerator-conflicts.pl - Scan a PO file for conflicting
|
||||
accelerator keys.
|
||||
msgaccel-check - Scan a PO file for conflicting accelerator keys.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<check-accelerator-conflicts.pl> [I<option> ...] F<I<language>.po> [...]
|
||||
B<msgaccel-check> [I<option> ...] F<I<language>.po> [...]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<check-accelerator-conflicts.pl> is part of a framework that detects
|
||||
conflicting accelerator keys in Gettext PO files. A conflict is when
|
||||
two items in the same menu or two buttons in the same dialog box use
|
||||
the same accelerator key.
|
||||
B<msgaccel-check> is part of a framework that detects conflicting
|
||||
accelerator keys in Gettext PO files. A conflict is when two items in
|
||||
the same menu or two buttons in the same dialog box use the same
|
||||
accelerator key.
|
||||
|
||||
The PO file format does not normally include any information on which
|
||||
strings will be used in the same menu or dialog box.
|
||||
B<check-accelerator-conflicts.pl> can only be used on PO files to which
|
||||
this information has been added with B<gather-accelerator-contexts.pl>
|
||||
or merged with B<msgmerge>.
|
||||
B<msgaccel-check> can only be used on PO files to which this
|
||||
information has been added with B<msgaccel-prepare> or merged with
|
||||
B<msgmerge>.
|
||||
|
||||
B<check-accelerator-conflicts.pl> reads the F<I<language>.po> file
|
||||
named on the command line and reports any conflicts to standard error.
|
||||
It also tries to suggest replacements for the conflicting accelerators.
|
||||
B<msgaccel-check> reads the F<I<language>.po> file named on the
|
||||
command line and reports any conflicts to standard error. It also
|
||||
tries to suggest replacements for the conflicting accelerators.
|
||||
|
||||
B<check-accelerator-conflicts.pl> does not access the source files to
|
||||
which F<I<language>.po> refers. Thus, it does not matter if the line
|
||||
B<msgaccel-check> does not access the source files to which
|
||||
F<I<language>.po> refers. Thus, it does not matter if the line
|
||||
numbers in "#:" lines are out of date.
|
||||
|
||||
=head1 OPTIONS
|
||||
@ -243,10 +242,9 @@ numbers in "#:" lines are out of date.
|
||||
=item B<--accelerator-tag=>I<character>
|
||||
|
||||
Specify the character that marks accelerators in C<msgstr> strings.
|
||||
Whenever this character occurs in a C<msgstr>,
|
||||
B<check-accelerator-conflicts.pl> treats the next character as an
|
||||
accelerator and checks that it is unique in each of the contexts in
|
||||
which the C<msgstr> is used.
|
||||
Whenever this character occurs in a C<msgstr>, B<msgaccel-check>
|
||||
treats the next character as an accelerator and checks that it is
|
||||
unique in each of the contexts in which the C<msgstr> is used.
|
||||
|
||||
Omitting the B<--accelerator-tag> option implies
|
||||
B<--accelerator-tag="~">. The option must be given to each program
|
||||
@ -258,14 +256,13 @@ in the PO file.
|
||||
=item B<--no-msgid-fallback>
|
||||
|
||||
Select how to check entries where the C<msgstr> is missing or fuzzy.
|
||||
The default is B<--msgid-fallback>, which makes
|
||||
B<check-accelerator-conflicts.pl> use the C<msgid> instead, and report
|
||||
any conflicts between C<msgid> and C<msgstr> strings. The alternative
|
||||
is B<--no-msgid-fallback>, which makes B<check-accelerator-conflicts.pl>
|
||||
completely ignore such entries.
|
||||
The default is B<--msgid-fallback>, which makes B<msgaccel-check> use
|
||||
the C<msgid> instead, and report any conflicts between C<msgid> and
|
||||
C<msgstr> strings. The alternative is B<--no-msgid-fallback>, which
|
||||
makes B<msgaccel-check> completely ignore such entries.
|
||||
|
||||
Regardless of these options, B<check-accelerator-conflicts.pl> will
|
||||
suggest accelerators that would conflict with ones defined in C<msgid>
|
||||
Regardless of these options, B<msgaccel-check> will suggest
|
||||
accelerators that would conflict with ones defined in C<msgid>
|
||||
strings. Those strings will be eventually shadowed by C<msgstr>
|
||||
strings, so their accelerators should not affect which accelerators
|
||||
the translator chooses for C<msgstr> strings.
|
||||
@ -278,8 +275,8 @@ the translator chooses for C<msgstr> strings.
|
||||
|
||||
=item F<I<language>.po> [...]
|
||||
|
||||
The PO files to be scanned for conflicts. These files must include the
|
||||
"accelerator_context" comments added by B<gather-accelerator-contexts.pl>.
|
||||
The PO files to be scanned for conflicts. These files must include
|
||||
the "accelerator_context" comments added by B<msgaccel-prepare>.
|
||||
If the special comments are missing, no conflicts will be found.
|
||||
|
||||
=back
|
||||
@ -296,9 +293,9 @@ If the special comments are missing, no conflicts will be found.
|
||||
|
||||
=head2 Waiting for Locale::PO fixes
|
||||
|
||||
When B<check-accelerator-conflicts.pl> includes C<msgstr> strings in
|
||||
warnings, it should transcode them from the charset of the PO file to
|
||||
the one specified by the user's locale.
|
||||
When B<msgaccel-check> includes C<msgstr> strings in warnings, it
|
||||
should transcode them from the charset of the PO file to the one
|
||||
specified by the user's locale.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
@ -335,4 +332,4 @@ DEALINGS IN THE SOFTWARE.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<gather-accelerator-contexts.pl>, C<xgettext(1)>, C<msgmerge(1)>
|
||||
L<msgaccel-prepare>, C<xgettext(1)>, C<msgmerge(1)>
|
@ -8,11 +8,11 @@ use Getopt::Long qw(GetOptions :config bundling gnu_compat);
|
||||
use autouse 'Pod::Usage' => qw(pod2usage);
|
||||
use autouse 'File::Spec::Functions' => qw(catfile);
|
||||
|
||||
my $VERSION = "1.1";
|
||||
my $VERSION = "1.2";
|
||||
|
||||
sub show_version
|
||||
{
|
||||
print "gather-accelerator-contexts.pl $VERSION\n";
|
||||
print "msgaccel-prepare $VERSION\n";
|
||||
pod2usage({-verbose => 99, -sections => "COPYRIGHT AND LICENSE",
|
||||
-exitval => 0});
|
||||
}
|
||||
@ -168,24 +168,24 @@ __END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
gather-accelerator-contexts.pl - Augment a PO file with information
|
||||
for detecting accelerator conflicts.
|
||||
msgaccel-prepare - Augment a PO file with information for detecting
|
||||
accelerator conflicts.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
B<gather-accelerator-contexts.pl> [I<option> ...] F<I<program>.pot>
|
||||
B<msgaccel-prepare> [I<option> ...] F<I<program>.pot>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
B<gather-accelerator-contexts.pl> is part of a framework that detects
|
||||
conflicting accelerator keys in Gettext PO files. A conflict is when
|
||||
two items in the same menu or two buttons in the same dialog box use
|
||||
the same accelerator key.
|
||||
B<msgaccel-prepare> is part of a framework that detects conflicting
|
||||
accelerator keys in Gettext PO files. A conflict is when two items in
|
||||
the same menu or two buttons in the same dialog box use the same
|
||||
accelerator key.
|
||||
|
||||
The PO file format does not normally include any information on which
|
||||
strings will be used in the same menu or dialog box.
|
||||
B<gather-accelerator-contexts.pl> adds this information in the form of
|
||||
"accelerator_context" comments, which B<check-accelerator-conflicts.pl>
|
||||
The PO file format does not normally include any information
|
||||
on which strings will be used in the same menu or dialog box.
|
||||
B<msgaccel-prepare> adds this information in the form of
|
||||
"accelerator_context" comments, which B<msgaccel-check>
|
||||
then parses in order to detect the conflicts.
|
||||
|
||||
The PO file format also does not directly support definitions of
|
||||
@ -194,17 +194,17 @@ strings, by placing a tilde in front of the character that should be
|
||||
used as the accelerator key. That is also the syntax supported by
|
||||
this framework and by B<msgfmt --check-accelerators> of GNU Gettext.
|
||||
|
||||
B<gather-accelerator-contexts.pl> first reads the F<I<program>.pot>
|
||||
file named on the command line. This file must include "#:" comments
|
||||
that point to the source files from which B<xgettext> extracted each
|
||||
C<msgid>. B<gather-accelerator-contexts.pl> then scans those source
|
||||
files for context information and rewrites F<I<program>.pot> to
|
||||
include the "accelerator_context" comments. Finally, the standard
|
||||
tool B<msgmerge> can be used to copy the added comments to all the
|
||||
B<msgaccel-prepare> first reads the F<I<program>.pot> file named on
|
||||
the command line. This file must include "#:" comments that point
|
||||
to the source files from which B<xgettext> extracted each C<msgid>.
|
||||
B<msgaccel-prepare> then scans those source files for context
|
||||
information and rewrites F<I<program>.pot> to include the
|
||||
"accelerator_context" comments. Finally, the standard tool
|
||||
B<msgmerge> can be used to copy the added comments to all the
|
||||
F<I<language>.po> files.
|
||||
|
||||
It is best to run B<gather-accelerator-contexts.pl> immediately after
|
||||
B<xgettext> so that the source references will be up to date.
|
||||
It is best to run B<msgaccel-prepare> immediately after B<xgettext>
|
||||
so that the source references will be up to date.
|
||||
|
||||
=head2 Contexts
|
||||
|
||||
@ -249,17 +249,16 @@ formatted like this:
|
||||
[gettext_accelerator_context()]
|
||||
ends the region. */
|
||||
|
||||
B<gather-accelerator-contexts.pl> removes from F<I<program>.pot> any
|
||||
B<msgaccel-prepare> removes from F<I<program>.pot> any
|
||||
"gettext_accelerator_context" comments that B<xgettext --add-comments>
|
||||
may have copied there.
|
||||
may have copied there.
|
||||
|
||||
B<gather-accelerator-contexts.pl> warns if it does not find any
|
||||
contexts for some use of an C<msgid> that contains the character
|
||||
specified with the B<--accelerator-tag> option. If the character does
|
||||
not actually indicate an accelerator in that C<msgid> (e.g. "~" in
|
||||
"~/.bashrc"), the warning can be silenced by specifying the special
|
||||
context "IGNORE", which B<gather-accelerator-contexts.pl> otherwise
|
||||
ignores.
|
||||
B<msgaccel-prepare> warns if it does not find any contexts for some
|
||||
use of an C<msgid> that contains the character specified with the
|
||||
B<--accelerator-tag> option. If the character does not actually
|
||||
indicate an accelerator in that C<msgid> (e.g. "~" in "~/.bashrc"),
|
||||
the warning can be silenced by specifying the special context
|
||||
"IGNORE", which B<msgaccel-prepare> otherwise ignores.
|
||||
|
||||
=head1 OPTIONS
|
||||
|
||||
@ -270,15 +269,14 @@ B<--source-directory=>F<I<srcdir>>
|
||||
|
||||
The directory to which the source references in "#:" lines are
|
||||
relative. Each use of this option adds one directory to the search
|
||||
path. If you do not specify this option,
|
||||
B<gather-accelerator-contexts.pl> implicitly searches the current
|
||||
directory.
|
||||
path. If you do not specify this option, B<msgaccel-prepare>
|
||||
implicitly searches the current directory.
|
||||
|
||||
=item B<--accelerator-tag=>I<character>
|
||||
|
||||
Specify the character that marks accelerators in C<msgid> strings.
|
||||
B<gather-accelerator-contexts.pl> looks up accelerator contexts for
|
||||
any C<msgid> that contains this character.
|
||||
B<msgaccel-prepare> looks up accelerator contexts for any C<msgid>
|
||||
that contains this character.
|
||||
|
||||
Omitting the B<--accelerator-tag> option implies
|
||||
B<--accelerator-tag="~">. The option must be given to each program
|
||||
@ -293,24 +291,23 @@ in the PO file.
|
||||
|
||||
=item F<I<program>.pot>
|
||||
|
||||
The file to augment with context information.
|
||||
B<gather-accelerator-contexts.pl> first reads this file and then
|
||||
overwrites it.
|
||||
The file to augment with context information. B<msgaccel-prepare>
|
||||
first reads this file and then overwrites it.
|
||||
|
||||
Although this documentation keeps referring to F<I<program>.pot>,
|
||||
you can also use B<gather-accelerator-contexts.pl> on an already
|
||||
translated F<I<language>.po>. However, that will only work correctly
|
||||
if the source references in the "#:" lines are still up to date.
|
||||
you can also use B<msgaccel-prepare> on an already translated
|
||||
F<I<language>.po>. However, that will only work correctly if the
|
||||
source references in the "#:" lines are still up to date.
|
||||
|
||||
=back
|
||||
|
||||
=head1 BUGS
|
||||
|
||||
B<gather-accelerator-contexts.pl> assumes that source files are in
|
||||
the C programming language: specifically, that a closing brace at
|
||||
the beginning of a line marks the end of a function.
|
||||
B<msgaccel-prepare> assumes that source files are in the C programming
|
||||
language: specifically, that a closing brace at the beginning of a
|
||||
line marks the end of a function.
|
||||
|
||||
B<gather-accelerator-contexts.pl> doesn't check whether the
|
||||
B<msgaccel-prepare> doesn't check whether the
|
||||
"gettext_accelerator_context" comments actually are comments.
|
||||
|
||||
=head1 AUTHOR
|
||||
@ -348,4 +345,4 @@ DEALINGS IN THE SOFTWARE.
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<check-accelerator-conflicts.pl>, C<xgettext(1)>, C<msgmerge(1)>
|
||||
L<msgaccel-check>, C<xgettext(1)>, C<msgmerge(1)>
|
@ -111,8 +111,14 @@ get_home(void)
|
||||
{
|
||||
unsigned char *home_elinks;
|
||||
unsigned char *envhome = getenv("HOME");
|
||||
unsigned char *home = envhome ? stracpy(envhome)
|
||||
: elinks_dirname(program.path);
|
||||
unsigned char *home = NULL;
|
||||
|
||||
if (!home && envhome)
|
||||
home = stracpy(envhome);
|
||||
if (!home)
|
||||
home = user_appdata_directory();
|
||||
if (!home)
|
||||
home = elinks_dirname(program.path);
|
||||
|
||||
if (home)
|
||||
strip_trailing_dir_sep(home);
|
||||
|
@ -90,12 +90,23 @@ ride_on:
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
skip_css_block(struct scanner *scanner)
|
||||
{
|
||||
if (skip_css_tokens(scanner, '{')) {
|
||||
const int preclimit = get_css_precedence('}');
|
||||
int depth = 1;
|
||||
struct scanner_token *token = get_scanner_token(scanner);
|
||||
|
||||
/* TODO: We should handle support for skipping blocks better like "{ { } }"
|
||||
* will be handled correctly. --jonas */
|
||||
#define skip_css_block(scanner) \
|
||||
if (skip_css_tokens(scanner, '{')) skip_css_tokens(scanner, '}');
|
||||
|
||||
while (token && token->precedence <= preclimit && depth > 0) {
|
||||
if (token->type == '{')
|
||||
++depth;
|
||||
else if (token->type == '}')
|
||||
--depth;
|
||||
token = get_next_scanner_token(scanner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Atrules grammer:
|
||||
*
|
||||
|
@ -1108,7 +1108,13 @@ justify_line(struct html_context *html_context, int y)
|
||||
int prev_end = 0;
|
||||
int word;
|
||||
|
||||
clear_hchars(html_context, 0, y, overlap(par_format));
|
||||
/* Allocate enough memory for the justified line.
|
||||
* If the memory is not available, then leave the
|
||||
* line unchanged, rather than halfway there. The
|
||||
* following loop assumes the allocation succeeded. */
|
||||
if (!realloc_line(html_context, html_context->part->document,
|
||||
Y(y), X(overlap(par_format))))
|
||||
goto out_of_memory;
|
||||
|
||||
for (word = 0; word < spaces; word++) {
|
||||
/* We have to increase line length by 'diff' num. of
|
||||
@ -1122,14 +1128,40 @@ justify_line(struct html_context *html_context, int y)
|
||||
|
||||
assert(word_len >= 0);
|
||||
if_assert_failed continue;
|
||||
if (!word_len) continue;
|
||||
|
||||
word_shift = (word * diff) / (spaces - 1);
|
||||
new_start = word_start + word_shift;
|
||||
|
||||
/* Copy the original word, without any spaces. */
|
||||
copy_chars(html_context, new_start, y, word_len,
|
||||
&line[word_start]);
|
||||
|
||||
/* Copy the space that preceded the word,
|
||||
* duplicating it as many times as necessary.
|
||||
* This preserves its attributes, such as
|
||||
* background color and underlining. If this
|
||||
* is the first word, then skip the copy
|
||||
* because there might not be a space there
|
||||
* and anyway it need not be duplicated. */
|
||||
if (word) {
|
||||
int spacex;
|
||||
|
||||
/* realloc_line() was called above. */
|
||||
assert(LEN(y) >= new_start);
|
||||
if_assert_failed continue;
|
||||
|
||||
for (spacex = prev_end; spacex < new_start;
|
||||
++spacex) {
|
||||
copy_screen_chars(&POS(spacex, y),
|
||||
&line[word_start - 1],
|
||||
1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Remember that any links at the right side
|
||||
* of the added spaces have moved, and the
|
||||
* spaces themselves may also belong to a
|
||||
* link. */
|
||||
new_spaces = new_start - prev_end - 1;
|
||||
if (word && new_spaces) {
|
||||
move_links(html_context, prev_end + 1, y, new_start, y);
|
||||
@ -1141,6 +1173,7 @@ justify_line(struct html_context *html_context, int y)
|
||||
}
|
||||
}
|
||||
|
||||
out_of_memory:
|
||||
fmem_free(space_list);
|
||||
fmem_free(line);
|
||||
}
|
||||
|
@ -19,6 +19,9 @@
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#ifdef HAVE_WS2TCPIP_H
|
||||
#include <ws2tcpip.h> /* socklen_t for MinGW */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETIFADDRS
|
||||
#ifdef HAVE_NETDB_H
|
||||
|
@ -75,4 +75,8 @@ unsigned char *get_shell(void);
|
||||
* available at all. Face it, we are just cool. */
|
||||
void elinks_cfmakeraw(struct termios *t);
|
||||
|
||||
#ifndef user_appdata_directory
|
||||
#define user_appdata_directory() NULL
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -4,7 +4,11 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
/* Get SHGFP_TYPE_CURRENT from <shlobj.h>. */
|
||||
#define _WIN32_IE 0x500
|
||||
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
|
||||
#include "osdep/system.h"
|
||||
|
||||
@ -258,3 +262,21 @@ gettext__parse(void *arg)
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned char *
|
||||
user_appdata_directory(void)
|
||||
{
|
||||
#if _WIN32_WINNT >= 0x0500
|
||||
HWND hwnd = GetConsoleWindow();
|
||||
#else
|
||||
HWND hwnd = NULL;
|
||||
#endif
|
||||
char path[MAX_PATH];
|
||||
HRESULT hr;
|
||||
|
||||
hr = SHGetFolderPath(hwnd, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, path);
|
||||
if (hr == S_OK) /* Don't even allow S_FALSE. */
|
||||
return stracpy(path);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ struct terminal;
|
||||
|
||||
void open_in_new_win32(struct terminal *term, unsigned char *exe_name,
|
||||
unsigned char *param);
|
||||
unsigned char *user_appdata_directory(void);
|
||||
#define user_appdata_directory user_appdata_directory
|
||||
|
||||
|
||||
/* Stub functions: */
|
||||
|
@ -10,7 +10,7 @@ SUBDIRS-$(CONFIG_NNTP) += nntp
|
||||
SUBDIRS-$(CONFIG_SMB) += smb
|
||||
SUBDIRS-$(CONFIG_URI_REWRITE) += rewrite
|
||||
|
||||
SUBDIRS = auth file http
|
||||
SUBDIRS = auth file http test
|
||||
|
||||
OBJS-$(CONFIG_DATA) += data.o
|
||||
|
||||
|
@ -102,7 +102,7 @@ add_dir_entry(struct directory_entry *entry, struct string *page,
|
||||
add_string_to_string(page, &uri_encoded_name);
|
||||
|
||||
if (entry->attrib[0] == 'd') {
|
||||
add_char_to_string(page, CHAR_DIR_SEP);
|
||||
add_char_to_string(page, '/');
|
||||
|
||||
#ifdef FS_UNIX_SOFTLINKS
|
||||
} else if (entry->attrib[0] == 'l') {
|
||||
@ -271,7 +271,10 @@ file_protocol_handler(struct connection *connection)
|
||||
|
||||
decode_uri_string(&name);
|
||||
|
||||
if (file_is_dir(name.source)) {
|
||||
/* In Win32, file_is_dir seems to always return 0 if the name
|
||||
* ends with a directory separator. */
|
||||
if ((name.length > 0 && dir_sep(name.source[name.length - 1]))
|
||||
|| file_is_dir(name.source)) {
|
||||
/* In order for global history and directory listing to
|
||||
* function properly the directory url must end with a
|
||||
* directory separator. */
|
||||
|
16
src/protocol/test/Makefile
Normal file
16
src/protocol/test/Makefile
Normal file
@ -0,0 +1,16 @@
|
||||
top_builddir=../../..
|
||||
include $(top_builddir)/Makefile.config
|
||||
|
||||
TEST_PROGS = \
|
||||
test_uri
|
||||
|
||||
TESTDEPS = \
|
||||
$(top_builddir)/src/protocol/protocol.o \
|
||||
$(top_builddir)/src/protocol/uri.o \
|
||||
stub.o
|
||||
|
||||
CLEAN = stub.o
|
||||
|
||||
test_uri:: stub.o
|
||||
|
||||
include $(top_srcdir)/Makefile.lib
|
6
src/protocol/test/harness.h
Normal file
6
src/protocol/test/harness.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef EL__PROTOCOL_TEST_HARNESS_H
|
||||
#define EL__PROTOCOL_TEST_HARNESS_H
|
||||
|
||||
void test_failed();
|
||||
|
||||
#endif
|
109
src/protocol/test/stub.c
Normal file
109
src/protocol/test/stub.c
Normal file
@ -0,0 +1,109 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "elinks.h"
|
||||
|
||||
#include "bfu/msgbox.h"
|
||||
#include "main/module.h"
|
||||
#include "protocol/test/harness.h"
|
||||
#include "protocol/user.h"
|
||||
#include "session/session.h"
|
||||
|
||||
#define STUB_MODULE(name) \
|
||||
struct module name = struct_module( \
|
||||
/* name: */ "Stub " #name, \
|
||||
/* options: */ NULL, \
|
||||
/* hooks: */ NULL, \
|
||||
/* submodules: */ NULL, \
|
||||
/* data: */ NULL, \
|
||||
/* init: */ NULL, \
|
||||
/* done: */ NULL \
|
||||
)
|
||||
STUB_MODULE(auth_module);
|
||||
STUB_MODULE(bittorrent_protocol_module);
|
||||
STUB_MODULE(cgi_protocol_module);
|
||||
STUB_MODULE(file_protocol_module);
|
||||
STUB_MODULE(finger_protocol_module);
|
||||
STUB_MODULE(fsp_protocol_module);
|
||||
STUB_MODULE(ftp_protocol_module);
|
||||
STUB_MODULE(gopher_protocol_module);
|
||||
STUB_MODULE(http_protocol_module);
|
||||
STUB_MODULE(nntp_protocol_module);
|
||||
STUB_MODULE(smb_protocol_module);
|
||||
STUB_MODULE(uri_rewrite_module);
|
||||
STUB_MODULE(user_protocol_module);
|
||||
|
||||
static void
|
||||
stub_called(const unsigned char *fun)
|
||||
{
|
||||
fprintf(stderr, "FAIL: stub %s\n", fun);
|
||||
test_failed();
|
||||
}
|
||||
|
||||
#define STUB_PROTOCOL_HANDLER(name) \
|
||||
void \
|
||||
name(struct connection *conn) \
|
||||
{ \
|
||||
stub_called(#name); \
|
||||
} \
|
||||
protocol_handler_T name /* consume semicolon */
|
||||
#define STUB_PROTOCOL_EXTERNAL_HANDLER(name) \
|
||||
void \
|
||||
name(struct session *ses, struct uri *uri) \
|
||||
{ \
|
||||
stub_called(#name); \
|
||||
} \
|
||||
protocol_external_handler_T name /* consume semicolon */
|
||||
STUB_PROTOCOL_HANDLER(about_protocol_handler);
|
||||
STUB_PROTOCOL_HANDLER(bittorrent_protocol_handler);
|
||||
STUB_PROTOCOL_HANDLER(data_protocol_handler);
|
||||
STUB_PROTOCOL_EXTERNAL_HANDLER(ecmascript_protocol_handler);
|
||||
STUB_PROTOCOL_HANDLER(file_protocol_handler);
|
||||
STUB_PROTOCOL_HANDLER(finger_protocol_handler);
|
||||
STUB_PROTOCOL_HANDLER(fsp_protocol_handler);
|
||||
STUB_PROTOCOL_HANDLER(ftp_protocol_handler);
|
||||
STUB_PROTOCOL_HANDLER(gopher_protocol_handler);
|
||||
STUB_PROTOCOL_HANDLER(http_protocol_handler);
|
||||
STUB_PROTOCOL_HANDLER(news_protocol_handler);
|
||||
STUB_PROTOCOL_HANDLER(nntp_protocol_handler);
|
||||
STUB_PROTOCOL_HANDLER(proxy_protocol_handler);
|
||||
STUB_PROTOCOL_HANDLER(smb_protocol_handler);
|
||||
STUB_PROTOCOL_EXTERNAL_HANDLER(user_protocol_handler);
|
||||
|
||||
/* declared in "protocol/user.h" */
|
||||
unsigned char *
|
||||
get_user_program(struct terminal *term, unsigned char *progid, int progidlen)
|
||||
{
|
||||
stub_called("get_user_program");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* declared in "session/session.h" */
|
||||
void
|
||||
print_error_dialog(struct session *ses, enum connection_state state,
|
||||
struct uri *uri, enum connection_priority priority)
|
||||
{
|
||||
stub_called("print_error_dialog");
|
||||
}
|
||||
|
||||
/* declared in "bfu/msgbox.h" */
|
||||
unsigned char *
|
||||
msg_text(struct terminal *term, unsigned char *format, ...)
|
||||
{
|
||||
stub_called("msg_text");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* declared in "bfu/msgbox.h" */
|
||||
struct dialog_data *
|
||||
msg_box(struct terminal *term, struct memory_list *mem_list,
|
||||
enum msgbox_flags flags, unsigned char *title, enum format_align align,
|
||||
unsigned char *text, void *udata, int buttons, ...)
|
||||
{
|
||||
/* mem_list should be freed here but because this is just a
|
||||
* test program it won't matter. */
|
||||
stub_called("msg_box");
|
||||
return NULL;
|
||||
}
|
||||
|
2
src/protocol/test/test-uri
Normal file
2
src/protocol/test/test-uri
Normal file
@ -0,0 +1,2 @@
|
||||
#! /bin/sh -e
|
||||
./test_uri
|
142
src/protocol/test/test_uri.c
Normal file
142
src/protocol/test/test_uri.c
Normal file
@ -0,0 +1,142 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "elinks.h"
|
||||
|
||||
#include "protocol/test/harness.h"
|
||||
#include "protocol/uri.h"
|
||||
#include "util/string.h"
|
||||
|
||||
static int failures = 0;
|
||||
static int successes = 0;
|
||||
|
||||
void
|
||||
test_failed(void)
|
||||
{
|
||||
++failures;
|
||||
}
|
||||
|
||||
void
|
||||
test_succeeded(void)
|
||||
{
|
||||
++successes;
|
||||
}
|
||||
|
||||
static void
|
||||
test_1_normalize_uri(const unsigned char *orig, const unsigned char *good)
|
||||
{
|
||||
struct string s;
|
||||
unsigned char *norm;
|
||||
|
||||
if (!init_string(&s)) {
|
||||
fputs("FAIL: init_string\n", stderr);
|
||||
test_failed();
|
||||
goto out;
|
||||
}
|
||||
if (!add_to_string(&s, orig)) {
|
||||
fputs("FAIL: add_to_string\n", stderr);
|
||||
test_failed();
|
||||
goto out;
|
||||
}
|
||||
|
||||
norm = normalize_uri(NULL, s.source);
|
||||
if (norm == NULL) {
|
||||
fprintf(stderr, "FAIL: normalize_uri NULL %s\n", orig);
|
||||
test_failed();
|
||||
goto out;
|
||||
}
|
||||
if (strcmp(norm, good) != 0) {
|
||||
fprintf(stderr, "FAIL: normalize_uri mismatch:\n"
|
||||
"\toriginal: %s\n"
|
||||
"\tresult: %s\n"
|
||||
"\texpected: %s\n",
|
||||
orig, norm, good);
|
||||
test_failed();
|
||||
goto out;
|
||||
}
|
||||
|
||||
test_succeeded();
|
||||
|
||||
out:
|
||||
done_string(&s);
|
||||
}
|
||||
|
||||
static void
|
||||
test_normalize_uri(void)
|
||||
{
|
||||
static const struct {
|
||||
unsigned char *orig;
|
||||
unsigned char *norm;
|
||||
} tests[] = {
|
||||
{ "http://example.org/foo/bar/baz?a=1&b=2#frag",
|
||||
"http://example.org/foo/bar/baz?a=1&b=2#frag" },
|
||||
{ "http://example.org/foo/bar/../?a=1&b=2#frag",
|
||||
"http://example.org/foo/?a=1&b=2#frag" },
|
||||
{ "http://example.org/foo/bar/../../baz?a=1&b=2#frag",
|
||||
"http://example.org/baz?a=1&b=2#frag" },
|
||||
{ "http://example.org/foo/bar/..",
|
||||
"http://example.org/foo/" },
|
||||
{ "http://example.org/foo/bar;a=1/..",
|
||||
"http://example.org/foo/" },
|
||||
{ "http://example.org/foo/bar..",
|
||||
"http://example.org/foo/bar.." },
|
||||
|
||||
/* Bug 744 - ELinks changes "//" to "/" in path
|
||||
* component of URI */
|
||||
{ "http://example.org/foo/bar/baz",
|
||||
"http://example.org/foo/bar/baz" },
|
||||
{ "http://example.org/foo/bar/",
|
||||
"http://example.org/foo/bar/" },
|
||||
{ "http://example.org/foo//baz",
|
||||
"http://example.org/foo//baz" },
|
||||
{ "http://example.org/foo//",
|
||||
"http://example.org/foo//" },
|
||||
{ "http://example.org//bar/baz",
|
||||
"http://example.org//bar/baz" },
|
||||
{ "http://example.org//bar/",
|
||||
"http://example.org//bar/" },
|
||||
{ "http://example.org///baz",
|
||||
"http://example.org///baz" },
|
||||
{ "http://example.org///",
|
||||
"http://example.org///" },
|
||||
{ "http://example.org/foo/bar/baz/..",
|
||||
"http://example.org/foo/bar/" },
|
||||
{ "http://example.org/foo/bar//..",
|
||||
"http://example.org/foo/bar/" },
|
||||
{ "http://example.org/foo//baz/..",
|
||||
"http://example.org/foo//" },
|
||||
{ "http://example.org/foo///..",
|
||||
"http://example.org/foo//" },
|
||||
{ "http://example.org//bar/baz/..",
|
||||
"http://example.org//bar/" },
|
||||
{ "http://example.org//bar//..",
|
||||
"http://example.org//bar/" },
|
||||
{ "http://example.org///baz/..",
|
||||
"http://example.org///" },
|
||||
{ "http://example.org////..",
|
||||
"http://example.org///" },
|
||||
{ "http://example.org/foo/..//bar/baz",
|
||||
"http://example.org//bar/baz" },
|
||||
{ "http://example.org//.//foo",
|
||||
"http://example.org///foo" },
|
||||
{ "http://example.org//./../foo",
|
||||
"http://example.org/foo" },
|
||||
{ "http://example.org/gag///./../..",
|
||||
"http://example.org/gag/" },
|
||||
};
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof_array(tests); ++i)
|
||||
test_1_normalize_uri(tests[i].orig, tests[i].norm);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
test_normalize_uri();
|
||||
printf("Total %d failures, %d successes.\n", failures, successes);
|
||||
return failures ? EXIT_FAILURE : 0;
|
||||
}
|
@ -43,7 +43,11 @@
|
||||
static inline int
|
||||
end_of_dir(unsigned char c)
|
||||
{
|
||||
return c == POST_CHAR || c == '#' || c == ';' || c == '?';
|
||||
/* This used to check for c == ';' as well. But section 3.3
|
||||
* of RFC 2396 explicitly says that parameters in a path
|
||||
* segment "are not significant to the parsing of relative
|
||||
* references." */
|
||||
return c == POST_CHAR || c == '#' || c == '?';
|
||||
}
|
||||
|
||||
static inline int
|
||||
@ -700,16 +704,14 @@ normalize_uri(struct uri *uri, unsigned char *uristring)
|
||||
if (uri->protocol != PROTOCOL_UNKNOWN)
|
||||
need_slash = get_protocol_need_slash_after_host(uri->protocol);
|
||||
|
||||
/* We want to start at the first slash to also reduce URIs like
|
||||
* http://host//index.html to http://host/index.html */
|
||||
path = uri->data - need_slash;
|
||||
dest = src = path;
|
||||
|
||||
/* This loop mangles the URI string by removing directory elevators and
|
||||
* other cruft. Example: /.././etc////..//usr/ -> /usr/ */
|
||||
/* This loop mangles the URI string by removing ".." and "." segments.
|
||||
* However it must not alter "//" without reason; see bug 744. */
|
||||
while (*dest) {
|
||||
/* If the following pieces are the LAST parts of URL, we remove
|
||||
* them as well. See RFC 1808 for details. */
|
||||
* them as well. See RFC 2396 section 5.2 for details. */
|
||||
|
||||
if (end_of_dir(src[0])) {
|
||||
/* URL data contains no more path. */
|
||||
@ -734,20 +736,25 @@ normalize_uri(struct uri *uri, unsigned char *uristring)
|
||||
|
||||
} else if (src[2] == '.'
|
||||
&& (is_uri_dir_sep(uri, src[3]) || !src[3])) {
|
||||
/* /../ or /.. - skip it and preceding element. */
|
||||
/* /../ or /.. - skip it and preceding element.
|
||||
*
|
||||
* <path> "/foo/bar" <dest> ...
|
||||
* <src> ("/../" or "/..\0") ...
|
||||
*
|
||||
* Remove "bar" and the directory
|
||||
* separator that precedes it. The
|
||||
* separator will be added back in the
|
||||
* next iteration unless another ".."
|
||||
* follows, in which case it will be
|
||||
* added later. "bar" may be empty. */
|
||||
|
||||
/* First back out the last incrementation of
|
||||
* @dest (dest++) to get the position that was
|
||||
* last asigned to. */
|
||||
if (dest > path) dest--;
|
||||
|
||||
/* @dest might be pointing to a dir separator
|
||||
* so we decrement before any testing. */
|
||||
while (dest > path) {
|
||||
dest--;
|
||||
if (is_uri_dir_sep(uri, *dest)) break;
|
||||
}
|
||||
|
||||
/* <path> "/foo" <dest> "/bar" ...
|
||||
* <src> ("/../" or "/..\0") ... */
|
||||
if (!src[3]) {
|
||||
/* /.. - add ending slash and stop */
|
||||
*dest++ = *src;
|
||||
@ -759,10 +766,6 @@ normalize_uri(struct uri *uri, unsigned char *uristring)
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (is_uri_dir_sep(uri, src[1])) {
|
||||
/* // - ignore first '/'. */
|
||||
src += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* We don't want to access memory past the NUL char. */
|
||||
|
@ -575,6 +575,9 @@ has_nul_byte:
|
||||
unsigned char *param;
|
||||
int path_len, del_len, param_len;
|
||||
|
||||
/* TODO: Should this be changed to allow TERM_EXEC_NEWWIN
|
||||
* in a blocked terminal? There is similar code in
|
||||
* exec_on_terminal(). --KON, 2007 */
|
||||
if (is_blocked() && fg != TERM_EXEC_BG) {
|
||||
if (*delete.source) unlink(delete.source);
|
||||
goto nasty_thing;
|
||||
|
@ -288,6 +288,9 @@ exec_on_terminal(struct terminal *term, unsigned char *path,
|
||||
return;
|
||||
}
|
||||
|
||||
/* TODO: Should this be changed to allow TERM_EXEC_NEWWIN
|
||||
* in a blocked terminal? There is similar code in
|
||||
* in_sock(). --KON, 2007 */
|
||||
if (fg != TERM_EXEC_BG && is_blocked()) {
|
||||
unlink(delete);
|
||||
return;
|
||||
|
Loading…
Reference in New Issue
Block a user