|
L'équipe progG de Ti-Fr
|
Voici les nicks de vos serviteurs ;-)
chickensaver_john
Kevin Kofler
Thibaut
janjan2
TiMad
Iceman89
fréka
Zewoo
Squale92
Verstand
ZdRUbAl
UtOpIaH
et nEUrOne ...
|
|
Une idée ?
|
Une idée pour améliorez cette partie?
ou tout simplement vous souhaitez participer à l'élaborations
des tutos.
Mailez-nous ici
|
| |
Chapitre
X
Manipuler la VAT (Variable Allocation Table,
ou Table d'Allocation de Variables, qui équivaut à la FAT sur PC) est une
chose plus complexe à réaliser que tout ce que nous avons jusqu'à présent
réalisé.
Malgré tous mes efforts, il est possible que ce chapitre
contienne encore des erreurs. Dans ce cas, ça serait sympa de votre part de m'envoyer
un mail, afin que je puisse les corriger, pour que ce tutorial vous permette
(ou aux suivants !) de comprendre ces manipulations.
Dans ce chapitre, nous allons essayer de
comprendre les manipulations de base de la VAT. Cependant, avant que vous ne
commenciez à la lire, je tiens à vous prévenir que c'est loin d'être simple,
et que des erreurs ont pu être commises... Comme toujours, je ne peux donc que
vous recommander fortement de tester vos programmes sur VTI avant de les essayer
sur votre véritable TI !
Le meilleur exemple qui puisse correspondre à ce Chapitre
serait un Explorer. J'ai commencé à en écrire un dans ce but.
Sinon, si vous vous sentez prêt à étudier un source plus
"professionnel" que le mien, vous pouvez télécharger l'explorer de
la TICT, qui est open-source.
Nous avons vu au chapitre précédent les boucles de
récupération d'erreurs. J'espère que vous vous en souvenez, parce qu'elles
seront utiles ici. En effet, je vous conseille d'en faire bon usage : par
exemple, si vous essayez de cacher un répertoire, alors qu'il n'existe pas,
vous aurez de fortes chances de voir se produire une "Protected Memory
Violation". Cela est aussi possible avec d'autres fonctions...
Avant de commencer :
Pour les manipulations de noms de variables,
ou de répertoires, nous ne pourrons généralement pas utiliser de chaînes de
caractères "normales", du type "nom_de_variable". En
fait, les chaînes de caractères utilisées pour les manipulations de la VAT
sont du type "\0nom_de_variable"+taille_du_nom_en_caractères.
Compliqué, n'est-ce pas. heureusement, nous n'aurons pas à utiliser cette
écriture désagréable : nous pourrons l'éviter grâce à ce qui est appelé
macro constructeur dans la documentation de TIGCC. Au lieu d'écrire "\0nom_de_variable"+taille_du_nom_en_caractères,
nous écrirons tout simplement $(nom_de_variable).
Cette écriture est beaucoup plus simple à mettre en oeuvre, et donc moins
difficile à retenir !
Cependant, utiliser cette macro constructeur ne permet pas
d'utiliser des noms de variables définis au cours de l'exécution du programme.
Il faudra utiliser une astuce, c'est-à-dire cette portion de code :
char TIOSname[10];
TIOSname[0]
= ;
intruction(strcpy(TIOSname+,
str_qui_contient_le_nom_de_la_var) + strlen(str_qui_contient_le_nom_de_la_var));
Il existe deux types de pointeurs vers des variables :
ceux de type HSym, et ceux de type SYM_ENTRY.
Dans ce Chapitre, nous serons amenés à traiter des deux types, et même, plus
souvent, à "jongler" avec l'un et l'autre. Il est possible que cela
paraisse un peu "déboussolant", mais vous vous y ferez, n'ayez
crainte...
Tout de même, je vous conseille d'utiliser le plus souvent
possible les pointeurs de type SYM_ENTRY,
car ce sont eux qui apportent le plus d'informations sur la variable.
Si vous voulez quelques informations supplémentaires à ce
sujet, vous pouvez aller lire CE
topic de la FAQ de notre Tutorial...
Encore une chose : dans la documentation de TIGCC, vous
pourrez trouver quelques fonctions concernant des répertoires temporaires. Nous
n'en ferons pas mention ici, car je pense que ce qui vous intéresse en premier
lieu est la partie de la VAT où le TIOS stocke les variables permanentes (Les
répertoires temporaires servent, par exemple, à stocker les variables locales
des programmes en TI-BASIC).
Table des matières :
I:\ Manipulations
de répertoires
A:
Pointeur vers un nom de
répertoire
B:
Manipulations diverses
II:\ Manipulations
de variables
A:
Pointeur de type HSym
B:
Pointeur de type SYM_ENTRY
C:
Cacher ou verrouiller des
variables
D:
Manipulations diverses
III:\ Rechercher
des variables (et des répertoires)
I:\ Manipulations
de répertoires :
A:
Pointeurs vers un
nom de répertoire :
Il est possible d'obtenir un pointeur de type
HSym vers un nom de répertoire en
utilisant la fonction
SymFindHome($(nom_du_répertoire));
Cette fonction cherche dans la partie de la VAT qui
concerne les répertoires.
Il est ensuite possible de transformer ce
pointeur de type HSym en pointeur de
type SYM_ENTRY en utilisant la fonction
DerefSym. En fait, si vous voulez
obtenir ce type de pointeur, vous pouvez directement faire :
DerefSym(SymFindHome($(nom_du_répertoire)));
Vous obtenez ainsi un pointeur de type SYM_ENTRY
vers le nom du répertoire.
Vous avez sans doute déjà utilisé le menu
VAR-LINK de votre TI pour verrouiller un répertoire. Eh bien, cette
manipulation est possible à partir d'un programme écrit en C, à partir
de la suite de fonctions que nous venons d'étudier. pour cela, il faut
effectuer l'opération suivante :
DerefSym(SymFindHome($(nom_du_répertoire)))->flags.bits.locked=1;
Cette série d'instructions fait passer l'état du bit
marquant si le répertoire est verrouillé ou non à 1, au lieu de 0 quand il
n'est pas verrouillé.
Vous qui êtes en train d'apprendre le C
avez sûrement aussi déjà utilisé une fonction incluse dans la plus grande
partie des Explorers actuels, celle qui permet de cacher des variables, ou
plutôt des répertoires dans le cas qui nous intéresse, afin qu'ils
n'apparaissent plus dans le menu VAR-LINK. Pour faire cela, il faut utiliser une
commande qui fera passer à 1 le bit marquant si le répertoire est caché ou
non. Pour cela, on utilisera :
DerefSym(SymFindHome($(nom_du_répertoire)))->flags.bits.hidden=1;
Si, pour une raison quelconque (par exemple,
vous en avez besoin pour une autre fonction), vous souhaitez conserver le
pointeur de type HSym, mais que vous
avez quand même besoin de celui de type SYM_ENTRY,
vous pouvez utiliser ceci :
ptrhsym = SymFindHome($(nom_du_répertoire));
ptrsymentry = DerefSym(ptrhsym);
B:
Manipulations diverses
sur les répertoires :
1:
Changer de répertoire courrant
:
Nous allons commencer ce chapitre par cette manipulation,
qui est simple. Pour la mettre en oeuvre, il faut utiliser la fonction suivante
:
FolderCur($(nom_du_répertoire),FALSE);
Cette fonction permet de changer de répertoire
courrant, mais elle ne change pas le nom de répertoire affiché dans la Status
line. Si vous voulez changer cet affichage, il vous faudra utiliser :
ST_folder("nom_du_répertoire"); //
Attention, ici, c'est une chaîne de caractères normale qu'il convient
d'utiliser, au contraire des autres instructions de ce chapitre !
2:
Nombre de variables dans un répertoire :
Pour connaître le nombre de variables contenues dans un
répertoire, il faut utiliser l'instruction :
FolderCount(DerefSym(SymFindHome($(nom_du_répertoire))));
Cette fonction renvoie un nombre de type
unsigned short.
Donc, il sera possible de faire :
unsigned
short nbr_var = 0;
nbr_var = FolderCount(DerefSym(SymFindHome($(nom_du_répertoire))));
3:
Créer un répertoire :
Pour créer un répertoire, il faut utiliser la commande :
FolderAdd($(nom_du_répertoire));
Attention, contrairement au TI-BASIC, quand on
crée un répertoire à partir du C, celui-ci ne devient pas le
répertoire courrant !!! Si nom_du_répertoire est plus long que 8
caractères, il est tronqué.
Cette fonction renvoie une valeur de type HANDLE.
Elle pourra valoir H_NULL en cas
d'erreur (par exemple, si le répertoire existe déjà, ou alors si vous avez
essayé de créer un répertoire ayant pour premier caractère un chiffre.).
Dans le cas contraire, ce HANDLE
pointera vers la partie de la VAT qui correspond au répertoire.
4:
Effacer un répertoire :
Pour effacer un répertoire, il faut utiliser la commande :
FolderDel($(nom_du_répertoire));
Cette fonction renvoie un short,
qui a pour valeur TRUE si le
répertoire a été effacé, et FALSE
s'il ne l'a pas été, pour une cause quelconque. Attention, si le répertoire
contient des variables, elles sont aussi effacées. (Contrairement au TI-BASIC,
où un répertoire ne peut être effacé que s'il est vide !). Le répertoire
est effacé, même s'il est verrouillé (encore une fois, contrairement au TI-BASIC
!)
Donc, pensez à utiliser une sécurité (par exemple en
vérifiant que le répertoire est vide) avant d'utiliser cette commande...
5:
Renommer un répertoire :
Pour renommer un répertoire, il faut utiliser l'instruction
suivante :
FolderRename($(nom_d'origine), $(nom_d'arrivée));
Cette fonction renvoie un short,
qui a pour valeur TRUE si le
répertoire a été renommé, et FALSE
s'il ne l'a pas été (par exemple, s'il n'existe pas). Il est possible de
changer le nom du répertoire même s'il contient des variables, mais aussi s'il
est verrouillé (dans ce cas, le répertoire d'arrivée sera lui aussi
verrouillé !).
6:
Déterminer le répertoire courrant et changer de répertoire :
L'instruction FolderGetCur(str);
permet de déterminer le répertoire courrant de la TI, qu'il sera par la suite
possible de restaurer avec l'instruction FolDerCur($(str),
TRUE);
Nous allons illustrer ceci par un exemple : voici comment
mémoriser le répertoire courrant, par exemple au lancement d'un programme
char
TIOSname[10];
char
rep_courrant[10];
FolderGetCur(rep_courrant);
Par la suite, il sera possible de remettre ce
répertoire en répertoire courrant, en effectuant cette instruction, par
exemple à la fin du programme :
TIOSname[0]=0;
FolderCur(strcpy(TIOSname+1, rep_courrant)
+ strlen(rep_courrant),
TRUE);
II:\ Manipulations
de variables :
Nous venons de voir comment fonctionnent les
manipulations de bases que l'on peut faire sur les répertoires. Eh bien, il est
possible de faire les mêmes choses, ou presque, pour les variables.
A: Obtenir
un pointeur de type HSym vers une variable
:
La différence majeure qu'ils existe entre les variables
et les répertoire est que les variables sont dans les répertoires, et, de
plus, il est possible d'avoir plusieurs fois le même nom de variable, dans
plusieurs répertoires.
Si on veut obtenir un pointeur de type HSym
vers une variable, mais que l'on sait que celle-ci est dans le répertoire
courrant (par exemple, si on a utilisé FolderCur
pour changer de répertoire auparavant), il est possible d'utiliser
l'instruction :
SymFind($(nom_de_variable));
Si l'on veut chercher dans un répertoire
précis, que ce soit ou non le répertoire courrant, on a deux possibilités :
* Utiliser SymFind($(nom_rep\\nom_var));
// Attention, il faut
mettre deux fois le symbole "\"
* Soit utiliser FindSymInFolder($(nom_var),
$(nom_rep));
Le résultat que l'on obtient avec ces deux fonctions est le
même. Vous pouvez donc choisir celle que vous préférez, selon sa syntaxe...
B:
Obtenir un pointeur de type SYM_ENTRY
vers une variable :
Il existe deux façons d'obtenir ce type de pointeur vers une
variable :
* Le première consiste à utiliser DerefSym,
comme nous le faisions pour les répertoires. On aura quelque chose du type :
DerefSym(SymFind($(nom_de_variable)));
* Le seconde consiste à utiliser une fonction de TIGCC, faite
pour cela. sa syntaxe est :
SymFindPtr($(nom_rep\\nom_var), 0);
Encore une fois, vous avez le choix entre deux
instruction... La première a l'avantage de ressembler à celle qui est
utilisée pour les noms de répertoires, et la seconde a l'avantage d'être plus
courte...
De la même façon que pour les noms de
répertoires, vous pouvez conserver le pointeur de type HSym
quand vous souhaitez en obtenir un de type SYM_ENTRY.
C: Cacher
ou verrouiller des variables :
Pour verrouiller ou cacher des variables, vous pouvez
effectuer les mêmes opérations que pour les répertoires, en n'oubliant pas de
changer l'instruction SymFindHome en SymFind,
puisqu'il ne s'agit plus de répertoires, mais de variables.
D: Manipulations
diverses sur les variables :
1:
Pour Copier une variable d'un répertoire vers un autre, en changeant
éventuellement son nom en même temps, il n'existe malheureusement pas encore
de fonction de TIGCC qui soit bien adaptée. En effet, les instructions de la
VAT qui s'en rapprochent le plus ne font rien de plus que copier le nom de la
variable. il faut ensuite copier son contenu. Dans la FAQ de TIGCC, Zeljko Juric
propose d'utiliser la fonction cmd_copyvar
du fichier <unknown.h>. Je n'ai pas réussi à utiliser cette fonction de
façon convenable. (je n'ai pas beaucoup cherché !). Donc, pour copier une
variable, je fais appel à la fonction utilisée en TI-BASIC, par ceci :
HANDLE copie;
push_parse_text("copyvar rep_origine\\var_origine,
rep_arrivée\\var_arrivée");
copie = HS_popEStack();
NG_execute(copie, 0);
HeapFree(copie);
Cette suite de commandes permet d'exécuter la majeure
partie des fonctions BASIC de la TI. cependant, je pense qu'il vaut mieux ne pas
y faire appel trop souvent, car il est fort probable que cette opération
ralentirait fortement les performances du programme. Il ne faut donc utiliser
cette "astuce" que quand on ne parvient pas à faire autrement !
Utiliser un seul "\" entre le nom du répertoire et
celui de la variable ne fonctionne pas (alors que c'est ce qui est fait en TI-BASIC
!). Il faut en mettre deux. Cela est du au fait que TIGCC interprète le symbole
"\"+quelque_chose comme une balise (Pour la fonction printf,
par exemple).
2:
Archiver une variable :
Pour cela, il existe une fonction, mais qui peut être
utilisée de deux façons différentes (en simplifiant !) :
* EM_moveSymToExtMem
($(nom_var), HS_NULL); // To = vers
Dans ce cas, on place, en premier argument, le nom de la
variable que l'on souhaite déplacer de la mémoire RAM à la mémoire
d'Archive, et, en second argument, HS_NULL.
D'après les essais que j'ai fait, je pense qu'il n'est pas possible de choisir
un répertoire autre que le répertoire courrant pour effectuer cette fonction.
Il faut donc se placer dans la répertoire où se trouve la variable avant de
pouvoir l'archiver. (Merci de me signaler si je dis une bêtise).
* EM_moveSymToExtMem
(NULL, pointeur_de_type_HSym);
Dans ce cas, on place NULL
en premier argument, et un pointeur de type HSym
en second. Celui-ci aura pu être obtenu auparavant, ou alors, il est possible
de l'obtenir "sur place". (Voir plus haut).
Dans les deux cas, cette fonction renvoie un short,
qui a pour valeur TRUE si la variable a
été archivée, et FALSE dans le cas
contraire.
3:
Désarchiver une variable :
Pour désarchiver une variable, on peut, de la même façon
que ci-dessus, utiliser la même fonction, mais avec deux possibilités
différentes :
* EM_moveSymFromExtMem
($(nom_var), HS_NULL); // From = à
partir de
* EM_moveSymfromExtMem
(NULL, pointeur_de_type_HSym);
4:
Effacer une variable :
Pour effacer une variable, il faut utiliser la fonction :
SymDel($(nom_var));
Cette fonction renvoie un short,
qui a pour valeur TRUE si la variable a
été effacée, et FALSE si elle ne l'a
pas été.
Ici aussi, je pense qu'il faut se placer dans le répertoire
où se trouve la variable à effacer avant de pouvoir effectivement l'effacer :
il me semble que cette fonction n'admet pas le nom d'un répertoire pour
accompagner celui de la variable.
Autre façon
d'effacer une variable : La fonction que nous venons d'étudier nous permet
d'effacer une variable précise, dont on connaît le nom. Cependant, il existe
une autre méthode, qui consiste à utiliser cette fonction :
HSymDel(pointeur_de_type_HSym);
Cette fonction permet d'effacer une variable, mais
dont le nom est déterminé lors de l'exécution du programme, et non pas lors
de la création. Elle renvoie un short qui a
pour valeur TRUE si la variable a été
effacée, et FALSE si elle ne 'a pas
été.
5:
Déplacer une variable ;
Pour déplacer une variable d'un répertoire vers un autre,
il faut utiliser l'instruction suivante :
SymMove ($(rep_origine\\nom_var1),$(rep_arrivée\\nom_var2));
Cette instruction déplace la variable nom_var1
du répertoire rep_origine au répertoire rep_arrivée, en la
renommant éventuellement au passage en nom_var2. Si on ne met pas de
noms de répertoires, ou si ceux-ci sont identiques, alors la variable sera
simplement renommée. Si le répertoire de destination n'existe pas, vous aurez
a possibilité de le créer (comme en TI-BASIC, une boite de dialogue
apparaîtra.).
Cette fonction renvoie un short,
qui aura pour valeur TRUE si la
variable a été déplacée (ou renommée), et FALSE
si elle ne l'a pas été.
III:\
Rechercher des variables :
Nous avons choisi de faire une troisième
partie uniquement à ce sujet, car les fonctions que nous allons utiliser ici
vont nous permettre de rechercher des variables, mais aussi des répertoires.
Étant donné que nos deux autres parties étaient déjà longues, le fait d'en
faire apparaître une troisième permettra peut-être (je l'espère !) de ne pas
s'embrouiller l'esprit encore plus que nécessaire.
La première instruction permettant de
rechercher des variables ou des répertoires dans la VAT est la fonction
suivante :
SymFindFirst (nom, flag);
Le nom est celui du répertoire où la recherche sera
menée, mais elle peut ne pas être prise en compte, selon la valeur du
paramètre flag. Dans le cas où la recherche doit se faire pour un
répertoire, et que ce paramètre sera ignoré, il peut prendre la valeur NULL.
Le paramètre flag détermine de quelle façon les
deux fonctions que nous allons utiliser ci-dessous seront utilisées. Si flag
= 0, la recherche se fera dans la partie de la VAT concernant les répertoires
(le paramètre nom sera donc ignoré.). Si flag = 1, la recherche
ne se fera que dans le répertoire qui sera précisé par le paramètre nom.
Si flag = 2, la recherche se fera à la fois dans la partie de la VAT qui
concerne les répertoires et celle qui concerne les variables. Dans ce cas, il
sera possible de dresser une liste de toutes les variables présentes sur la TI.
(Le paramètre nom sera ignoré.). Si flag = 4, la recherche se fera dans la
partie de la VAT concernant les répertoires, mais les répertoires temporaires
seront ignorés. (le paramètre nom sera ignoré.). Si flag = 6, la recherche
sera menée de la même façon que si flag = 2, mais les répertoires
temporaires seront ignorés. Enfin, si flag = 17, la recherche se fera dans le
répertoire déterminé par nom, à partir de sa première variable.
Cette fonction renvoie un pointeur de type SYM_ENTRY
vers le nom du répertoire, ou de la variable.
En fait, pour résumer, cette fonction permet
"d'amorcer" une recherche à travers la VAT, qui sera continuée par
les deux instructions que nous allons à présent étudier.
Pour continuer une recherche dans la VAT,
amorcée par l'instruction SymfindFirst,
il faut utiliser l'instruction suivante :
SymFindNext();
La façon dont cette fonction se comportera dépendra
des paramètres qui auront été déterminés à partir de la fonction
précédente. Elle renvoie un pointeur de type SYM_ENTRY vers le répertoire ou
la variable, ou alors, NULL, s'il n'y a plus d'entrées dans la VAT qui
correspondent à ce que l'on recherche.
La fonction que nous venons d'étudier nous
permettra de chercher à travers la VAT, dans un certain ordre : à chaque
utilisation, cette fonction cherchera la variable (ou le répertoire) suivant. A
présent, intéressons-nous à une autre instruction, qui permet de faire à peu
près la même chose, mais en cherchant à chaque utilisation la variable (ou le
répertoire) précédent :
SymFindPrev ();
Cette fonction se comporte exactement comme SymFindNext,
sauf pour l'ordre de recherche.
Nous sommes enfin arrivé à la fin de ce Chapitre,
et j'espère que vous avez compris son contenu. Si tel n'est pas le cas, je vous
encourage à vous acharner, et à persévérer : les manipulations de la VAT sont
des choses complexes, à manier avec prudence (essayez donc vos programmes avec
VTI !). Si, après plusieurs tentatives, vous ne comprenez toujours pas, ou si
une fonction ne fonctionne pas comme prévu, je ne peux que vous encourager à
vous mettre un peu à l'anglais, pour étudier la documentation de TIGCC. Celle-ci
a été rédigée par la personne qui a écrit le librairies, et qui est donc le
mieux placé pour expliquer comment elles fonctionnent.
Ce Chapitre est déjà long, de par la taille de la liste de
fonctions utilisables pour la gestion de la VAT, mais aussi par sa difficulté
de compréhension. Donc, pour ne pas le rallonger plus que nécessaire, et aussi
ne pas vous forcer à rester trop longtemps dessus, nous avons jugé préférable
de ne pas mettre d'exemples au milieu des différentes fonctions énoncées ici.
Vous trouverez donc des exemples concernant la gestion de la VAT dans le chapitre
suivant :
Retour au menu général
Chapitre
XI
|
|