1

J'aimerais quelques précisions sur cette fonction :
pedrom::tmpnam
char *tmpnam(char *s asm("a0"))
{
  if (!s)
    s = TMPNAME, *s++ = 0;
  do {
    /* Don't check if we do a loop, since Ti can't have 65536 files */
    sprintf(s, "temp%04x", TMPNAME_COUNT++);
  } while (SymFindPtr(s+9,0));
  return s;
}

Comme c'est du C, j'y comprends pas grand chose cry malgré tous mes efforts

Si je lis bien :
- on doit passer à la fonction un pointeur vers un buffer pour recevoir un nom de fichier
- le pointeur est initialisé à TMPNAME (buffer de 10 bytes) à peine arrivé. A quoi sert donc ce qu'on y a mis ?
- Le premier caractère est mis à 0, puis on le passe (s est incrémenté de 1 ?), comme ça on construit en fait une SYM_STR ? C'est bien ça ?

J'aimerais comprendre, parce que je suis perplexe sur ce que renvoie cette fonction.
"return s", ça renvoie un pointeur vers l'octet #1 de TMPNAME, rien à voir avec l'argument qu'on aura passé à la fonction oO ?

2

En gros on peut passer son buffer perso à la fonction, dans ce cas elle l'utilise, sinon on lui passe NULL et elle utilise son buffer interne TMPNAME
Ensuite elle génère un nom de fichier temporaire, et elle boucle en le modifiant tant que le fichier existe.
À la fin, elle renvoie le pointeur sur le buffer qui contient le nom de fichier (le tien, ou le buffer interne)

PS : le zéro en début de chaine, je suppose que c'est le format des SYM_STR (j'ai un vague souvenir d'un truc dans le genre)

PPS : pour l'argument, je suppose qu'il faut lui passer un pointeur sur le deuxième char du buffer, le premier étant à 0.

3

Ok, merci, c'est bien ce que Lionel avait fini par réussir à me faire comprendre grin J'avais pas percuté le coup du "if (!s)" et ce que ça induisait. Ouep, une SYM_STR c'est 0,filename,0 et un SYM_STR* pointe sur le dernier 0 couic

Mais du coup, ce que je ne comprends pas, c'est que si s pointe sur le caractère #0 du nom de fichier s+9 pointe sur quoi ? C'est pas s+8 qui pointe sur le dernier 0 ?

Et au fait, vu comme SymFindPtr est écrit, PpHd pourrait écrire while( SymFindPtr( s , 0 )); #sauce_interne# hehe

4

s pointe sur le premier zéro.
s+1 pointe sur la premiere lettre.
s+8 pointe sur la 8e lettre.
s+9 pointe sur le zero final.

nan?

5

oO

Quand je passe un pointeur en paramètre, il pointe sur le début de la chaine à écrire, pas sur un 0 qui ne sera pas utilisé...
Et le *s++ sert à quoi ?
Et je vois pas où tu vois que sprintf va écrire à un octet plus loin que s...

6

s = TMPNAME ;//s pointe sur le premier char du buffer
 *s++ = 0; // on écrit un \0 dans le premier char du buffer, et on avance le pointeur s sur le deuxième char du buffer



Ce qui veut dire que pour appeler tmpnam(), il faut faire :

char buf[42] ;
buf[0]=  '\0' ; // on réserve le premier char
tmpnam(&buf[1]) ;

7

Oui ben c'est bien ce que je fais, ie j'ai toujours un buffer dans mon stack frame, qui commence à SYM_STR_FRAME, et en assembleur, j'écris :
lea.l SYM_STR_FRAME(a6),a0
clr.b (a0)+
jsr pedrom::tmpnam

Et pedrom écrit bien à partir du premier char que je lui passe, ça ça va.

Maintenant, si il vérifie à 9(a0) (ie s+9), il va un caractère trop loin... non ? Le 0 terminal est à 8(a0), puisque le premier caractère est à 0(a0)...

8

non , le premier caractère est à 1(a0)

0(a0) contient un zéro.

9

squalyl (./8) :
0(a0) contient un zéro.

Tu vois ça où ?
Si on a utilisé TMPNAME, on a fait *s++
Si on a pas utilisé TMPNAME, on balance un buffer dont le premier caractère sera rempli par sprintf... je vois pas où tu vois que 1(a0) contient le premier char...


Bref, PpHd ne devrait pas tarder à passer grin

10

on ne fait *s++ QUE si s==NULL. sinon, on le fait pas.

même si on le faisait, s est une variable locale à tmpnam, quand tu reviens dans ta fonction, s n'est pas modifié. il conserve la valeur qu'il avait avant l'appel.

11

On est bien d'accord. Mais le sprintf :
sprintf(s, "temp%04x", TMPNAME_COUNT++);
va commencer à copier 8 caractère à partir de s[ 0 ] jusqu'à s[ 7 ], non ?
Donc pourquoi tester à s[ 9 ] (s+9) après ?

12

non. Deux cas:

- si tu donnes null, il va copier de s[ 1 ] à s[ 8 ] grâce au s++

- si tu donnes autre chose,....


ok y'a un souci on dirait...

j'attends le chef.

13

À quand pedrom::mkstemp? wink
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é

14

folco@desktop:~$ man mkstemp
No manual entry for mkstemp

cry

15

Comme d'habitude, tu n'as rien installé sur ton système, même pas les manpages de base. roll Utilise un moteur de recherche, tu trouveras sans doute une copie en ligne.
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é

16

Ouep, j'ai trouvé. Et où est le problème à ce que mon install ne soit pas finalisée ?

PpHd -> est-on assuré que si l'on passe NULL à tmpnam, un 0 précède le nom de fichier renvoyé (ce qui assure qu'on puisse l'utiliser comme SYM_STR) ?

17

[nosmile] Ca vous va comme correction:
--- a/src/c/files.c
+++ b/src/c/files.c
@@ -429,15 +429,15 @@ short fprintf(FILE *f, const char *fmt, ...)
   return length;
 }
 
-char *tmpnam(char *s asm("a0"))
+char *tmpnam(char *out asm("a0"))
 {
-  if (!s)
-    s = TMPNAME, *s++ = 0;
+  char buffer[10], *s = buffer;
+  *s++ = 0;
   do {
     /* Don't check if we do a loop, since Ti can't have 65536 files */
     sprintf(s, "temp%04x", TMPNAME_COUNT++);
-  } while (SymFindPtr(s+9,0));
-  return s;
+  } while (SymFindPtr(s+8,0));
+  return strcpy (s == 0 ? TMPNAME : out, s);
 }


18

Je me permets, en plus clair :
char *tmpnam(char *out asm("a0")) 
 { 
  char buffer[10], *s = buffer; 
  *s++ = 0; 
  do { 
     sprintf(s, "temp%04x", TMPNAME_COUNT++); 
  } while (SymFindPtr(s+8,0)); 
  return strcpy (s == 0 ? TMPNAME : out, s); 
 } 


PpHd -> tu serais intéressé par une implémentation en assembleur ?

19

La condition du "?:" dans le strcpy devrait être "out == 0", non ?

Aussi, est-ce que le fait d'utiliser une variable locale sur la pile, et strcpy à la fin, n'est pas un gaspillage de place par rapport à la version de ./1 ?
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

20

Oui, pourquoi ne pas avoir remplacé le 9 par 8 dans la version initiale ?

Qui plus est, cette version qui renvoie TMPNAME, mais t'écris jamais dans ce buffer, non ? Et TMPNAME+1 serait pas mieux (je sais pas si c'est la syntaxe, mais je parle du premier caractère du nom de fichier).

Ca serait pas mieux d'initialiser TMPNAME[ 0 ] au boot de PedroM, puis de toujours bosser après à partir de TMPNAME+1 ?

21

Il écrit dans TMPNAME si out == 0 (enfin, s == 0 dans ./18).
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

22

argh sick Je parle décidémment très très mal le C... Alors faudrait faire le strcpy à TMPNAME+1 peut être

23

Lionel Debroux (./19) :
La condition du "?:" dans le strcpy devrait être "out == 0", non ?

Oui
Lionel Debroux (./19) :
Aussi, est-ce que le fait d'utiliser une variable locale sur la pile, et strcpy à la fin, n'est pas un gaspillage de place par rapport à la version de ./1 ?

Mais ./1 ne marche pas.
Folco (./18) :
PpHd -> tu serais intéressé par une implémentation en assembleur ?

Non.

24

PpHd (./23) :
Mais ./1 ne marche pas.

Comme je suis nul, (embarrassed) je comprends pas pourquoi le ./1 ne marche pas hormis le fait que la vérification soit faire trop loin. Quelqu'un pourrait me dire svp ?

25

Oui, mais pourquoi pas:
char *tmpnam(char *out asm("a0"))
{
  char *s = ((out == 0) ? TMPNAME : out);
  *s++ = 0;
  do {
     sprintf(s, "temp%04x", TMPNAME_COUNT++);
  } while (SymFindPtr(s+8,0));
  return s;
}

Vu qu'on utilise sprintf, je ne vois pas l'intérêt du strcpy dans ./18 confus
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

26

Exemple:

 char buffer[9];
 tmpname(buffer);
 FILE * f = fopen(buffer, "w");

27

Hmm. J'ai peut-être compris.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

28

Est-ce qu'il est garanti que tmpnam(0) renvoit une chaine en forme de SYM_STR ?

29

Nope

30

Merde. En fait, c'est finalement pas trop une bonne idée de souvent plonger le nez dans les sources de PedroM pour voir ce qu'on peut en tirer, on fiinrait par faire des conneries et prendre de mauvaises habitudes. grin