/*************************************************************************************************************************************/ /* */ /* 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