Bon je pense avoir compris le problème du double CR.
Ce qu'il se passe: Je suis sous cygwin, et git effectue une conversion de fin de ligne dans la convention "Windows". Résultat: les fichiers ASM sous src/hw/ ont tous la convention windows "\r\n" pour les fin de lignes. Jusque là tout est bon.
Ensuite dans le makefile les règles comme
Code : Tout sélectionner
SOURCES_6809 := $(subst src/hw/6809/,src-generated/6809_,$(MODULES_6809:.asm=.c))
src-generated/6809_%.c: $(MODULES_6809)
@xxd -i $(subst src-generated/6809_,src/hw/6809/,$(@:.c=.asm)) >$@
convertissent, via "xxd", les fichiers ASM en tableau de caractères pour pouvoir être écrits "tels quels" dans les fichiers ASM:
Code : Tout sélectionner
unsigned char src_hw_ef936x_startup_asm[] = {
0x45, 0x46, 0x39, 0x33, 0x36, 0x58, 0x53, 0x54, 0x41, 0x52, 0x54, 0x55,
0x50, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x4c, 0x44, 0x58,
^^^^^^^^^^
(..snip..)
0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x52, 0x54, 0x53
};
unsigned int src_hw_ef936x_startup_asm_len = 225;
Bien évidemment on retrouve une trace du "\r\n" dans ce "dump" binaire des fichiers textes (regardez au dessus de ^^^^^).
Plus loin dans le code quand on doit écrire ces modules
Code : Tout sélectionner
ugbc/src/hw/ef936x.c: deploy( ef936xstartup, src_hw_ef936x_startup_asm );
on utilise ultimement la macro
Code : Tout sélectionner
#define outembedded0(e) \
{ \
fwrite( e, e##_len, 1, ((Environment *)_environment)->asmFile ); \
fputs( "\n", ((Environment *)_environment)->asmFile ); \
}
qui fait grosso-modo un fwrite() du tableau "en bloc".
Mais voilà que "asmFile" est un fichier ouvert en mode texte, et contrairement à ce qu'on croit, fwrite() effectue une conversion de ligne sur ce type de fichiers.
Résultat le "\n" final de "\r\n" est lui même sorti comme "\r\n", et ob obtient un joli (?) "\r\r\n" dans le fichier.
Je sais que c'est très surprenant. Je m'attendais que fwrite() fasse une écriture binaire, y compris sur les fichiers textes, jusqu'à ce que je fasse ceci sous cygwin;
Code : Tout sélectionner
$ cat tst.c
/* strictement le même fwrite() mais l'un sur un fichier "wb" et l'autre "wt" */
#include <stdio.h>
unsigned char tst[] = {13,10};
int main(void)
{
FILE *f;
f = fopen("tst.txt", "wt");
fwrite(tst, 2, 1, f);
fclose(f);
f = fopen("tst.bin", "wb");
fwrite(tst, 2, 1, f);
fclose(f);
return 0;
}
$ gcc tst.c -o tst
$ ./tst
$ xxd tst.bin
00000000: 0d0a .. # <== \r\n as expected
$ xxd tst.txt
00000000: 0d0d 0a ... # <== \r\r\n !!!!
On voit clairement que le fichier ouvert en "wt" (texte donc) fait 3 octets alors qu'on en a écrit 2 via fwrite(), et qu'en outre le "\r" y est dédoublé.
Donc voilà l'explication de l'apparition de ces "\r\r". Je ne sais pas si c'est un bug(*) de fwrite() ou si c'est juste un comportement inattendu sur un système ayant une notion de fichier texte.
Oui mais comment on contourne alors ?
Idéalement il faudrait dire à la bibliothèque C de ne pas interpréter les fins de ligne dans fwrite(). Je n'ai pas trouvé. Cependant si on défini outembedded0(e) comme suit:
Code : Tout sélectionner
#define outembedded0(e) \
{ \
int i; for(i = 0; i<e##_len; ++i) {int c = e[i]; if(c!='\r') {fputc(c, ((Environment *)_environment)->asmFile);}} \
fputs( "\n", ((Environment *)_environment)->asmFile ); \
}
(on saute au dessus des '\r', et ainsi '\n' peut être étendu par les routines fXXX() comme fputc() sans que cela ne pose de problème), alors j'obtiens un ugcb.mo5 qui marche
- Je note au passage que la fonte Thomson est remplacée par une fonte ressemblant à celle de l'AMSTRAD ;)
- dcmoto02.png (5.72 Kio) Consulté 3061 fois
___
(*) D'après "man fwrite" on est pas supposé l'utiliser sur autre chose que des fichiers binaires, et en outre, un échange d'il y a 18 ans sur cygwin reporte un soucis similaire:
https://cygwin.com/pipermail/cygwin/200 ... 93124.html, donc ce problème existe depuis quasiment toujours.