Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[GNU readline] Entrées multilignes

4 réponses
Avatar
JKB
Bonjour à tous,

Pardonnez-moi de légèrement dépasser le périmètre du groupe. Je
poste ici parce que je pense que d'autres que moi se sont déjà posés
la question.

J'utilise readline (6.2) dans un bout de code écrit en C et je dois
traiter des entrées multilignes. J'ai donc suivi la documentation de
readline() et écrit :

ancien_keymap = rl_get_keymap();
nouveau_keymap = rl_copy_keymap(ancien_keymap);
rl_set_keymap(nouveau_keymap);

rl_bind_key(NEWLINE, readline_analyse_syntaxique);
rl_bind_key(RETURN, readline_analyse_syntaxique);
rl_done = 0;

ligne = readline("1> ");

rl_set_keymap(ancien_keymap);
rl_free(nouveau_keymap);

La fonction readline_analyse_syntaxique set la suivante :

int
readline_analyse_syntaxique(int count, int key)
{
if ((*rl_line_buffer) == 0)
{
rl_done = 1;
}
else
{
if (analyse_syntaxique(<snip>) == 0)
{
rl_done = 1;
}
else
{
rl_done = 0;
rl_mark = rl_end;
rl_crlf();
rl_expand_prompt("2> ");
rl_on_new_line();
}
}

if (rl_done != 0)
{
printf("\n");
}

return(0);
}

Cela fonctionne presque :

1> [
2> [ 1 ]
1>

En effet, '[' est pour l'outil une entrée non conforme donc un
retour à la ligne est requis pour compléter l'entrée. '[ 1 ]' est
conforme et readline() rend la main au programme appelant.

Mon problème est tout bête et je n'ai strictement rien vu dans la
doc pour le régler. Je voudrais éviter que le contenu du buffer soit
réafficher lors du passage à la ligne :

1> [
2> 1 ]
1>

psql fonctionne comme cela. Je viens de regarder le code, mais je ne
vois pas comment est faite la manipulation.

Merci pour toute lumière...

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr

4 réponses

Avatar
Damien Wyart
* JKB in fr.comp.lang.c:
Mon problème est tout bête et je n'ai strictement rien vu dans la doc
pour le régler. Je voudrais éviter que le contenu du buffer soit
réafficher lors du passage à la ligne :

1> [
2> 1 ]
1>

psql fonctionne comme cela. Je viens de regarder le code, mais je ne
vois pas comment est faite la manipulation.



Il faudrait sans doute surcharger rl_redisplay mais je pense que ça n'en
vaut pas la peine...

En général, les programmes appellent readline() pour lire une ligne,
puis font un traitement dessus, et si la saisie n'est pas terminée,
rappellent readline, etc. Et la saisie finale est obtenue par
concaténation des lignes traitées au fur et à mesure.

C'est ce que fait psql, par exemple ; pour les shells, ça doit être
similaire (là, le code est beaucoup plus difficile à lire).

Dans ton exemple, plutôt de de changer le prompt et de passer à la
ligne, tu pourrais rappeler readline avec le prompt de 2e niveau, puis
concaténer les deux saisies.
--
DW
Avatar
JKB
Le Thu, 26 Jan 2012 15:58:51 +0100,
Damien Wyart écrivait :
* JKB in fr.comp.lang.c:
Mon problème est tout bête et je n'ai strictement rien vu dans la doc
pour le régler. Je voudrais éviter que le contenu du buffer soit
réafficher lors du passage à la ligne :



1> [
2> 1 ]
1>



psql fonctionne comme cela. Je viens de regarder le code, mais je ne
vois pas comment est faite la manipulation.



Il faudrait sans doute surcharger rl_redisplay mais je pense que ça n'en
vaut pas la peine...

En général, les programmes appellent readline() pour lire une ligne,
puis font un traitement dessus, et si la saisie n'est pas terminée,
rappellent readline, etc. Et la saisie finale est obtenue par
concaténation des lignes traitées au fur et à mesure.

C'est ce que fait psql, par exemple ; pour les shells, ça doit être
similaire (là, le code est beaucoup plus difficile à lire).

Dans ton exemple, plutôt de de changer le prompt et de passer à la
ligne, tu pourrais rappeler readline avec le prompt de 2e niveau, puis
concaténer les deux saisies.



Dans mon cas (et pour des raisons trop longues à expliquer ici), ce
n'est pas possible... Et justement, j'aurais bien aimé ne pas avoir
à surcharger rl_redisplay. Je pensais bêtement qu'il y avait un truc
pour dire à redisplay de ne commencer l'affichage qu'au n-ieme
caractère (en positionnant rl_mark par exemple).

Cordialement,

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr
Avatar
Lucas Levrel
Le 26 janvier 2012, JKB a écrit :
Dans mon cas (et pour des raisons trop longues à expliquer ici), ce
n'est pas possible... Et justement, j'aurais bien aimé ne pas avoir
à surcharger rl_redisplay.



Si tu peux manipuler rl_line_buffer, une bidouille consisterait à lui
ajouter des backspaces dans le else interne (et les enlever dans
analyse_syntaxique())...


--
LL
Avatar
JKB
Le Fri, 27 Jan 2012 09:50:11 +0100,
Lucas Levrel écrivait :
Le 26 janvier 2012, JKB a écrit :
Dans mon cas (et pour des raisons trop longues à expliquer ici), ce
n'est pas possible... Et justement, j'aurais bien aimé ne pas avoir
à surcharger rl_redisplay.



Si tu peux manipuler rl_line_buffer, une bidouille consisterait à lui
ajouter des backspaces dans le else interne (et les enlever dans
analyse_syntaxique())...



Ça, je peux le faire. Enfin, je vais essayer ;-)

Cordialement,

JKB

--
Si votre demande me parvient sur carte perforée, je titiouaillerai très
volontiers une réponse...
=> http://grincheux.de-charybde-en-scylla.fr