Mon sprintf à môa

9 sujets de 1 à 9 (sur un total de 9)

  • Gilloo

      #5531

      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! :-D

      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!

      henes

        #92813

        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…

        Alex

          #92814

          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 ;

          }

          Gilloo

            #92815

            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 ?

            Yomgui

              #92816

              Kékondit à Gillou ?

              Bah que __REGxx() tu trouves que c’est du C ?

              Gilloo

                #92817

                Yomgui a écrit :

                Kékondit à Gillou ?

                Bah que __REGxx() tu trouves que c’est du C ?

                Ben oui, c’est du C à la sauce SAS.

                C’est une macro qui cache register __xx ;-)

                C’est déjà mieux que de l’assembleur en ligne, qui n’est pas compatible avec autre chose qu’un 680×0.

                Yomgui

                  #92818

                  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 ;-)

                  Gilloo

                    #92819

                    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. :-D

                    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! ;-)

                    Yomgui

                      #92820

                      Mais qu’est-ce que j’y peux moi qu’on trouve encore ce genre de mer** dans l’API AmigaOS ;-)

                      Forcer les registres comme ca c’est baaaaad ! :-P

                    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

                    Amiga Impact