1
0
mirror of https://github.com/rkd77/elinks.git synced 2024-12-04 14:46:47 -05:00

Merge with /srv/git/elinks.git

This commit is contained in:
Petr Baudis 2005-12-14 19:32:55 +01:00 committed by Petr Baudis
commit 2f6f0341c2
26 changed files with 583 additions and 449 deletions

View File

@ -12,10 +12,13 @@ MSGMERGE = msgmerge
POTFILES_ABS_LIST = potfiles.list POTFILES_ABS_LIST = potfiles.list
# Distributed elinks-*.tar.gz packages include po/*.gmo files, so that
# users can install ELinks even if they don't have a msgfmt program.
# However, if srcdir != builddir, then this Makefile ignores the *.gmo
# files in the srcdir and builds new ones in the builddir.
%.gmo: $(srcdir)/%.po %.gmo: $(srcdir)/%.po
@file=`echo $* | sed 's,.*/,,'`.gmo \ @rm -f -- "$@" && printf "%s: " "$*" \
&& rm -f $$file && echo -n $*": " \ && $(GMSGFMT) --statistics -o "$@" -- "$<"
&& $(GMSGFMT) --statistics -o $$file $<
### The default rule ### The default rule
@ -65,8 +68,8 @@ update-po: Makefile $(srcdir)/$(PACKAGE).pot
@cd $(srcdir) @cd $(srcdir)
@$(foreach lang,$(basename $(if $(strip $(PO)),$(PO),$(GMOFILES))), \ @$(foreach lang,$(basename $(if $(strip $(PO)),$(PO),$(GMOFILES))), \
echo -n "$(lang): "; \ echo -n "$(lang): "; \
if $(MSGMERGE) $(lang).po $(PACKAGE).pot -o $(lang).new.po; then \ if $(MSGMERGE) $(srcdir)/$(lang).po $(srcdir)/$(PACKAGE).pot -o $(lang).new.po; then \
mv -f $(lang).new.po $(lang).po; \ mv -f $(lang).new.po $(srcdir)/$(lang).po; \
else \ else \
echo "msgmerge failed!"; \ echo "msgmerge failed!"; \
rm -f $(lang).new.po; \ rm -f $(lang).new.po; \
@ -84,7 +87,7 @@ update-gmo: Makefile $(GMOFILES)
check-po: check-po:
@$(foreach lang,$(basename $(if $(strip $(PO)),$(PO),$(GMOFILES))), \ @$(foreach lang,$(basename $(if $(strip $(PO)),$(PO),$(GMOFILES))), \
echo -n "$(lang): "; \ echo -n "$(lang): "; \
$(GMSGFMT) --check --check-accelerators=~ --verbose --statistics -o /dev/null $(lang).po; \ $(GMSGFMT) --check --check-accelerators="~" --verbose --statistics -o /dev/null $(srcdir)/$(lang).po; \
) )
### Installation and distribution ### Installation and distribution

200
po/fr.po
View File

@ -6,8 +6,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: ELinks 0.10.CVS\n" "Project-Id-Version: ELinks 0.10.CVS\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2005-12-06 22:02+0100\n" "POT-Creation-Date: 2005-12-13 17:20+0100\n"
"PO-Revision-Date: 2005-12-06 22:03+0100\n" "PO-Revision-Date: 2005-12-13 17:21+0100\n"
"Last-Translator: Laurent Monin <zas@norz.org>\n" "Last-Translator: Laurent Monin <zas@norz.org>\n"
"Language-Team: French <zas@norz.org>\n" "Language-Team: French <zas@norz.org>\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -35,7 +35,7 @@ msgstr "Pressez espace pour d
#: src/dialogs/options.c:210 src/dialogs/options.c:290 src/mime/dialogs.c:129 #: src/dialogs/options.c:210 src/dialogs/options.c:290 src/mime/dialogs.c:129
#: src/protocol/auth/dialogs.c:110 src/protocol/protocol.c:231 #: src/protocol/auth/dialogs.c:110 src/protocol/protocol.c:231
#: src/scripting/lua/core.c:377 src/scripting/lua/core.c:457 #: src/scripting/lua/core.c:377 src/scripting/lua/core.c:457
#: src/session/session.c:799 src/viewer/text/search.c:1593 #: src/session/session.c:802 src/viewer/text/search.c:1593
msgid "~OK" msgid "~OK"
msgstr "~OK" msgstr "~OK"
@ -1784,7 +1784,7 @@ msgstr "Description"
#: src/config/dialogs.c:320 src/protocol/bittorrent/dialogs.c:594 #: src/config/dialogs.c:320 src/protocol/bittorrent/dialogs.c:594
#: src/protocol/protocol.c:225 src/session/session.c:282 #: src/protocol/protocol.c:225 src/session/session.c:282
#: src/session/session.c:961 src/viewer/text/textarea.c:362 #: src/session/session.c:964 src/viewer/text/textarea.c:362
#: src/viewer/text/textarea.c:369 #: src/viewer/text/textarea.c:369
msgid "Error" msgid "Error"
msgstr "Erreur" msgstr "Erreur"
@ -3738,7 +3738,7 @@ msgstr "Texte"
msgid "Dialog text colors." msgid "Dialog text colors."
msgstr "Couleurs du texte des dialogues." msgstr "Couleurs du texte des dialogues."
#: src/config/options.inc:978 src/viewer/text/form.c:1451 #: src/config/options.inc:978 src/viewer/text/form.c:1460
msgid "Checkbox" msgid "Checkbox"
msgstr "Case à cocher" msgstr "Case à cocher"
@ -3786,7 +3786,7 @@ msgstr "Raccourci du bouton"
msgid "Selected button shortcut" msgid "Selected button shortcut"
msgstr "Raccourci du bouton sélectionné" msgstr "Raccourci du bouton sélectionné"
#: src/config/options.inc:1006 src/viewer/text/form.c:1455 #: src/config/options.inc:1006 src/viewer/text/form.c:1464
msgid "Text field" msgid "Text field"
msgstr "Champ texte" msgstr "Champ texte"
@ -4302,7 +4302,7 @@ msgid "Goto URL History"
msgstr "Historique Aller à" msgstr "Historique Aller à"
#. name: #. name:
#: src/cookies/cookies.c:80 src/cookies/cookies.c:824 #: src/cookies/cookies.c:80 src/cookies/cookies.c:827
msgid "Cookies" msgid "Cookies"
msgstr "Cookies" msgstr "Cookies"
@ -6547,7 +6547,7 @@ msgstr "Gestionnaire d'authentification"
#. name: #. name:
#: src/protocol/bittorrent/bittorrent.c:26 #: src/protocol/bittorrent/bittorrent.c:26
#: src/protocol/bittorrent/bittorrent.c:327 #: src/protocol/bittorrent/bittorrent.c:335
msgid "BitTorrent" msgid "BitTorrent"
msgstr "BitTorrent" msgstr "BitTorrent"
@ -6636,10 +6636,28 @@ msgstr ""
"l'adresse appropriée." "l'adresse appropriée."
#: src/protocol/bittorrent/bittorrent.c:73 #: src/protocol/bittorrent/bittorrent.c:73
msgid "User identification string"
msgstr "Identification de l'utilisateur"
#: src/protocol/bittorrent/bittorrent.c:75
msgid ""
"An additional identification that is not shared with any users.\n"
"It is intended to allow a client to prove their identity should\n"
"their IP address change. It is an optional parameter, but some\n"
"trackers require this parameter. If set to \"\" no user key will\n"
"be sent to the tracker."
msgstr ""
"Une clé d'identification additionnelle qui n'est pas partagée avec\n"
"d'autres utilisateurs. L'objectif est de permette l'identification\n"
"d'un client même après un changement d'IP. Ce paramètre est optionnel,\n"
"mais certains trackers le demandent. Si mis à \"\" aucune clé ne sera\n"
"envoyée."
#: src/protocol/bittorrent/bittorrent.c:81
msgid "Maximum number of peers to request" msgid "Maximum number of peers to request"
msgstr "Nombre maximum de postes à demander" msgstr "Nombre maximum de postes à demander"
#: src/protocol/bittorrent/bittorrent.c:75 #: src/protocol/bittorrent/bittorrent.c:83
msgid "" msgid ""
"The maximum number of peers to request from the tracker.\n" "The maximum number of peers to request from the tracker.\n"
"Set to 0 to use the server default." "Set to 0 to use the server default."
@ -6647,11 +6665,11 @@ msgstr ""
"Nombre maximum de postes à demander au serveur.\n" "Nombre maximum de postes à demander au serveur.\n"
"Mettre à 0 pour utiliser la valeur par défaut du serveur." "Mettre à 0 pour utiliser la valeur par défaut du serveur."
#: src/protocol/bittorrent/bittorrent.c:78 #: src/protocol/bittorrent/bittorrent.c:86
msgid "Minimum peers to skip rerequesting" msgid "Minimum peers to skip rerequesting"
msgstr "Nombre minimal de postes avant abandon de requêtes" msgstr "Nombre minimal de postes avant abandon de requêtes"
#: src/protocol/bittorrent/bittorrent.c:80 #: src/protocol/bittorrent/bittorrent.c:88
msgid "" msgid ""
"The minimum number of peers to have in the current peer info\n" "The minimum number of peers to have in the current peer info\n"
"pool before skipping requesting of more peers. I.e. setting\n" "pool before skipping requesting of more peers. I.e. setting\n"
@ -6665,19 +6683,19 @@ msgstr ""
#. ****************************************************************** #. ******************************************************************
#. Lowlevel peer-wire options: #. Lowlevel peer-wire options:
#. ****************************************************************** #. ******************************************************************
#: src/protocol/bittorrent/bittorrent.c:90 #: src/protocol/bittorrent/bittorrent.c:98
msgid "Peer-wire" msgid "Peer-wire"
msgstr "Liens postes" msgstr "Liens postes"
#: src/protocol/bittorrent/bittorrent.c:92 #: src/protocol/bittorrent/bittorrent.c:100
msgid "Lowlevel peer-wire options." msgid "Lowlevel peer-wire options."
msgstr "Options de bas niveau pour les liens postes." msgstr "Options de bas niveau pour les liens postes."
#: src/protocol/bittorrent/bittorrent.c:94 #: src/protocol/bittorrent/bittorrent.c:102
msgid "Maximum number of peer connections" msgid "Maximum number of peer connections"
msgstr "Nombre maximum de connexions aux postes" msgstr "Nombre maximum de connexions aux postes"
#: src/protocol/bittorrent/bittorrent.c:96 #: src/protocol/bittorrent/bittorrent.c:104
msgid "" msgid ""
"The maximum number of allowed connections to both active and\n" "The maximum number of allowed connections to both active and\n"
"non-active peers. By increasing the number of allowed connections,\n" "non-active peers. By increasing the number of allowed connections,\n"
@ -6691,11 +6709,11 @@ msgstr ""
"Toutefois, trop de connexions peuvent conduire à une congestion TCP.\n" "Toutefois, trop de connexions peuvent conduire à une congestion TCP.\n"
"Si le maximum est atteint, toutes les nouvelles connexions seront fermées." "Si le maximum est atteint, toutes les nouvelles connexions seront fermées."
#: src/protocol/bittorrent/bittorrent.c:102 #: src/protocol/bittorrent/bittorrent.c:110
msgid "Maximum peer message length" msgid "Maximum peer message length"
msgstr "Longueur maximale des messages" msgstr "Longueur maximale des messages"
#: src/protocol/bittorrent/bittorrent.c:104 #: src/protocol/bittorrent/bittorrent.c:112
msgid "" msgid ""
"The maximum length of messages to accept over the wire.\n" "The maximum length of messages to accept over the wire.\n"
"Larger values will cause the connection to be dropped." "Larger values will cause the connection to be dropped."
@ -6703,11 +6721,11 @@ msgstr ""
"Longueur maximale des messages à accepter sur le lien.\n" "Longueur maximale des messages à accepter sur le lien.\n"
"De plus grande valeurs causeront une déconnexion." "De plus grande valeurs causeront une déconnexion."
#: src/protocol/bittorrent/bittorrent.c:107 #: src/protocol/bittorrent/bittorrent.c:115
msgid "Maximum allowed request length" msgid "Maximum allowed request length"
msgstr "Longueur maximale de requête autorisée" msgstr "Longueur maximale de requête autorisée"
#: src/protocol/bittorrent/bittorrent.c:109 #: src/protocol/bittorrent/bittorrent.c:117
msgid "" msgid ""
"The maximum length to allow for incoming requests.\n" "The maximum length to allow for incoming requests.\n"
"Larger requests will cause the connection to be dropped." "Larger requests will cause the connection to be dropped."
@ -6715,11 +6733,11 @@ msgstr ""
"Longueur maximale autorisée pour les requêtes entrantes.\n" "Longueur maximale autorisée pour les requêtes entrantes.\n"
"De plus grande valeurs causeront une déconnexion." "De plus grande valeurs causeront une déconnexion."
#: src/protocol/bittorrent/bittorrent.c:112 #: src/protocol/bittorrent/bittorrent.c:120
msgid "Length of requests" msgid "Length of requests"
msgstr "Longueur des requêtes" msgstr "Longueur des requêtes"
#: src/protocol/bittorrent/bittorrent.c:114 #: src/protocol/bittorrent/bittorrent.c:122
msgid "" msgid ""
"How many bytes to query for per request. This is complementary\n" "How many bytes to query for per request. This is complementary\n"
"to the max_request_length option. If the configured length is\n" "to the max_request_length option. If the configured length is\n"
@ -6729,11 +6747,11 @@ msgstr ""
"l'option max_request_length. Si la valeur configurée est plus\n" "l'option max_request_length. Si la valeur configurée est plus\n"
"grande que la longueur des morceaux celle-ci sera tronquée." "grande que la longueur des morceaux celle-ci sera tronquée."
#: src/protocol/bittorrent/bittorrent.c:118 #: src/protocol/bittorrent/bittorrent.c:126
msgid "Peer inactivity timeout" msgid "Peer inactivity timeout"
msgstr "Délai d'inactivité pour un poste" msgstr "Délai d'inactivité pour un poste"
#: src/protocol/bittorrent/bittorrent.c:120 #: src/protocol/bittorrent/bittorrent.c:128
msgid "" msgid ""
"The number of seconds to wait before closing a socket on\n" "The number of seconds to wait before closing a socket on\n"
"which nothing has been received or sent." "which nothing has been received or sent."
@ -6741,11 +6759,11 @@ msgstr ""
"Le nombre de secondes à attendre avant de fermer une\n" "Le nombre de secondes à attendre avant de fermer une\n"
"connexion sur laquelle rien n'a circulé." "connexion sur laquelle rien n'a circulé."
#: src/protocol/bittorrent/bittorrent.c:123 #: src/protocol/bittorrent/bittorrent.c:131
msgid "Maximum peer pool size" msgid "Maximum peer pool size"
msgstr "Taille maximale du groupe de postes" msgstr "Taille maximale du groupe de postes"
#: src/protocol/bittorrent/bittorrent.c:125 #: src/protocol/bittorrent/bittorrent.c:133
msgid "" msgid ""
"Maximum number of items in the peer pool. The peer pool\n" "Maximum number of items in the peer pool. The peer pool\n"
"contains information used for establishing connections to\n" "contains information used for establishing connections to\n"
@ -6760,11 +6778,11 @@ msgstr ""
#. ****************************************************************** #. ******************************************************************
#. Piece management options: #. Piece management options:
#. ****************************************************************** #. ******************************************************************
#: src/protocol/bittorrent/bittorrent.c:135 #: src/protocol/bittorrent/bittorrent.c:143
msgid "Maximum piece cache size" msgid "Maximum piece cache size"
msgstr "Taille maximale du cache de morceaux" msgstr "Taille maximale du cache de morceaux"
#: src/protocol/bittorrent/bittorrent.c:137 #: src/protocol/bittorrent/bittorrent.c:145
msgid "" msgid ""
"The maximum amount of memory used to hold recently\n" "The maximum amount of memory used to hold recently\n"
"downloaded pieces.\n" "downloaded pieces.\n"
@ -6774,11 +6792,11 @@ msgstr ""
"les morceaux récemment téléchargés.\n" "les morceaux récemment téléchargés.\n"
"Mettre à 0 pour une taille illimitée." "Mettre à 0 pour une taille illimitée."
#: src/protocol/bittorrent/bittorrent.c:146 #: src/protocol/bittorrent/bittorrent.c:154
msgid "Sharing rate" msgid "Sharing rate"
msgstr "Ratio de partage" msgstr "Ratio de partage"
#: src/protocol/bittorrent/bittorrent.c:148 #: src/protocol/bittorrent/bittorrent.c:156
msgid "" msgid ""
"The minimum sharing rate to achieve before stop seeding.\n" "The minimum sharing rate to achieve before stop seeding.\n"
"The sharing rate is computed as the number of uploaded bytes\n" "The sharing rate is computed as the number of uploaded bytes\n"
@ -6794,22 +6812,22 @@ msgstr ""
"Mettre à 1.0 pour uploader une copie complète des données et\n" "Mettre à 1.0 pour uploader une copie complète des données et\n"
"à 0.0 pour avoir un ratio de partage sans limite." "à 0.0 pour avoir un ratio de partage sans limite."
#: src/protocol/bittorrent/bittorrent.c:155 #: src/protocol/bittorrent/bittorrent.c:163
msgid "Maximum number of uploads" msgid "Maximum number of uploads"
msgstr "Nombre maximal de téléchargements montants" msgstr "Nombre maximal de téléchargements montants"
#: src/protocol/bittorrent/bittorrent.c:157 #: src/protocol/bittorrent/bittorrent.c:165
msgid "The maximum number of uploads to allow at once." msgid "The maximum number of uploads to allow at once."
msgstr "" msgstr ""
"Nombre maximal de téléchargements montants autorisés\n" "Nombre maximal de téléchargements montants autorisés\n"
"à un instant." "à un instant."
#. The number of uploads to fill out to with extra optimistic unchokes #. The number of uploads to fill out to with extra optimistic unchokes
#: src/protocol/bittorrent/bittorrent.c:160 #: src/protocol/bittorrent/bittorrent.c:168
msgid "Minimum number of uploads" msgid "Minimum number of uploads"
msgstr "Nombre minimal de téléchargements montants" msgstr "Nombre minimal de téléchargements montants"
#: src/protocol/bittorrent/bittorrent.c:162 #: src/protocol/bittorrent/bittorrent.c:170
msgid "" msgid ""
"The minimum number of uploads which should at least\n" "The minimum number of uploads which should at least\n"
"be used for new connections." "be used for new connections."
@ -6817,11 +6835,11 @@ msgstr ""
"Le nombre minimal de téléchargements montants qui devraient\n" "Le nombre minimal de téléchargements montants qui devraient\n"
"être utilisés pour les nouvelles connexions." "être utilisés pour les nouvelles connexions."
#: src/protocol/bittorrent/bittorrent.c:166 #: src/protocol/bittorrent/bittorrent.c:174
msgid "Keepalive interval" msgid "Keepalive interval"
msgstr "Intervalle pour le maintien en vie des connexions" msgstr "Intervalle pour le maintien en vie des connexions"
#: src/protocol/bittorrent/bittorrent.c:168 #: src/protocol/bittorrent/bittorrent.c:176
msgid "" msgid ""
"The number of seconds to pause between sending keepalive\n" "The number of seconds to pause between sending keepalive\n"
"messages." "messages."
@ -6829,11 +6847,11 @@ msgstr ""
"Nombre de secondes entre chaque envoi de messages de maintien\n" "Nombre de secondes entre chaque envoi de messages de maintien\n"
"en vie." "en vie."
#: src/protocol/bittorrent/bittorrent.c:171 #: src/protocol/bittorrent/bittorrent.c:179
msgid "Number of pending requests" msgid "Number of pending requests"
msgstr "Nombre de requêtes en attente" msgstr "Nombre de requêtes en attente"
#: src/protocol/bittorrent/bittorrent.c:173 #: src/protocol/bittorrent/bittorrent.c:181
msgid "" msgid ""
"How many piece requests to continuously keep in queue. Pipelining\n" "How many piece requests to continuously keep in queue. Pipelining\n"
"of requests is essential to saturate connections and get a good\n" "of requests is essential to saturate connections and get a good\n"
@ -6850,11 +6868,11 @@ msgstr ""
"demandés à de multiples postes." "demandés à de multiples postes."
#. Bram uses 30 seconds here. #. Bram uses 30 seconds here.
#: src/protocol/bittorrent/bittorrent.c:182 #: src/protocol/bittorrent/bittorrent.c:190
msgid "Peer snubbing interval" msgid "Peer snubbing interval"
msgstr "Intervalle de subbing pour les postes" msgstr "Intervalle de subbing pour les postes"
#: src/protocol/bittorrent/bittorrent.c:184 #: src/protocol/bittorrent/bittorrent.c:192
msgid "" msgid ""
"The number of seconds to wait for file data before assuming\n" "The number of seconds to wait for file data before assuming\n"
"the peer has been snubbed." "the peer has been snubbed."
@ -6862,11 +6880,11 @@ msgstr ""
"Nombre de secondes à attendre les données avant de supposer\n" "Nombre de secondes à attendre les données avant de supposer\n"
"qu'un poste a été snubbé." "qu'un poste a été snubbé."
#: src/protocol/bittorrent/bittorrent.c:187 #: src/protocol/bittorrent/bittorrent.c:195
msgid "Peer choke interval" msgid "Peer choke interval"
msgstr "Intervalle de choke pour les postes" msgstr "Intervalle de choke pour les postes"
#: src/protocol/bittorrent/bittorrent.c:189 #: src/protocol/bittorrent/bittorrent.c:197
msgid "" msgid ""
"The number of seconds between updating the connection state\n" "The number of seconds between updating the connection state\n"
"and most importantly choke and unchoke peer connections. The\n" "and most importantly choke and unchoke peer connections. The\n"
@ -6880,11 +6898,11 @@ msgstr ""
"connexions unchokées démarrent mais assez petite pour ne pas permettre\n" "connexions unchokées démarrent mais assez petite pour ne pas permettre\n"
"à certains d'utiliser trop de bande passante." "à certains d'utiliser trop de bande passante."
#: src/protocol/bittorrent/bittorrent.c:195 #: src/protocol/bittorrent/bittorrent.c:203
msgid "Rarest first piece selection cutoff" msgid "Rarest first piece selection cutoff"
msgstr "Limite pour la sélection des morceaux par rareté" msgstr "Limite pour la sélection des morceaux par rareté"
#: src/protocol/bittorrent/bittorrent.c:197 #: src/protocol/bittorrent/bittorrent.c:205
msgid "" msgid ""
"The number of pieces to obtain before switching piece\n" "The number of pieces to obtain before switching piece\n"
"selection strategy from random to rarest first." "selection strategy from random to rarest first."
@ -6892,11 +6910,11 @@ msgstr ""
"Nombre de morceaux à obtenir avant de modifier la stratégie\n" "Nombre de morceaux à obtenir avant de modifier la stratégie\n"
"de sélection de morceaux du mode hasard au mode rareté." "de sélection de morceaux du mode hasard au mode rareté."
#: src/protocol/bittorrent/bittorrent.c:200 src/protocol/http/http.c:106 #: src/protocol/bittorrent/bittorrent.c:208 src/protocol/http/http.c:106
msgid "Allow blacklisting" msgid "Allow blacklisting"
msgstr "Autoriser la mise en liste noire" msgstr "Autoriser la mise en liste noire"
#: src/protocol/bittorrent/bittorrent.c:202 #: src/protocol/bittorrent/bittorrent.c:210
msgid "Allow blacklisting of buggy peers." msgid "Allow blacklisting of buggy peers."
msgstr "Autoriser la mise en liste noire des postes bogués." msgstr "Autoriser la mise en liste noire des postes bogués."
@ -7904,11 +7922,11 @@ msgstr "Le fichier sera ouvert avec le programme '%s'."
msgid "~Open" msgid "~Open"
msgstr "~Ouvrir" msgstr "~Ouvrir"
#: src/session/session.c:749 src/session/session.c:768 src/session/task.c:269 #: src/session/session.c:752 src/session/session.c:771 src/session/task.c:269
msgid "Warning" msgid "Warning"
msgstr "Avertissement" msgstr "Avertissement"
#: src/session/session.c:750 #: src/session/session.c:753
msgid "" msgid ""
"You have empty string in protocol.http.user_agent - this was a default value " "You have empty string in protocol.http.user_agent - this was a default value "
"in the past, substituted by default ELinks User-Agent string. However, " "in the past, substituted by default ELinks User-Agent string. However, "
@ -7927,7 +7945,7 @@ msgstr ""
"défaut sera utilisée. Si vous n'avez aucune idée de quoi nous parlons alors " "défaut sera utilisée. Si vous n'avez aucune idée de quoi nous parlons alors "
"faites juste ça. Toutes nos excuses pour ce désagrément." "faites juste ça. Toutes nos excuses pour ce désagrément."
#: src/session/session.c:769 #: src/session/session.c:772
msgid "" msgid ""
"You have option config.saving_style set to a de facto obsolete value. The " "You have option config.saving_style set to a de facto obsolete value. The "
"configuration saving algorithms of ELinks were changed from the last time " "configuration saving algorithms of ELinks were changed from the last time "
@ -7948,11 +7966,11 @@ msgstr ""
"l'option config.saving_style dans le but d'obtenir un fonctionnement " "l'option config.saving_style dans le but d'obtenir un fonctionnement "
"correct. Toutes nos excuses pour l'éventuel désagrément causé." "correct. Toutes nos excuses pour l'éventuel désagrément causé."
#: src/session/session.c:794 #: src/session/session.c:797
msgid "Welcome" msgid "Welcome"
msgstr "Bienvenue" msgstr "Bienvenue"
#: src/session/session.c:795 #: src/session/session.c:798
msgid "" msgid ""
"Welcome to ELinks!\n" "Welcome to ELinks!\n"
"\n" "\n"
@ -8063,164 +8081,164 @@ msgstr "Ancre manquante"
msgid "The requested fragment \"#%s\" doesn't exist." msgid "The requested fragment \"#%s\" doesn't exist."
msgstr "L'ancre recherchée \"#%s\" n'existe pas." msgstr "L'ancre recherchée \"#%s\" n'existe pas."
#: src/viewer/text/form.c:855 #: src/viewer/text/form.c:864
msgid "Error while posting form" msgid "Error while posting form"
msgstr "Erreur lors de l'envoi du formulaire" msgstr "Erreur lors de l'envoi du formulaire"
#: src/viewer/text/form.c:856 #: src/viewer/text/form.c:865
#, c-format #, c-format
msgid "Could not load file %s: %s" msgid "Could not load file %s: %s"
msgstr "Impossible de charger le fichier %s: %s" msgstr "Impossible de charger le fichier %s: %s"
#: src/viewer/text/form.c:1436 #: src/viewer/text/form.c:1445
msgid "Reset form" msgid "Reset form"
msgstr "Réinitialiser le formulaire" msgstr "Réinitialiser le formulaire"
#: src/viewer/text/form.c:1438 #: src/viewer/text/form.c:1447
msgid "Harmless button" msgid "Harmless button"
msgstr "Bouton sans impact" msgstr "Bouton sans impact"
#: src/viewer/text/form.c:1446 #: src/viewer/text/form.c:1455
msgid "Submit form to" msgid "Submit form to"
msgstr "Envoi du formulaire à" msgstr "Envoi du formulaire à"
#: src/viewer/text/form.c:1447 #: src/viewer/text/form.c:1456
msgid "Post form to" msgid "Post form to"
msgstr "Transfert du formulaire à" msgstr "Transfert du formulaire à"
#: src/viewer/text/form.c:1449 #: src/viewer/text/form.c:1458
msgid "Radio button" msgid "Radio button"
msgstr "Bouton radio" msgstr "Bouton radio"
#: src/viewer/text/form.c:1453 #: src/viewer/text/form.c:1462
msgid "Select field" msgid "Select field"
msgstr "Liste" msgstr "Liste"
#: src/viewer/text/form.c:1457 #: src/viewer/text/form.c:1466
msgid "Text area" msgid "Text area"
msgstr "Champ texte multiligne" msgstr "Champ texte multiligne"
#: src/viewer/text/form.c:1459 #: src/viewer/text/form.c:1468
msgid "File upload" msgid "File upload"
msgstr "Envoi de fichier" msgstr "Envoi de fichier"
#: src/viewer/text/form.c:1461 #: src/viewer/text/form.c:1470
msgid "Password field" msgid "Password field"
msgstr "Champ mot de passe" msgstr "Champ mot de passe"
#: src/viewer/text/form.c:1499 #: src/viewer/text/form.c:1508
msgid "name" msgid "name"
msgstr "Nom" msgstr "Nom"
#: src/viewer/text/form.c:1511 #: src/viewer/text/form.c:1520
msgid "value" msgid "value"
msgstr "Valeur" msgstr "Valeur"
#: src/viewer/text/form.c:1524 #: src/viewer/text/form.c:1533
msgid "read only" msgid "read only"
msgstr "lecture seule" msgstr "lecture seule"
#: src/viewer/text/form.c:1535 #: src/viewer/text/form.c:1544
#, c-format #, c-format
msgid "press %s to navigate" msgid "press %s to navigate"
msgstr "pressez %s pour naviguer" msgstr "pressez %s pour naviguer"
#: src/viewer/text/form.c:1537 #: src/viewer/text/form.c:1546
#, c-format #, c-format
msgid "press %s to edit" msgid "press %s to edit"
msgstr "pressez %s pour éditer" msgstr "pressez %s pour éditer"
#: src/viewer/text/form.c:1573 #: src/viewer/text/form.c:1582
#, c-format #, c-format
msgid "press %s to submit to %s" msgid "press %s to submit to %s"
msgstr "pressez %s pour soumettre à %s" msgstr "pressez %s pour soumettre à %s"
#: src/viewer/text/form.c:1575 #: src/viewer/text/form.c:1584
#, c-format #, c-format
msgid "press %s to post to %s" msgid "press %s to post to %s"
msgstr "pressez %s pour poster à %s" msgstr "pressez %s pour poster à %s"
#: src/viewer/text/link.c:1145 #: src/viewer/text/link.c:1148
msgid "Display ~usemap" msgid "Display ~usemap"
msgstr "Afficher ~usemap" msgstr "Afficher ~usemap"
#: src/viewer/text/link.c:1148 #: src/viewer/text/link.c:1151
msgid "~Follow link" msgid "~Follow link"
msgstr "~Suivre le lien" msgstr "~Suivre le lien"
#: src/viewer/text/link.c:1150 #: src/viewer/text/link.c:1153
msgid "Follow link and r~eload" msgid "Follow link and r~eload"
msgstr "Suivre le lien et ~recharger" msgstr "Suivre le lien et ~recharger"
#: src/viewer/text/link.c:1154 #: src/viewer/text/link.c:1157
msgid "Open in new ~window" msgid "Open in new ~window"
msgstr "Ouvrir dans une nouvelle ~fenêtre" msgstr "Ouvrir dans une nouvelle ~fenêtre"
#: src/viewer/text/link.c:1156 #: src/viewer/text/link.c:1159
msgid "Open in new ~tab" msgid "Open in new ~tab"
msgstr "Ouvrir dans un nouvel ongle~t" msgstr "Ouvrir dans un nouvel ongle~t"
#: src/viewer/text/link.c:1158 #: src/viewer/text/link.c:1161
msgid "Open in new tab in ~background" msgid "Open in new tab in ~background"
msgstr "Ouvrir dans un nouvel onglet en arrière-~plan" msgstr "Ouvrir dans un nouvel onglet en arrière-~plan"
#: src/viewer/text/link.c:1163 #: src/viewer/text/link.c:1166
msgid "~Download link" msgid "~Download link"
msgstr "~Enregistrer le lien" msgstr "~Enregistrer le lien"
#: src/viewer/text/link.c:1166 #: src/viewer/text/link.c:1169
msgid "~Add link to bookmarks" msgid "~Add link to bookmarks"
msgstr "~Ajouter ce lien aux signets" msgstr "~Ajouter ce lien aux signets"
#: src/viewer/text/link.c:1178 src/viewer/text/link.c:1214 #: src/viewer/text/link.c:1181 src/viewer/text/link.c:1217
msgid "~Reset form" msgid "~Reset form"
msgstr "Remettre à ~zéro le formulaire" msgstr "Remettre à ~zéro le formulaire"
#: src/viewer/text/link.c:1191 #: src/viewer/text/link.c:1194
msgid "Open in ~external editor" msgid "Open in ~external editor"
msgstr "Ouvrir dans un ~éditeur externe" msgstr "Ouvrir dans un ~éditeur externe"
#: src/viewer/text/link.c:1197 #: src/viewer/text/link.c:1200
msgid "~Submit form" msgid "~Submit form"
msgstr "~Envoyer le formulaire" msgstr "~Envoyer le formulaire"
#: src/viewer/text/link.c:1198 #: src/viewer/text/link.c:1201
msgid "Submit form and rel~oad" msgid "Submit form and rel~oad"
msgstr "Envoyer le formulaire et ~recharger" msgstr "Envoyer le formulaire et ~recharger"
#: src/viewer/text/link.c:1202 #: src/viewer/text/link.c:1205
msgid "Submit form and open in new ~window" msgid "Submit form and open in new ~window"
msgstr "Envoyer le formulaire et ouvrir dans une nouvelle ~fenêtre" msgstr "Envoyer le formulaire et ouvrir dans une nouvelle ~fenêtre"
#: src/viewer/text/link.c:1204 #: src/viewer/text/link.c:1207
msgid "Submit form and open in new ~tab" msgid "Submit form and open in new ~tab"
msgstr "Envoyer le formulaire et ouvrir un ~onglet" msgstr "Envoyer le formulaire et ouvrir un ~onglet"
#: src/viewer/text/link.c:1207 #: src/viewer/text/link.c:1210
msgid "Submit form and open in new tab in ~background" msgid "Submit form and open in new tab in ~background"
msgstr "Envoyer le formulaire et ouvrir un onglet en ~arrière-plan" msgstr "Envoyer le formulaire et ouvrir un onglet en ~arrière-plan"
#: src/viewer/text/link.c:1212 #: src/viewer/text/link.c:1215
msgid "Submit form and ~download" msgid "Submit form and ~download"
msgstr "Envoyer le formulaire et ~télécharger" msgstr "Envoyer le formulaire et ~télécharger"
#: src/viewer/text/link.c:1219 #: src/viewer/text/link.c:1222
msgid "V~iew image" msgid "V~iew image"
msgstr "~Voir l'image" msgstr "~Voir l'image"
#: src/viewer/text/link.c:1221 #: src/viewer/text/link.c:1224
msgid "Download ima~ge" msgid "Download ima~ge"
msgstr "Enregistrer l'~image" msgstr "Enregistrer l'~image"
#: src/viewer/text/link.c:1229 #: src/viewer/text/link.c:1232
msgid "No link selected" msgid "No link selected"
msgstr "Aucun lien sélectionné" msgstr "Aucun lien sélectionné"
#: src/viewer/text/link.c:1281 #: src/viewer/text/link.c:1280
msgid "Image" msgid "Image"
msgstr "Image" msgstr "Image"
#: src/viewer/text/link.c:1286 #: src/viewer/text/link.c:1285
msgid "Usemap" msgid "Usemap"
msgstr "Usemap" msgstr "Usemap"
@ -8308,10 +8326,10 @@ msgstr "Aller au lien"
msgid "Enter link number" msgid "Enter link number"
msgstr "Entrez un numéro de lien" msgstr "Entrez un numéro de lien"
#: src/viewer/text/view.c:1287 #: src/viewer/text/view.c:1288
msgid "Save error" msgid "Save error"
msgstr "Erreur lors de la sauvegarde" msgstr "Erreur lors de la sauvegarde"
#: src/viewer/text/view.c:1288 #: src/viewer/text/view.c:1289
msgid "Error writing to file" msgid "Error writing to file"
msgstr "Erreur lors de l'écriture du fichier" msgstr "Erreur lors de l'écriture du fichier"

View File

@ -602,9 +602,6 @@ is_path_prefix(unsigned char *d, unsigned char *s)
} }
#define is_expired(t) ((t) && (t) <= time(NULL))
#define is_dead(t) (!(t) || (t) <= time(NULL))
struct string * struct string *
send_cookies(struct uri *uri) send_cookies(struct uri *uri)
{ {
@ -612,6 +609,7 @@ send_cookies(struct uri *uri)
struct cookie *c, *next; struct cookie *c, *next;
unsigned char *path = NULL; unsigned char *path = NULL;
static struct string header; static struct string header;
time_t now;
if (!uri->host || !uri->data) if (!uri->host || !uri->data)
return NULL; return NULL;
@ -626,12 +624,13 @@ send_cookies(struct uri *uri)
init_string(&header); init_string(&header);
now = time(NULL);
foreachsafe (c, next, cookies) { foreachsafe (c, next, cookies) {
if (!is_in_domain(c->domain, uri->host, uri->hostlen) if (!is_in_domain(c->domain, uri->host, uri->hostlen)
|| !is_path_prefix(c->path, path)) || !is_path_prefix(c->path, path))
continue; continue;
if (is_expired(c->expires)) { if (c->expires && c->expires <= now) {
#ifdef DEBUG_COOKIES #ifdef DEBUG_COOKIES
DBG("Cookie %s=%s (exp %d) expired.", DBG("Cookie %s=%s (exp %d) expired.",
c->name, c->value, c->expires); c->name, c->value, c->expires);
@ -681,6 +680,7 @@ load_cookies(void) {
unsigned char in_buffer[6 * MAX_STR_LEN]; unsigned char in_buffer[6 * MAX_STR_LEN];
unsigned char *cookfile = COOKIES_FILENAME; unsigned char *cookfile = COOKIES_FILENAME;
FILE *fp; FILE *fp;
time_t now;
if (elinks_home) { if (elinks_home) {
cookfile = straconcat(elinks_home, cookfile, NULL); cookfile = straconcat(elinks_home, cookfile, NULL);
@ -701,6 +701,7 @@ load_cookies(void) {
* periodically to our death. */ * periodically to our death. */
cookies_nosave = 1; cookies_nosave = 1;
now = time(NULL);
while (fgets(in_buffer, 6 * MAX_STR_LEN, fp)) { while (fgets(in_buffer, 6 * MAX_STR_LEN, fp)) {
struct cookie *cookie; struct cookie *cookie;
unsigned char *p, *q = in_buffer; unsigned char *p, *q = in_buffer;
@ -728,7 +729,7 @@ load_cookies(void) {
/* Skip expired cookies if any. */ /* Skip expired cookies if any. */
expires = str_to_time_t(members[EXPIRES].pos); expires = str_to_time_t(members[EXPIRES].pos);
if (is_dead(expires)) { if (!expires || expires <= now) {
cookies_dirty = 1; cookies_dirty = 1;
continue; continue;
} }
@ -765,6 +766,7 @@ save_cookies(void) {
struct cookie *c; struct cookie *c;
unsigned char *cookfile; unsigned char *cookfile;
struct secure_save_info *ssi; struct secure_save_info *ssi;
time_t now;
if (cookies_nosave || !elinks_home || !cookies_dirty if (cookies_nosave || !elinks_home || !cookies_dirty
|| get_cmd_opt_bool("anonymous")) || get_cmd_opt_bool("anonymous"))
@ -777,8 +779,9 @@ save_cookies(void) {
mem_free(cookfile); mem_free(cookfile);
if (!ssi) return; if (!ssi) return;
now = time(NULL);
foreach (c, cookies) { foreach (c, cookies) {
if (is_dead(c->expires)) continue; if (!c->expires || c->expires <= now) continue;
if (secure_fprintf(ssi, "%s\t%s\t%s\t%s\t%s\t%ld\t%d\n", if (secure_fprintf(ssi, "%s\t%s\t%s\t%s\t%s\t%ld\t%d\n",
c->name, c->value, c->name, c->value,
c->server->host, c->server->host,

View File

@ -43,12 +43,12 @@ static const struct scan_table_info css_scan_table_info[] = {
SCAN_TABLE_STRING(" \f\n\r\t\v\000", CSS_CHAR_WHITESPACE), SCAN_TABLE_STRING(" \f\n\r\t\v\000", CSS_CHAR_WHITESPACE),
SCAN_TABLE_STRING("\f\n\r", CSS_CHAR_NEWLINE), SCAN_TABLE_STRING("\f\n\r", CSS_CHAR_NEWLINE),
SCAN_TABLE_STRING("-", CSS_CHAR_IDENT), SCAN_TABLE_STRING("-", CSS_CHAR_IDENT),
SCAN_TABLE_STRING(".#@!\"'<-/", CSS_CHAR_TOKEN_START), SCAN_TABLE_STRING(".#@!\"'<-/|^$*", CSS_CHAR_TOKEN_START),
/* Unicode escape (that we do not handle yet) + other special chars */ /* Unicode escape (that we do not handle yet) + other special chars */
SCAN_TABLE_STRING("\\_*", CSS_CHAR_IDENT | CSS_CHAR_IDENT_START), SCAN_TABLE_STRING("\\_", CSS_CHAR_IDENT | CSS_CHAR_IDENT_START),
/* This should contain mostly used char tokens like ':' and maybe a few /* This should contain mostly used char tokens like ':' and maybe a few
* garbage chars that people might put in their CSS code */ * garbage chars that people might put in their CSS code */
SCAN_TABLE_STRING("({});:,.>", CSS_CHAR_TOKEN), SCAN_TABLE_STRING("[({})];:,.>+~", CSS_CHAR_TOKEN),
SCAN_TABLE_STRING("<![CDATA]->", CSS_CHAR_SGML_MARKUP), SCAN_TABLE_STRING("<![CDATA]->", CSS_CHAR_SGML_MARKUP),
SCAN_TABLE_END, SCAN_TABLE_END,
@ -259,6 +259,32 @@ scan_css_token(struct scanner *scanner, struct scanner_token *token)
CSS_TOKEN_AT_KEYWORD); CSS_TOKEN_AT_KEYWORD);
} }
} else if (first_char == '*') {
if (*string == '=') {
type = CSS_TOKEN_SELECT_CONTAINS;
string++;
} else {
type = CSS_TOKEN_IDENT;
}
} else if (first_char == '^') {
if (*string == '=') {
type = CSS_TOKEN_SELECT_BEGIN;
string++;
}
} else if (first_char == '$') {
if (*string == '=') {
type = CSS_TOKEN_SELECT_END;
string++;
}
} else if (first_char == '|') {
if (*string == '=') {
type = CSS_TOKEN_SELECT_HYPHEN_LIST;
string++;
}
} else if (first_char == '!') { } else if (first_char == '!') {
scan_css(scanner, string, CSS_CHAR_WHITESPACE); scan_css(scanner, string, CSS_CHAR_WHITESPACE);
if (!strncasecmp(string, "important", 9)) { if (!strncasecmp(string, "important", 9)) {

View File

@ -69,7 +69,12 @@ enum css_token_type {
CSS_TOKEN_IMPORTANT, /* !<whitespace>important */ CSS_TOKEN_IMPORTANT, /* !<whitespace>important */
/* TODO: Selector stuff like "|=" and "~=" */ /* TODO: Selector stuff: */
CSS_TOKEN_SELECT_SPACE_LIST, /* ~= */
CSS_TOKEN_SELECT_HYPHEN_LIST, /* |= */
CSS_TOKEN_SELECT_BEGIN, /* ^= */
CSS_TOKEN_SELECT_END, /* $= */
CSS_TOKEN_SELECT_CONTAINS, /* *= */
/* Special tokens: */ /* Special tokens: */

View File

@ -154,15 +154,8 @@ dom_node_cmp(struct dom_node_search *search, struct dom_node *node)
break; break;
} }
} }
{
int length = int_min(key->length, node->length);
int string_diff = strncasecmp(key->string, node->string, length);
/* If the lengths or strings don't match strncasecmp() does the return dom_string_casecmp(&key->string, &node->string);
* job else return which ever is bigger. */
return string_diff ? string_diff : key->length - node->length;
}
} }
static inline int static inline int
@ -211,9 +204,9 @@ int get_dom_node_map_index(struct dom_node_list *list, struct dom_node *node)
struct dom_node * struct dom_node *
get_dom_node_map_entry(struct dom_node_list *list, enum dom_node_type type, get_dom_node_map_entry(struct dom_node_list *list, enum dom_node_type type,
uint16_t subtype, unsigned char *name, int namelen) uint16_t subtype, struct dom_string *name)
{ {
struct dom_node node = { type, namelen, name }; struct dom_node node = { type, INIT_DOM_STRING(name->string, name->length) };
struct dom_node_search search = INIT_DOM_NODE_SEARCH(&node, subtype, list); struct dom_node_search search = INIT_DOM_NODE_SEARCH(&node, subtype, list);
return dom_node_list_bsearch(&search, list); return dom_node_list_bsearch(&search, list);
@ -224,7 +217,7 @@ get_dom_node_map_entry(struct dom_node_list *list, enum dom_node_type type,
struct dom_node * struct dom_node *
init_dom_node_(unsigned char *file, int line, init_dom_node_(unsigned char *file, int line,
struct dom_node *parent, enum dom_node_type type, struct dom_node *parent, enum dom_node_type type,
unsigned char *string, uint16_t length) unsigned char *string, size_t length)
{ {
#ifdef DEBUG_MEMLEAK #ifdef DEBUG_MEMLEAK
struct dom_node *node = debug_mem_calloc(file, line, 1, sizeof(*node)); struct dom_node *node = debug_mem_calloc(file, line, 1, sizeof(*node));
@ -235,18 +228,16 @@ init_dom_node_(unsigned char *file, int line,
if (!node) return NULL; if (!node) return NULL;
node->type = type; node->type = type;
node->string = string;
node->length = length;
node->parent = parent; node->parent = parent;
set_dom_string(&node->string, string, length);
if (parent) { if (parent) {
struct dom_node_list **list = get_dom_node_list(parent, node); struct dom_node_list **list = get_dom_node_list(parent, node);
int sort = (type == DOM_NODE_ATTRIBUTE); int sort = (type == DOM_NODE_ATTRIBUTE);
int index; int index;
assertm(list, "Adding %s to bad parent %s", assertm(list, "Adding node %d to bad parent %d",
get_dom_node_type_name(node->type), node->type, parent->type);
get_dom_node_type_name(parent->type));
index = *list && (*list)->size > 0 && sort index = *list && (*list)->size > 0 && sort
? get_dom_node_map_index(*list, node) : -1; ? get_dom_node_map_index(*list, node) : -1;
@ -272,7 +263,7 @@ done_dom_node_data(struct dom_node *node)
switch (node->type) { switch (node->type) {
case DOM_NODE_ATTRIBUTE: case DOM_NODE_ATTRIBUTE:
if (data->attribute.allocated) if (data->attribute.allocated)
mem_free(node->string); done_dom_string(&node->string);
break; break;
case DOM_NODE_DOCUMENT: case DOM_NODE_DOCUMENT:
@ -296,7 +287,7 @@ done_dom_node_data(struct dom_node *node)
case DOM_NODE_TEXT: case DOM_NODE_TEXT:
if (data->text.allocated) if (data->text.allocated)
mem_free(node->string); done_dom_string(&node->string);
break; break;
case DOM_NODE_PROCESSING_INSTRUCTION: case DOM_NODE_PROCESSING_INSTRUCTION:
@ -346,140 +337,94 @@ done_dom_node(struct dom_node *node)
#define set_node_name(name, namelen, str) \ #define set_node_name(name, namelen, str) \
do { (name) = (str); (namelen) = sizeof(str) - 1; } while (0) do { (name) = (str); (namelen) = sizeof(str) - 1; } while (0)
unsigned char * struct dom_string *
get_dom_node_name(struct dom_node *node) get_dom_node_name(struct dom_node *node)
{ {
unsigned char *name; static struct dom_string cdata_section_str = INIT_DOM_STRING("#cdata-section", -1);
uint16_t namelen; static struct dom_string comment_str = INIT_DOM_STRING("#comment", -1);
static struct dom_string document_str = INIT_DOM_STRING("#document", -1);
static struct dom_string document_fragment_str = INIT_DOM_STRING("#document-fragment", -1);
static struct dom_string text_str = INIT_DOM_STRING("#text", -1);
assert(node); assert(node);
switch (node->type) { switch (node->type) {
case DOM_NODE_CDATA_SECTION: case DOM_NODE_CDATA_SECTION:
set_node_name(name, namelen, "#cdata-section"); return &cdata_section_str;
break;
case DOM_NODE_COMMENT: case DOM_NODE_COMMENT:
set_node_name(name, namelen, "#comment"); return &comment_str;
break;
case DOM_NODE_DOCUMENT: case DOM_NODE_DOCUMENT:
set_node_name(name, namelen, "#document"); return &document_str;
break;
case DOM_NODE_DOCUMENT_FRAGMENT: case DOM_NODE_DOCUMENT_FRAGMENT:
set_node_name(name, namelen, "#document-fragment"); return &document_fragment_str;
break;
case DOM_NODE_TEXT: case DOM_NODE_TEXT:
set_node_name(name, namelen, "#text"); return &text_str;
break;
case DOM_NODE_ATTRIBUTE: case DOM_NODE_ATTRIBUTE:
case DOM_NODE_DOCUMENT_TYPE: case DOM_NODE_DOCUMENT_TYPE:
case DOM_NODE_ELEMENT: case DOM_NODE_ELEMENT:
case DOM_NODE_ENTITY: case DOM_NODE_ENTITY:
case DOM_NODE_ENTITY_REFERENCE: case DOM_NODE_ENTITY_REFERENCE:
case DOM_NODE_NOTATION: case DOM_NODE_NOTATION:
case DOM_NODE_PROCESSING_INSTRUCTION: case DOM_NODE_PROCESSING_INSTRUCTION:
default: default:
name = node->string; return &node->string;
namelen = node->length;
} }
return memacpy(name, namelen);
} }
static inline unsigned char * struct dom_string *
compress_string(unsigned char *string, unsigned int length) get_dom_node_value(struct dom_node *node)
{ {
struct string buffer;
unsigned char escape[2] = "\\";
if (!init_string(&buffer)) return NULL;
for (; length > 0; string++, length--) {
unsigned char *bytes = string;
if (*string == '\n' || *string == '\r' || *string == '\t') {
bytes = escape;
escape[1] = *string == '\n' ? 'n'
: (*string == '\r' ? 'r' : 't');
}
add_bytes_to_string(&buffer, bytes, bytes == escape ? 2 : 1);
}
return buffer.source;
}
unsigned char *
get_dom_node_value(struct dom_node *node, int codepage)
{
unsigned char *value;
uint16_t valuelen;
assert(node); assert(node);
switch (node->type) { switch (node->type) {
case DOM_NODE_ATTRIBUTE: case DOM_NODE_ATTRIBUTE:
value = node->data.attribute.value; return &node->data.attribute.value;
valuelen = node->data.attribute.valuelen;
break;
case DOM_NODE_PROCESSING_INSTRUCTION: case DOM_NODE_PROCESSING_INSTRUCTION:
value = node->data.proc_instruction.instruction; return &node->data.proc_instruction.instruction;
valuelen = node->data.proc_instruction.instructionlen;
break;
case DOM_NODE_CDATA_SECTION: case DOM_NODE_CDATA_SECTION:
case DOM_NODE_COMMENT: case DOM_NODE_COMMENT:
case DOM_NODE_TEXT: case DOM_NODE_TEXT:
value = node->string; return &node->string;
valuelen = node->length;
break;
case DOM_NODE_ENTITY_REFERENCE: case DOM_NODE_ENTITY_REFERENCE:
value = get_entity_string(node->string, node->length, case DOM_NODE_NOTATION:
codepage); case DOM_NODE_DOCUMENT:
valuelen = value ? strlen(value) : 0; case DOM_NODE_DOCUMENT_FRAGMENT:
break; case DOM_NODE_DOCUMENT_TYPE:
case DOM_NODE_ELEMENT:
case DOM_NODE_NOTATION: case DOM_NODE_ENTITY:
case DOM_NODE_DOCUMENT: default:
case DOM_NODE_DOCUMENT_FRAGMENT: return NULL;
case DOM_NODE_DOCUMENT_TYPE:
case DOM_NODE_ELEMENT:
case DOM_NODE_ENTITY:
default:
return NULL;
} }
if (!value) value = "";
return compress_string(value, valuelen);
} }
unsigned char * struct dom_string *
get_dom_node_type_name(enum dom_node_type type) get_dom_node_type_name(enum dom_node_type type)
{ {
static unsigned char *dom_node_type_names[DOM_NODES] = { static struct dom_string dom_node_type_names[DOM_NODES] = {
NULL, INIT_DOM_STRING(NULL, 0),
/* DOM_NODE_ELEMENT */ "element", /* DOM_NODE_ELEMENT */ INIT_DOM_STRING("element", -1),
/* DOM_NODE_ATTRIBUTE */ "attribute", /* DOM_NODE_ATTRIBUTE */ INIT_DOM_STRING("attribute", -1),
/* DOM_NODE_TEXT */ "text", /* DOM_NODE_TEXT */ INIT_DOM_STRING("text", -1),
/* DOM_NODE_CDATA_SECTION */ "cdata-section", /* DOM_NODE_CDATA_SECTION */ INIT_DOM_STRING("cdata-section", -1),
/* DOM_NODE_ENTITY_REFERENCE */ "entity-reference", /* DOM_NODE_ENTITY_REFERENCE */ INIT_DOM_STRING("entity-reference", -1),
/* DOM_NODE_ENTITY */ "entity", /* DOM_NODE_ENTITY */ INIT_DOM_STRING("entity", -1),
/* DOM_NODE_PROCESSING_INSTRUCTION */ "proc-instruction", /* DOM_NODE_PROCESSING_INSTRUCTION */ INIT_DOM_STRING("proc-instruction", -1),
/* DOM_NODE_COMMENT */ "comment", /* DOM_NODE_COMMENT */ INIT_DOM_STRING("comment", -1),
/* DOM_NODE_DOCUMENT */ "document", /* DOM_NODE_DOCUMENT */ INIT_DOM_STRING("document", -1),
/* DOM_NODE_DOCUMENT_TYPE */ "document-type", /* DOM_NODE_DOCUMENT_TYPE */ INIT_DOM_STRING("document-type", -1),
/* DOM_NODE_DOCUMENT_FRAGMENT */ "document-fragment", /* DOM_NODE_DOCUMENT_FRAGMENT */ INIT_DOM_STRING("document-fragment", -1),
/* DOM_NODE_NOTATION */ "notation", /* DOM_NODE_NOTATION */ INIT_DOM_STRING("notation", -1),
}; };
assert(type < DOM_NODES); assert(type < DOM_NODES);
return dom_node_type_names[type]; return &dom_node_type_names[type];
} }

View File

@ -2,11 +2,14 @@
#ifndef EL__DOCUMENT_DOM_NODE_H #ifndef EL__DOCUMENT_DOM_NODE_H
#define EL__DOCUMENT_DOM_NODE_H #define EL__DOCUMENT_DOM_NODE_H
#include "document/dom/string.h"
#include "util/hash.h" #include "util/hash.h"
struct dom_node_list; struct dom_node_list;
enum dom_node_type { enum dom_node_type {
DOM_NODE_UNKNOWN = 0, /* for internal purpose only */
DOM_NODE_ELEMENT = 1, DOM_NODE_ELEMENT = 1,
DOM_NODE_ATTRIBUTE = 2, DOM_NODE_ATTRIBUTE = 2,
DOM_NODE_TEXT = 3, DOM_NODE_TEXT = 3,
@ -30,11 +33,6 @@ struct dom_node_id_item {
/* The attibute node containing the id value */ /* The attibute node containing the id value */
struct dom_node *id_attribute; struct dom_node *id_attribute;
/* The path to the node. This can be passed to the DOM navigator to
* locate the node. The path should not contain the id node itself.
* E.g. for <a id="..."> element "html/body/p/span". */
unsigned char *path;
/* The node with the @id attribute */ /* The node with the @id attribute */
struct dom_node *node; struct dom_node *node;
}; };
@ -54,15 +52,12 @@ struct dom_document_node {
}; };
struct dom_id { struct dom_id {
unsigned char *public_id; struct dom_string public_id;
uint16_t pid_length; struct dom_string system_id;
uint16_t sid_length;
unsigned char *system_id;
}; };
struct dom_doctype_subset_info { struct dom_doctype_subset_info {
uint16_t internallen; struct dom_string internal;
unsigned char *internal;
struct dom_id external; struct dom_id external;
}; };
@ -106,8 +101,7 @@ struct dom_attribute_node {
/* The string that hold the attribute value. The @string / @length /* The string that hold the attribute value. The @string / @length
* members of {struct dom_node} holds the name that identifies the node * members of {struct dom_node} holds the name that identifies the node
* in the map. */ * in the map. */
unsigned char *value; struct dom_string value;
uint16_t valuelen;
/* For xml:lang="en" attributes this holds the offset of 'lang' */ /* For xml:lang="en" attributes this holds the offset of 'lang' */
uint16_t namespace_offset; uint16_t namespace_offset;
@ -168,8 +162,7 @@ struct dom_proc_instruction_node {
/* The target of the processing instruction (xml for '<?xml ... ?>') /* The target of the processing instruction (xml for '<?xml ... ?>')
* is in the @string / @length members. */ * is in the @string / @length members. */
/* This holds the value to be processed */ /* This holds the value to be processed */
unsigned char *instruction; struct dom_string instruction;
uint16_t instructionlen;
/* For fast checking of the target type */ /* For fast checking of the target type */
uint16_t type; /* enum dom_proc_instruction_type */ uint16_t type; /* enum dom_proc_instruction_type */
@ -207,8 +200,7 @@ struct dom_node {
/* Can contain either stuff like element name or for attributes the /* Can contain either stuff like element name or for attributes the
* attribute name. */ * attribute name. */
uint16_t length; struct dom_string string;
unsigned char *string;
struct dom_node *parent; struct dom_node *parent;
@ -253,12 +245,12 @@ int get_dom_node_map_index(struct dom_node_list *list, struct dom_node *node);
struct dom_node * struct dom_node *
get_dom_node_map_entry(struct dom_node_list *node_map, get_dom_node_map_entry(struct dom_node_list *node_map,
enum dom_node_type type, uint16_t subtype, enum dom_node_type type, uint16_t subtype,
unsigned char *name, int namelen); struct dom_string *name);
struct dom_node * struct dom_node *
init_dom_node_(unsigned char *file, int line, init_dom_node_(unsigned char *file, int line,
struct dom_node *parent, enum dom_node_type type, struct dom_node *parent, enum dom_node_type type,
unsigned char *string, uint16_t length); unsigned char *string, size_t length);
#define init_dom_node(type, string, length) init_dom_node_(__FILE__, __LINE__, NULL, type, string, length) #define init_dom_node(type, string, length) init_dom_node_(__FILE__, __LINE__, NULL, type, string, length)
#define add_dom_node(parent, type, string, length) init_dom_node_(__FILE__, __LINE__, parent, type, string, length) #define add_dom_node(parent, type, string, length) init_dom_node_(__FILE__, __LINE__, parent, type, string, length)
@ -267,13 +259,12 @@ init_dom_node_(unsigned char *file, int line,
static inline struct dom_node * static inline struct dom_node *
add_dom_attribute(struct dom_node *parent, unsigned char *string, int length, add_dom_attribute(struct dom_node *parent, unsigned char *string, int length,
unsigned char *value, uint16_t valuelen) unsigned char *value, size_t valuelen)
{ {
struct dom_node *node = add_dom_node(parent, DOM_NODE_ATTRIBUTE, string, length); struct dom_node *node = add_dom_node(parent, DOM_NODE_ATTRIBUTE, string, length);
if (node && value) { if (node && value) {
node->data.attribute.value = value; set_dom_string(&node->data.attribute.value, value, valuelen);
node->data.attribute.valuelen = valuelen;
} }
return node; return node;
@ -281,13 +272,12 @@ add_dom_attribute(struct dom_node *parent, unsigned char *string, int length,
static inline struct dom_node * static inline struct dom_node *
add_dom_proc_instruction(struct dom_node *parent, unsigned char *string, int length, add_dom_proc_instruction(struct dom_node *parent, unsigned char *string, int length,
unsigned char *instruction, uint16_t instructionlen) unsigned char *instruction, size_t instructionlen)
{ {
struct dom_node *node = add_dom_node(parent, DOM_NODE_PROCESSING_INSTRUCTION, string, length); struct dom_node *node = add_dom_node(parent, DOM_NODE_PROCESSING_INSTRUCTION, string, length);
if (node && instruction) { if (node && instruction) {
node->data.proc_instruction.instruction = instruction; set_dom_string(&node->data.proc_instruction.instruction, instruction, instructionlen);
node->data.proc_instruction.instructionlen = instructionlen;
} }
return node; return node;
@ -297,14 +287,14 @@ add_dom_proc_instruction(struct dom_node *parent, unsigned char *string, int len
void done_dom_node(struct dom_node *node); void done_dom_node(struct dom_node *node);
/* Returns the name of the node in an allocated string. */ /* Returns the name of the node in an allocated string. */
unsigned char *get_dom_node_name(struct dom_node *node); struct dom_string *get_dom_node_name(struct dom_node *node);
/* Returns the value of the node in an allocated string. /* Returns the value of the node or NULL if no value is defined for the node
* @codepage denotes how entity strings should be decoded. */ * type. */
unsigned char *get_dom_node_value(struct dom_node *node, int codepage); struct dom_string *get_dom_node_value(struct dom_node *node);
/* Returns the name used for identifying the node type. */ /* Returns the name used for identifying the node type. */
unsigned char *get_dom_node_type_name(enum dom_node_type type); struct dom_string *get_dom_node_type_name(enum dom_node_type type);
/* Returns a pointer to a node list containing attributes. */ /* Returns a pointer to a node list containing attributes. */
#define get_dom_node_attributes(node) \ #define get_dom_node_attributes(node) \

View File

@ -97,8 +97,7 @@ init_dom_renderer(struct dom_renderer *renderer, struct document *document,
color_T foreground = document->options.default_fg; color_T foreground = document->options.default_fg;
static int i_want_struct_module_for_dom; static int i_want_struct_module_for_dom;
unsigned char *name = get_dom_node_type_name(type); struct dom_string *name = get_dom_node_type_name(type);
int namelen = name ? strlen(name) : 0;
struct css_selector *selector = NULL; struct css_selector *selector = NULL;
if (!i_want_struct_module_for_dom) { if (!i_want_struct_module_for_dom) {
@ -119,9 +118,10 @@ init_dom_renderer(struct dom_renderer *renderer, struct document *document,
} }
if (name) if (name)
if (is_dom_string_set(name))
selector = find_css_selector(&css->selectors, selector = find_css_selector(&css->selectors,
CST_ELEMENT, CSR_ROOT, CST_ELEMENT, CSR_ROOT,
name, namelen); name->string, name->length);
if (selector) { if (selector) {
struct list_head *properties = &selector->properties; struct list_head *properties = &selector->properties;
@ -286,6 +286,8 @@ render_dom_text(struct dom_renderer *renderer, struct screen_char *template,
} }
} }
/*#define DOM_TREE_RENDERER*/
#ifdef DOM_TREE_RENDERER #ifdef DOM_TREE_RENDERER
static void static void
render_dom_printf(struct dom_renderer *renderer, struct screen_char *template, render_dom_printf(struct dom_renderer *renderer, struct screen_char *template,
@ -385,22 +387,71 @@ add_dom_link(struct dom_renderer *renderer, unsigned char *string, int length)
/* DOM Tree Renderer */ /* DOM Tree Renderer */
#ifdef DOM_TREE_RENDERER #ifdef DOM_TREE_RENDERER
static inline unsigned char *
compress_string(unsigned char *string, unsigned int length)
{
struct string buffer;
unsigned char escape[2] = "\\";
if (!init_string(&buffer)) return NULL;
for (; length > 0; string++, length--) {
unsigned char *bytes = string;
if (*string == '\n' || *string == '\r' || *string == '\t') {
bytes = escape;
escape[1] = *string == '\n' ? 'n'
: (*string == '\r' ? 'r' : 't');
}
add_bytes_to_string(&buffer, bytes, bytes == escape ? 2 : 1);
}
return buffer.source;
}
/* @codepage denotes how entity strings should be decoded. */
static void
set_enhanced_dom_node_value(struct dom_string *string, struct dom_node *node,
int codepage)
{
struct dom_string *value;
assert(node);
switch (node->type) {
case DOM_NODE_ENTITY_REFERENCE:
string->string = get_entity_string(node->string.string,
node->string.length,
codepage);
break;
default:
value = get_dom_node_value(node);
if (!value) {
set_dom_string(string, NULL, 0);
return;
}
string->string = compress_string(value->string, value->length);
}
string->length = string->string ? strlen(string->string) : 0;
}
static struct dom_node * static struct dom_node *
render_dom_tree(struct dom_stack *stack, struct dom_node *node, void *data) render_dom_tree(struct dom_stack *stack, struct dom_node *node, void *data)
{ {
struct dom_renderer *renderer = stack->renderer; struct dom_renderer *renderer = stack->renderer;
struct screen_char *template = &renderer->styles[node->type]; struct screen_char *template = &renderer->styles[node->type];
unsigned char *name, *value; struct dom_string *value = &node->string;
struct dom_string *name = get_dom_node_name(node);
assert(node && renderer); render_dom_printf(renderer, template, "%.*s: %.*s\n",
name->length, name->string,
name = get_dom_node_name(node); value->length, value->string);
value = memacpy(node->string, node->length);
render_dom_printf(renderer, template, "%-16s: %s\n", name, value);
mem_free_if(name); mem_free_if(name);
mem_free_if(value);
return node; return node;
} }
@ -411,19 +462,23 @@ render_dom_tree_id_leaf(struct dom_stack *stack, struct dom_node *node, void *da
struct dom_renderer *renderer = stack->renderer; struct dom_renderer *renderer = stack->renderer;
struct document *document = renderer->document; struct document *document = renderer->document;
struct screen_char *template = &renderer->styles[node->type]; struct screen_char *template = &renderer->styles[node->type];
unsigned char *name, *value, *id; struct dom_string value;
struct dom_string *name;
struct dom_string *id;
assert(node && document); assert(node && document);
name = get_dom_node_name(node); name = get_dom_node_name(node);
value = get_dom_node_value(node, document->options.cp);
id = get_dom_node_type_name(node->type); id = get_dom_node_type_name(node->type);
set_enhanced_dom_node_value(&value, node, document->options.cp);
renderer->canvas_x += stack->depth; renderer->canvas_x += stack->depth;
render_dom_printf(renderer, template, "%-16s: %s -> %s\n", id, name, value); render_dom_printf(renderer, template, "%.*s: %.*s -> %.*s\n",
id->length, id->string, name->length, name->string,
value.length, value.string);
mem_free_if(name); if (is_dom_string_set(&value))
mem_free_if(value); done_dom_string(&value);
return node; return node;
} }
@ -434,18 +489,21 @@ render_dom_tree_leaf(struct dom_stack *stack, struct dom_node *node, void *data)
struct dom_renderer *renderer = stack->renderer; struct dom_renderer *renderer = stack->renderer;
struct document *document = renderer->document; struct document *document = renderer->document;
struct screen_char *template = &renderer->styles[node->type]; struct screen_char *template = &renderer->styles[node->type];
unsigned char *name, *value; struct dom_string *name;
struct dom_string value;
assert(node && document); assert(node && document);
name = get_dom_node_name(node); name = get_dom_node_name(node);
value = get_dom_node_value(node, document->options.cp); set_enhanced_dom_node_value(&value, node, document->options.cp);
renderer->canvas_x += stack->depth; renderer->canvas_x += stack->depth;
render_dom_printf(renderer, template, "%-16s: %s\n", name, value); render_dom_printf(renderer, template, "%.*s: %.*s\n",
name->length, name->string,
value.length, value.string);
mem_free_if(name); if (is_dom_string_set(&value))
mem_free_if(value); done_dom_string(&value);
return node; return node;
} }
@ -456,7 +514,8 @@ render_dom_tree_branch(struct dom_stack *stack, struct dom_node *node, void *dat
struct dom_renderer *renderer = stack->renderer; struct dom_renderer *renderer = stack->renderer;
struct document *document = renderer->document; struct document *document = renderer->document;
struct screen_char *template = &renderer->styles[node->type]; struct screen_char *template = &renderer->styles[node->type];
unsigned char *name, *id; struct dom_string *name;
struct dom_string *id;
assert(node && document); assert(node && document);
@ -464,7 +523,8 @@ render_dom_tree_branch(struct dom_stack *stack, struct dom_node *node, void *dat
id = get_dom_node_type_name(node->type); id = get_dom_node_type_name(node->type);
renderer->canvas_x += stack->depth; renderer->canvas_x += stack->depth;
render_dom_printf(renderer, template, "%-16s: %s\n", id, name); render_dom_printf(renderer, template, "%.*s: %.*s\n",
id->length, id->string, name->length, name->string);
mem_free_if(name); mem_free_if(name);
@ -517,8 +577,8 @@ static inline void
render_dom_node_text(struct dom_renderer *renderer, struct screen_char *template, render_dom_node_text(struct dom_renderer *renderer, struct screen_char *template,
struct dom_node *node) struct dom_node *node)
{ {
unsigned char *string = node->string; unsigned char *string = node->string.string;
int length = node->length; int length = node->string.length;
if (node->type == DOM_NODE_ENTITY_REFERENCE) { if (node->type == DOM_NODE_ENTITY_REFERENCE) {
string -= 1; string -= 1;
@ -537,7 +597,8 @@ render_dom_node_text(struct dom_renderer *renderer, struct screen_char *template
static struct dom_node * static struct dom_node *
render_dom_node_source(struct dom_stack *stack, struct dom_node *node, void *data) render_dom_node_source(struct dom_stack *stack, struct dom_node *node, void *data)
{ {
struct dom_renderer *renderer = stack->renderer; struct sgml_parser *parser = stack->data;
struct dom_renderer *renderer = parser->data;
assert(node && renderer && renderer->document); assert(node && renderer && renderer->document);
@ -551,7 +612,8 @@ render_dom_node_source(struct dom_stack *stack, struct dom_node *node, void *dat
static struct dom_node * static struct dom_node *
render_dom_proc_instr_source(struct dom_stack *stack, struct dom_node *node, void *data) render_dom_proc_instr_source(struct dom_stack *stack, struct dom_node *node, void *data)
{ {
struct dom_renderer *renderer = stack->renderer; struct sgml_parser *parser = stack->data;
struct dom_renderer *renderer = parser->data;
unsigned char *value; unsigned char *value;
int valuelen; int valuelen;
@ -559,13 +621,13 @@ render_dom_proc_instr_source(struct dom_stack *stack, struct dom_node *node, voi
render_dom_node_text(renderer, &renderer->styles[node->type], node); render_dom_node_text(renderer, &renderer->styles[node->type], node);
value = node->data.proc_instruction.instruction; value = node->data.proc_instruction.instruction.string;
valuelen = node->data.proc_instruction.instructionlen; valuelen = node->data.proc_instruction.instruction.length;
if (!value || node->data.proc_instruction.map) if (!value || node->data.proc_instruction.map)
return node; return node;
if (check_dom_node_source(renderer, node->string, node->length)) { if (check_dom_node_source(renderer, node->string.string, node->string.length)) {
render_dom_flush(renderer, value); render_dom_flush(renderer, value);
renderer->position = value + valuelen; renderer->position = value + valuelen;
} }
@ -578,7 +640,8 @@ render_dom_proc_instr_source(struct dom_stack *stack, struct dom_node *node, voi
static struct dom_node * static struct dom_node *
render_dom_element_source(struct dom_stack *stack, struct dom_node *node, void *data) render_dom_element_source(struct dom_stack *stack, struct dom_node *node, void *data)
{ {
struct dom_renderer *renderer = stack->renderer; struct sgml_parser *parser = stack->data;
struct dom_renderer *renderer = parser->data;
assert(node && renderer && renderer->document); assert(node && renderer && renderer->document);
@ -590,7 +653,8 @@ render_dom_element_source(struct dom_stack *stack, struct dom_node *node, void *
static struct dom_node * static struct dom_node *
render_dom_element_end_source(struct dom_stack *stack, struct dom_node *node, void *data) render_dom_element_end_source(struct dom_stack *stack, struct dom_node *node, void *data)
{ {
struct dom_renderer *renderer = stack->renderer; struct sgml_parser *parser = stack->data;
struct dom_renderer *renderer = parser->data;
struct sgml_parser_state *pstate = data; struct sgml_parser_state *pstate = data;
struct scanner_token *token = &pstate->end_token; struct scanner_token *token = &pstate->end_token;
unsigned char *string = token->string; unsigned char *string = token->string;
@ -615,7 +679,8 @@ render_dom_element_end_source(struct dom_stack *stack, struct dom_node *node, vo
static struct dom_node * static struct dom_node *
render_dom_attribute_source(struct dom_stack *stack, struct dom_node *node, void *data) render_dom_attribute_source(struct dom_stack *stack, struct dom_node *node, void *data)
{ {
struct dom_renderer *renderer = stack->renderer; struct sgml_parser *parser = stack->data;
struct dom_renderer *renderer = parser->data;
struct screen_char *template = &renderer->styles[node->type]; struct screen_char *template = &renderer->styles[node->type];
assert(node && renderer->document); assert(node && renderer->document);
@ -645,10 +710,10 @@ render_dom_attribute_source(struct dom_stack *stack, struct dom_node *node, void
#endif #endif
render_dom_node_text(renderer, template, node); render_dom_node_text(renderer, template, node);
if (node->data.attribute.value) { if (is_dom_string_set(&node->data.attribute.value)) {
int quoted = node->data.attribute.quoted == 1; int quoted = node->data.attribute.quoted == 1;
unsigned char *value = node->data.attribute.value - quoted; unsigned char *value = node->data.attribute.value.string - quoted;
int valuelen = node->data.attribute.valuelen + quoted * 2; int valuelen = node->data.attribute.value.length + quoted * 2;
if (check_dom_node_source(renderer, value, 0)) { if (check_dom_node_source(renderer, value, 0)) {
render_dom_flush(renderer, value); render_dom_flush(renderer, value);

View File

@ -45,7 +45,7 @@ realloc_dom_stack_state_objects(struct dom_stack *stack)
} }
void void
init_dom_stack(struct dom_stack *stack, void *parser, void *renderer, init_dom_stack(struct dom_stack *stack, void *data,
dom_stack_callback_T push_callbacks[DOM_NODES], dom_stack_callback_T push_callbacks[DOM_NODES],
dom_stack_callback_T pop_callbacks[DOM_NODES], dom_stack_callback_T pop_callbacks[DOM_NODES],
size_t object_size, int keep_nodes) size_t object_size, int keep_nodes)
@ -54,8 +54,7 @@ init_dom_stack(struct dom_stack *stack, void *parser, void *renderer,
memset(stack, 0, sizeof(*stack)); memset(stack, 0, sizeof(*stack));
stack->parser = parser; stack->data = data;
stack->renderer = renderer;
stack->object_size = object_size; stack->object_size = object_size;
stack->keep_nodes = !!keep_nodes; stack->keep_nodes = !!keep_nodes;
@ -177,13 +176,13 @@ pop_dom_node(struct dom_stack *stack)
void void
pop_dom_nodes(struct dom_stack *stack, enum dom_node_type type, pop_dom_nodes(struct dom_stack *stack, enum dom_node_type type,
unsigned char *string, uint16_t length) struct dom_string *string)
{ {
struct dom_stack_state *state; struct dom_stack_state *state;
if (!dom_stack_has_parents(stack)) return; if (!dom_stack_has_parents(stack)) return;
state = search_dom_stack(stack, type, string, length); state = search_dom_stack(stack, type, string);
if (state) if (state)
pop_dom_state(stack, type, state); pop_dom_state(stack, type, state);
} }

View File

@ -52,8 +52,7 @@ struct dom_stack {
dom_stack_callback_T pop_callbacks[DOM_NODES]; dom_stack_callback_T pop_callbacks[DOM_NODES];
/* Data specific to the parser and renderer. */ /* Data specific to the parser and renderer. */
void *renderer; void *data;
void *parser;
}; };
#define dom_stack_has_parents(nav) \ #define dom_stack_has_parents(nav) \
@ -86,7 +85,7 @@ get_dom_stack_state(struct dom_stack *stack, int top_offset)
/* Dive through the stack states in search for the specified match. */ /* Dive through the stack states in search for the specified match. */
static inline struct dom_stack_state * static inline struct dom_stack_state *
search_dom_stack(struct dom_stack *stack, enum dom_node_type type, search_dom_stack(struct dom_stack *stack, enum dom_node_type type,
unsigned char *string, uint16_t length) struct dom_string *string)
{ {
struct dom_stack_state *state; struct dom_stack_state *state;
int pos; int pos;
@ -96,8 +95,8 @@ search_dom_stack(struct dom_stack *stack, enum dom_node_type type,
struct dom_node *parent = state->node; struct dom_node *parent = state->node;
if (parent->type == type if (parent->type == type
&& parent->length == length && parent->string.length == string->length
&& !strncasecmp(parent->string, string, length)) && !strncasecmp(parent->string.string, string->string, string->length))
return state; return state;
} }
@ -110,7 +109,7 @@ search_dom_stack(struct dom_stack *stack, enum dom_node_type type,
/* The @object_size arg tells whether the stack should allocate objects for each /* The @object_size arg tells whether the stack should allocate objects for each
* state to be assigned to the state's @data member. Zero means no state data should * state to be assigned to the state's @data member. Zero means no state data should
* be allocated. */ * be allocated. */
void init_dom_stack(struct dom_stack *stack, void *parser, void *renderer, void init_dom_stack(struct dom_stack *stack, void *data,
dom_stack_callback_T push_callbacks[DOM_NODES], dom_stack_callback_T push_callbacks[DOM_NODES],
dom_stack_callback_T pop_callbacks[DOM_NODES], dom_stack_callback_T pop_callbacks[DOM_NODES],
size_t object_size, int keep_nodes); size_t object_size, int keep_nodes);
@ -125,7 +124,7 @@ void pop_dom_node(struct dom_stack *stack);
/* Ascends the stack looking for specific parent */ /* Ascends the stack looking for specific parent */
void pop_dom_nodes(struct dom_stack *stack, enum dom_node_type type, void pop_dom_nodes(struct dom_stack *stack, enum dom_node_type type,
unsigned char *string, uint16_t length); struct dom_string *string);
/* Pop all stack states until a specific state is reached. */ /* Pop all stack states until a specific state is reached. */
void void

34
src/document/dom/string.h Normal file
View File

@ -0,0 +1,34 @@
#ifndef EL__DOCUMENT_DOM_STRING_H
#define EL__DOCUMENT_DOM_STRING_H
struct dom_string {
size_t length;
unsigned char *string;
};
#define INIT_DOM_STRING(strvalue, strlength) \
{ (strlength) == -1 ? sizeof(strvalue) - 1 : (strlength), (strvalue) }
static inline void
set_dom_string(struct dom_string *string, unsigned char *value, size_t length)
{
string->string = value;
string->length = length == -1 ? strlen(value) : length;
}
static inline int
dom_string_casecmp(struct dom_string *string1, struct dom_string *string2)
{
size_t length = int_min(string1->length, string2->length);
size_t string_diff = strncasecmp(string1->string, string2->string, length);
/* If the lengths or strings don't match strncasecmp() does the
* job else return which ever is bigger. */
return string_diff ? string_diff : string1->length - string2->length;
}
#define is_dom_string_set(str) ((str)->string && (str)->length)
#define done_dom_string(str) mem_free((str)->string);
#endif

View File

@ -417,8 +417,6 @@ abort:
if (!closing_tag) { if (!closing_tag) {
unsigned char *value, *label; unsigned char *value, *label;
add_select_item(&lnk_menu, &lbl, &orig_lbl, values, order, nnmi);
if (has_attr(t_attr, "disabled", html_context->options)) if (has_attr(t_attr, "disabled", html_context->options))
goto see; goto see;
if (preselect == -1 if (preselect == -1

View File

@ -28,7 +28,7 @@ static inline struct dom_node *
add_sgml_document(struct dom_stack *stack, struct uri *uri) add_sgml_document(struct dom_stack *stack, struct uri *uri)
{ {
unsigned char *string = struri(uri); unsigned char *string = struri(uri);
int length = strlen(string); size_t length = strlen(string);
struct dom_node *node = init_dom_node(DOM_NODE_DOCUMENT, string, length); struct dom_node *node = init_dom_node(DOM_NODE_DOCUMENT, string, length);
return node ? push_dom_node(stack, node) : node; return node ? push_dom_node(stack, node) : node;
@ -37,7 +37,7 @@ add_sgml_document(struct dom_stack *stack, struct uri *uri)
static inline struct dom_node * static inline struct dom_node *
add_sgml_element(struct dom_stack *stack, struct scanner_token *token) add_sgml_element(struct dom_stack *stack, struct scanner_token *token)
{ {
struct sgml_parser *parser = stack->parser; struct sgml_parser *parser = stack->data;
struct dom_node *parent = get_dom_stack_top(stack)->node; struct dom_node *parent = get_dom_stack_top(stack)->node;
struct dom_stack_state *state; struct dom_stack_state *state;
struct sgml_parser_state *pstate; struct sgml_parser_state *pstate;
@ -67,10 +67,10 @@ static inline void
add_sgml_attribute(struct dom_stack *stack, add_sgml_attribute(struct dom_stack *stack,
struct scanner_token *token, struct scanner_token *valtoken) struct scanner_token *token, struct scanner_token *valtoken)
{ {
struct sgml_parser *parser = stack->parser; struct sgml_parser *parser = stack->data;
struct dom_node *parent = get_dom_stack_top(stack)->node; struct dom_node *parent = get_dom_stack_top(stack)->node;
unsigned char *value = valtoken ? valtoken->string : NULL; unsigned char *value = valtoken ? valtoken->string : NULL;
uint16_t valuelen = valtoken ? valtoken->length : 0; size_t valuelen = valtoken ? valtoken->length : 0;
struct sgml_node_info *info; struct sgml_node_info *info;
struct dom_node *node; struct dom_node *node;
@ -102,11 +102,11 @@ add_sgml_proc_instruction(struct dom_stack *stack, struct scanner_token *token)
/* Anything before the separator becomes the target name ... */ /* Anything before the separator becomes the target name ... */
unsigned char *name = token->string; unsigned char *name = token->string;
int namelen = separator ? separator - token->string : token->length; size_t namelen = separator ? separator - token->string : token->length;
/* ... and everything after the instruction value. */ /* ... and everything after the instruction value. */
unsigned char *value = separator ? separator + 1 : NULL; unsigned char *value = separator ? separator + 1 : NULL;
int valuelen = value ? token->length - namelen - 1 : 0; size_t valuelen = value ? token->length - namelen - 1 : 0;
node = add_dom_proc_instruction(parent, name, namelen, value, valuelen); node = add_dom_proc_instruction(parent, name, namelen, value, valuelen);
if (!node) return NULL; if (!node) return NULL;
@ -243,10 +243,12 @@ parse_sgml_document(struct dom_stack *stack, struct scanner *scanner)
if (!token->length) { if (!token->length) {
pop_dom_node(stack); pop_dom_node(stack);
} else { } else {
struct dom_string string;
struct dom_stack_state *state; struct dom_stack_state *state;
set_dom_string(&string, token->string, token->length);
state = search_dom_stack(stack, DOM_NODE_ELEMENT, state = search_dom_stack(stack, DOM_NODE_ELEMENT,
token->string, token->length); &string);
if (state) { if (state) {
struct sgml_parser_state *pstate; struct sgml_parser_state *pstate;
@ -303,7 +305,7 @@ parse_sgml_document(struct dom_stack *stack, struct scanner *scanner)
struct sgml_parser * struct sgml_parser *
init_sgml_parser(enum sgml_parser_type type, void *renderer, struct uri *uri, init_sgml_parser(enum sgml_parser_type type, void *data, struct uri *uri,
dom_stack_callback_T push_callbacks[DOM_NODES], dom_stack_callback_T push_callbacks[DOM_NODES],
dom_stack_callback_T pop_callbacks[DOM_NODES]) dom_stack_callback_T pop_callbacks[DOM_NODES])
{ {
@ -316,8 +318,9 @@ init_sgml_parser(enum sgml_parser_type type, void *renderer, struct uri *uri,
parser->type = type; parser->type = type;
parser->uri = get_uri_reference(uri); parser->uri = get_uri_reference(uri);
parser->info = &sgml_html_info; parser->info = &sgml_html_info;
parser->data = data;
init_dom_stack(&parser->stack, parser, renderer, init_dom_stack(&parser->stack, parser,
push_callbacks, pop_callbacks, obj_size, push_callbacks, pop_callbacks, obj_size,
type != SGML_PARSER_STREAM); type != SGML_PARSER_STREAM);

View File

@ -29,6 +29,7 @@ struct sgml_parser {
struct uri *uri; struct uri *uri;
struct dom_node *root; struct dom_node *root;
void *data;
struct scanner scanner; struct scanner scanner;
struct dom_stack stack; struct dom_stack stack;
@ -42,7 +43,7 @@ struct sgml_parser_state {
}; };
struct sgml_parser * struct sgml_parser *
init_sgml_parser(enum sgml_parser_type type, void *renderer, struct uri *uri, init_sgml_parser(enum sgml_parser_type type, void *data, struct uri *uri,
dom_stack_callback_T push_callbacks[DOM_NODES], dom_stack_callback_T push_callbacks[DOM_NODES],
dom_stack_callback_T pop_callbacks[DOM_NODES]); dom_stack_callback_T pop_callbacks[DOM_NODES]);

View File

@ -20,12 +20,6 @@ sgml_info_strcmp(const void *key_, const void *node_)
{ {
struct dom_node *key = (struct dom_node *) key_; struct dom_node *key = (struct dom_node *) key_;
struct sgml_node_info *node = (struct sgml_node_info *) node_; struct sgml_node_info *node = (struct sgml_node_info *) node_;
int length = int_min(key->length, node->length);
int string_diff = strncasecmp(key->string, node->string, length);
int length_diff = key->length - node->length;
/* If the lengths or strings don't match strncasecmp() does the job return dom_string_casecmp(&key->string, &node->string);
* else return which ever is bigger. */
return (!length_diff || string_diff) ? string_diff : length_diff;
} }

View File

@ -5,6 +5,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "document/dom/stack.h" #include "document/dom/stack.h"
#include "document/dom/string.h"
/* The flags stored in the attribute sgml node info data */ /* The flags stored in the attribute sgml node info data */
/* TODO: Other potential flags (there can be only 16) /* TODO: Other potential flags (there can be only 16)
@ -43,20 +44,21 @@ enum sgml_element_flags {
}; };
struct sgml_node_info { struct sgml_node_info {
unsigned char *string; struct dom_string string;
int length;
uint16_t type; uint16_t type;
uint16_t flags; uint16_t flags;
}; };
/* The header node is special. It is used for storing the number of nodes and
* for returning the default 'unknown' node. */
#define SGML_NODE_HEAD(doctype, nodetype) \ #define SGML_NODE_HEAD(doctype, nodetype) \
{ NULL, doctype##_##nodetype##S - 1, doctype##_##nodetype##_UNKNOWN } { INIT_DOM_STRING(NULL, doctype##_##nodetype##S - 1), doctype##_##nodetype##_UNKNOWN }
#define SGML_NODE_INFO(doctype, nodetype, name, data) \ #define SGML_NODE_INFO(doctype, nodetype, name, data) \
{ #name, sizeof(#name) - 1, doctype##_##nodetype##_##name, data } { INIT_DOM_STRING(#name, sizeof(#name) - 1), doctype##_##nodetype##_##name, data }
#define SGML_NODE_INF2(doctype, nodetype, name, ident, data) \ #define SGML_NODE_INF2(doctype, nodetype, name, ident, data) \
{ ident, sizeof(ident) - 1, doctype##_##nodetype##_##name, data } { INIT_DOM_STRING(ident, sizeof(ident) - 1), doctype##_##nodetype##_##name, data }
#define SGML_NODE_INFO_TYPE(doctype, nodetype, name) doctype##_##nodetype##_##name #define SGML_NODE_INFO_TYPE(doctype, nodetype, name) doctype##_##nodetype##_##name
@ -66,7 +68,7 @@ static inline struct sgml_node_info *
get_sgml_node_info(struct sgml_node_info list[], struct dom_node *node) get_sgml_node_info(struct sgml_node_info list[], struct dom_node *node)
{ {
struct sgml_node_info *map = &list[1]; struct sgml_node_info *map = &list[1];
size_t map_size = list->length; size_t map_size = list->string.length;
size_t obj_size = sizeof(struct sgml_node_info); size_t obj_size = sizeof(struct sgml_node_info);
void *match = bsearch(node, map, map_size, obj_size, sgml_info_strcmp); void *match = bsearch(node, map, map_size, obj_size, sgml_info_strcmp);

View File

@ -662,12 +662,10 @@ abort_all_keepalive_connections(void)
static void static void
sort_queue(void) sort_queue(void)
{ {
int swp; while (1) {
do {
struct connection *conn; struct connection *conn;
int swp = 0;
swp = 0;
foreach (conn, connection_queue) { foreach (conn, connection_queue) {
if (!list_has_next(connection_queue, conn)) break; if (!list_has_next(connection_queue, conn)) break;
@ -679,7 +677,9 @@ sort_queue(void)
swp = 1; swp = 1;
} }
} }
} while (swp);
if (!swp) break;
};
} }
static void static void

View File

@ -70,6 +70,14 @@ static struct option_info bittorrent_protocol_options[] = {
"no IP address will be sent and the tracker will automatically\n" "no IP address will be sent and the tracker will automatically\n"
"determine an appropriate IP address.")), "determine an appropriate IP address.")),
INIT_OPT_STRING("protocol.bittorrent.tracker", N_("User identification string"),
"key", 0, "",
N_("An additional identification that is not shared with any users.\n"
"It is intended to allow a client to prove their identity should\n"
"their IP address change. It is an optional parameter, but some\n"
"trackers require this parameter. If set to \"\" no user key will\n"
"be sent to the tracker.")),
INIT_OPT_INT("protocol.bittorrent.tracker", N_("Maximum number of peers to request"), INIT_OPT_INT("protocol.bittorrent.tracker", N_("Maximum number of peers to request"),
"numwant", 0, 0, INT_MAX, 50, "numwant", 0, 0, INT_MAX, 50,
N_("The maximum number of peers to request from the tracker.\n" N_("The maximum number of peers to request from the tracker.\n"

View File

@ -54,13 +54,12 @@ static void
sort_bittorrent_peer_connections(struct bittorrent_connection *bittorrent) sort_bittorrent_peer_connections(struct bittorrent_connection *bittorrent)
{ {
struct bittorrent_peer_connection *peer, *prev; struct bittorrent_peer_connection *peer, *prev;
int resort = 0;
do { while (1) {
struct bittorrent_peer_connection *next; struct bittorrent_peer_connection *next;
int resort = 0;
prev = NULL; prev = NULL;
resort = 0;
foreachsafe (peer, next, bittorrent->peers) { foreachsafe (peer, next, bittorrent->peers) {
if (prev && prev->stats.download_rate < peer->stats.download_rate) { if (prev && prev->stats.download_rate < peer->stats.download_rate) {
@ -72,7 +71,8 @@ sort_bittorrent_peer_connections(struct bittorrent_connection *bittorrent)
prev = peer; prev = peer;
} }
} while (resort); if (!resort) break;
};
#ifdef CONFIG_DEBUG #ifdef CONFIG_DEBUG
prev = NULL; prev = NULL;

View File

@ -140,7 +140,7 @@ do_send_bittorrent_tracker_request(struct connection *conn)
{ {
struct bittorrent_connection *bittorrent = conn->info; struct bittorrent_connection *bittorrent = conn->info;
int stopped = (bittorrent->tracker.event == BITTORRENT_EVENT_STOPPED); int stopped = (bittorrent->tracker.event == BITTORRENT_EVENT_STOPPED);
unsigned char *ip; unsigned char *ip, *key;
struct string request; struct string request;
struct uri *uri = NULL; struct uri *uri = NULL;
int numwant, index, min_size; int numwant, index, min_size;
@ -193,6 +193,12 @@ do_send_bittorrent_tracker_request(struct connection *conn)
/* This one is required for each request. */ /* This one is required for each request. */
add_format_to_string(&request, "&port=%u", bittorrent->port); add_format_to_string(&request, "&port=%u", bittorrent->port);
key = get_opt_str("protocol.bittorrent.tracker.key");
if (*key) {
add_to_string(&request, "&key=");
encode_uri_string(&request, key, strlen(key), 1);
}
if (bittorrent->tracker.event != BITTORRENT_EVENT_REGULAR) { if (bittorrent->tracker.event != BITTORRENT_EVENT_REGULAR) {
unsigned char *event; unsigned char *event;

View File

@ -1183,8 +1183,9 @@ setup_download_handler(struct session *ses, struct download *loading,
if (type_query) { if (type_query) {
ret = 1; ret = 1;
#ifdef CONFIG_BITTORRENT #ifdef CONFIG_BITTORRENT
if (!handler /* A terrible waste of a good MIME handler here, but we want
&& (!strcasecmp(ctype, "application/x-bittorrent") * to use the type_query this is easier. */
if ((!strcasecmp(ctype, "application/x-bittorrent")
|| !strcasecmp(ctype, "application/x-torrent")) || !strcasecmp(ctype, "application/x-torrent"))
&& !get_cmd_opt_bool("anonymous")) && !get_cmd_opt_bool("anonymous"))
query_bittorrent_dialog(type_query); query_bittorrent_dialog(type_query);

View File

@ -288,11 +288,10 @@ print_error_dialog(struct session *ses, enum connection_state state,
static void static void
abort_files_load(struct session *ses, int interrupt) abort_files_load(struct session *ses, int interrupt)
{ {
struct file_to_load *ftl; while (1) {
int more; struct file_to_load *ftl;
int more = 0;
do {
more = 0;
foreach (ftl, ses->more_files) { foreach (ftl, ses->more_files) {
if (!file_to_load_is_active(ftl)) if (!file_to_load_is_active(ftl))
continue; continue;
@ -300,7 +299,9 @@ abort_files_load(struct session *ses, int interrupt)
more = 1; more = 1;
change_connection(&ftl->download, NULL, PRI_CANCEL, interrupt); change_connection(&ftl->download, NULL, PRI_CANCEL, interrupt);
} }
} while (more);
if (!more) break;
};
} }
void void
@ -706,16 +707,16 @@ load_additional_file(struct file_to_load *ftl, struct document_view *doc_view,
void void
process_file_requests(struct session *ses) process_file_requests(struct session *ses)
{ {
struct file_to_load *ftl;
struct document_view *doc_view = NULL;
int more;
if (ses->status.processing_file_requests) return; if (ses->status.processing_file_requests) return;
ses->status.processing_file_requests = 1; ses->status.processing_file_requests = 1;
do { while (1) {
more = 0; struct file_to_load *ftl;
int more = 0;
foreach (ftl, ses->more_files) { foreach (ftl, ses->more_files) {
struct document_view *doc_view;
if (ftl->req_sent) if (ftl->req_sent)
continue; continue;
@ -725,7 +726,9 @@ process_file_requests(struct session *ses)
load_additional_file(ftl, doc_view, CACHE_MODE_NORMAL); load_additional_file(ftl, doc_view, CACHE_MODE_NORMAL);
more = 1; more = 1;
} }
} while (more);
if (!more) break;
};
ses->status.processing_file_requests = 0; ses->status.processing_file_requests = 0;
} }

View File

@ -291,7 +291,7 @@ draw_frames(struct session *ses)
{ {
struct document_view *doc_view, *current_doc_view; struct document_view *doc_view, *current_doc_view;
int *l; int *l;
int n, d, more; int n, d;
assert(ses && ses->doc_view && ses->doc_view->document); assert(ses && ses->doc_view && ses->doc_view->document);
if_assert_failed return; if_assert_failed return;
@ -308,16 +308,19 @@ draw_frames(struct session *ses)
current_doc_view = current_frame(ses); current_doc_view = current_frame(ses);
d = 0; d = 0;
do { while (1) {
more = 0; int more = 0;
foreach (doc_view, ses->scrn_frames) { foreach (doc_view, ses->scrn_frames) {
if (doc_view->depth == d) if (doc_view->depth == d)
draw_doc(ses, doc_view, doc_view == current_doc_view); draw_doc(ses, doc_view, doc_view == current_doc_view);
else if (doc_view->depth > d) else if (doc_view->depth > d)
more = 1; more = 1;
} }
if (!more) break;
d++; d++;
} while (more); };
} }
/* @rerender is ridiciously wound-up. */ /* @rerender is ridiciously wound-up. */

View File

@ -518,29 +518,32 @@ add_submitted_value_to_list(struct form_control *fc,
static void static void
sort_submitted_values(struct list_head *list) sort_submitted_values(struct list_head *list)
{ {
int changed; while (1) {
struct submitted_value *sub;
int changed = 0;
do {
struct submitted_value *sub, *next;
changed = 0;
foreach (sub, *list) if (list_has_next(*list, sub)) foreach (sub, *list) if (list_has_next(*list, sub))
if (sub->next->position < sub->position) { if (sub->next->position < sub->position) {
next = sub->next; struct submitted_value *next = sub->next;
del_from_list(sub); del_from_list(sub);
add_at_pos(next, sub); add_at_pos(next, sub);
sub = next; sub = next;
changed = 1; changed = 1;
} }
foreachback (sub, *list) if (list_has_next(*list, sub)) foreachback (sub, *list) if (list_has_next(*list, sub))
if (sub->next->position < sub->position) { if (sub->next->position < sub->position) {
next = sub->next; struct submitted_value *next = sub->next;
del_from_list(sub); del_from_list(sub);
add_at_pos(next, sub); add_at_pos(next, sub);
sub = next; sub = next;
changed = 1; changed = 1;
} }
} while (changed);
if (!changed) break;
};
} }
static void static void
@ -781,7 +784,6 @@ encode_multipart(struct session *ses, struct list_head *l, struct string *data,
if (*sv->value) { if (*sv->value) {
unsigned char *filename; unsigned char *filename;
ssize_t rd;
if (get_cmd_opt_bool("anonymous")) { if (get_cmd_opt_bool("anonymous")) {
errno = EPERM; errno = EPERM;
@ -797,14 +799,21 @@ encode_multipart(struct session *ses, struct list_head *l, struct string *data,
if (fh == -1) goto encode_error; if (fh == -1) goto encode_error;
set_bin(fh); set_bin(fh);
do { while (1) {
rd = safe_read(fh, buffer, F_BUFLEN); ssize_t rd = safe_read(fh, buffer, F_BUFLEN);
if (rd == -1) {
close(fh); if (rd) {
goto encode_error; if (rd == -1) {
close(fh);
goto encode_error;
}
add_bytes_to_string(data, buffer, rd);
} else {
break;
} }
if (rd) add_bytes_to_string(data, buffer, rd); };
} while (rd);
close(fh); close(fh);
} }
#undef F_BUFLEN #undef F_BUFLEN

View File

@ -888,10 +888,85 @@ goto_current_link(struct session *ses, struct document_view *doc_view, int do_re
return link; return link;
} }
static enum frame_event_status
activate_link(struct session *ses, struct document_view *doc_view,
struct link *link, int do_reload)
{
struct form_control *link_fc;
struct form_state *fs;
struct form *form;
switch (link->type) {
case LINK_HYPERTEXT:
case LINK_MAP:
case LINK_FIELD:
case LINK_AREA:
case LINK_BUTTON:
if (goto_current_link(ses, doc_view, do_reload))
return FRAME_EVENT_OK;
break;
case LINK_CHECKBOX:
link_fc = get_link_form_control(link);
if (form_field_is_readonly(link_fc))
return FRAME_EVENT_OK;
fs = find_form_state(doc_view, link_fc);
if (!fs) return FRAME_EVENT_OK;
if (link_fc->type == FC_CHECKBOX) {
fs->state = !fs->state;
return FRAME_EVENT_REFRESH;
}
foreach (form, doc_view->document->forms) {
struct form_control *fc;
if (form != link_fc->form)
continue;
foreach (fc, form->items) {
if (fc->type == FC_RADIO
&& !xstrcmp(fc->name, link_fc->name)) {
struct form_state *frm_st;
frm_st = find_form_state(doc_view, fc);
if (frm_st) frm_st->state = 0;
}
}
}
fs->state = 1;
break;
case LINK_SELECT:
link_fc = get_link_form_control(link);
if (form_field_is_readonly(link_fc))
return FRAME_EVENT_OK;
object_lock(doc_view->document);
add_empty_window(ses->tab->term,
(void (*)(void *)) release_document,
doc_view->document);
do_select_submenu(ses->tab->term, link_fc->menu, ses);
break;
default:
INTERNAL("bad link type %d", link->type);
}
return FRAME_EVENT_REFRESH;
}
enum frame_event_status enum frame_event_status
enter(struct session *ses, struct document_view *doc_view, int do_reload) enter(struct session *ses, struct document_view *doc_view, int do_reload)
{ {
struct form_control *link_fc; enum frame_event_status ret;
struct link *link; struct link *link;
assert(ses && doc_view && doc_view->vs && doc_view->document); assert(ses && doc_view && doc_view->vs && doc_view->document);
@ -900,69 +975,12 @@ enter(struct session *ses, struct document_view *doc_view, int do_reload)
link = get_current_link(doc_view); link = get_current_link(doc_view);
if (!link) return FRAME_EVENT_REFRESH; if (!link) return FRAME_EVENT_REFRESH;
if (!link_is_form(link) ret = activate_link(ses, doc_view, link, do_reload);
|| link_is_textinput(link) if (ret != FRAME_EVENT_IGNORED)
|| link->type == LINK_BUTTON) {
if (!current_link_evhook(doc_view, SEVHOOK_ONCLICK)) if (!current_link_evhook(doc_view, SEVHOOK_ONCLICK))
return FRAME_EVENT_REFRESH; return FRAME_EVENT_REFRESH;
if (goto_current_link(ses, doc_view, do_reload)) return ret;
return FRAME_EVENT_OK;
return FRAME_EVENT_REFRESH;
}
link_fc = get_link_form_control(link);
if (form_field_is_readonly(link_fc))
return FRAME_EVENT_OK;
if (link->type == LINK_CHECKBOX) {
struct form_state *fs;
fs = find_form_state(doc_view, link_fc);
if (!fs) return FRAME_EVENT_OK;
if (link_fc->type == FC_CHECKBOX) {
fs->state = !fs->state;
} else {
struct form *form;
foreach (form, doc_view->document->forms) {
struct form_control *fc;
if (form != link_fc->form)
continue;
foreach (fc, form->items) {
if (fc->type == FC_RADIO
&& !xstrcmp(fc->name, link_fc->name)) {
struct form_state *frm_st;
frm_st = find_form_state(doc_view, fc);
if (frm_st) frm_st->state = 0;
}
}
}
fs->state = 1;
}
} else if (link->type == LINK_SELECT) {
object_lock(doc_view->document);
add_empty_window(ses->tab->term,
(void (*)(void *)) release_document,
doc_view->document);
do_select_submenu(ses->tab->term, link_fc->menu, ses);
} else {
INTERNAL("bad link type %d", link->type);
}
if (!current_link_evhook(doc_view, SEVHOOK_ONCLICK))
return FRAME_EVENT_REFRESH;
return FRAME_EVENT_REFRESH;
} }
struct link * struct link *
@ -1269,11 +1287,7 @@ get_current_link_info(struct session *ses, struct document_view *doc_view)
/* TODO: Provide info about script event hooks too. --pasky */ /* TODO: Provide info about script event hooks too. --pasky */
if (link_is_form(link)) { if (!link_is_form(link)) {
if (!get_link_form_control(link)) return NULL;
return get_form_info(ses, doc_view);
} else {
struct terminal *term = ses->tab->term; struct terminal *term = ses->tab->term;
struct string str; struct string str;
unsigned char *uristring = link->where; unsigned char *uristring = link->where;
@ -1302,4 +1316,8 @@ get_current_link_info(struct session *ses, struct document_view *doc_view)
decode_uri_string_for_display(&str); decode_uri_string_for_display(&str);
return str.source; return str.source;
} }
if (!get_link_form_control(link)) return NULL;
return get_form_info(ses, doc_view);
} }

View File

@ -1185,22 +1185,23 @@ quit:
void void
send_event(struct session *ses, struct term_event *ev) send_event(struct session *ses, struct term_event *ev)
{ {
struct document_view *doc_view;
assert(ses && ev); assert(ses && ev);
if_assert_failed return; if_assert_failed return;
doc_view = current_frame(ses);
if (ev->ev == EVENT_KBD) { if (ev->ev == EVENT_KBD) {
struct document_view *doc_view = current_frame(ses);
ses = send_kbd_event(ses, doc_view, ev); ses = send_kbd_event(ses, doc_view, ev);
} }
#ifdef CONFIG_MOUSE #ifdef CONFIG_MOUSE
if (ev->ev == EVENT_MOUSE) { else if (ev->ev == EVENT_MOUSE) {
struct document_view *doc_view = current_frame(ses);
ses = send_mouse_event(ses, doc_view, ev); ses = send_mouse_event(ses, doc_view, ev);
} }
#endif /* CONFIG_MOUSE */ #endif /* CONFIG_MOUSE */
/* ses may disappear ie. in close_tab() */ /* @ses may disappear ie. in close_tab() */
if (ses) ses->kbdprefix.repeat_count = 0; if (ses) ses->kbdprefix.repeat_count = 0;
} }