1

Encore et toujours smile

Pour lire une liste placée en argument, il faut tout d'abord obtenir un pointeur ESI :

if(GetArgType(esi_argument))==LIST_TAG)
pointeurs_vers_listes[i++]=esi_argument-1;


Et ensuite on lit la liste avec des GetIntArg ou GetStrnArg...

Mais je voulais aussi lire des listes quand on place leur nom sous cette forme : prog("#liste"). Ce qui donne :

ptr_chaine=(char*)GetStrnArg(esi_argument);
if(ptr_chaine[0]=='#' && peek(esi_liste=HToESI(vat_open(ptr_chaine+1)->handle)) // vat_open renvoie le SYM_ENTRY d'une variable TiOS
pointeurs_vers_listes[i++]=esi_liste-1;


Mais avec la deuxième méthode, j'ai un problème assez étrange : ça marche quand j'appelle le prog depuis l'écran HOME, mais pas depuis un programme en basic.
Quelqun voit une explication logique à ça confus
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

2

La variable utilisée dans ton programme BASIC est-elle bien globale?
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

3

Dans ce cas oui, mais vat_open est aussi capable d'ouvrir les variables locales.
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

4

Vérifie alors que, dans vat_open, tu regardes bien à la fois dans la liste des variables locales et dans celle des variables globales.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

5

Voilà vat_open :

SYM_ENTRY *vat_open(const char *ssc_var)
{
SYM_ENTRY *sxs_var;
return (sxs_var=DerefSym(FindSymInFolder(vat_name(ssc_var),TempFolderName(ssc_tmp[1]))))?sxs_varsorryymFindPtr(vat_name(ssc_var),0);
}

Je traduis grin

SYM_ENTRY *vat_open(const char *nom_variable)
{
SYM_ENTRY *sym_variable;

return (sym_variable = DerefSym(FindSymInFolder(vat_name(nom_variable),TempFolderName(numero_dossier_local)))) ?
sym_variable : SymFindPtr(vat_name(nom_variable),0);
}

(vat_name converti une chaine de caractère en nom de variable TiOS, en ajoutant un zéro devant)
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

6

C'est du code illisible ! Je pense que ça peut être une source d'erreurs...

Peut-être qu'en traversant la VAT complète, tu auras moins de problèmes (je ne sais pas, c'est juste une suggestion).
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

7

La plupart du temps une ligne immense coupées en petits morceaux d'augmente pas la taille du résultat, ça ne peut être que bénéfique de rendre du code lisible.

8

tiens, je suis pas le seul à le dire grin
Bob> ton code est pas clair du tout sad
avatar
Tutorial C (TI-89/92+/v200) - Articles Développement Web (PHP, Javascript, ...)
« What is the sound of Perl? Is it not the sound of a wall that people have stopped banging their heads against? » - Larry Wall

9

Rah... Y'a qu'une ligne, ça va encore non ?

Bon je dé-optimise grin


SYM_ENTRY *vat_open(const char *nom_variable)
{
SYM_ENTRY *sym_variable;

sym_variable = DerefSym(FindSymInFolder(vat_name(nom_variable),TempFolderName(numero_dossier_local)))) // Essaye de trouver la variable dans le dossier "local"

if(sym_variable) return sym_variable; // Retourne son pointeur SYM_ENTRY si elle a été trouvée
else return SymFindPtr(vat_name(nom_variable),0); // Sinon, essaye de la trouver en global et retourne un pointeur SYM_ENTRY

}
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

10

Je trouve que la ligne
return (sym_variable = DerefSym(FindSymInFolder(vat_name(nom_variable),TempFolderName(numero_dossier_local)))) ?
sym_variable : SymFindPtr(vat_name(nom_variable),0);

est très claire.

Essaye de faire le test de validité autour de FindSymInFolder plutôt qu'autour de DerefSym:
HSYM hsym_variable;

return (({hsym_variable = FindSymInFolder(vat_name(nom_variable),TempFolderName(numero_dossier_local))));
*(unsigned long *)&hsym_variable;}) ? DerefSym(hsym_variable) : SymFindPtr(vat_name(nom_variable),0);
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

11

D'ailleurs, XDanger, tu n'as pas l'air d'avoir jeté un coup d'œil sur la source de Backgammon. grin Il y a des lignes comme ça:
    DrawSprite((unsigned char *)(n>0?white_checker:black_checker),
               x+(abs(n)<=5)+Q((i/5)*((abs(n)<=10)+1),(abs(n)<=10)+(i/5)*2),
               y+(i%5)*dir*Q(9,11));

avec:
#define white_checker (TI89?white_checker89:white_checker92)
#define black_checker (TI89?black_checker89:black_checker92)
#define Q(ti89value,ti92pv200value) (TI89?(ti89value):
(ti92pv200value))
(J'ai trouvé que C89_92 prend trop de place, donc j'ai pris une macro d'une lettre. grin)
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

12

Kevin > Ok, j'ai pas trop le temps d'essayer là mais ce soir je teste smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

13

Ce n'est pas complètement optimisé:
SYM_ENTRY *vat_open(const char *nom_variable)
{
return (DerefSym(FindSymInFolder(vat_name(nom_variable),TempFolderName(numero_dossier_local)))) ?: SymFindPtr(vat_name(nom_variable),0);
}
Mais SYMSTR fait la même chose que vat_name, donc je l'utiliserai:

SYM_ENTRY *vat_open(const char *nom_variable)
{
return (DerefSym(FindSymInFolder(SYMSTR(nom_variable),TempFolderName(numero_dossier_local)))) ?: SymFindPtr(SYMSTR(nom_variable),0);
}

?: est une extension de GCC, au fait, x?:y est la même que x?x:y.

14

Oui, avec la différence que le x est évalué une seule fois. (C'est bien ce qui convient ici, mais j'ai quand-même préféré le préciser.)
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

15

J'ai déjà eu des problèmes avec x?:y, donc je préfere la méthode "classique"...

Quand à SYMSTR c'est volontairement que je ne l'utilise pas. Le fait d'appeller ma fonction à chaque fois que j'ai besoin de convertir un nom me fait gagner environ 100 octets...
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

16

Non, le changement du post #9 ne fait rien sad

En fait si la liste est placée directement en argument ça marche, et si c'est son nom qui est placé en argument, ça ne marche pas... Voilà comment ça se passe dans les deux cas :

// Detection du type de l'argument (liste ou bien str qui contient le nom de variable de la liste)
switch(GetArgType(esi_argument))
{
case LIST_TAG: arg_list(&esi_argument); break;
case STR_TAG: arg_strn(&esi_argument); break;
}


// Optention d'un pointeur ESI vers la liste, à partir de son nom (le passage de l'ESI en pointeur est normal)
char arg_strn(ESI *argument_esi)
{
ESI esi_liste=NULL;
char *pointeur_chaine=NULL;
pointeur_chaine=(char*)GetStrnArg(*argument_esi);
esi_liste=HToESI(vat_open(pointeur_chaine)->handle;
arg_list(&esi_liste);
}


// Optention d'un pointeur ESI vers la liste directement placée en argument
char arg_list(ESI *esi_liste)
{
tableau_esi_listes[i++]=*esi_liste-1;
*esi_liste=next_expression_index(*esi_liste);
}



"arg_strn" est donc sensé rajouter une étape pour optenir le pointeur ESI, et ensuite appeller la fonction qui stoque ce pointeur dans un tableau. Par ailleurs je passe les ESI par leurs adresses, de façon à pouvoir utiliser next_expression_index pour capturer les arguments suivants, une fois retourné dans la boucle principale.

Mais voilà, quand je place la liste en argument ça marche, quand je passe son nom ça marche très mal (j'ai l'impression que les listes sont "mal" lues, des élements sont ignorés).
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

17

> D'ailleurs, XDanger, tu n'as pas l'air d'avoir jeté un coup d'œil sur la source de Backgammon.
Je n'ai pas regardé en détail, en effet... J'ai regardé un peu DrawSprite, mais c'est tout (je n'ai pas vu un appel à DrawSprite, heureusement grin).
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

18

J'aurais besoin d'une explication :

// Optention d'un pointeur ESI vers la liste, à partir de son nom (le passage de l'ESI en pointeur est normal)
char arg_strn(ESI *argument_esi)
{
ESI esi_liste=NULL;
char *pointeur_chaine=NULL;
pointeur_chaine=(char*)GetStrnArg(*argument_esi);
esi_liste=HToESI(vat_open(pointeur_chaine)->handle;
arg_list(&esi_liste);
}


Or la doc dit à propos de HToESI :
Note: If the handle is not locked, HToESI must be called again after a heap compression since the block of memory associated with the handle may have moved.
> Qu'est-ce que ça signifie, et est-ce que ça pourrait être la cause de l'erreur ?
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

19

Ah oui, ça pourrait être l'origine du problème.
Essaye de mettre:
HANDLE h_global; int booleen_global;
en variables globales et:
h_global=vat_open(pointeur_chaine)->handle
booleen_global=HeapGetLock(h_global);
HeapLock(h_global);
esi_liste=HToESI(h_global);

au début et:
if (!booleen_global) HeapUnlock(h_global);
quand tu as fini de lire la liste.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

21

n>0?white_checker:black_checker
ça veut dire que si n est supérieur à 0 on retourne white checker, sinon black_checker.

D'une façon générale :
condition?instruction_si_vraie:instruction_si_fausse

22

C'est l'équivalent du when en BASIC. Cf. http://tigcc.ticalc.org/doc/faq.html#47.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

23

Kevin > Hum ça va allourdir bcp le code parceque "esi_liste" est en fait un tableau de pointeurs ESI, donc va falloir que je crée aussi des tableaux de handle et de short...

HeapUnlock plante si le handle n'est pas locké avant d'appeller la fonction ?
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

24

Le problème, c'est qu'il ne faut pas appeler HeapUnlock si le bloc était déjà locké au moment de l'appel à HeapLock, d'où l'utilisation de mon booléen.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

25

Arg sad
Je vais être obligé d'utiliser bcp plus de variables que ce que j'avais pensé au départ sad

Tant pis...

Edit : Arg c'est encore plus problematique que ce que je pensais... Il n'y a vraiment pas d'autre solution ???
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

26

Je viens de voir que tu peux te passer du booléen en utilisant l'astuce suivante (inspirée de ce que fait ttstart):
HANDLE h_global;
...
HANDLE h_local;
h_local=vat_open(pointeur_chaine)->handle;
if (HeapGetLock(h_local)) h_global=0; else h_global=h_local;
HeapLock(h_local);
esi_liste=HToESI(h_local);

...
if (h_global) HeapUnlock(h_global);
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

27

Ah, bien smile
Ça m'économise une liste, je vais mettre ça tout de suite smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

28

Kevin Kofler a écrit :
HANDLE h_global;
...
HANDLE h_local;
h_local=vat_open(pointeur_chaine)->handle;
if (HeapGetLock(h_local)) h_global=0; else h_global=h_local;
HeapLock(h_local);
esi_liste=HToESI(h_local);

...
if (h_global) HeapUnlock(h_global);


Y'a un truc que je ne comprends pas... L'état "normal" d'un handle c'est locké ou délocké ?
- Si l'handle n'était pas lockée au départ, il est locké avec HeapLock et le reste même après la fin du programme, puisque h_global vaudra 0.
- Si l'handle était locké avant de lancer le prog (je ne sais pas si c possible ou pas), le HeapGetLock() retourne une valeur non-nulle, ensuite le handle est re-locké avec HeapLock (c'est inutile j'imagine), et à la fin, l'handle sera dé-locké.

Dans les deux cas il se retrouve donc à la fin dans l'état inverse de celui dans lequel il était au début confus
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)

29

Non. HeapGetLock renvoie une valeur non-nulle si le bloc est verrouillé (locké).
Donc:
if (HeapGetLock(h_local)) h_global=0; else h_global=h_local;
Si le bloc était déjà verrouillé, on met h_global à 0 pour qu'il ne sera pas déverrouillé à la fin (mais restera locké). Si le bloc n'était pas verrouillé, on stocke h_local en h_global pour pouvoir le déverrouiller à la fin.
Dans les 2 cas, on retrouve l'état d'origine du bloc.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

30

Ah ok smile
J'avais mal lu la doc... Désolé smile
avatar
All right. Keep doing whatever it is you think you're doing.
------------------------------------------
Besoin d'aide sur le site ? Essayez par ici :)