Eh ben, nous y voilà. Le chapitre II
Tout d'abord, avant de commencer ma parlotte, il va vous falloir quelques "pré-requis" : vous devez avoir bien compris
le chapitre I et avoir quelques connaissances sur les structures et les pointeurs.
Si vous n'êtes absolument pas familier avec ces structures et ces pointeurs, allez voir des tutos; Ce n'est pas obligatoire pour ce tuto, mais recommandé
Une fois que vous êtes prêts, nous pouvons commencer à apprendre :)
- Citation :
Cool.
On dit "bonjour, monsieur"
Allez, on commence...
Chapitre II : Les variables (2)
Pas très original comme titre, huh ? ^^
Comme promis dans le chapitre I, nous allons aujourd'hui apprendre à obtenir la liste de tous les dossiers et tous les fichiers présents dans la TI, et à faire des manipulations "basiques" sur un fichier, comme le cacher, le verrouiller. Une fois ce chapitre lu, avec une jolie interface, vous devriez être capable de faire un exploreur plus ou moins convenable.
Alors, allons-y, commençons ! ^^
I Dossiers et fichiersDans le chapitre I, on a appris comment obtenir un pointeur vers 1 variable. Mais un problème se pose pour plusieurs variables : comment allons-nous faire pour accéder à toutes les variables d'un dossier ?
En effet, on ne connait ni le nombre de fichiers qu'il y a (on pourrait à la limite trouver une fonction pour connaitre le nombre de fichiers qu'il y a dans un dossier), ni leurs noms...
- Citation :
- Code:
-
SYM_ENTRY *sym=SymFindFirst(SYMSTR("main"),0);
char name[];
while(sym)
{
strcpy(name,sym->name);
printf("%s",name);
ngetchx();
sym = SymFindNext();
}
Tricheur :p
Bon, en effet, on va utiliser plus ou moins ce code qu'on va adapter selon ce qu'on souhaite faire.
On va garder ce code de côté, à la fin de ce paragraphe (j'appelle paragraphe le
I), vous devriez normalement être capable
de comprendre entièrement ce bout de code.
Et hop, un joli trait. C'est ici que commence la leçon.
Regardons de plus près le mot VAT : dans VAT, il y a T pour Table.
On peut supposer que les informations à propos des différentes variables/dossiers se situent à la suite dans une table située quelque part en mémoire (à vrai dire, je ne sais pas trop, mais c'est comme ça que je suppose la VAT). Les pointeurs qu'on a appris à créer dans le chapitre I serviraient à accéder à un endroit bien précis de cette table.
L'astuce pour obtenir ce qu'on veut consisterait donc à parcourir la VAT élément par élément.
Pour ça, il faut donc un pointeur qui pointerait sur chacun des éléments qui constituent la VAT.
Maintenant, la question qui se pose est : comment allons-nous faire ça ?
- Citation :
C'est pas l'objet de ce tuto ?
Sisi, mais j'voudrais faire réfléchir un peu avant de donner la réponse
v Ceci est un spoiler : cliquez dessus pour regarder ce qu'il contient- Spoiler:
C'est simple, on va commencer par le début et terminer par la fin
- Citation :
...
Mais encore ?
Eh bien, nous allons obtenir un pointeur vers le 1er élément de la VAT et parcourir chaque élément de la VAT jusqu'à arriver au dernier.
Vous avez compris le principe ?
- Citation :
Je pense, oui...
Bien, alors, maintenant nous allons mettre cette théorie en oeuvre
Tout d'abord, il faut initialiser le pointeur. Deux solutions alors :
- La première consiste à donner la valeur NULL au pointeur. (rappel : NULL pour un pointeur correspond environ à 0 pour un nombre)
- La deuxième est plus directe : on fait directement pointer le pointeur sur la première variable. Pour cela, on utilise la fonction SymFindFirst()
La première méthode ne nécessite pas plus d'explications. Regardons plus en détail la deuxième méthode, et la fonction
SymFindFirst()D'après la doc, nous avons ceci :
- Citation :
SymFindFirst
SYM_ENTRY *SymFindFirst (SYM_STR SymName, unsigned short Flags); |
Begins looping through the VAT.
(il est conseillé de connaitre un minimum d'anglais, sinon
vous sera bien utile
)
Cette fonction prend donc 2 arguments : la première est de type
SYM_STR. Si vous ne savez pas ce que c'est, c'est que vous avez mal/pas compris le chapitre
I, alors reprenez-le ! Sinon, rien de nouveau...
A noter que cet argument est le nom du dossier pour obtenir la liste des fichiers d'un dossier précis, ou
NULL si l'on veut obtenir la liste des dossiers présents dans la calculette
Le deuxième argument est de type
unsigned short, il s'agit d'un "flag"
Pour simplifier les choses, disons que cet argument correspond permet à la fonction d'effectuer différentes tâches pourtant similaires entre elles, dans notre exemple chercher uniquement les dossiers, ou les fichiers...
Nous allons utiliser par la suite flag=0
Une fois l'appel à la fonction
SymFindFirst() terminé, nous obtenons un pointeur de type
SYM_ENTRY vers la 1ère variable (il semblerait que ce soit par ordre alphabétique), dossier ou fichier.
Nous allons ensuite parcourir la VAT à l'aide des instructions
SymFindNext() (ou
SymFindPrev() pour "revenir en arrière").
Ces fonctions s'appellent sans argument, et retournent un pointeur
SYM_ENTRY vers l'élément suivant (ou précédent) de la VAT.
Nous pouvons ainsi obtenir ce que nous voulons, car la fonction
SymFindNext() retournera
NULL lorsqu'il n'y aura plus aucune variable qui correspond aux "critères de recherche" définis par la fonction
SymFindFirst() au départ.
A noter que la fonction
SymFindFirst() retournera également
NULL si elle n'a rien trouvé (par exemple, en argument un nom de dossier qui n'existe pas)
Bon, je viens de faire un gros pâté, mais ceci est à comprendre, c'est la "colonne vertébrale" de ce 1er paragraphe. Maintenant nous allons pouvoir passer à la pratique : nous voulons afficher le nom de toutes les variables présentes dans le dossier
MAIN.
Réfléchissez avant de regarder la solution.
v Ceci est un spoiler : cliquez dessus pour regarder ce qu'il contient- Spoiler:
Alors, vous avez trouvé ? non ? pourtant la réponse se trouve pas loin...
- Code:
-
SYM_ENTRY *sym=SymFindFirst(SYMSTR("main"),0);
char name[];
while(sym)
{
strcpy(name,sym->name);
printf("%s",name);
ngetchx();
sym = SymFindNext();
}
Eh oui, il s'agit bien de ce code-là
J'avais dit que j'allais le garder de côté et qu'on allait pouvoir l'expliquer à la fin du paragraphe.
Nous voici à la fin dudit paragraphe. Commençons alors les explications, mais essayez d'abord de comprendre par vous-même.
- Citation :
Euh non...j'y arrive pas...
Tiens, ça f'sait longtemps qu'j't'avais pas entendu toi ^^
Bien, alors, nous allons voir ce code ensemble, ligne par ligne
- Citation :
Cool :)
- Code:
-
SYM_ENTRY *sym=SymFindFirst(SYMSTR("main"),0);
Ici, on initialise le pointeur. Le pointeur
*sym pointe sur la 1ère variable du dossier MAIN.
- Code:
-
char name[];
Cette deuxième ligne sert à définir
name : ce tableau à taille indéterminée pour l'instant (notez qu'on aurait pu mettre 8, taille maximale du nom d'une variable) contiendra le nom des variables quand on les aura trouvés.
- Code:
-
while(sym)
{
strcpy(name,sym->name);
printf("%s",name);
ngetchx();
sym = SymFindNext();
}
Le corps du programme.
La première ligne continue la recherche tant que
sym est différent de
NULL, constante signifiant qu'il n'y a plus de variable.
- Code:
-
strcpy(name,sym->name);
Cette ligne copie le nom de la variable contenue dans la structure
SYM_ENTRY nommée
sym dans la variable
name
- Citation :
Attends, attends. Je croyais que, pour accéder à un élément d'une structure, on utilisait le point (.) ?
C'est vrai. Mais ici notre structure est un pointeur (
*sym), on n'utilise alors plus le point, mais la flèche (->) (attention, pas la flèche STO> comme en basic, mais cette fois-ci c'est bien - > !)
- Code:
-
ngetchx();
Pas besoin d'explications ici ?
- Code:
-
sym = SymFindNext();
Et enfin, la dernière ligne.
Ici, on fait pointer le pointeur
sym vers l'élément suivant de la VAT, puis on recommence la boucle.
Et voilà, c'est tout pour ce premier paragraphe. Maintenant vous devriez être capable d'obtenir la liste de tous les fichiers et dossiers de la TI et d'en faire un joli petit explorateur, comme celui de Windows
Le 2ème paragraphe nous permettra d'y rajouter des fonctions, pour cacher, verrouiller, renommer etc...une variable
II Manipulations basiquesEnfin, nous y sommes :)
Le plus intéressant va enfin commencer : quoi d'excitant dans le fait de pouvoir avoir la liste des variables si on ne peut rien faire dessus ?
Vous souvenez-vous de ce que j'avais dit au chapitre I concernant le détail de la structure
SYM_ENTRY ?
- Citation :
Regardons dans la doc ce qui constitue un pointeur SYM_ENTRY :
- Code:
-
typedef struct
{
char name[8];
unsigned short compat;
union
{
unsigned short flags_n;
struct
{
unsigned short busy:1, local:1, flag1_5:1, flag1_4:1,
collapsed:1, twin:1, archived:1, in_view:1;
unsigend short folder:1, overwritten:1, checked:1, hidden:1, locked:1,
statvar:1, graph_ref_1:1, graph_ref_0:1;
}bits;
}flags;
HANDLE handle;
}_;
ça vous revient
- Citation :
o_O oui !
ça m'avait presque donné envie de gerber !
euh...tu rencontreras des choses plus compliquées que ça plus tard, alors réprime cette envie x_x
Bon, trève de plaisanteries
Supposons que nous avons réussi à obtenir un pointeur
SYM_ENTRY vers la variable "main\test" par exemple
Maintenant, supposons que nous voulons cacher cette variable.
Un élément dans cette structure va particulièrement nous intéresser : lequel ?
Non ? regardez mieux :p
- Citation :
...
- Citation :
unsigend short folder:1, overwritten:1, checked:1, hidden:1, locked:1,
statvar:1, graph_ref_1:1, graph_ref_0:1;
c'est ça ?
Oui, effectivement, il s'agit bien de cet élément là.
Nous voulons changer cette valeur. Il s'agit d'un "champ de bits"
- Citation :
Ahem...
Nan,
bits, pas de e supplémentaire !
, va !
Il s'agit pour simplifier (une fois de plus ^^) d'éléments ne pouvant prendre que les valeurs 0 et 1, comme le binaire
Ici, 1 signifie "la variable est cachée" et 0 "la variable n'est pas cachée"
Nous allons donc logiquement mettre la valeur 1 à cet élément.
- Citation :
Génial !
...
...
...
mais comment on fait pour modifier ça ?
Bonne question.
Nous avons un pointeur *sym, et cet élément se trouve bien difficile d'accès.
En fait non, il n'est pas si inaccessible, mieux, il est facilement possible d'y accéder !
- Citation :
aaaaah ! comment ?
- Code:
-
sym->flags.bit.hidden
Comme ça. Regardez en parallèle la structure et cette ligne de code :
sym->flags.bit.hidden | typedef struct { char name[8]; unsigned short compat; union { unsigned short flags_n; struct { unsigned short busy:1, local:1, flag1_5:1, flag1_4:1, collapsed:1, twin:1, archived:1, in_view:1; unsigend short folder:1, overwritten:1, checked:1, hidden:1, locked:1, statvar:1, graph_ref_1:1, graph_ref_0:1; }bits; }flags; HANDLE handle; }_; |
Nous "traçons le chemin" jusqu'à l'élément auquel nous voulons accéder
Une fois qu'on a ça, bah c'est tout simple, il ne reste plus qu'à mettre une valeur, comme n'importe quelle variable "classique" :
ainsi, pour cacher la variable main\test, on fera
- Code:
-
SYM_ENTRY *sym = SymFindPtr($(main\\test),0);
sym->flags.bit.hidden = 1; //cache la variable
Tout simplement.
Pour verrouiller, on fait la même chose, mais cette fois avec "locked" (sym->flags.bit.locked). On peut également tester si une variable est archivée en regardant la valeur de l'élément "archived" (sym->flags.bit.archived)
Voilà.
Vous savez maintenant comment verrouiller, cacher une variable.
Pour terminer ce tuto, on va faire un code qui cache toutes les variables contenues dans le dossier main
Si vous avez bien suivi, vous devriez être capable de comprendre ce code. Sinon, reprenez ce tuto :)
- Code:
-
#include < tigcclib.h >
void _main()
{
SYM_ENTRY *sym = SymFindFirst (SYMSTR("main"), 0);
if (sym==NULL)
{
ST_HelpMsg("Erreur !");
return;
}
while(sym)
{
sym->flags.bit.hidden = 1;
SymFindNext();
}
}
Voilà voilà. Ceci clot ce 2ème chapitre.
Dans le prochain chapitre, nous allons manipuler les fichiers "à l'intérieur", c'est-à-dire apprendre à manipuler les données à l'intérieur des fichiers, tel que vous le faisiez avec les fonctions de stdio.h (fputc(), fputs(), fread()...)