Home   Archives    Hardware   Programmation   Challenges   Forum   Le Mag    Faq   La Communauté   L'Equipe
 
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

Les raccourcis
 

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


 


Copyright © Ti-Fr v2.0 1999-2002