The 2009-08-15 fix for bug 1083 made read_encoded() return -1 of EOF,
like decompress_data() expects. Unfortunately, read_file() too calls
read_encoded(), and it treated the -1 as an error and reporter
whatever error had been left in errno. This made it impossible to
display local files, compressed or not.
Apparently then, read_encoded() needs to distinguish between decoded
bytes, EOF, EAGAIN, and true errors. Make it return an enum.
INIT_OPTION used to initialize union option_value at compile time by
casting the default value to LIST_OF(struct option) *, which is the
type of the first member. On sparc64 and other big-endian systems
where sizeof(int) < sizeof(struct list_head *), this tended to leave
option->value.number as zero, thus messing up OPT_INT and OPT_BOOL
at least. OPT_LONG however tended to work right.
This would be easy to fix with C99 designated initializers,
but doc/hacking.txt says ELinks must be kept C89 compatible.
Another solution would be to make register_options() read the
value from option->value.tree (the first member), cast it back
to the right type, and write it to the appropriate member;
but that would still require somewhat dubious conversions
between integers, data pointers, and function pointers.
So here's a rather more invasive solution. Add struct option_init,
which is somewhat similar to struct option but has non-overlapping
members for different types of values, to ensure nothing is lost
in compile-time conversions. Move unsigned char *path from struct
option_info to struct option_init, and replace struct option_info
with a union that contains struct option_init and struct option.
Now, this union can be initialized with no portability problems,
and register_options() then moves the values from struct option_init
to their final places in struct option.
In my x86 ELinks build with plenty of options configured in, this
change bloated the text section by 340 bytes but compressed the data
section by 2784 bytes, presumably because union option_info is a
pointer smaller than struct option_info was.
decompress_data() supposed that read_encoded() would return a positive
number if it decompressed something, 0 if no data is available yet but
may be later, or -1 if no more data will be available. However,
several backends actually returned 0 if they had seen an EOF marker or
an error in the stream, causing decompress_data() to keep calling
them. Make them return -1 in this situation.
http://buildd.debian-ports.org/fetch.php?pkg=elinks&arch=hurd-i386&ver=0.12%7Epre5-1&stamp=1247378205&file=log&as=raw
shows two unsightly errors, apparently triggered by TERM=unknown:
tput: unknown terminal "unknown"
/build/buildd/elinks-0.12~pre5/configure: line 25480: test: -ge: unary operator expected
Hide the first of them by redirecting to /dev/null,
and avoid the second one by substituting "0" if tput fails.
I'm not sure why `which tput` is used instead of plain tput,
but it doesn't seem to be causing any problems in practice.
(There are problems in theory if tput is not installed,
tput is found in a directory whose name contains spaces,
or tput is a shell function or builtin.)
Fix this GCC 3.4.6 warning, which becomes an error
if configure --enable-debug adds -Werror to CFLAGS:
[CC] src/document/css/apply.o
In file included from /home/Kalle/src/elinks-0.12/src/document/html/internal.h:6,
from /home/Kalle/src/elinks-0.12/src/document/css/apply.c:35:
/home/Kalle/src/elinks-0.12/src/document/html/parser.h:149: warning: parameter has incomplete type
In file included from /home/Kalle/src/elinks-0.12/src/document/css/apply.c:35:
/home/Kalle/src/elinks-0.12/src/document/html/internal.h:125: warning: parameter has incomplete type
Even without this warning, "enum html_special_type;"
would not be standard C89.
location_goto() was defined identically in
src/ecmascript/spidermonkey/location.c and
src/ecmascript/see/location.c, and declared in four other files.
Merge both definitions to the new src/ecmascript/location-goto.c
and all declarations to src/ecmascript/ecmascript.h.
Call get_window_title() at most once per terminal, even if it fails.
If ELinks is configured with X11 support, get_window_title() calls
XOpenDisplay(), which can sleep if $DISPLAY does not respond.
This delay was previously incurred every time ELinks changed the
title. Besides, if ELinks had already changed the title, setting
ditrm->orig_title = get_window_title(); did not make sense anyway.
Bring the code closer to ELinks 0.13.GIT commit
71ccbe0f8d made on 2007-11-07.
Don't define a separate download_flags_T typedef though,
because Doxygen generates nicer links if the enum is used directly.
There are two identical tp_show_header() functions: one in
src/session/download.c and one in src/protocol/bittorrent/dialogs.c.
Neither is declared in any header, but the latter was not static.
If msg_box() runs out of memory, it returns NULL. In this case,
the done_handler_T callbacks of the buttons will not be called. So
lookup_unique_name() must instead free the struct lun_hop on its own.
Remove the stracpy(ofile) call that could never be executed.
This removes the need to handle errors from that call,
and makes it clear that lun_hop->file need not be separately freed
if an error occurs in lookup_unique_name().
With GCC 4.3.1 on i686, this changes the sizes of sections as follows:
section before after change
.text 682428 682492 +64
.rodata 212668 216352 +3684
.data 58092 54444 -3648
.debug_info 1482388 1482472 +84
.debug_abbrev 153714 153723 +9
.debug_line 272299 272319 +20
.debug_loc 540394 540372 -22
.debug_ranges 113784 113792 +8
Total 3917695 3917894 +199
The surprising .text change comes from src/config/dialogs.o.
Some of that is in get_keybinding_text(), where GCC changes the
order of basic blocks and apparently misses some optimizations.
I added this bug last night. continue_download_do() passed the
file descriptor to transform_codw_to_cmdw(), which saved it, but
continue_download_do() then closed it.
In common_download(), move session.download_uri to the new member
cmdw_hop.download_uri, which common_download_do() then reads. This
shields the download request against possible session.download_uri
changes made for other downloads. And transform_codw_to_cmdw() no
longer needs to touch session.download_uri at all, solving a FIXME.
Commit ff136e5116 on 2006-07-16 made
lun_resume() check if cdf_hop->data points to struct codw_hop,
and transform that to struct cmdw_hop if so. Move the transform
into a separate function called from continue_download_do().
This way, the structures used with create_download_file() no longer
need to begin with int magic.
To reproduce:
- Configure with --enable-debug.
- Go to http://elinks.cz/
- Set the cursor on the "About" link and press d to download,
- ELinks asks where to save the file. Cancel that with Esc.
This leaves session.download_uri != NULL.
- Go to /etc/passwd
- ELinks asks what to do with the file. Choose to download.
- ELinks asks where to save the file. Type the name of a new file
and press Enter.
- Again go to /etc/passwd
- ELinks asks what to do with the file. Choose to download.
- ELinks asks where to save the file. Type the same name as before
and press Enter.
- ELinks asks whether to resume or overwrite. Choose to resume.
This changes session.download_uri and leaks the original URI.
- Quit ELinks. It reports memory leaks:
0x88936d8:28 @ alloc'd at /home/Kalle/src/elinks-0.12/src/util/hash.c:89
0x88dac00:95 @ alloc'd at /home/Kalle/src/elinks-0.12/src/protocol/uri.c:1551
0x88c33a8:4104 @ alloc'd at /home/Kalle/src/elinks-0.12/src/util/hash.c:41
This commit fixes the leak, but it's still a bug that lun_resume() can
replace the session.download_uri that will be used by another pending
download. In particular, this might happen if the user first presses
d to download, and then while ELinks is asking for the file name, a
web script changes window.location to a different URI and that causes
ELinks to ask what to do with the file. So I'm leaving the FIXME
comment in for now.
If init_file_download() succeeds (returning non-NULL), it saves the
file descriptor to file_download->handle, whence abort_download() will
close it. However, if init_file_download() fails, the caller is
responsible of closing the file, something common_download_do() and
continue_download_do() failed to do. There was no problem with
bittorrent_download() because that uses -1 as the fd.
If init_file_download() succeeds (returning non-NULL), it saves the
file-name pointer to file_download->file, whence abort_download() will
free it. However, if init_file_download() fails, the caller is
responsible of freeing the name. bittorrent_download() already did so
but common_download_do() and continue_download_do() didn't.
Remove enum main_action_offset, enum edit_action_offset, and enum
menu_action_offset. It seems the original plan (in commit
174eabf1a448d3f084a318aab77805828f35c42e on 2005-05-16) was to include
the action flags in the action IDs, perhaps with something like:
ACT_##map##_##action = ACT_##map##_OFFSET_##action | flags
However, this OR operation was never implemented; each ACT_*_*
constant had the same value as the corresponding ACT_*_OFFSET_*,
and the code that looked for flags in action IDs found only zeroes.
Then on 2005-06-10, a separate action.flags member was added, and
the flag checks were corrected to read that instead. So, it seems
safe to say that the original plan has been discarded and the offset
enumerations won't be needed.
Doxygen isn't too good at documenting the parameters of a callback
within the documentation of a parameter that points to the callback.
A typedef provides a better place to document the parameters.
If the user chose File -> Save formatted document and typed the name
of an existing file, ELinks offered to resume downloading the file.
There are a few problems with that:
* save_formatted_finish does not actually support resuming. It would
instead overwrite the beginning of the file and not truncate it.
* When save_formatted calls create_download_file, cdf_hop->data
ends up pointing to struct document. If the user then chooses to
resume, lun_resume would read *(int *)cdf_hop->data, hoping to
get cmdw_hop.magic or codw_hop.magic. struct document does not
begin with any such magic value.
* Because ELinks already has the formatted document in memory,
resuming saves neither time nor I/O.
So don't show the "Resume download of the original file" button in
this situation.
In recent ELinks release announcements, I have described:
This release of ELinks is mostly licensed under version 2 of the GNU
General Public License. More permissive licences apply to some parts
of it, and there is also one test file under the GNU Free Documentation
License; please see COPYING for the list.
Remove that test file, so its GPL-incompatible licence need not be
mentioned in future announcements. The file however remains
downloadable as part of the elinks.git repository and releases like
elinks-0.11.6.tar.gz. Those should still be covered by the licence.
After the recent ecmascript_get_interpreter change, I got an assertion
failure in render_document, which calls ecmascript_reset_state and
then asserts that it has set vs->ecmascript != NULL.
ecmascript_reset_state cannot guarantee that because there might not
even be enough free memory for mem_calloc(1, sizeof(struct
ecmascript_interpreter). So, replace the assertion in render_document
with error handling, and likewise in call_onsubmit_and_submit.