Mon sprintf à môa
9 sujets de 1 à 9 (sur un total de 9)
-
Des fois il m’arrive d’écrire des saletés comme ça:
static void __asm myputchar(
register __d0 char car,
register __a3 char *buffer
)
{
*buffer++ = car ;
}
long MSprintf(
char *buffer,
char *format_string,
…
)
{
va_list args ;
long len = 0 ;
va_start(args, format_string) ;
RawDoFmt(format_string, (APTR)args, myputchar, (APTR)buffer) ;
va_end(args) ;
len = strlen(buffer) ;
return len ;
}
ben ça mârche pâs!
cet empaté de compilo me transforme le myputchar en
move.b d0,(A3)
rts
au lieu de
move.b d0,(A3)+
rts
du coup j’ai viré le myputchar et j’ai mis le code en ligne, dans une chaine de caractères niak niak 😮
RawDoFmt(format_string,
(APTR)args,
(VOID(*)()) »x16xc0x4ex75″,
(APTR)buffer) ;
Et du coup ca fonctionne comme je l’attends!
Est-ce que quelqu’un à déjà réussi à utiliser RawDoFmt en « full » C
Pinaise c’est tard, dodo!
Cela me semble normal. Ta post incrémentation est inutile dans cette fonction donc il l’optimise.
Tente *(++buffer – 1) = car; au cas où le compilo est un peu nul et n’y voit que du feu.
Ou peut-être un volatile.
Sinon, j’ai toujours vu tout le monde mettre le code 68k en dur dans un tableau également…
Et comme ça c’est pas mieux par hasard ?
static void __asm myputchar(
register __d0 char car,
register __a3 char **buffer
)
{
*(*buffer)++ = car ;
}
long MSprintf(
char *buffer,
char *format_string,
...
)
{
va_list args ;
long len = 0 ;
va_start(args, format_string) ;
RawDoFmt(format_string, (APTR)args, myputchar, (APTR)&buffer) ;
va_end(args) ;
len = strlen(buffer) ;
return len ;
}
A y est! J’ai enfin réussi à faire marcher RawDoFmt en full C.
Eloignez les enfants de l’écran, ca va vous faire le même choc que pour votre premier printf(« hello worldn ») ;
#define USE_AMIGADOS 1
#include
#include
#include
#include
#include
#include
#include
void KPutStr(char *str)
{
#if USE_AMIGADOS
BPTR f ;
f = Open("stddebug.txt", MODE_READWRITE) ;
if (f != NULL)
{
Seek(f, 0, OFFSET_END) ;
Write(f, str, strlen(str)) ;
Close(f) ;
}
#else
FILE *f ;
f = fopen("stddebug.txt", "a+") ;
if (f != NULL)
{
fseek(f, 0, SEEK_END) ;
fputs(str, f) ;
fclose(f) ;
}
#endif
}
#define MAXCHAR 8
struct dbuffer
{
ULONG len ;
UBYTE *data ;
} ;
static void ASM myputstr(
__REGD0(char car),
__REGA3(struct dbuffer *db)
)
{
ULONG len = db->len ;
db->data[len] = car ;
if (car != 0)
{
db->len ++ ;
if (len < MAXCHAR-1) { return ; } db->data[len+1] = 0 ;
}
KPutStr(db->data) ;
db->len = 0 ;
}
void KPrintF(const char *format_string, ...)
{
va_list args ;
struct dbuffer db ;
UBYTE data[MAXCHAR] ;
db.len = 0 ;
db.data = &data[0] ;
va_start(args, format_string) ;
RawDoFmt( format_string,
(APTR)args,
myputstr,
(APTR)&db ) ;
va_end(args) ;
}
static void ASM myputchar(
__REGD0(char car),
__REGA3(struct dbuffer *db)
)
{
db->data[db->len++] = car ;
}
int KSprintF(char *str, const char *format_string, ...)
{
va_list args ;
struct dbuffer db ;
db.len = 0 ;
db.data = str ;
va_start(args, format_string) ;
RawDoFmt( format_string,
(APTR)args,
myputchar,
(APTR)&db ) ;
va_end(args) ;
return (int)strlen(str) ;
}
Dans le registre A3 on peut mettre n’importe quoi.
Alors pourquoi pas un pointeur sur une structure contenant une longueur courante et un pointeur sur une chaine ?
On pourrait même envisager de faire passer un pointeur sur un descripteur de fichier… pour faire un équivalent de fprintf.
KPrintF fonctionne sur la pile (on peut aussi remplacer MAXCHAR 8 par 80, bof……) et sort directement dans un fichier, sans allouer quoi que ce soit!
KSprintF peut provoquer des dégats si on déborde, mais bon sprintf le fait aussi.
K&R vont m’envoyer des fleurs => pas une ligne d’assembleur!
Kékondit à Gillou ?
Merci Gilloo, je sais ce que c’est
Mais c’était surtout pour te faire la remarque que cette macro explicite un registre CPU donné pour une architecture donnée: soit de l’assembleur.
On appel cela de l’assembleur embarquée dans du code C.
Ce n’est pas parce que cela n’est pas un OP code ASM que ce n’est pas de l’assembleur. Par exemple en assembleur écrire: » .word 0x45; » n’exécute rien… pourtant c’est bien de l’assembleur, on dirige le compilo pour qu’il fasse qq chose de précis dans le code assembleur.
En C pure on indique pas les registres CPU
Yomgui a écrit :
Merci Gilloo, je sais ce que c’est
Mais c’était surtout pour te faire la remarque que cette macro explicite un registre CPU donné pour une architecture donnée: soit de l’assembleur.
On appel cela de l’assembleur embarquée dans du code C.
Ce n’est pas parce que cela n’est pas un OP code ASM que ce n’est pas de l’assembleur. Par exemple en assembleur écrire: » .word 0x45; » n’exécute rien… pourtant c’est bien de l’assembleur, on dirige le compilo pour qu’il fasse qq chose de précis dans le code assembleur.
En C pure on indique pas les registres CPU
Je ne vais pas me fâcher, pourtant y m’cherche le Yomgui.
Comme les registres sont spécifiques pour putchar, on ne fait pas ce que l’on veut: si tu les enlèves, ça plante et c’est normal.
On peut utiliser RawDoFmt sans cette daube de move.b D0,(A3)+; rts en ligne, pour éviter les printf, sprintf, fprintf du C standard, qui ne fonctionnent pas dans un « device » ou une « library ».
J’oubliais de signaler que RawDoFmt existe depuis la nuit des temps dans exec.library. Alors pourquoi s’en priver!
9 sujets de 1 à 9 (sur un total de 9)
- Vous devez être connecté pour répondre à ce sujet.
› Forums › AmigaOS, MorphOS et AROS › Développement › Mon sprintf à môa