/*************************************************************************************************************************************/
/* */
/* D E C O U P A G E D E S L I G N E S T R O P L O N G U E S : */
/* */
/* */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * ** * * * * * ** * */
/* * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * */
/* * * * * ** * * * * * ** */
/* * * * * * * * * * * * * * * * * * * * * * * */
/* */
/* */
/* ATTENTION : */
/* */
/* Il est imperatif que le decoupage */
/* n'ait pas lieu sur l'un des caracteres */
/* contenus dans '$SeparateurListe_1' et */
/* dans '$SeparateurListe_2' (voir a ce */
/* propos 'v $xcc/cpp$Z SeparateurListe'). */
/* */
/* */
/* Author of '$xcp/decoupage$K' : */
/* */
/* Jean-Francois COLONNA (LACTAMME, 1988??????????). */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* I N T E R F A C E ' listG ' : */
/* */
/* */
/* :Debut_listG: */
/* :Fin_listG: */
/* */
/*************************************************************************************************************************************/
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D I R E C T I V E S S P E C I F I Q U E S D E C O M P I L A T I O N : */
/* */
/*************************************************************************************************************************************/
@define PRAGMA_CL_____PAS_DE_LIBRAIRIES_DYNAMIQUES
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* F I C H I E R S D ' I N C L U D E S : */
/* */
/*************************************************************************************************************************************/
#include INCLUDES_MINI
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* P A R A M E T R E S : */
/* */
/*************************************************************************************************************************************/
#define LONGUEUR_DE_DECOUPAGE \
NEUT(LONGUEUR_D_UNE_LIGNE_SOURCE) \
/* Longueur arbitraire de decoupage. Cette longueur a ete augmentee en passant de */ \
/* 'QUAD(...)' a 'NEUT(...)' afin de favoriser la passe de compactage eventuelle... */
#define MARQUER_LE_DECOUPAGE \
FAUX \
/* Faut-il introduire un marqueur de decoupage ? */
#define MARQUEUR_DE_DECOUPAGE \
K_DOLLAR \
/* A priori, on utilise le premier 'SUBSTITUT_DE_L_UNDERSCORE' (voir '$Z_UNDERSCORE'), car */ \
/* en effet il a en general ete substitue au prealable (voir 'PASSE_1' dans $xcc/cpp$Z)... */
#define DECOUPER_SUR_K_PLUS_ET_K_MOINS_ET_K_BLANC \
FAUX \
/* Faut-il decouper sur les operateurs arithmetiques "+" et "-", ainsi que sur " " ? */
#define DECOUPER_SUR_K_BLANC_SI_DECOUPER_SUR_K_PLUS_ET_K_MOINS_ET_K_BLANC \
VRAI \
/* Si 'IL_FAUT(decouper_sur_K_PLUS_et_K_MOINS_et_K_BLANC)', faut-il alors vraiment decouper */ \
/* sur " " ? */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* M A C R O S U T I L E S : */
/* */
/*************************************************************************************************************************************/
#define CHANGEMENT_DE_LIGNE \
Bblock \
CLIR(compteur_de_caracteres); \
/* Apres chaque 'LINE-FEED', on remet a zero le compte courant de caracteres. */ \
EGAL(on_vient_de_rencontrer_une_apostrophe,FAUX); \
EGAL(on_vient_de_rencontrer_une_quote,FAUX); \
/* Apres chaque 'LINE-FEED', on reinitialise les detecteurs de quotes et d'apostrophes. */ \
Eblock
#define NOUS_NE_SOMMES_PAS_DANS_UN_EXPOSANT_FLOTTANT \
IFET(IFNE(caractere_precedent,K_E),IFNE(caractere_precedent,K_e)) \
/* Procedure detectant si il y a une forte probabilite pour que l'on ne soit actuellement */ \
/* pas dans un exposant flottant ; quatre possibilites existent qui sont dangereuses : */ \
/* */ \
/* E+ */ \
/* e+ */ \
/* E- */ \
/* e- */ \
/* */ \
/* et qu'il faut donc eliminer du decoupage... */
/*===================================================================================================================================*/
/*************************************************************************************************************************************/
/* */
/* D E C O U P A G E D E S L I G N E S T R O P L O N G U E S : */
/* */
/*************************************************************************************************************************************/
BCommande(nombre_d_arguments,arguments)
/*-----------------------------------------------------------------------------------------------------------------------------------*/
Bblock
DEFV(Int,INIT(longueur_de_decoupage,LONGUEUR_DE_DECOUPAGE));
/* Longueur approximative des lignes a generer... */
DEFV(Logical,INIT(marquer_le_decoupage,MARQUER_LE_DECOUPAGE));
/* Faut-il introduire un marqueur de decoupage ? Ce dispositif permet donc de decouper */
/* un source pour permettre d'utiliser '$SE', puis ensuite de recoller ce qui a ete */
/* decoupe... */
DEFV(CHAR,INIT(marqueur_de_decoupage,MARQUEUR_DE_DECOUPAGE));
/* A priori, on utilise 'SUBSTITUT_DE_L_UNDERSCORE'... */
DEFV(Logical,INIT(decouper_sur_K_PLUS_et_K_MOINS_et_K_BLANC,DECOUPER_SUR_K_PLUS_ET_K_MOINS_ET_K_BLANC));
/* Faut-il decouper sur les operateurs arithmetiques "+" et "-", ainsi que sur " " ? */
DEFV(Logical,INIT(decouper_sur_K_BLANC_si_decouper_sur_K_PLUS_et_K_MOINS_et_K_BLANC
,DECOUPER_SUR_K_BLANC_SI_DECOUPER_SUR_K_PLUS_ET_K_MOINS_ET_K_BLANC
)
);
/* Si 'IL_FAUT(decouper_sur_K_PLUS_et_K_MOINS_et_K_BLANC)', faut-il alors vraiment decouper */
/* sur " " ? */
DEFV(Int,INIT(compteur_de_caracteres,ZERO));
/* Indique le nombre de caracteres rencontres depuis le dernier */
/* 'LINE-FEED' reel ou insere. */
DEFV(Char,INIT(caractere_precedent,K_UNDEF));
/* Caractere precedent. */
DEFV(Char,INIT(caractere_courant,K_UNDEF));
/* Caractere courant. */
DEFV(Logical,INIT(on_vient_de_rencontrer_une_apostrophe,FAUX));
/* Cet indicateur indique en permanence si l'on vient de rencontrer */
/* immediatement une apostrophe (') : */
/* */
/* VRAI : apres la premiere rencontree, */
/* FAUX : apres la seconde, */
/* */
/* cet indicateur fonctionnant en bascule, puisque les apostrophes forment */
/* des couples de parentheses... */
DEFV(Logical,INIT(on_vient_de_rencontrer_une_quote,FAUX));
/* Cet indicateur indique en permanence si l'on vient de rencontrer */
/* immediatement une quote (") : */
/* */
/* VRAI : apres la premiere rencontree, */
/* FAUX : apres la seconde, */
/* */
/* cet indicateur fonctionnant en bascule, puisque les quotes forment */
/* des couples de parentheses... */
/*..............................................................................................................................*/
GET_ARGUMENTS_(nombre_d_arguments
,BLOC(GET_ARGUMENT_I("longueur=""l=""L=",longueur_de_decoupage);
GET_ARGUMENT_L("marquer=",marquer_le_decoupage);
GET_ARGUMENT_K("marqueur=",marqueur_de_decoupage);
GET_ARGUMENT_L("pmb=",decouper_sur_K_PLUS_et_K_MOINS_et_K_BLANC);
GET_ARGUMENT_L("b=",decouper_sur_K_BLANC_si_decouper_sur_K_PLUS_et_K_MOINS_et_K_BLANC);
)
);
Tant(GetcharT(caractere_courant))
Bblock
/* Le caractere courant de l'entree courante est recupere ; et on boucle */
/* sur cette recuperation tant que l'on n'est pas au bout du fichier. */
DEFV(Logical,INIT(on_vient_de_decouper_la_ligne_courante,FAUX));
/* Cet indicateur introduit le 19970313172600 permet de ne pas transmetter un 'K_LF' */
/* qui suivrait immediatement un decoupage de la ligne. */
Test(IFET(IFEQ(caractere_courant,K_QUOTE),EST_FAUX(on_vient_de_rencontrer_une_apostrophe)))
Bblock
EGAL(on_vient_de_rencontrer_une_quote,NOTL(on_vient_de_rencontrer_une_quote));
/* On gere les quotes comme des parentheses... */
Eblock
ATes
Bblock
Eblock
ETes
Test(IFET(IFEQ(caractere_courant,K_APOSTROPHE),EST_FAUX(on_vient_de_rencontrer_une_quote)))
Bblock
EGAL(on_vient_de_rencontrer_une_apostrophe,NOTL(on_vient_de_rencontrer_une_apostrophe));
/* On gere les apostrophes comme des parentheses... */
Eblock
ATes
Bblock
Eblock
ETes
Test(IFEQ(caractere_courant,K_LF))
Bblock
CHANGEMENT_DE_LIGNE;
Eblock
ATes
Bblock
Test(IFOU(IFET(EST_FAUX(on_vient_de_rencontrer_une_apostrophe)
,EST_FAUX(on_vient_de_rencontrer_une_quote)
)
,IFOU(IFEQ(caractere_courant,K_QUOTE)
,IFEQ(caractere_courant,K_APOSTROPHE)
)
)
)
Bblock
INCR(compteur_de_caracteres,I);
/* Hors des "parentheses" constituees par les quotes et les apostrophes, */
/* on compte les caracteres rencontres. On notera qu'une hypothese */
/* simplificatrice est faite : ces pseudo-parentheses doivent etre */
/* logiquement imbriquees : "...", '...', "...'...'...", '..."..."...', */
/* les imbrications du type "...'..."...' donnant lieu a erreurs. */
Eblock
ATes
Bblock
Eblock
ETes
Eblock
ETes
Test(I3ET(IFNE(caractere_courant,K_LF)
,IFGE(compteur_de_caracteres,longueur_de_decoupage)
,IFET(IFET(EST_FAUX(on_vient_de_rencontrer_une_quote)
,EST_FAUX(on_vient_de_rencontrer_une_apostrophe)
)
,I3OU(IFOU(I3OU(IFEQ(caractere_courant,K_VIRGULE)
,IFEQ(caractere_courant,K_DEUX_POINTS)
,IFEQ(caractere_courant,K_INTERROGATION)
)
,IFEQ(caractere_courant,K_POINT_VIRGULE)
)
,IFET(IL_FAUT(decouper_sur_K_PLUS_et_K_MOINS_et_K_BLANC)
,I3OU(IFET(IFEQ(caractere_courant,K_PLUS)
,NOUS_NE_SOMMES_PAS_DANS_UN_EXPOSANT_FLOTTANT
)
,IFET(IFEQ(caractere_courant,K_MOINS)
,NOUS_NE_SOMMES_PAS_DANS_UN_EXPOSANT_FLOTTANT
)
,IFET(IFEQ(caractere_courant,K_BLANC)
,IL_FAUT(decouper_sur_K_BLANC_si_decouper_sur_K_PLUS_et_K_MOINS_et_K_BLANC)
)
)
)
,IFOU(IFEQ(caractere_courant,K_ETOILE)
,IFEQ(caractere_courant,K_SLASH)
)
)
)
)
)
/* Jusqu'a present, le decoupage se faisait uniquement sur 'K_PG' et 'K_VIRGULE' avec : */
/* */
/* ,IFOU(IFEQ(caractere_courant,K_PG) */
/* ,IFEQ(caractere_courant,K_VIRGULE) */
/* ) */
/* */
/* mais afin de traiter correctement le cas special des procedure du type 'Prerr', il est */
/* necessaire de ne pas toucher aux parentheses (droites ou gauche), ainsi qu'aux virgules */
/* (mais ATTENTION a ce qui suit...). Dorenavant, le decoupage se fera sur les operateurs */
/* arithmetiques. On notera que j'ai tente de decouper sur 'K_PD' et 'K_VIRGULE', mais que */
/* que cela a interfere malheureusement avec '$xcc/cpp$D/fARGUMENT$sed' qui assure le */
/* traitement differe de 'aFONCTION(...)'. Il est essentiel de conserver le decoupage sur */
/* 'K_VIRGULE', car en effet, il y a parfois des listes tres longues (voir les declarations */
/* de type 'Denum...(...)') que '$SE' tronquerait alors... */
/* */
/* ATTENTION : on supprime les operateurs 'K_PLUS' et 'K_MOINS' lorsqu'ils ont precedes de */
/* l'indicateur d'exposant de constante flottante ("E" ou "e") car les compilateurs n'aiment */
/* pas que l'on decoupe les constantes flottantes ; en effet, pour la plupart d'entre eux */
/* il y a alors ambiguite. Par exemple, l'ecriture : */
/* */
/* 3.14e -2 */
/* */
/* (ou il y a des espaces, ou un changement de ligne entre le "e" de l'exposant et sa */
/* valeur proprement dite) peut s'interpreter d'au moins deux facons : */
/* */
/* (3.14e-2) = 0.0314 */
/* (3.14e0)-(2) = 1.14 */
/* */
/* malheureusement, sauf pour certains compilateurs ('SYSTEME_VAX9000_ULTRIX_GCC', par */
/* exemple, dit "floating constant exponent has no digits"), c'est la derniere des deux */
/* interpretations qui l'emporte. */
/* */
/* ATTENTION, depuis l'introduction de '$PASSE_D', il a ete necessaire d'augmenter la */
/* "probabilite" de decoupage ; en effet, il subsistait alors des lignes trop longues qui se */
/* retrouvaient tronquees par les appels a '$SE'. C'est pourquoi, on decoupe aussi lors de */
/* la rencontre des "blancs"... */
/* */
/* Finalement, a cause de l'introduction de la derivation formelle d'ordre superieure a 1, */
/* il est devenu impossible de decouper selon 'K_PLUS', 'K_MOINS' et 'K_BLANC' lors de */
/* certaines passes de la compilation puisque les deux premiers caracteres ('K_PLUS' et */
/* 'K_MOINS') font partie du nom de l'operateur de derivation courant, et que le dernier */
/* ('K_BLANC') peut se trouver intercale en nombre quelconque dans ce meme nom ; c'est */
/* pourquoi l'option 'decouper_sur_K_PLUS_et_K_MOINS_et_K_BLANC' a ete introduite... */
Bblock
Test(IL_FAUT(marquer_le_decoupage))
Bblock
CALS(Putchar(marqueur_de_decoupage));
/* Lorsque cela est demande, le 'K_LF' est precede d'un marqueur, et ce afin de pouvoir, */
/* si besoin est, de l'annuler ensuite... */
Eblock
ATes
Bblock
Eblock
ETes
CALS(Putchar(K_LF));
/* On decoupe les lignes trop longues avant les vraies parentheses gauche '(' ; */
/* ainsi on ne risque pas de separer les sequences ')####' generees par */
/* '$xcp/cpp$X' pour montrer ou des fonctions servant d'arguments ont ete detectees, */
/* puisqu'alors, la liste d'arguments derriere elles est vide... */
EGAL(on_vient_de_decouper_la_ligne_courante,VRAI);
/* On memorise que l'on vient de decouper... */
CHANGEMENT_DE_LIGNE;
Eblock
ATes
Bblock
Eblock
ETes
Test(IFOU(IFNE(caractere_courant,K_LF)
,IFET(IFEQ(caractere_courant,K_LF),EST_FAUX(on_vient_de_decouper_la_ligne_courante))
)
)
Bblock
CALS(Putchar(caractere_courant));
/* Tous les caracteres sont integralement transmis, sauf les 'K_LF' qui suivraient */
/* immediatement un decoupage de ligne... */
Eblock
ATes
Bblock
Eblock
ETes
EGAL(on_vient_de_decouper_la_ligne_courante,FAUX);
/* Et on reinitialise le processus... */
EGAL(caractere_precedent,caractere_courant);
/* Changement de caractere precedent... */
Eblock
ETan
RETU_Commande;
Eblock
ECommande