1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-06-25 01:05:37 +00:00

Merge commit 'pasky.or.cz/elinks-0.12' into elinks-0.13

This commit is contained in:
Kalle Olavi Niemitalo 2007-07-22 18:48:45 +03:00 committed by Kalle Olavi Niemitalo
commit ab9e0821d6
29 changed files with 627 additions and 322 deletions

3
NEWS
View File

@ -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:

View File

@ -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

View File

@ -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
View 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
View File

@ -0,0 +1,3 @@
gen
proxy.py
*.http

View File

@ -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;

View File

@ -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:

View File

@ -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
View File

@ -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:

View 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.

View File

@ -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)>

View File

@ -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)>

View File

@ -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);

View File

@ -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:
*

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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: */

View File

@ -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

View File

@ -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. */

View 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

View 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
View 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;
}

View File

@ -0,0 +1,2 @@
#! /bin/sh -e
./test_uri

View 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;
}

View File

@ -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. */

View File

@ -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;

View File

@ -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;