tester si une fonction existe dans giac
Modérateur : xcasadmin
tester si une fonction existe dans giac
Bonjour Bernard,
dans mon extension pour OOo-Writer, je me suis fabriqué une fonction qui teste si la fonction tapée dans le traitement de texte est une fonction giac pour éventuellement l'évaluer.
Ce que j'ai fait n'est pas très joli :
j'envoie à giac l'instruction "?ma_fonction" et je teste si le retour contient "no help"
Ca fonctionne bien mais je viens de me rendre compte que j'ai un soucis avec, par exemple, la fonction forme_canonique.
Dans mon extension OOo, cette fonction n'existe pas alors que j'utilise la version 0.8.6 de libgiac.
Or mon xcas sur le même ubuntu est aussi en version 0.8.6 et connaît forme_canonique. Bizarre...
Dans le fichier usr share giac aide_cas effectivement, pas de trace de forme_canonique
Où va chercher Xcas ?
Je m'y perds un peu...
Autrement, vois-tu un moyen plus élégant de tester si une fonction existe ou non dans Giac ?
A bientôt.
dans mon extension pour OOo-Writer, je me suis fabriqué une fonction qui teste si la fonction tapée dans le traitement de texte est une fonction giac pour éventuellement l'évaluer.
Ce que j'ai fait n'est pas très joli :
j'envoie à giac l'instruction "?ma_fonction" et je teste si le retour contient "no help"
Ca fonctionne bien mais je viens de me rendre compte que j'ai un soucis avec, par exemple, la fonction forme_canonique.
Dans mon extension OOo, cette fonction n'existe pas alors que j'utilise la version 0.8.6 de libgiac.
Or mon xcas sur le même ubuntu est aussi en version 0.8.6 et connaît forme_canonique. Bizarre...
Dans le fichier usr share giac aide_cas effectivement, pas de trace de forme_canonique
Où va chercher Xcas ?
Je m'y perds un peu...
Autrement, vois-tu un moyen plus élégant de tester si une fonction existe ou non dans Giac ?
A bientôt.
Re: tester si une fonction existe dans giac
Salut!
Toutes les fonctions de xcas ne sont pas forcément commentées dans l'aide, et en plus il faut tenir compte des traductions de commandes (dans le fichier keywords de $SHARE/doc/fr). Je pense qu'il serait plus judicieux de parser le nom de commande entre quotes et de voir si c'est un gen de type _FUNC, un truc du genre
gen g("'"+nom_de_commande+"'",contextptr);
if (g.type==_FUNC){ ... }
Sinon, tu peux aussi te baser (à la compilation) sur le fichier static_lexer.h.
Toutes les fonctions de xcas ne sont pas forcément commentées dans l'aide, et en plus il faut tenir compte des traductions de commandes (dans le fichier keywords de $SHARE/doc/fr). Je pense qu'il serait plus judicieux de parser le nom de commande entre quotes et de voir si c'est un gen de type _FUNC, un truc du genre
gen g("'"+nom_de_commande+"'",contextptr);
if (g.type==_FUNC){ ... }
Sinon, tu peux aussi te baser (à la compilation) sur le fichier static_lexer.h.
Re: tester si une fonction existe dans giac
salut,
effectivement, je n'avais pas pensé à utiliser la fonction type(). ça marche parfaitement : J'envoie à partir de OOo-basic l'instruction giac "type(ma_fonction)" et je récupère l'entier correspondant.
C'est parfait car ça marche aussi pour les fonctions définies par l'utilisateur, je vais pouvoir simplifier mon code.
En ce qui concerne les traductions, je comprends maintenant pourquoi ma librairie giac ne reconnaît pas "forme_canonique" dans OOo : je n'ai pas tenu compte du fichier keywords.
Pour les aides, j'appelle giac::readhelp en lui fournissant le fichier aide_cas.
Existe-t-il l'équivalent de giac::readhelp pour les traductions ?
merci et bon week end
effectivement, je n'avais pas pensé à utiliser la fonction type(). ça marche parfaitement : J'envoie à partir de OOo-basic l'instruction giac "type(ma_fonction)" et je récupère l'entier correspondant.
C'est parfait car ça marche aussi pour les fonctions définies par l'utilisateur, je vais pouvoir simplifier mon code.
En ce qui concerne les traductions, je comprends maintenant pourquoi ma librairie giac ne reconnaît pas "forme_canonique" dans OOo : je n'ai pas tenu compte du fichier keywords.
Pour les aides, j'appelle giac::readhelp en lui fournissant le fichier aide_cas.
Existe-t-il l'équivalent de giac::readhelp pour les traductions ?
merci et bon week end
Re: tester si une fonction existe dans giac
La fonction set_language permet de changer de langue (1 pour le français). Tu peux regarder dans global.cc comment elle fonctionne, en particulier pour l'aide on peut ajouter des aides localisées pour les commandes (et il rajoute des synonymes aux noms de commande existant).
Re: tester si une fonction existe dans giac
ok, j'ai trouvé le code qui m'intéresse. Mais il va falloir que je le modifie car le fichier keywords doit être situé dans mon extension, donc pas à l'endroit habituel pour giac.
J'avais déjà fait le boulot pour les aides, uniquement en fr pour l'instant il est vrai mais je saurais localiser facilement à partir de mon code en basic puisque je fournis le chemin de aide_cas en argument à ma fonction c++, ce qui me permet de le mettre ou je veux dans mon extension :
il me reste à faire le même travail pour les synonymes.
Si je ne fais pas d'erreur, ça se situe dans le code ci-dessous, au paragraphe "add synonyms" :
mais ça ne semble pas aussi simple que le readhelp. Il va falloir que je trie en espérant que ça se compile bien dans mon extension. Je vais tenter le coup dès que j'ai un peu de temps libre. J'y tiens parce que, pour le moment, je ne peux pas appeler de fonctions telles que "forme_canonique", "cercle", "droite"... dans le traitement de texte.
Je te tiens au courant. A+
J'avais déjà fait le boulot pour les aides, uniquement en fr pour l'instant il est vrai mais je saurais localiser facilement à partir de mon code en basic puisque je fournis le chemin de aide_cas en argument à ma fonction c++, ce qui me permet de le mettre ou je veux dans mon extension :
Code : Tout sélectionner
// fonctionnement interne à OOoBasic : permet d'initialiser l'aide "?command"
// dans la boite de dialogue CAS.
if (!helpitems){
OUString chemin;
aValList[0] >>= chemin;
std::string helpfile=string(OUStringToOString(chemin,RTL_TEXTENCODING_UTF8));
(*giac::vector_aide_ptr)=giac::readhelp(helpfile.c_str(),(int&) helpitems);
}
Si je ne fais pas d'erreur, ça se situe dans le code ci-dessous, au paragraphe "add synonyms" :
Code : Tout sélectionner
void add_language(int i){
if (!equalposcomp(lexer_localization_vector,i)){
lexer_localization_vector.push_back(i);
update_lexer_localization(lexer_localization_vector,lexer_localization_map(),back_lexer_localization_map);
if (vector_aide_ptr){
// add locale command description
int count;
string filename=giac_aide_dir()+find_doc_prefix(i)+"aide_cas";
readhelp(*vector_aide_ptr,filename.c_str(),count,true);
// add synonyms
multimap<string,localized_string>::iterator it,backend=back_lexer_localization_map.end(),itend;
vector<aide>::iterator jt = vector_aide_ptr->begin(),jtend=vector_aide_ptr->end();
for (;jt!=jtend;++jt){
it=back_lexer_localization_map.find(jt->cmd_name);
itend=back_lexer_localization_map.upper_bound(jt->cmd_name);
if (it!=backend){
for (;it!=itend;++it){
if (it->second.language==i)
jt->synonymes.push_back(it->second);
}
}
}
int s = vector_aide_ptr->size();
for (int j=0;j<s;++j){
aide a=(*vector_aide_ptr)[j];
it=back_lexer_localization_map.find(a.cmd_name);
itend=back_lexer_localization_map.upper_bound(a.cmd_name);
if (it!=backend){
for (;it!=itend;++it){
if (it->second.language==i){
a.cmd_name=it->second.chaine;
a.language=it->second.language;
vector_aide_ptr->push_back(a);
}
}
}
}
cerr << "Added " << vector_aide_ptr->size()-s << " synonyms" << endl;
sort(vector_aide_ptr->begin(),vector_aide_ptr->end(),alpha_order);
update_completions();
}
}
}
Je te tiens au courant. A+
Re: tester si une fonction existe dans giac
ça y est j'ai réussi à définir les synonymes dans mon extension :
j'ai ajouté un :
puis repris le code de global.cc/void add_language
j'ai simplement court-circuité la fonction update_lexer_localization pour une autre que j'ai créée et insérée dans mon code afin de tenir compte du chemin d'accès au fichier keywords dans mon extension.
Je n'ai pas complètement fini la localisation du code, mais avant je voulais régler mon problème de la localisation des aides. Je l'ai depuis toujours, avant l'ajout des synonymes mais je ne m'en étais pas occupé. Tu peux voir sur la copie d'écran que les aides sont toujours en anglais. Là je sèche.
Voilà mon code :
A+
pour info, ça peut servir à d'autres :j'ai ajouté un :
Code : Tout sélectionner
#include <giac/input_lexer.h>
j'ai simplement court-circuité la fonction update_lexer_localization pour une autre que j'ai créée et insérée dans mon code afin de tenir compte du chemin d'accès au fichier keywords dans mon extension.
Je n'ai pas complètement fini la localisation du code, mais avant je voulais régler mon problème de la localisation des aides. Je l'ai depuis toujours, avant l'ajout des synonymes mais je ne m'en étais pas occupé. Tu peux voir sur la copie d'écran que les aides sont toujours en anglais. Là je sèche.
Voilà mon code :
Code : Tout sélectionner
Sequence< Sequence< Any > > CASImpl::cas1(const Sequence< Any > &aValList)
throw (RuntimeException)
{
// fonctionnement interne à OOoBasic : permet d'initialiser l'aide "?command"
// dans la boite de dialogue CAS.
if (!nbAides){
OUString chemin;
aValList[0] >>= chemin;
OUString language;
aValList[1] >>= language;
OUString cheminAides;
OUString cheminSynonymes;
cheminAides=chemin+OUString::createFromAscii("aide_cas");
cheminSynonymes=chemin+language+OUString::createFromAscii("/keywords");
std::string helpFile=string(OUStringToOString(cheminAides,RTL_TEXTENCODING_UTF8));
std::string synonymsFile=string(OUStringToOString(cheminSynonymes,RTL_TEXTENCODING_UTF8));
// ajoute les synonymes, code de giac/global.cc/add_language modifié ligne 2190
// pour les lexer, reprise du code de giac/input_lexer.cc ligne 7848
lexer_localization_vector.push_back(1); // 1 pour fr, todo : tenir compte de "language"
// fonction suivante modifiée pour tenir compte du chemin d'accès de keywords dans l'extension OOo
cmath_update_lexer_localization(lexer_localization_vector,lexer_localization_map(),back_lexer_localization_map, synonymsFile);
// ajoute les aides
giac::readhelp(*vector_aide_ptr,helpFile.c_str(),(int&) nbAides,true);
// (*giac::vector_aide_ptr)=giac::readhelp(helpFile.c_str(),(int&) nbAides);
if (vector_aide_ptr){
// add locale command description
// int count;
// string filename=giac_aide_dir()+find_doc_prefix(i)+"aide_cas";
// readhelp(*vector_aide_ptr,filename.c_str(),count,true);
// add synonyms
multimap<string,localized_string>::iterator it,backend=back_lexer_localization_map.end(),itend;
vector<aide>::iterator jt = vector_aide_ptr->begin(),jtend=vector_aide_ptr->end();
for (;jt!=jtend;++jt){
it=back_lexer_localization_map.find(jt->cmd_name);
itend=back_lexer_localization_map.upper_bound(jt->cmd_name);
if (it!=backend){
for (;it!=itend;++it){
if (it->second.language==1)
jt->synonymes.push_back(it->second);
}
}
}
sal_Int32 s = vector_aide_ptr->size();
for (sal_Int32 j=0;j<s;++j){
aide a=(*vector_aide_ptr)[j];
it=back_lexer_localization_map.find(a.cmd_name);
itend=back_lexer_localization_map.upper_bound(a.cmd_name);
if (it!=backend){
for (;it!=itend;++it){
if (it->second.language==1){
a.cmd_name=it->second.chaine;
a.language=it->second.language;
vector_aide_ptr->push_back(a);
}
}
}
}
nbSynonymes=vector_aide_ptr->size()-s;
// cerr << "Added " << vector_aide_ptr->size()-s << " synonyms" << endl;
// sort(vector_aide_ptr->begin(),vector_aide_ptr->end(),alpha_order);
// update_completions();
}
}
OUString sNbAides;
OUString sNbSynonymes;
sNbAides=OUString::valueOf(nbAides);
sNbSynonymes=OUString::valueOf(nbSynonymes);
Sequence< Any > solList1D(2);
Sequence< Sequence< Any > > solList2D(1);
solList1D[0]=makeAny(sNbAides);
solList1D[1]=makeAny(sNbSynonymes);
solList2D[0]=solList1D;
return solList2D;
}
Re: tester si une fonction existe dans giac
Pour l'affichage de l'aide, tu peux appeler writehelp(helpon(...)), ou regarder comment fonctionne _findhelp dans prog.cc (voire directement appeler _findhelp(string2gen("nom_de_commande",false)),contextptr)),
Re: tester si une fonction existe dans giac
c'est bon, j'avais juste oublié de définir la variable globale "language" avec :
il ne me restait plus que le problème de l'encodage :
je me suis rendu compte que je ne convertissais pas en utf8 les sorties de giac qui venait de e.print(contextptr).c_str(). Une fonction fournie par OOo fait ça très bien. Maintenant c'est bon, l'aide est correcte dans OOo.
merci encore.
Code : Tout sélectionner
giac::language(1,contextptr);
merci encore.