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



Copyright © Jean-François COLONNA, 2019-2024.
Copyright © CMAP (Centre de Mathématiques APpliquées) UMR CNRS 7641 / École polytechnique, Institut Polytechnique de Paris, 2019-2024.